aboutsummaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/common/misc_helpers.lua57
-rw-r--r--builtin/common/serialize.lua11
-rw-r--r--builtin/common/strict.lua5
-rw-r--r--builtin/fstk/ui.lua71
-rw-r--r--builtin/game/auth.lua1
-rw-r--r--builtin/game/chatcommands.lua109
-rw-r--r--builtin/game/detached_inventory.lua1
-rw-r--r--builtin/game/item.lua61
-rw-r--r--builtin/game/item_entity.lua113
-rw-r--r--builtin/game/misc.lua90
-rw-r--r--builtin/game/register.lua73
-rw-r--r--builtin/mainmenu/common.lua79
-rw-r--r--builtin/mainmenu/init.lua7
-rw-r--r--builtin/mainmenu/modmgr.lua8
-rw-r--r--builtin/mainmenu/store.lua44
-rw-r--r--builtin/mainmenu/tab_credits.lua87
-rw-r--r--builtin/mainmenu/tab_mods.lua5
-rw-r--r--builtin/mainmenu/tab_multiplayer.lua5
-rw-r--r--builtin/mainmenu/tab_server.lua27
-rw-r--r--builtin/mainmenu/tab_settings.lua111
-rw-r--r--builtin/mainmenu/tab_simple_main.lua19
-rw-r--r--builtin/mainmenu/tab_singleplayer.lua40
-rw-r--r--builtin/mainmenu/tab_texturepacks.lua18
-rw-r--r--builtin/mainmenu/textures.lua31
24 files changed, 761 insertions, 312 deletions
diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua
index 39fca7d1e..bf672e6da 100644
--- a/builtin/common/misc_helpers.lua
+++ b/builtin/common/misc_helpers.lua
@@ -1,6 +1,11 @@
-- Minetest: builtin/misc_helpers.lua
--------------------------------------------------------------------------------
+-- Localize functions to avoid table lookups (better performance).
+local table_insert = table.insert
+local string_sub, string_find = string.sub, string.find
+
+--------------------------------------------------------------------------------
function basic_dump(o)
local tp = type(o)
if tp == "number" then
@@ -89,13 +94,13 @@ function dump2(o, name, dumped)
-- the form _G["table: 0xFFFFFFF"]
keyStr = string.format("_G[%q]", tostring(k))
-- Dump key table
- table.insert(t, dump2(k, keyStr, dumped))
+ table_insert(t, dump2(k, keyStr, dumped))
end
else
keyStr = basic_dump(k)
end
local vname = string.format("%s[%s]", name, keyStr)
- table.insert(t, dump2(v, vname, dumped))
+ table_insert(t, dump2(v, vname, dumped))
end
return string.format("%s = {}\n%s", name, table.concat(t))
end
@@ -130,7 +135,7 @@ function dump(o, indent, nested, level)
local t = {}
local dumped_indexes = {}
for i, v in ipairs(o) do
- table.insert(t, dump(v, indent, nested, level + 1))
+ table_insert(t, dump(v, indent, nested, level + 1))
dumped_indexes[i] = true
end
for k, v in pairs(o) do
@@ -139,7 +144,7 @@ function dump(o, indent, nested, level)
k = "["..dump(k, indent, nested, level + 1).."]"
end
v = dump(v, indent, nested, level + 1)
- table.insert(t, k.." = "..v)
+ table_insert(t, k.." = "..v)
end
end
nested[o] = nil
@@ -155,9 +160,6 @@ function dump(o, indent, nested, level)
end
--------------------------------------------------------------------------------
--- Localize functions to avoid table lookups (better performance).
-local table_insert = table.insert
-local str_sub, str_find = string.sub, string.find
function string.split(str, delim, include_empty, max_splits, sep_is_pattern)
delim = delim or ","
max_splits = max_splits or -1
@@ -166,13 +168,13 @@ function string.split(str, delim, include_empty, max_splits, sep_is_pattern)
local plain = not sep_is_pattern
max_splits = max_splits + 1
repeat
- local np, npe = str_find(str, delim, pos, plain)
+ local np, npe = string_find(str, delim, pos, plain)
np, npe = (np or (len+1)), (npe or (len+1))
if (not np) or (max_splits == 1) then
np = len + 1
npe = np
end
- local s = str_sub(str, pos, np - 1)
+ local s = string_sub(str, pos, np - 1)
if include_empty or (s ~= "") then
max_splits = max_splits - 1
table_insert(items, s)
@@ -183,9 +185,22 @@ function string.split(str, delim, include_empty, max_splits, sep_is_pattern)
end
--------------------------------------------------------------------------------
+function table.indexof(list, val)
+ for i = 1, #list do
+ if list[i] == val then
+ return i
+ end
+ end
+ return -1
+end
+
+assert(table.indexof({"foo", "bar"}, "foo") == 1)
+assert(table.indexof({"foo", "bar"}, "baz") == -1)
+
+--------------------------------------------------------------------------------
function file_exists(filename)
local f = io.open(filename, "r")
- if f==nil then
+ if f == nil then
return false
else
f:close()
@@ -298,8 +313,8 @@ function core.splittext(text,charlimit)
local current_idx = 1
- local start,stop = string.find(text," ",current_idx)
- local nl_start,nl_stop = string.find(text,"\n",current_idx)
+ local start,stop = string_find(text, " ", current_idx)
+ local nl_start,nl_stop = string_find(text, "\n", current_idx)
local gotnewline = false
if nl_start ~= nil and (start == nil or nl_start < start) then
start = nl_start
@@ -309,7 +324,7 @@ function core.splittext(text,charlimit)
local last_line = ""
while start ~= nil do
if string.len(last_line) + (stop-start) > charlimit then
- table.insert(retval,last_line)
+ table_insert(retval, last_line)
last_line = ""
end
@@ -317,17 +332,17 @@ function core.splittext(text,charlimit)
last_line = last_line .. " "
end
- last_line = last_line .. string.sub(text,current_idx,stop -1)
+ last_line = last_line .. string_sub(text, current_idx, stop - 1)
if gotnewline then
- table.insert(retval,last_line)
+ table_insert(retval, last_line)
last_line = ""
gotnewline = false
end
current_idx = stop+1
- start,stop = string.find(text," ",current_idx)
- nl_start,nl_stop = string.find(text,"\n",current_idx)
+ start,stop = string_find(text, " ", current_idx)
+ nl_start,nl_stop = string_find(text, "\n", current_idx)
if nl_start ~= nil and (start == nil or nl_start < start) then
start = nl_start
@@ -338,11 +353,11 @@ function core.splittext(text,charlimit)
--add last part of text
if string.len(last_line) + (string.len(text) - current_idx) > charlimit then
- table.insert(retval,last_line)
- table.insert(retval,string.sub(text,current_idx))
+ table_insert(retval, last_line)
+ table_insert(retval, string_sub(text, current_idx))
else
- last_line = last_line .. " " .. string.sub(text,current_idx)
- table.insert(retval,last_line)
+ last_line = last_line .. " " .. string_sub(text, current_idx)
+ table_insert(retval, last_line)
end
return retval
diff --git a/builtin/common/serialize.lua b/builtin/common/serialize.lua
index 24b2a12ee..90b8b2ad6 100644
--- a/builtin/common/serialize.lua
+++ b/builtin/common/serialize.lua
@@ -115,11 +115,20 @@ function core.serialize(x)
function dump_val(x)
local tp = type(x)
if x == nil then return "nil"
- elseif tp == "number" then return string.format("%d", x)
elseif tp == "string" then return string.format("%q", x)
elseif tp == "boolean" then return x and "true" or "false"
elseif tp == "function" then
return string.format("loadstring(%q)", string.dump(x))
+ elseif tp == "number" then
+ -- Serialize integers with string.format to prevent
+ -- scientific notation, which doesn't preserve
+ -- precision and breaks things like node position
+ -- hashes. Serialize floats normally.
+ if math.floor(x) == x then
+ return string.format("%d", x)
+ else
+ return tostring(x)
+ end
elseif tp == "table" then
local vals = {}
local idx_dumped = {}
diff --git a/builtin/common/strict.lua b/builtin/common/strict.lua
index c353bb913..c7b86461f 100644
--- a/builtin/common/strict.lua
+++ b/builtin/common/strict.lua
@@ -4,6 +4,11 @@
local WARN_INIT = false
+function core.global_exists(name)
+ return rawget(_G, name) ~= nil
+end
+
+
local function warn(message)
print(os.date("%H:%M:%S: WARNING: ")..message)
end
diff --git a/builtin/fstk/ui.lua b/builtin/fstk/ui.lua
index 708ea19cf..de8ae4d2c 100644
--- a/builtin/fstk/ui.lua
+++ b/builtin/fstk/ui.lua
@@ -23,7 +23,7 @@ ui.default = nil
function ui.add(child)
--TODO check child
ui.childlist[child.name] = child
-
+
return child.name
end
@@ -33,7 +33,7 @@ function ui.delete(child)
if ui.childlist[child.name] == nil then
return false
end
-
+
ui.childlist[child.name] = nil
return true
end
@@ -54,17 +54,52 @@ end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
+local function wordwrap_quickhack(str)
+ local res = ""
+ local ar = str:split("\n")
+ for i = 1, #ar do
+ local text = ar[i]
+ -- Hack to add word wrapping.
+ -- TODO: Add engine support for wrapping in formspecs
+ while #text > 80 do
+ if res ~= "" then
+ res = res .. ","
+ end
+ res = res .. core.formspec_escape(string.sub(text, 1, 79))
+ text = string.sub(text, 80, #text)
+ end
+ if res ~= "" then
+ res = res .. ","
+ end
+ res = res .. core.formspec_escape(text)
+ end
+ return res
+end
+
--------------------------------------------------------------------------------
function ui.update()
local formspec = ""
-- handle errors
- if gamedata ~= nil and gamedata.errormessage ~= nil then
- formspec = "size[12,3.2]" ..
- "textarea[1,1;10,2;;ERROR: " ..
- core.formspec_escape(gamedata.errormessage) ..
- ";]"..
- "button[4.5,2.5;3,0.5;btn_error_confirm;" .. fgettext("Ok") .. "]"
+ if gamedata ~= nil and gamedata.reconnect_requested then
+ formspec = wordwrap_quickhack(gamedata.errormessage or "")
+ formspec = "size[12,5]" ..
+ "label[0.5,0;" .. fgettext("The server has requested a reconnect:") ..
+ "]textlist[0.2,0.8;11.5,3.5;;" .. formspec ..
+ "]button[6,4.6;3,0.5;btn_reconnect_no;" .. fgettext("Main menu") .. "]" ..
+ "button[3,4.6;3,0.5;btn_reconnect_yes;" .. fgettext("Reconnect") .. "]"
+ elseif gamedata ~= nil and gamedata.errormessage ~= nil then
+ formspec = wordwrap_quickhack(gamedata.errormessage)
+ local error_title
+ if string.find(gamedata.errormessage, "ModError") then
+ error_title = fgettext("An error occured in a Lua script, such as a mod:")
+ else
+ error_title = fgettext("An error occured:")
+ end
+ formspec = "size[12,5]" ..
+ "label[0.5,0;" .. error_title ..
+ "]textlist[0.2,0.8;11.5,3.5;;" .. formspec ..
+ "]button[4.5,4.6;3,0.5;btn_error_confirm;" .. fgettext("Ok") .. "]"
else
local active_toplevel_ui_elements = 0
for key,value in pairs(ui.childlist) do
@@ -77,7 +112,7 @@ function ui.update()
end
end
end
-
+
-- no need to show addons if there ain't a toplevel element
if (active_toplevel_ui_elements > 0) then
for key,value in pairs(ui.childlist) do
@@ -106,13 +141,6 @@ end
--------------------------------------------------------------------------------
function ui.handle_buttons(fields)
-
- if fields["btn_error_confirm"] then
- gamedata.errormessage = nil
- update_menu()
- return
- end
-
for key,value in pairs(ui.childlist) do
local retval = value:handle_buttons(fields)
@@ -127,7 +155,7 @@ end
--------------------------------------------------------------------------------
function ui.handle_events(event)
-
+
for key,value in pairs(ui.childlist) do
if value.handle_events ~= nil then
@@ -146,8 +174,15 @@ end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
core.button_handler = function(fields)
- if fields["btn_error_confirm"] then
+ if fields["btn_reconnect_yes"] then
+ gamedata.reconnect_requested = false
+ gamedata.errormessage = nil
+ gamedata.do_reconnect = true
+ core.start()
+ return
+ elseif fields["btn_reconnect_no"] or fields["btn_error_confirm"] then
gamedata.errormessage = nil
+ gamedata.reconnect_requested = false
ui.update()
return
end
diff --git a/builtin/game/auth.lua b/builtin/game/auth.lua
index 93b009981..423eb3134 100644
--- a/builtin/game/auth.lua
+++ b/builtin/game/auth.lua
@@ -171,6 +171,7 @@ function core.register_authentication_handler(handler)
end
core.registered_auth_handler = handler
core.registered_auth_handler_modname = core.get_current_modname()
+ handler.mod_origin = core.registered_auth_handler_modname
end
function core.get_auth_handler()
diff --git a/builtin/game/chatcommands.lua b/builtin/game/chatcommands.lua
index 91b685fdf..5d317de4b 100644
--- a/builtin/game/chatcommands.lua
+++ b/builtin/game/chatcommands.lua
@@ -10,6 +10,7 @@ function core.register_chatcommand(cmd, def)
def.params = def.params or ""
def.description = def.description or ""
def.privs = def.privs or {}
+ def.mod_origin = core.get_current_modname() or "??"
core.chatcommands[cmd] = def
end
@@ -37,6 +38,7 @@ core.register_on_chat_message(function(name, message)
end
local has_privs, missing_privs = core.check_player_privs(name, cmd_def.privs)
if has_privs then
+ core.set_last_run_mod(cmd_def.mod_origin)
local success, message = cmd_def.func(name, param)
if message then
core.chat_send_player(name, message)
@@ -189,7 +191,7 @@ core.register_chatcommand("revoke", {
local revoke_privs = core.string_to_privs(revoke_priv_str)
local privs = core.get_player_privs(revoke_name)
for priv, _ in pairs(revoke_privs) do
- if priv ~= "interact" and priv ~= "shout" and priv ~= "interact_extra" and
+ if priv ~= "interact" and priv ~= "shout" and
not core.check_player_privs(name, {privs=true}) then
return false, "Your privileges are insufficient."
end
@@ -229,21 +231,28 @@ core.register_chatcommand("setpassword", {
if not toname then
return false, "Name field required"
end
- local actstr = "?"
+ local act_str_past = "?"
+ local act_str_pres = "?"
if not raw_password then
core.set_player_password(toname, "")
- actstr = "cleared"
+ act_str_past = "cleared"
+ act_str_pres = "clears"
else
core.set_player_password(toname,
core.get_password_hash(toname,
raw_password))
- actstr = "set"
+ act_str_past = "set"
+ act_str_pres = "sets"
end
if toname ~= name then
core.chat_send_player(toname, "Your password was "
- .. actstr .. " by " .. name)
+ .. act_str_past .. " by " .. name)
end
- return true, "Password of player \"" .. toname .. "\" " .. actstr
+
+ core.log("action", name .. " " .. act_str_pres
+ .. " password of " .. toname .. ".")
+
+ return true, "Password of player \"" .. toname .. "\" " .. act_str_past
end,
})
@@ -257,6 +266,9 @@ core.register_chatcommand("clearpassword", {
return false, "Name field required"
end
core.set_player_password(toname, '')
+
+ core.log("action", name .. " clears password of " .. toname .. ".")
+
return true, "Password of player \"" .. toname .. "\" cleared"
end,
})
@@ -308,7 +320,7 @@ core.register_chatcommand("teleport", {
teleportee:setpos(p)
return true, "Teleporting to "..core.pos_to_string(p)
end
-
+
local teleportee = nil
local p = nil
local target_name = nil
@@ -345,7 +357,7 @@ core.register_chatcommand("teleport", {
return true, "Teleporting " .. teleportee_name
.. " to " .. core.pos_to_string(p)
end
-
+
local teleportee = nil
local p = nil
local teleportee_name = nil
@@ -367,7 +379,7 @@ core.register_chatcommand("teleport", {
.. " to " .. target_name
.. " at " .. core.pos_to_string(p)
end
-
+
return false, 'Invalid parameters ("' .. param
.. '") or player not found (see /help teleport)'
end,
@@ -404,13 +416,14 @@ core.register_chatcommand("set", {
})
core.register_chatcommand("deleteblocks", {
- params = "[here] [<pos1> <pos2>]",
+ params = "(here [radius]) | (<pos1> <pos2>)",
description = "delete map blocks contained in area pos1 to pos2",
privs = {server=true},
func = function(name, param)
local p1 = {}
local p2 = {}
- if param == "here" then
+ local args = param:split(" ")
+ if args[1] == "here" then
local player = core.get_player_by_name(name)
if player == nil then
core.log("error", "player is nil")
@@ -418,6 +431,12 @@ core.register_chatcommand("deleteblocks", {
end
p1 = player:getpos()
p2 = p1
+
+ if #args >= 2 then
+ local radius = tonumber(args[2]) or 0
+ p1 = vector.add(p1, radius)
+ p2 = vector.subtract(p2, radius)
+ end
else
local pos1, pos2 = unpack(param:split(") ("))
if pos1 == nil or pos2 == nil then
@@ -513,22 +532,29 @@ core.register_chatcommand("giveme", {
})
core.register_chatcommand("spawnentity", {
- params = "<EntityName>",
- description = "Spawn entity at your position",
+ params = "<EntityName> [<X>,<Y>,<Z>]",
+ description = "Spawn entity at given (or your) position",
privs = {give=true, interact=true},
func = function(name, param)
- local entityname = string.match(param, "(.+)$")
+ local entityname, p = string.match(param, "^([^ ]+) *(.*)$")
if not entityname then
return false, "EntityName required"
end
- core.log("action", ("/spawnentity invoked, entityname=%q")
- :format(entityname))
+ core.log("action", ("%s invokes /spawnentity, entityname=%q")
+ :format(name, entityname))
local player = core.get_player_by_name(name)
if player == nil then
core.log("error", "Unable to spawn entity, player is nil")
return false, "Unable to spawn entity, player is nil"
end
- local p = player:getpos()
+ if p == "" then
+ p = player:getpos()
+ else
+ p = core.string_to_pos(p)
+ if p == nil then
+ return false, "Invalid parameters ('" .. param .. "')"
+ end
+ end
p.y = p.y + 1
core.add_entity(p, entityname)
return true, ("%q spawned."):format(entityname)
@@ -662,19 +688,41 @@ core.register_chatcommand("status", {
})
core.register_chatcommand("time", {
- params = "<0...24000>",
+ params = "<0..23>:<0..59> | <0..24000>",
description = "set time of day",
- privs = {settime=true},
+ privs = {},
func = function(name, param)
if param == "" then
- return false, "Missing time."
- end
- local newtime = tonumber(param)
- if newtime == nil then
- return false, "Invalid time."
- end
- core.set_timeofday((newtime % 24000) / 24000)
- core.log("action", name .. " sets time " .. newtime)
+ local current_time = math.floor(core.get_timeofday() * 1440)
+ local minutes = current_time % 60
+ local hour = (current_time - minutes) / 60
+ return true, ("Current time is %d:%02d"):format(hour, minutes)
+ end
+ local player_privs = minetest.get_player_privs(name)
+ if not player_privs.settime then
+ return false, "You don't have permission to run this command " ..
+ "(missing privilege: settime)."
+ end
+ local hour, minute = param:match("^(%d+):(%d+)$")
+ if not hour then
+ local new_time = tonumber(param)
+ if not new_time then
+ return false, "Invalid time."
+ end
+ -- Backward compatibility.
+ core.set_timeofday((new_time % 24000) / 24000)
+ core.log("action", name .. " sets time to " .. new_time)
+ return true, "Time of day changed."
+ end
+ hour = tonumber(hour)
+ minute = tonumber(minute)
+ if hour < 0 or hour > 23 then
+ return false, "Invalid hour (must be between 0 and 23 inclusive)."
+ elseif minute < 0 or minute > 59 then
+ return false, "Invalid minute (must be between 0 and 59 inclusive)."
+ end
+ core.set_timeofday((hour * 60 + minute) / 1440)
+ core.log("action", ("%s sets time to %d:%02d"):format(name, hour, minute))
return true, "Time of day changed."
end,
})
@@ -732,7 +780,11 @@ core.register_chatcommand("kick", {
if not core.kick_player(tokick, reason) then
return false, "Failed to kick player " .. tokick
end
- core.log("action", name .. " kicked " .. tokick)
+ local log_reason = ""
+ if reason then
+ log_reason = " with reason \"" .. reason .. "\""
+ end
+ core.log("action", name .. " kicks " .. tokick .. log_reason)
return true, "Kicked " .. tokick
end,
})
@@ -788,4 +840,3 @@ core.register_chatcommand("last-login", {
return false, "Last login time is unknown"
end,
})
-
diff --git a/builtin/game/detached_inventory.lua b/builtin/game/detached_inventory.lua
index e8f03b56c..b5d106b04 100644
--- a/builtin/game/detached_inventory.lua
+++ b/builtin/game/detached_inventory.lua
@@ -13,6 +13,7 @@ function core.create_detached_inventory(name, callbacks)
stuff.on_put = callbacks.on_put
stuff.on_take = callbacks.on_take
end
+ stuff.mod_origin = core.get_current_modname() or "??"
core.detached_inventories[name] = stuff
return core.create_detached_inventory_raw(name)
end
diff --git a/builtin/game/item.lua b/builtin/game/item.lua
index e136d4f4c..6628a4081 100644
--- a/builtin/game/item.lua
+++ b/builtin/game/item.lua
@@ -106,7 +106,7 @@ function core.facedir_to_dir(facedir)
{x=0, y=1, z=0}})
--indexed into by a table of correlating facedirs
- [({[0]=1, 2, 3, 4,
+ [({[0]=1, 2, 3, 4,
5, 2, 6, 4,
6, 2, 5, 4,
1, 5, 3, 6,
@@ -238,7 +238,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
core.log("action", placer:get_player_name() .. " 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}
@@ -357,19 +357,37 @@ function core.item_drop(itemstack, dropper, pos)
return itemstack
end
-function core.item_eat(hp_change, replace_with_item)
- return function(itemstack, user, pointed_thing) -- closure
- for _, callback in pairs(core.registered_on_item_eats) do
- local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing)
- if result then
- return result
- end
+function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing)
+ for _, callback in pairs(core.registered_on_item_eats) do
+ local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing)
+ if result then
+ return result
end
- if itemstack:take_item() ~= nil then
- user:set_hp(user:get_hp() + hp_change)
- itemstack:add_item(replace_with_item) -- note: replace_with_item is optional
+ end
+ if itemstack:take_item() ~= nil then
+ user:set_hp(user:get_hp() + hp_change)
+
+ if replace_with_item then
+ if itemstack:is_empty() then
+ itemstack:add_item(replace_with_item)
+ else
+ local inv = user:get_inventory()
+ if inv:room_for_item("main", {name=replace_with_item}) then
+ inv:add_item("main", replace_with_item)
+ else
+ local pos = user:getpos()
+ pos.y = math.floor(pos.y + 0.5)
+ core.add_item(pos, replace_with_item)
+ end
+ end
end
- return itemstack
+ end
+ return itemstack
+end
+
+function core.item_eat(hp_change, replace_with_item)
+ return function(itemstack, user, pointed_thing) -- closure
+ return core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing)
end
end
@@ -425,7 +443,7 @@ function core.node_dig(pos, node, digger)
local wielded = digger:get_wielded_item()
local drops = core.get_node_drops(node.name, wielded:get_name())
-
+
local wdef = wielded:get_definition()
local tp = wielded:get_tool_capabilities()
local dp = core.get_dig_params(def.groups, tp)
@@ -438,7 +456,7 @@ function core.node_dig(pos, node, digger)
end
end
digger:set_wielded_item(wielded)
-
+
-- Handle drops
core.handle_node_drops(pos, drops, digger)
@@ -449,7 +467,7 @@ function core.node_dig(pos, node, digger)
-- Remove node and update
core.remove_node(pos)
-
+
-- Run callback
if def.after_dig_node then
-- Copy pos and node because callback can modify them
@@ -461,6 +479,15 @@ function core.node_dig(pos, node, digger)
-- Run script hook
local _, callback
for _, callback in ipairs(core.registered_on_dignodes) do
+ local origin = core.callback_origins[callback]
+ if origin then
+ core.set_last_run_mod(origin.mod)
+ --print("Running " .. tostring(callback) ..
+ -- " (a " .. origin.name .. " callback in " .. origin.mod .. ")")
+ else
+ --print("No data associated with callback")
+ end
+
-- Copy pos and node because callback can modify them
local pos_copy = {x=pos.x, y=pos.y, z=pos.z}
local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
@@ -507,7 +534,7 @@ core.nodedef_default = {
on_dig = redef_wrapper(core, 'node_dig'), -- core.node_dig
on_receive_fields = nil,
-
+
on_metadata_inventory_move = core.node_metadata_inventory_move_allow_all,
on_metadata_inventory_offer = core.node_metadata_inventory_offer_allow_all,
on_metadata_inventory_take = core.node_metadata_inventory_take_allow_all,
diff --git a/builtin/game/item_entity.lua b/builtin/game/item_entity.lua
index d6781feca..6425a10aa 100644
--- a/builtin/game/item_entity.lua
+++ b/builtin/game/item_entity.lua
@@ -96,6 +96,56 @@ core.register_entity(":__builtin:item", {
self:set_item(self.itemstring)
end,
+ try_merge_with = function(self, own_stack, object, obj)
+ local stack = ItemStack(obj.itemstring)
+ if own_stack:get_name() == stack:get_name() and stack:get_free_space() > 0 then
+ local overflow = false
+ local count = stack:get_count() + own_stack:get_count()
+ local max_count = stack:get_stack_max()
+ if count > max_count then
+ overflow = true
+ count = count - max_count
+ else
+ self.itemstring = ''
+ end
+ local pos = object:getpos()
+ pos.y = pos.y + (count - stack:get_count()) / max_count * 0.15
+ object:moveto(pos, false)
+ local s, c
+ local max_count = stack:get_stack_max()
+ local name = stack:get_name()
+ if not overflow then
+ obj.itemstring = name .. " " .. count
+ s = 0.2 + 0.1 * (count / max_count)
+ c = s
+ object:set_properties({
+ visual_size = {x = s, y = s},
+ collisionbox = {-c, -c, -c, c, c, c}
+ })
+ self.object:remove()
+ -- merging succeeded
+ return true
+ else
+ s = 0.4
+ c = 0.3
+ object:set_properties({
+ visual_size = {x = s, y = s},
+ collisionbox = {-c, -c, -c, c, c, c}
+ })
+ obj.itemstring = name .. " " .. max_count
+ s = 0.2 + 0.1 * (count / max_count)
+ c = s
+ self.object:set_properties({
+ visual_size = {x = s, y = s},
+ collisionbox = {-c, -c, -c, c, c, c}
+ })
+ self.itemstring = name .. " " .. count
+ end
+ end
+ -- merging didn't succeed
+ return false
+ end,
+
on_step = function(self, dtime)
self.age = self.age + dtime
if time_to_live > 0 and self.age > time_to_live then
@@ -105,58 +155,29 @@ core.register_entity(":__builtin:item", {
end
local p = self.object:getpos()
p.y = p.y - 0.5
- local nn = core.get_node(p).name
+ local node = core.get_node_or_nil(p)
+ local in_unloaded = (node == nil)
+ if in_unloaded then
+ -- Don't infinetly fall into unloaded map
+ self.object:setvelocity({x = 0, y = 0, z = 0})
+ self.object:setacceleration({x = 0, y = 0, z = 0})
+ self.physical_state = false
+ self.object:set_properties({physical = false})
+ return
+ end
+ local nn = node.name
-- If node is not registered or node is walkably solid and resting on nodebox
local v = self.object:getvelocity()
if not core.registered_nodes[nn] or core.registered_nodes[nn].walkable and v.y == 0 then
if self.physical_state then
local own_stack = ItemStack(self.object:get_luaentity().itemstring)
- for _,object in ipairs(core.get_objects_inside_radius(p, 0.8)) do
+ -- Merge with close entities of the same item
+ for _, object in ipairs(core.get_objects_inside_radius(p, 0.8)) do
local obj = object:get_luaentity()
- if obj and obj.name == "__builtin:item" and obj.physical_state == false then
- local stack = ItemStack(obj.itemstring)
- if own_stack:get_name() == stack:get_name() and stack:get_free_space() > 0 then
- local overflow = false
- local count = stack:get_count() + own_stack:get_count()
- local max_count = stack:get_stack_max()
- if count>max_count then
- overflow = true
- count = count - max_count
- else
- self.itemstring = ''
- end
- local pos=object:getpos()
- pos.y = pos.y + (count - stack:get_count()) / max_count * 0.15
- object:moveto(pos, false)
- local s, c
- local max_count = stack:get_stack_max()
- local name = stack:get_name()
- if not overflow then
- obj.itemstring = name.." "..count
- s = 0.2 + 0.1 * (count / max_count)
- c = s
- object:set_properties({
- visual_size = {x = s, y = s},
- collisionbox = {-c, -c, -c, c, c, c}
- })
- self.object:remove()
- return
- else
- s = 0.4
- c = 0.3
- object:set_properties({
- visual_size = {x = s, y = s},
- collisionbox = {-c, -c, -c, c, c, c}
- })
- obj.itemstring = name.." "..max_count
- s = 0.2 + 0.1 * (count / max_count)
- c = s
- self.object:set_properties({
- visual_size = {x = s, y = s},
- collisionbox = {-c, -c, -c, c, c, c}
- })
- self.itemstring = name.." "..count
- end
+ if obj and obj.name == "__builtin:item"
+ and obj.physical_state == false then
+ if self:try_merge_with(own_stack, object, obj) then
+ return
end
end
end
diff --git a/builtin/game/misc.lua b/builtin/game/misc.lua
index c31df541d..e3b7d82bc 100644
--- a/builtin/game/misc.lua
+++ b/builtin/game/misc.lua
@@ -4,40 +4,83 @@
-- Misc. API functions
--
-core.timers_to_add = {}
-core.timers = {}
-core.register_globalstep(function(dtime)
- for _, timer in ipairs(core.timers_to_add) do
- table.insert(core.timers, timer)
- end
- core.timers_to_add = {}
- local index = 1
- while index <= #core.timers do
- local timer = core.timers[index]
- timer.time = timer.time - dtime
+local timers = {}
+local mintime
+local function update_timers(delay)
+ mintime = false
+ local sub = 0
+ for index = 1, #timers do
+ index = index - sub
+ local timer = timers[index]
+ timer.time = timer.time - delay
if timer.time <= 0 then
+ core.set_last_run_mod(timer.mod_origin)
timer.func(unpack(timer.args or {}))
- table.remove(core.timers,index)
+ table.remove(timers, index)
+ sub = sub + 1
+ elseif mintime then
+ mintime = math.min(mintime, timer.time)
else
- index = index + 1
+ mintime = timer.time
end
end
+end
+
+local timers_to_add
+local function add_timers()
+ for _, timer in ipairs(timers_to_add) do
+ table.insert(timers, timer)
+ end
+ timers_to_add = false
+end
+
+local delay = 0
+core.register_globalstep(function(dtime)
+ if not mintime then
+ -- abort if no timers are running
+ return
+ end
+ if timers_to_add then
+ add_timers()
+ end
+ delay = delay + dtime
+ if delay < mintime then
+ return
+ end
+ update_timers(delay)
+ delay = 0
end)
function core.after(time, func, ...)
assert(tonumber(time) and type(func) == "function",
"Invalid core.after invocation")
- table.insert(core.timers_to_add, {time=time, func=func, args={...}})
+ if not mintime then
+ mintime = time
+ timers_to_add = {{
+ time = time+delay,
+ func = func,
+ args = {...},
+ mod_origin = core.get_last_run_mod(),
+ }}
+ return
+ end
+ mintime = math.min(mintime, time)
+ timers_to_add = timers_to_add or {}
+ timers_to_add[#timers_to_add+1] = {
+ time = time+delay,
+ func = func,
+ args = {...},
+ mod_origin = core.get_last_run_mod(),
+ }
end
function core.check_player_privs(name, privs)
local player_privs = core.get_player_privs(name)
local missing_privileges = {}
for priv, val in pairs(privs) do
- if val then
- if not player_privs[priv] then
- table.insert(missing_privileges, priv)
- end
+ if val
+ and not player_privs[priv] then
+ table.insert(missing_privileges, priv)
end
end
if #missing_privileges > 0 then
@@ -112,3 +155,14 @@ function core.record_protection_violation(pos, name)
end
end
+local raillike_ids = {}
+local raillike_cur_id = 0
+function core.raillike_group(name)
+ local id = raillike_ids[name]
+ if not id then
+ raillike_cur_id = raillike_cur_id + 1
+ raillike_ids[name] = raillike_cur_id
+ id = raillike_cur_id
+ end
+ return id
+end
diff --git a/builtin/game/register.lua b/builtin/game/register.lua
index f286113ec..d0e04bfc3 100644
--- a/builtin/game/register.lua
+++ b/builtin/game/register.lua
@@ -72,6 +72,7 @@ end
function core.register_abm(spec)
-- Add to core.registered_abms
core.registered_abms[#core.registered_abms+1] = spec
+ spec.mod_origin = core.get_current_modname() or "??"
end
function core.register_entity(name, prototype)
@@ -86,6 +87,7 @@ function core.register_entity(name, prototype)
-- Add to core.registered_entities
core.registered_entities[name] = prototype
+ prototype.mod_origin = core.get_current_modname() or "??"
end
function core.register_item(name, itemdef)
@@ -147,6 +149,8 @@ function core.register_item(name, itemdef)
end
-- END Legacy stuff
+ itemdef.mod_origin = core.get_current_modname() or "??"
+
-- Disable all further modifications
getmetatable(itemdef).__newindex = {}
@@ -326,6 +330,8 @@ function core.override_item(name, redefinition)
end
+core.callback_origins = {}
+
function core.run_callbacks(callbacks, mode, ...)
assert(type(callbacks) == "table")
local cb_len = #callbacks
@@ -338,6 +344,14 @@ function core.run_callbacks(callbacks, mode, ...)
end
local ret = nil
for i = 1, cb_len do
+ local origin = core.callback_origins[callbacks[i]]
+ if origin then
+ core.set_last_run_mod(origin.mod)
+ --print("Running " .. tostring(callbacks[i]) ..
+ -- " (a " .. origin.name .. " callback in " .. origin.mod .. ")")
+ else
+ --print("No data associated with callback")
+ end
local cb_ret = callbacks[i](...)
if mode == 0 and i == 1 then
@@ -370,13 +384,29 @@ end
local function make_registration()
local t = {}
- local registerfunc = function(func) table.insert(t, func) end
+ local registerfunc = function(func)
+ table.insert(t, func)
+ core.callback_origins[func] = {
+ mod = core.get_current_modname() or "??",
+ name = debug.getinfo(1, "n").name or "??"
+ }
+ --local origin = core.callback_origins[func]
+ --print(origin.name .. ": " .. origin.mod .. " registering cbk " .. tostring(func))
+ end
return t, registerfunc
end
local function make_registration_reverse()
local t = {}
- local registerfunc = function(func) table.insert(t, 1, func) end
+ local registerfunc = function(func)
+ table.insert(t, 1, func)
+ core.callback_origins[func] = {
+ mod = core.get_current_modname() or "??",
+ name = debug.getinfo(1, "n").name or "??"
+ }
+ --local origin = core.callback_origins[func]
+ --print(origin.name .. ": " .. origin.mod .. " registering cbk " .. tostring(func))
+ end
return t, registerfunc
end
@@ -398,13 +428,49 @@ local function make_registration_wrap(reg_fn_name, clear_fn_name)
local orig_clear_fn = core[clear_fn_name]
core[clear_fn_name] = function()
- list = {}
+ for k in pairs(list) do
+ list[k] = nil
+ end
return orig_clear_fn()
end
return list
end
+core.registered_on_player_hpchanges = { modifiers = { }, loggers = { } }
+
+function core.registered_on_player_hpchange(player, hp_change)
+ local last = false
+ for i = #core.registered_on_player_hpchanges.modifiers, 1, -1 do
+ local func = core.registered_on_player_hpchanges.modifiers[i]
+ hp_change, last = func(player, hp_change)
+ if type(hp_change) ~= "number" then
+ local debuginfo = debug.getinfo(func)
+ error("The register_on_hp_changes function has to return a number at " ..
+ debuginfo.short_src .. " line " .. debuginfo.linedefined)
+ end
+ if last then
+ break
+ end
+ end
+ for i, func in ipairs(core.registered_on_player_hpchanges.loggers) do
+ func(player, hp_change)
+ end
+ return hp_change
+end
+
+function core.register_on_player_hpchange(func, modifier)
+ if modifier then
+ table.insert(core.registered_on_player_hpchanges.modifiers, func)
+ else
+ table.insert(core.registered_on_player_hpchanges.loggers, func)
+ end
+ core.callback_origins[func] = {
+ mod = core.get_current_modname() or "??",
+ name = debug.getinfo(1, "n").name or "??"
+ }
+end
+
core.registered_biomes = make_registration_wrap("register_biome", "clear_registered_biomes")
core.registered_ores = make_registration_wrap("register_ore", "clear_registered_ores")
core.registered_decorations = make_registration_wrap("register_decoration", "clear_registered_decorations")
@@ -429,6 +495,7 @@ core.registered_on_crafts, core.register_on_craft = make_registration()
core.registered_craft_predicts, core.register_craft_predict = make_registration()
core.registered_on_protection_violation, core.register_on_protection_violation = make_registration()
core.registered_on_item_eats, core.register_on_item_eat = make_registration()
+core.registered_on_punchplayers, core.register_on_punchplayer = make_registration()
--
-- Compatibility for on_mapgen_init()
diff --git a/builtin/mainmenu/common.lua b/builtin/mainmenu/common.lua
index f32d77f2a..6266d0220 100644
--- a/builtin/mainmenu/common.lua
+++ b/builtin/mainmenu/common.lua
@@ -40,6 +40,18 @@ local function render_client_count(n)
end
end
+local function configure_selected_world_params(idx)
+ local worldconfig = modmgr.get_worldconfig(
+ menudata.worldlist:get_list()[idx].path)
+
+ if worldconfig.creative_mode ~= nil then
+ core.setting_set("creative_mode", worldconfig.creative_mode)
+ end
+ if worldconfig.enable_damage ~= nil then
+ core.setting_set("enable_damage", worldconfig.enable_damage)
+ end
+end
+
--------------------------------------------------------------------------------
function image_column(tooltip, flagname)
return "image," ..
@@ -189,7 +201,6 @@ end
--------------------------------------------------------------------------------
function menu_handle_key_up_down(fields,textlist,settingname)
-
if fields["key_up"] then
local oldidx = core.get_textlist_index(textlist)
@@ -197,6 +208,8 @@ function menu_handle_key_up_down(fields,textlist,settingname)
local newidx = oldidx -1
core.setting_set(settingname,
menudata.worldlist:get_raw_index(newidx))
+
+ configure_selected_world_params(newidx)
end
return true
end
@@ -208,18 +221,26 @@ function menu_handle_key_up_down(fields,textlist,settingname)
local newidx = oldidx + 1
core.setting_set(settingname,
menudata.worldlist:get_raw_index(newidx))
+
+ configure_selected_world_params(newidx)
end
-
+
return true
end
-
+
return false
end
--------------------------------------------------------------------------------
function asyncOnlineFavourites()
- menudata.favorites = {}
+ if not menudata.public_known then
+ menudata.public_known = {{
+ name = fgettext("Loading..."),
+ description = fgettext_ne("Try reenabling public serverlist and check your internet connection.")
+ }}
+ end
+ menudata.favorites = menudata.public_known
core.handle_async(
function(param)
return core.get_favorites("online")
@@ -227,32 +248,36 @@ function asyncOnlineFavourites()
nil,
function(result)
if core.setting_getbool("public_serverlist") then
- menudata.favorites = order_favorite_list(result)
+ local favs = order_favorite_list(result)
+ if favs[1] then
+ menudata.public_known = favs
+ menudata.favorites = menudata.public_known
+ end
core.event_handler("Refresh")
end
end
- )
+ )
end
--------------------------------------------------------------------------------
function text2textlist(xpos,ypos,width,height,tl_name,textlen,text,transparency)
local textlines = core.splittext(text,textlen)
-
+
local retval = "textlist[" .. xpos .. "," .. ypos .. ";"
.. width .. "," .. height .. ";"
.. tl_name .. ";"
-
+
for i=1, #textlines, 1 do
textlines[i] = textlines[i]:gsub("\r","")
retval = retval .. core.formspec_escape(textlines[i]) .. ","
end
-
+
retval = retval .. ";0;"
-
+
if transparency then
retval = retval .. "true"
end
-
+
retval = retval .. "]"
return retval
@@ -275,3 +300,35 @@ function is_server_protocol_compat_or_error(proto_min, proto_max)
return true
end
+--------------------------------------------------------------------------------
+function menu_worldmt(selected, setting, value)
+ local world = menudata.worldlist:get_list()[selected]
+ if world then
+ local filename = world.path .. DIR_DELIM .. "world.mt"
+ local world_conf = Settings(filename)
+
+ if value ~= nil then
+ if not world_conf:write() then
+ core.log("error", "Failed to write world config file")
+ end
+ world_conf:set(setting, value)
+ world_conf:write()
+ else
+ return world_conf:get(setting)
+ end
+ else
+ return nil
+ end
+end
+
+function menu_worldmt_legacy(selected)
+ local modes_names = {"creative_mode", "enable_damage", "server_announce"}
+ for _, mode_name in pairs(modes_names) do
+ local mode_val = menu_worldmt(selected, mode_name)
+ if mode_val ~= nil then
+ core.setting_set(mode_name, mode_val)
+ else
+ menu_worldmt(selected, mode_name, core.setting_get(mode_name))
+ end
+ end
+end
diff --git a/builtin/mainmenu/init.lua b/builtin/mainmenu/init.lua
index d008ec8b0..176796bef 100644
--- a/builtin/mainmenu/init.lua
+++ b/builtin/mainmenu/init.lua
@@ -139,11 +139,8 @@ local function init_globals()
tv_main:add(tab_credits)
tv_main:set_global_event_handler(main_event_handler)
- if PLATFORM ~= "Android" then
- tv_main:set_fixed_size(true)
- else
- tv_main:set_fixed_size(false)
- end
+
+ tv_main:set_fixed_size(false)
if not (PLATFORM == "Android") then
tv_main:set_tab(core.setting_get("maintab_LAST"))
diff --git a/builtin/mainmenu/modmgr.lua b/builtin/mainmenu/modmgr.lua
index f2938685e..89292ed52 100644
--- a/builtin/mainmenu/modmgr.lua
+++ b/builtin/mainmenu/modmgr.lua
@@ -17,7 +17,7 @@
--------------------------------------------------------------------------------
function get_mods(path,retval,modpack)
- local mods = core.get_dirlist(path, true)
+ local mods = core.get_dir_list(path, true)
for i=1, #mods, 1 do
if mods[i]:sub(1,1) ~= "." then
@@ -94,7 +94,7 @@ function modmgr.getbasefolder(temppath)
}
end
- local subdirs = core.get_dirlist(temppath,true)
+ local subdirs = core.get_dir_list(temppath, true)
--only single mod or modpack allowed
if #subdirs ~= 1 then
@@ -321,8 +321,10 @@ function modmgr.get_worldconfig(worldpath)
for key,value in pairs(worldfile:to_table()) do
if key == "gameid" then
worldconfig.id = value
- else
+ elseif key:sub(0, 9) == "load_mod_" then
worldconfig.global_mods[key] = core.is_yes(value)
+ else
+ worldconfig[key] = value
end
end
diff --git a/builtin/mainmenu/store.lua b/builtin/mainmenu/store.lua
index 999125d6e..ad861082d 100644
--- a/builtin/mainmenu/store.lua
+++ b/builtin/mainmenu/store.lua
@@ -122,35 +122,36 @@ end
function modstore.showdownloading(title)
local new_dlg = dialog_create("store_downloading",
function(data)
- return "size[6,2]label[0.25,0.75;" .. fgettext("Downloading") ..
- " " .. data.title .. " " ..
- fgettext("please wait...") .. "]"
+ return "size[6,2]label[0.25,0.75;" ..
+ fgettext("Downloading $1, please wait...", data.title) .. "]"
end,
function(this,fields)
if fields["btn_hidden_close_download"] ~= nil then
if fields["btn_hidden_close_download"].successfull then
modstore.lastmodentry = fields["btn_hidden_close_download"]
- modstore.successfulldialog()
+ modstore.successfulldialog(this)
else
+ this.parent:show()
+ this:delete()
modstore.lastmodtitle = ""
end
- this:delete()
return true
end
return false
end,
- nil,
- modstore.tv_store)
+ nil)
+ new_dlg:set_parent(modstore.tv_store)
+ modstore.tv_store:hide()
new_dlg.data.title = title
new_dlg:show()
end
--------------------------------------------------------------------------------
-- @function [parent=#modstore] successfulldialog
-function modstore.successfulldialog()
+function modstore.successfulldialog(downloading_dlg)
local new_dlg = dialog_create("store_downloading",
function(data)
local retval = ""
@@ -158,18 +159,16 @@ function modstore.successfulldialog()
if modstore.lastmodentry ~= nil then
retval = retval .. "label[0,0.25;" .. fgettext("Successfully installed:") .. "]"
retval = retval .. "label[3,0.25;" .. modstore.lastmodentry.moddetails.title .. "]"
-
-
retval = retval .. "label[0,0.75;" .. fgettext("Shortname:") .. "]"
retval = retval .. "label[3,0.75;" .. core.formspec_escape(modstore.lastmodentry.moddetails.basename) .. "]"
-
end
- retval = retval .. "button[2.5,1.5;1,0.5;btn_confirm_mod_successfull;" .. fgettext("ok") .. "]"
+ retval = retval .. "button[2.2,1.5;1.5,0.5;btn_confirm_mod_successfull;" .. fgettext("Ok") .. "]"
+ return retval
end,
function(this,fields)
if fields["btn_confirm_mod_successfull"] ~= nil then
this.parent:show()
- this:hide()
+ downloading_dlg:delete()
this:delete()
return true
@@ -177,10 +176,10 @@ function modstore.successfulldialog()
return false
end,
- nil,
- modstore.tv_store)
+ nil)
- new_dlg.data.title = title
+ new_dlg:set_parent(modstore.tv_store)
+ modstore.tv_store:hide()
new_dlg:show()
end
@@ -217,7 +216,9 @@ function modstore.handle_buttons(parent, fields, name, data)
end
if fields["btn_modstore_close"] then
+ local maintab = ui.find_by_name("maintab")
parent:hide()
+ maintab:show()
return true
end
@@ -228,12 +229,7 @@ function modstore.handle_buttons(parent, fields, name, data)
for i=1,#modstore.modlist_unsorted.data,1 do
if modstore.modlist_unsorted.data[i].id == modid then
local moddetails = modstore.modlist_unsorted.data[i].details
-
- if modstore.lastmodtitle ~= "" then
- modstore.lastmodtitle = modstore.lastmodtitle .. ", "
- end
-
- modstore.lastmodtitle = modstore.lastmodtitle .. moddetails.title
+ modstore.lastmodtitle = moddetails.title
if not core.handle_async(
function(param)
@@ -281,7 +277,7 @@ function modstore.handle_buttons(parent, fields, name, data)
texturename = modstore.modlist_unsorted.data[i].texturename
},
function(result)
- print("Result from async: " .. dump(result.successfull))
+ --print("Result from async: " .. dump(result.successfull))
if result.successfull then
modmgr.installmod(result.filename,result.moddetails.basename)
os.remove(result.filename)
@@ -299,7 +295,7 @@ function modstore.handle_buttons(parent, fields, name, data)
print("ERROR: async event failed")
gamedata.errormessage = "Failed to download " .. modstore.lastmodtitle
end
- parent:hide()
+
modstore.showdownloading(modstore.lastmodtitle)
return true
end
diff --git a/builtin/mainmenu/tab_credits.lua b/builtin/mainmenu/tab_credits.lua
index 2a7aa26a5..33c84f58f 100644
--- a/builtin/mainmenu/tab_credits.lua
+++ b/builtin/mainmenu/tab_credits.lua
@@ -25,41 +25,56 @@ tab_credits = {
return "label[0.5,3.2;Minetest " .. core.get_version() .. "]" ..
"label[0.5,3.5;http://minetest.net]" ..
"image[0.5,1;" .. core.formspec_escape(logofile) .. "]" ..
- "textlist[3.5,-0.25;8.5,5.8;list_credits;" ..
- "#FFFF00" .. fgettext("Core Developers") .."," ..
- "Perttu Ahola (celeron55) <celeron55@gmail.com>,"..
- "Ryan Kwolek (kwolekr) <kwolekr@minetest.net>,"..
- "PilzAdam <pilzadam@minetest.net>," ..
- "Lisa Milne (darkrose) <lisa@ltmnet.com>,"..
- "Maciej Kasatkin (RealBadAngel) <mk@realbadangel.pl>,"..
- "sfan5 <sfan5@live.de>,"..
- "kahrl <kahrl@gmx.net>,"..
- "sapier,"..
- "ShadowNinja <shadowninja@minetest.net>,"..
- "Nathanael Courant (Nore/Novatux) <nore@mesecons.net>,"..
- "BlockMen,"..
- "Craig Robbins (Zeno),"..
- ","..
- "#FFFF00" .. fgettext("Active Contributors") .. "," ..
- "TriBlade9 <triblade9@mail.com>,"..
- "SmallJoker <mk939@ymail.com>,"..
- "Zefram <zefram@fysh.org>,"..
- "," ..
- "#FFFF00" .. fgettext("Previous Contributors") .. "," ..
- "Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>,"..
- "Jurgen Doser (doserj) <jurgen.doser@gmail.com>,"..
- "Jeija <jeija@mesecons.net>,"..
- "MirceaKitsune <mirceakitsune@gmail.com>,"..
- "dannydark <the_skeleton_of_a_child@yahoo.co.uk>,"..
- "0gb.us <0gb.us@0gb.us>,"..
- "proller <proler@gmail.com>,"..
- "Ilya Zhuravlev (xyz) <xyz@minetest.net>,"..
- "Guiseppe Bilotta (Oblomov) <guiseppe.bilotta@gmail.com>,"..
- "Jonathan Neuschafer <j.neuschaefer@gmx.net>,"..
- "Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>,"..
- "Constantin Wenger (SpeedProg) <constantin.wenger@googlemail.com>,"..
- "matttpt <matttpt@gmail.com>,"..
- "JacobF <queatz@gmail.com>,"..
- ";0;true]"
+ "tablecolumns[color;text]" ..
+ "tableoptions[background=#00000000;highlight=#00000000;border=false]" ..
+ "table[3.5,-0.25;8.5,5.8;list_credits;" ..
+ "#FFFF00," .. fgettext("Core Developers") .."," ..
+ ",Perttu Ahola (celeron55) <celeron55@gmail.com>,"..
+ ",Ryan Kwolek (kwolekr) <kwolekr@minetest.net>,"..
+ ",PilzAdam <pilzadam@minetest.net>," ..
+ ",sfan5 <sfan5@live.de>,"..
+ ",kahrl <kahrl@gmx.net>,"..
+ ",sapier,"..
+ ",ShadowNinja <shadowninja@minetest.net>,"..
+ ",Nathanael Courant (Nore/Ekdohibs) <nore@mesecons.net>,"..
+ ",BlockMen,"..
+ ",Craig Robbins (Zeno),"..
+ ",Loic Blot (nerzhul/nrz) <loic.blot@unix-experience.fr>,"..
+ ",Mat Gregory (paramat),"..
+ ",est31 <MTest31@outlook.com>," ..
+ ",,"..
+ "#FFFF00," .. fgettext("Active Contributors") .. "," ..
+ ",SmallJoker <mk939@ymail.com>," ..
+ ",Andrew Ward (rubenwardy) <rubenwardy@gmail.com>," ..
+ ",Aaron Suen <warr1024@gmail.com>," ..
+ ",Sokomine <wegwerf@anarres.dyndns.org>," ..
+ ",Břetislav Štec (TeTpaAka)," ..
+ ",Jean-Patrick G (kilbith) <jeanpatrick.guerrero@gmail.com>," ..
+ ",Rui <mrrst0914@gmail.com>," ..
+ ",Diego Martinez (kaeza) <kaeza@users.sf.net>," ..
+ ",," ..
+ "#FFFF00," .. fgettext("Previous Core Developers") .."," ..
+ ",Maciej Kasatkin (RealBadAngel) <maciej.kasatkin@o2.pl>,"..
+ ",Lisa Milne (darkrose) <lisa@ltmnet.com>," ..
+ ",proller," ..
+ ",Ilya Zhuravlev (xyz) <xyz@minetest.net>," ..
+ ",," ..
+ "#FFFF00," .. fgettext("Previous Contributors") .. "," ..
+ ",Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>,"..
+ ",Jurgen Doser (doserj) <jurgen.doser@gmail.com>,"..
+ ",Gregory Currie (gregorycu)," ..
+ ",Jeija <jeija@mesecons.net>,"..
+ ",MirceaKitsune <mirceakitsune@gmail.com>,"..
+ ",dannydark <the_skeleton_of_a_child@yahoo.co.uk>,"..
+ ",0gb.us <0gb.us@0gb.us>,"..
+ ",Guiseppe Bilotta (Oblomov) <guiseppe.bilotta@gmail.com>,"..
+ ",Jonathan Neuschafer <j.neuschaefer@gmx.net>,"..
+ ",Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>,"..
+ ",Constantin Wenger (SpeedProg) <constantin.wenger@googlemail.com>,"..
+ ",matttpt <matttpt@gmail.com>,"..
+ ",JacobF <queatz@gmail.com>,"..
+ ",TriBlade9 <triblade9@mail.com>,"..
+ ",Zefram <zefram@fysh.org>,"..
+ ";1]"
end
}
diff --git a/builtin/mainmenu/tab_mods.lua b/builtin/mainmenu/tab_mods.lua
index 901f14553..2ddc9b07c 100644
--- a/builtin/mainmenu/tab_mods.lua
+++ b/builtin/mainmenu/tab_mods.lua
@@ -36,7 +36,10 @@ local function get_formspec(tabview, name, tabdata)
-- "label[0.8,4.2;" .. fgettext("Add mod:") .. "]" ..
-- TODO Disabled due to upcoming release 0.4.8 and irrlicht messing up localization
-- "button[0.75,4.85;1.8,0.5;btn_mod_mgr_install_local;".. fgettext("Local install") .. "]" ..
- "button[0,4.85;5.25,0.5;btn_modstore;".. fgettext("Online mod repository") .. "]"
+
+-- TODO Disabled due to service being offline, and not likely to come online again, in this form
+-- "button[0,4.85;5.25,0.5;btn_modstore;".. fgettext("Online mod repository") .. "]"
+ ""
local selected_mod = nil
diff --git a/builtin/mainmenu/tab_multiplayer.lua b/builtin/mainmenu/tab_multiplayer.lua
index f9ac78f17..570259718 100644
--- a/builtin/mainmenu/tab_multiplayer.lua
+++ b/builtin/mainmenu/tab_multiplayer.lua
@@ -202,8 +202,9 @@ local function main_button_handler(tabview, fields, name, tabdata)
return true
end
- if fields["btn_mp_connect"] ~= nil or
- fields["key_enter"] ~= nil then
+ if (fields["btn_mp_connect"] ~= nil or
+ fields["key_enter"] ~= nil) and fields["te_address"] ~= nil and
+ fields["te_port"] ~= nil then
gamedata.playername = fields["te_name"]
gamedata.password = fields["te_pwd"]
diff --git a/builtin/mainmenu/tab_server.lua b/builtin/mainmenu/tab_server.lua
index 1ae2a0656..d08eecc21 100644
--- a/builtin/mainmenu/tab_server.lua
+++ b/builtin/mainmenu/tab_server.lua
@@ -67,6 +67,9 @@ local function main_button_handler(this, fields, name, tabdata)
if fields["srv_worlds"] ~= nil then
local event = core.explode_textlist_event(fields["srv_worlds"])
+ local selected = core.get_textlist_index("srv_worlds")
+
+ menu_worldmt_legacy(selected)
if event.type == "DCL" then
world_doubleclick = true
@@ -84,16 +87,25 @@ local function main_button_handler(this, fields, name, tabdata)
if fields["cb_creative_mode"] then
core.setting_set("creative_mode", fields["cb_creative_mode"])
+ local selected = core.get_textlist_index("srv_worlds")
+ menu_worldmt(selected, "creative_mode", fields["cb_creative_mode"])
+
return true
end
if fields["cb_enable_damage"] then
core.setting_set("enable_damage", fields["cb_enable_damage"])
+ local selected = core.get_textlist_index("srv_worlds")
+ menu_worldmt(selected, "enable_damage", fields["cb_enable_damage"])
+
return true
end
if fields["cb_server_announce"] then
core.setting_set("server_announce", fields["cb_server_announce"])
+ local selected = core.get_textlist_index("srv_worlds")
+ menu_worldmt(selected, "server_announce", fields["cb_server_announce"])
+
return true
end
@@ -101,12 +113,12 @@ local function main_button_handler(this, fields, name, tabdata)
world_doubleclick or
fields["key_enter"] then
local selected = core.get_textlist_index("srv_worlds")
- if selected ~= nil then
+ gamedata.selected_world = menudata.worldlist:get_raw_index(selected)
+ if selected ~= nil and gamedata.selected_world ~= 0 then
gamedata.playername = fields["te_playername"]
gamedata.password = fields["te_passwd"]
gamedata.port = fields["te_serverport"]
gamedata.address = ""
- gamedata.selected_world = menudata.worldlist:get_raw_index(selected)
core.setting_set("port",gamedata.port)
if fields["te_serveraddr"] ~= nil then
@@ -115,12 +127,17 @@ local function main_button_handler(this, fields, name, tabdata)
--update last game
local world = menudata.worldlist:get_raw_element(gamedata.selected_world)
+ if world then
+ local game, index = gamemgr.find_by_gameid(world.gameid)
+ core.setting_set("menu_last_game", game.id)
+ end
- local game,index = gamemgr.find_by_gameid(world.gameid)
- core.setting_set("menu_last_game",game.id)
core.start()
- return true
+ else
+ gamedata.errormessage =
+ fgettext("No world created or selected!")
end
+ return true
end
if fields["world_create"] ~= nil then
diff --git a/builtin/mainmenu/tab_settings.lua b/builtin/mainmenu/tab_settings.lua
index 881a63498..c17a39432 100644
--- a/builtin/mainmenu/tab_settings.lua
+++ b/builtin/mainmenu/tab_settings.lua
@@ -17,6 +17,17 @@
--------------------------------------------------------------------------------
+local leaves_style_labels = {
+ fgettext("Opaque Leaves"),
+ fgettext("Simple Leaves"),
+ fgettext("Fancy Leaves")
+}
+
+local leaves_style = {
+ {leaves_style_labels[1]..","..leaves_style_labels[2]..","..leaves_style_labels[3]},
+ {"opaque", "simple", "fancy"},
+}
+
local dd_filter_labels = {
fgettext("No Filter"),
fgettext("Bilinear Filter"),
@@ -39,6 +50,29 @@ local mipmap = {
{"", "mip_map", "anisotropic_filter"},
}
+local function getLeavesStyleSettingIndex()
+ local style = core.setting_get("leaves_style")
+ if (style == leaves_style[2][3]) then
+ return 3
+ elseif (style == leaves_style[2][2]) then
+ return 2
+ end
+ return 1
+end
+
+local dd_antialiasing_labels = {
+ fgettext("None"),
+ fgettext("2x"),
+ fgettext("4x"),
+ fgettext("8x"),
+}
+
+local antialiasing = {
+ {dd_antialiasing_labels[1]..","..dd_antialiasing_labels[2]..","..
+ dd_antialiasing_labels[3]..","..dd_antialiasing_labels[4]},
+ {"0", "2", "4", "8"}
+}
+
local function getFilterSettingIndex()
if (core.setting_get(filters[2][3]) == "true") then
return 3
@@ -59,16 +93,23 @@ local function getMipmapSettingIndex()
return 1
end
-local function video_driver_fname_to_name(selected_driver)
- local video_drivers = core.get_video_drivers()
-
- for i=1, #video_drivers do
- if selected_driver == video_drivers[i].friendly_name then
- return video_drivers[i].name:lower()
+local function getAntialiasingSettingIndex()
+ local antialiasing_setting = core.setting_get("fsaa")
+ for i = 1, #(antialiasing[2]) do
+ if antialiasing_setting == antialiasing[2][i] then
+ return i
end
end
+ return 1
+end
- return ""
+local function antialiasing_fname_to_name(fname)
+ for i = 1, #(dd_antialiasing_labels) do
+ if fname == dd_antialiasing_labels[i] then
+ return antialiasing[2][i]
+ end
+ end
+ return 0
end
local function dlg_confirm_reset_formspec(data)
@@ -159,50 +200,31 @@ local function scrollbar_to_gui_scale(value)
end
local function formspec(tabview, name, tabdata)
- local video_drivers = core.get_video_drivers()
- local current_video_driver = core.setting_get("video_driver"):lower()
-
- local driver_formspec_string = ""
- local driver_current_idx = 0
-
- for i=2, #video_drivers do
- driver_formspec_string = driver_formspec_string .. video_drivers[i].friendly_name
- if i ~= #video_drivers then
- driver_formspec_string = driver_formspec_string .. ","
- end
-
- if current_video_driver == video_drivers[i].name:lower() then
- driver_current_idx = i - 1
- end
- end
-
local tab_string =
- "box[0,0;3.5,3.9;#999999]" ..
+ "box[0,0;3.5,4.0;#999999]" ..
"checkbox[0.25,0;cb_smooth_lighting;".. fgettext("Smooth Lighting")
.. ";".. dump(core.setting_getbool("smooth_lighting")) .. "]"..
"checkbox[0.25,0.5;cb_particles;".. fgettext("Enable Particles") .. ";"
.. dump(core.setting_getbool("enable_particles")) .. "]"..
"checkbox[0.25,1;cb_3d_clouds;".. fgettext("3D Clouds") .. ";"
.. dump(core.setting_getbool("enable_3d_clouds")) .. "]"..
- "checkbox[0.25,1.5;cb_fancy_trees;".. fgettext("Fancy Trees") .. ";"
- .. dump(core.setting_getbool("new_style_leaves")) .. "]"..
- "checkbox[0.25,2.0;cb_opaque_water;".. fgettext("Opaque Water") .. ";"
+ "checkbox[0.25,1.5;cb_opaque_water;".. fgettext("Opaque Water") .. ";"
.. dump(core.setting_getbool("opaque_water")) .. "]"..
- "checkbox[0.25,2.5;cb_connected_glass;".. fgettext("Connected Glass") .. ";"
+ "checkbox[0.25,2.0;cb_connected_glass;".. fgettext("Connected Glass") .. ";"
.. dump(core.setting_getbool("connected_glass")) .. "]"..
- "checkbox[0.25,3.0;cb_node_highlighting;".. fgettext("Node Highlighting") .. ";"
+ "checkbox[0.25,2.5;cb_node_highlighting;".. fgettext("Node Highlighting") .. ";"
.. dump(core.setting_getbool("enable_node_highlighting")) .. "]"..
+ "dropdown[0.25,3.2;3.3;dd_leaves_style;" .. leaves_style[1][1] .. ";"
+ .. getLeavesStyleSettingIndex() .. "]" ..
"box[3.75,0;3.75,3.45;#999999]" ..
"label[3.85,0.1;".. fgettext("Texturing:") .. "]"..
"dropdown[3.85,0.55;3.85;dd_filters;" .. filters[1][1] .. ";"
.. getFilterSettingIndex() .. "]" ..
"dropdown[3.85,1.35;3.85;dd_mipmap;" .. mipmap[1][1] .. ";"
.. getMipmapSettingIndex() .. "]" ..
- "label[3.85,2.15;".. fgettext("Rendering:") .. "]"..
- "dropdown[3.85,2.6;3.85;dd_video_driver;"
- .. driver_formspec_string .. ";" .. driver_current_idx .. "]" ..
- "tooltip[dd_video_driver;" ..
- fgettext("Restart minetest for driver change to take effect") .. "]" ..
+ "label[3.85,2.15;".. fgettext("Antialiasing:") .. "]"..
+ "dropdown[3.85,2.6;3.85;dd_antialiasing;" .. antialiasing[1][1] .. ";"
+ .. getAntialiasingSettingIndex() .. "]" ..
"box[7.75,0;4,4;#999999]" ..
"checkbox[8,0;cb_shaders;".. fgettext("Shaders") .. ";"
.. dump(core.setting_getbool("enable_shaders")) .. "]"
@@ -353,10 +375,16 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
core.setting_set("touchscreen_threshold",fields["dd_touchthreshold"])
ddhandled = true
end
-
- if fields["dd_video_driver"] then
- core.setting_set("video_driver",
- video_driver_fname_to_name(fields["dd_video_driver"]))
+ if fields["dd_leaves_style"] == leaves_style_labels[3] then
+ core.setting_set("leaves_style", leaves_style[2][3])
+ ddhandled = true
+ end
+ if fields["dd_leaves_style"] == leaves_style_labels[2] then
+ core.setting_set("leaves_style", leaves_style[2][2])
+ ddhandled = true
+ end
+ if fields["dd_leaves_style"] == leaves_style_labels[1] then
+ core.setting_set("leaves_style", leaves_style[2][1])
ddhandled = true
end
if fields["dd_filters"] == dd_filter_labels[1] then
@@ -389,6 +417,11 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
core.setting_set("anisotropic_filter", "true")
ddhandled = true
end
+ if fields["dd_antialiasing"] then
+ core.setting_set("fsaa",
+ antialiasing_fname_to_name(fields["dd_antialiasing"]))
+ ddhandled = true
+ end
return ddhandled
end
diff --git a/builtin/mainmenu/tab_simple_main.lua b/builtin/mainmenu/tab_simple_main.lua
index 995c72132..434113b5f 100644
--- a/builtin/mainmenu/tab_simple_main.lua
+++ b/builtin/mainmenu/tab_simple_main.lua
@@ -69,20 +69,18 @@ local function get_formspec(tabview, name, tabdata)
-- separator
retval = retval ..
- "box[-0.3,3.75;12.4,0.1;#FFFFFF]"
+ "box[-0.28,3.75;12.4,0.1;#FFFFFF]"
-- checkboxes
retval = retval ..
- "checkbox[1.0,3.9;cb_creative;".. fgettext("Creative Mode") .. ";" ..
+ "checkbox[8.0,3.9;cb_creative;".. fgettext("Creative Mode") .. ";" ..
dump(core.setting_getbool("creative_mode")) .. "]"..
- "checkbox[5.0,3.9;cb_damage;".. fgettext("Enable Damage") .. ";" ..
- dump(core.setting_getbool("enable_damage")) .. "]" ..
- "checkbox[8,3.9;cb_fly_mode;".. fgettext("Fly mode") .. ";" ..
- dump(core.setting_getbool("free_move")) .. "]"
+ "checkbox[8.0,4.4;cb_damage;".. fgettext("Enable Damage") .. ";" ..
+ dump(core.setting_getbool("enable_damage")) .. "]"
-- buttons
retval = retval ..
- "button[2.0,4.5;6,1.5;btn_start_singleplayer;" .. fgettext("Start Singleplayer") .. "]" ..
- "button[8.25,4.5;2.5,1.5;btn_config_sp_world;" .. fgettext("Config mods") .. "]"
+ "button[0,3.7;8,1.5;btn_start_singleplayer;" .. fgettext("Start Singleplayer") .. "]" ..
+ "button[0,4.5;8,1.5;btn_config_sp_world;" .. fgettext("Config mods") .. "]"
return retval
end
@@ -138,11 +136,6 @@ local function main_button_handler(tabview, fields, name, tabdata)
return true
end
- if fields["cb_fly_mode"] then
- core.setting_set("free_move", fields["cb_fly_mode"])
- return true
- end
-
if fields["btn_mp_connect"] ~= nil or
fields["key_enter"] ~= nil then
diff --git a/builtin/mainmenu/tab_singleplayer.lua b/builtin/mainmenu/tab_singleplayer.lua
index 9dc377a8f..a40918af9 100644
--- a/builtin/mainmenu/tab_singleplayer.lua
+++ b/builtin/mainmenu/tab_singleplayer.lua
@@ -23,9 +23,9 @@ local function current_game()
end
local function singleplayer_refresh_gamebar()
-
+
local old_bar = ui.find_by_name("game_button_bar")
-
+
if old_bar ~= nil then
old_bar:delete()
end
@@ -38,6 +38,17 @@ local function singleplayer_refresh_gamebar()
core.set_topleft_text(gamemgr.games[j].name)
core.setting_set("menu_last_game",gamemgr.games[j].id)
menudata.worldlist:set_filtercriteria(gamemgr.games[j].id)
+ local index = filterlist.get_current_index(menudata.worldlist,
+ tonumber(core.setting_get("mainmenu_last_selected_world")))
+ if not index or index < 1 then
+ local selected = core.get_textlist_index("sp_worlds")
+ if selected ~= nil and selected < #menudata.worldlist:get_list() then
+ index = selected
+ else
+ index = #menudata.worldlist:get_list()
+ end
+ end
+ menu_worldmt_legacy(index)
return true
end
end
@@ -76,7 +87,7 @@ end
local function get_formspec(tabview, name, tabdata)
local retval = ""
-
+
local index = filterlist.get_current_index(menudata.worldlist,
tonumber(core.setting_get("mainmenu_last_selected_world"))
)
@@ -105,14 +116,17 @@ local function main_button_handler(this, fields, name, tabdata)
if fields["sp_worlds"] ~= nil then
local event = core.explode_textlist_event(fields["sp_worlds"])
+ local selected = core.get_textlist_index("sp_worlds")
+
+ menu_worldmt_legacy(selected)
if event.type == "DCL" then
world_doubleclick = true
end
- if event.type == "CHG" then
+ if event.type == "CHG" and selected ~= nil then
core.setting_set("mainmenu_last_selected_world",
- menudata.worldlist:get_raw_index(core.get_textlist_index("sp_worlds")))
+ menudata.worldlist:get_raw_index(selected))
return true
end
end
@@ -123,11 +137,17 @@ local function main_button_handler(this, fields, name, tabdata)
if fields["cb_creative_mode"] then
core.setting_set("creative_mode", fields["cb_creative_mode"])
+ local selected = core.get_textlist_index("sp_worlds")
+ menu_worldmt(selected, "creative_mode", fields["cb_creative_mode"])
+
return true
end
if fields["cb_enable_damage"] then
core.setting_set("enable_damage", fields["cb_enable_damage"])
+ local selected = core.get_textlist_index("sp_worlds")
+ menu_worldmt(selected, "enable_damage", fields["cb_enable_damage"])
+
return true
end
@@ -135,12 +155,14 @@ local function main_button_handler(this, fields, name, tabdata)
world_doubleclick or
fields["key_enter"] then
local selected = core.get_textlist_index("sp_worlds")
+ gamedata.selected_world = menudata.worldlist:get_raw_index(selected)
- if selected ~= nil then
- gamedata.selected_world = menudata.worldlist:get_raw_index(selected)
- gamedata.singleplayer = true
-
+ if selected ~= nil and gamedata.selected_world ~= 0 then
+ gamedata.singleplayer = true
core.start()
+ else
+ gamedata.errormessage =
+ fgettext("No world created or selected!")
end
return true
end
diff --git a/builtin/mainmenu/tab_texturepacks.lua b/builtin/mainmenu/tab_texturepacks.lua
index d32c073ab..3fb7b8598 100644
--- a/builtin/mainmenu/tab_texturepacks.lua
+++ b/builtin/mainmenu/tab_texturepacks.lua
@@ -45,12 +45,12 @@ end
--------------------------------------------------------------------------------
local function get_formspec(tabview, name, tabdata)
-
+
local retval = "label[4,-0.25;".. fgettext("Select texture pack:") .. "]"..
"textlist[4,0.25;7.5,5.0;TPs;"
local current_texture_path = core.setting_get("texture_path")
- local list = filter_texture_pack_list(core.get_dirlist(core.get_texturepath(), true))
+ local list = filter_texture_pack_list(core.get_dir_list(core.get_texturepath(), true))
local index = tonumber(core.setting_get("mainmenu_last_selected_TP"))
if index == nil then index = 1 end
@@ -62,10 +62,18 @@ local function get_formspec(tabview, name, tabdata)
return retval
end
- local infofile = current_texture_path ..DIR_DELIM.."info.txt"
+ local infofile = current_texture_path ..DIR_DELIM.."description.txt"
+ -- This adds backwards compatibility for old texture pack description files named
+ -- "info.txt", and should be removed once all such texture packs have been updated
+ if not file_exists(infofile) then
+ infofile = current_texture_path ..DIR_DELIM.."info.txt"
+ if file_exists(infofile) then
+ minetest.log("info.txt is depreciated. description.txt should be used instead.");
+ end
+ end
local infotext = ""
local f = io.open(infofile, "r")
- if f==nil then
+ if not f then
infotext = fgettext("No information available")
else
infotext = f:read("*all")
@@ -94,7 +102,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
local index = core.get_textlist_index("TPs")
core.setting_set("mainmenu_last_selected_TP",
index)
- local list = filter_texture_pack_list(core.get_dirlist(core.get_texturepath(), true))
+ local list = filter_texture_pack_list(core.get_dir_list(core.get_texturepath(), true))
local current_index = core.get_textlist_index("TPs")
if current_index ~= nil and #list >= current_index then
local new_path = core.get_texturepath()..DIR_DELIM..list[current_index]
diff --git a/builtin/mainmenu/textures.lua b/builtin/mainmenu/textures.lua
index 56992c0c5..075f38ee0 100644
--- a/builtin/mainmenu/textures.lua
+++ b/builtin/mainmenu/textures.lua
@@ -129,7 +129,7 @@ function mm_texture.set_generic(identifier)
end
--------------------------------------------------------------------------------
-function mm_texture.set_game(identifier,gamedetails)
+function mm_texture.set_game(identifier, gamedetails)
if gamedetails == nil then
return false
@@ -137,15 +137,34 @@ function mm_texture.set_game(identifier,gamedetails)
if mm_texture.texturepack ~= nil then
local path = mm_texture.texturepack .. DIR_DELIM ..
- gamedetails.id .. "_menu_" .. identifier .. ".png"
- if core.set_background(identifier,path) then
+ gamedetails.id .. "_menu_" .. identifier .. ".png"
+ if core.set_background(identifier, path) then
return true
end
end
- local path = gamedetails.path .. DIR_DELIM .."menu" ..
- DIR_DELIM .. identifier .. ".png"
- if core.set_background(identifier,path) then
+ -- Find out how many randomized textures the subgame provides
+ local n = 0
+ local filename
+ local menu_files = core.get_dir_list(gamedetails.path .. DIR_DELIM .. "menu", false)
+ for i = 1, #menu_files do
+ filename = identifier .. "." .. i .. ".png"
+ if table.indexof(menu_files, filename) == -1 then
+ n = i - 1
+ break
+ end
+ end
+ -- Select random texture, 0 means standard texture
+ n = math.random(0, n)
+ if n == 0 then
+ filename = identifier .. ".png"
+ else
+ filename = identifier .. "." .. n .. ".png"
+ end
+
+ local path = gamedetails.path .. DIR_DELIM .. "menu" ..
+ DIR_DELIM .. filename
+ if core.set_background(identifier, path) then
return true
end