1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-09-15 18:57:08 +00:00

Merge remote-tracking branch 'upstream/master' into Visuals-Vol-2

This commit is contained in:
Gefüllte Taubenbrust 2024-09-25 20:53:09 +02:00
commit 71e648a776
647 changed files with 60434 additions and 37195 deletions

View file

@ -1,15 +0,0 @@
-- CSM death formspec. Only used when clientside modding is enabled, otherwise
-- handled by the engine.
core.register_on_death(function()
local formspec = "size[11,5.5]bgcolor[#320000b4;true]" ..
"label[4.85,1.35;" .. fgettext("You died") ..
"]button_exit[4,3;3,0.5;btn_respawn;".. fgettext("Respawn") .."]"
core.show_formspec("bultin:death", formspec)
end)
core.register_on_formspec_input(function(formname, fields)
if formname == "bultin:death" then
core.send_respawn()
end
end)

View file

@ -9,6 +9,5 @@ dofile(commonpath .. "mod_storage.lua")
dofile(commonpath .. "chatcommands.lua")
dofile(commonpath .. "information_formspecs.lua")
dofile(clientpath .. "chatcommands.lua")
dofile(clientpath .. "death_formspec.lua")
dofile(clientpath .. "misc.lua")
assert(loadfile(commonpath .. "item_s.lua"))({}) -- Just for push/read node functions

View file

@ -69,7 +69,7 @@ local function build_chatcommands_formspec(name, sel, copy)
description = cmds[2].description
if copy then
local msg = S("Command: @1 @2",
core.colorize("#0FF", "/" .. cmds[1]), cmds[2].params)
core.colorize("#0FF", (INIT == "client" and "." or "/") .. cmds[1]), cmds[2].params)
if INIT == "client" then
core.display_chat_message(msg)
else

41
builtin/common/math.lua Normal file
View file

@ -0,0 +1,41 @@
--[[
Math utils.
--]]
function math.hypot(x, y)
return math.sqrt(x * x + y * y)
end
function math.sign(x, tolerance)
tolerance = tolerance or 0
if x > tolerance then
return 1
elseif x < -tolerance then
return -1
end
return 0
end
function math.factorial(x)
assert(x % 1 == 0 and x >= 0, "factorial expects a non-negative integer")
if x >= 171 then
-- 171! is greater than the biggest double, no need to calculate
return math.huge
end
local v = 1
for k = 2, x do
v = v * k
end
return v
end
function math.round(x)
if x < 0 then
local int = math.ceil(x)
local frac = x - int
return int - ((frac <= -0.5) and 1 or 0)
end
local int = math.floor(x)
local frac = x - int
return int + ((frac >= 0.5) and 1 or 0)
end

View file

@ -1,6 +1,6 @@
-- Registered metatables, used by the C++ packer
local known_metatables = {}
function core.register_async_metatable(name, mt)
function core.register_portable_metatable(name, mt)
assert(type(name) == "string", ("attempt to use %s value as metatable name"):format(type(name)))
assert(type(mt) == "table", ("attempt to register a %s value as metatable"):format(type(mt)))
assert(known_metatables[name] == nil or known_metatables[name] == mt,
@ -10,4 +10,10 @@ function core.register_async_metatable(name, mt)
end
core.known_metatables = known_metatables
core.register_async_metatable("__builtin:vector", vector.metatable)
function core.register_async_metatable(...)
core.log("deprecated", "minetest.register_async_metatable is deprecated. " ..
"Use minetest.register_portable_metatable instead.")
return core.register_portable_metatable(...)
end
core.register_portable_metatable("__builtin:vector", vector.metatable)

View file

@ -3,6 +3,7 @@
--------------------------------------------------------------------------------
-- Localize functions to avoid table lookups (better performance).
local string_sub, string_find = string.sub, string.find
local math = math
--------------------------------------------------------------------------------
local function basic_dump(o)
@ -205,49 +206,21 @@ function table.indexof(list, val)
return -1
end
--------------------------------------------------------------------------------
function table.keyof(tb, val)
for k, v in pairs(tb) do
if v == val then
return k
end
end
return nil
end
--------------------------------------------------------------------------------
function string:trim()
return self:match("^%s*(.-)%s*$")
end
--------------------------------------------------------------------------------
function math.hypot(x, y)
return math.sqrt(x * x + y * y)
end
--------------------------------------------------------------------------------
function math.sign(x, tolerance)
tolerance = tolerance or 0
if x > tolerance then
return 1
elseif x < -tolerance then
return -1
end
return 0
end
--------------------------------------------------------------------------------
function math.factorial(x)
assert(x % 1 == 0 and x >= 0, "factorial expects a non-negative integer")
if x >= 171 then
-- 171! is greater than the biggest double, no need to calculate
return math.huge
end
local v = 1
for k = 2, x do
v = v * k
end
return v
end
function math.round(x)
if x >= 0 then
return math.floor(x + 0.5)
end
return math.ceil(x - 0.5)
end
local formspec_escapes = {
["\\"] = "\\\\",
["["] = "\\[",
@ -689,6 +662,7 @@ function core.privs_to_string(privs, delim)
list[#list + 1] = priv
end
end
table.sort(list)
return table.concat(list, delim)
end

View file

@ -1,6 +1,7 @@
_G.core = {}
_G.vector = {metatable = {}}
dofile("builtin/common/math.lua")
dofile("builtin/common/vector.lua")
dofile("builtin/common/misc_helpers.lua")

View file

@ -0,0 +1,16 @@
_G.core = {}
dofile("builtin/common/math.lua")
describe("math", function()
it("round()", function()
assert.equal(0, math.round(0))
assert.equal(10, math.round(10.3))
assert.equal(11, math.round(10.5))
assert.equal(11, math.round(10.7))
assert.equal(-10, math.round(-10.3))
assert.equal(-11, math.round(-10.5))
assert.equal(-11, math.round(-10.7))
assert.equal(0, math.round(0.49999999999999994))
assert.equal(0, math.round(-0.49999999999999994))
end)
end)

View file

@ -1,4 +1,5 @@
_G.core = {}
dofile("builtin/common/math.lua")
dofile("builtin/common/vector.lua")
dofile("builtin/common/misc_helpers.lua")
@ -166,6 +167,16 @@ describe("table", function()
it("indexof()", function()
assert.equal(1, table.indexof({"foo", "bar"}, "foo"))
assert.equal(-1, table.indexof({"foo", "bar"}, "baz"))
assert.equal(-1, table.indexof({[2] = "foo", [3] = "bar"}, "foo"))
assert.equal(-1, table.indexof({[1] = "foo", [3] = "bar"}, "bar"))
end)
it("keyof()", function()
assert.equal("a", table.keyof({a = "foo", b = "bar"}, "foo"))
assert.equal(nil, table.keyof({a = "foo", b = "bar"}, "baz"))
assert.equal(1, table.keyof({"foo", "bar"}, "foo"))
assert.equal(2, table.keyof({[2] = "foo", [3] = "bar"}, "foo"))
assert.equal(3, table.keyof({[1] = "foo", [3] = "bar"}, "bar"))
end)
end)
@ -176,3 +187,17 @@ describe("formspec_escape", function()
assert.equal("\\[Hello\\\\\\[", core.formspec_escape("[Hello\\["))
end)
end)
describe("math", function()
it("round()", function()
assert.equal(0, math.round(0))
assert.equal(10, math.round(10.3))
assert.equal(11, math.round(10.5))
assert.equal(11, math.round(10.7))
assert.equal(-10, math.round(-10.3))
assert.equal(-11, math.round(-10.5))
assert.equal(-11, math.round(-10.7))
assert.equal(0, math.round(0.49999999999999994))
assert.equal(0, math.round(-0.49999999999999994))
end)
end)

View file

@ -1,4 +1,5 @@
_G.vector = {}
dofile("builtin/common/math.lua")
dofile("builtin/common/vector.lua")
describe("vector", function()
@ -113,12 +114,35 @@ describe("vector", function()
assert.equal(vector.new(0, 1, -1), a:round())
end)
it("ceil()", function()
local a = vector.new(0.1, 0.9, -0.5)
assert.equal(vector.new(1, 1, 0), vector.ceil(a))
assert.equal(vector.new(1, 1, 0), a:ceil())
end)
it("sign()", function()
local a = vector.new(-120.3, 0, 231.5)
assert.equal(vector.new(-1, 0, 1), vector.sign(a))
assert.equal(vector.new(-1, 0, 1), a:sign())
assert.equal(vector.new(0, 0, 1), vector.sign(a, 200))
assert.equal(vector.new(0, 0, 1), a:sign(200))
end)
it("abs()", function()
local a = vector.new(-123.456, 0, 13)
assert.equal(vector.new(123.456, 0, 13), vector.abs(a))
assert.equal(vector.new(123.456, 0, 13), a:abs())
end)
it("apply()", function()
local i = 0
local f = function(x)
i = i + 1
return x + i
end
local f2 = function(x, opt1, opt2, opt3)
return x + opt1 + opt2 + opt3
end
local a = vector.new(0.1, 0.9, -0.5)
assert.equal(vector.new(1, 1, 0), vector.apply(a, math.ceil))
assert.equal(vector.new(1, 1, 0), a:apply(math.ceil))
@ -126,6 +150,9 @@ describe("vector", function()
assert.equal(vector.new(0.1, 0.9, 0.5), a:apply(math.abs))
assert.equal(vector.new(1.1, 2.9, 2.5), vector.apply(a, f))
assert.equal(vector.new(4.1, 5.9, 5.5), a:apply(f))
local b = vector.new(1, 2, 3)
assert.equal(vector.new(4, 5, 6), vector.apply(b, f2, 1, 1, 1))
assert.equal(vector.new(4, 5, 6), b:apply(f2, 1, 1, 1))
end)
it("combine()", function()
@ -469,4 +496,13 @@ describe("vector", function()
assert.True(vector.in_area(vector.new(-10, -10, -10), vector.new(-10, -10, -10), vector.new(10, 10, 10)))
assert.False(vector.in_area(vector.new(-10, -10, -10), vector.new(10, 10, 10), vector.new(-11, -10, -10)))
end)
it("random_in_area()", function()
local min = vector.new(-100, -100, -100)
local max = vector.new(100, 100, 100)
for i = 1, 1000 do
local random = vector.random_in_area(min, max)
assert.True(vector.in_area(random, min, max))
end
end)
end)

View file

@ -5,6 +5,7 @@ Note: The vector.*-functions must be able to accept old vectors that had no meta
-- localize functions
local setmetatable = setmetatable
local math = math
vector = {}
@ -97,18 +98,26 @@ function vector.floor(v)
end
function vector.round(v)
return fast_new(
math.round(v.x),
math.round(v.y),
math.round(v.z)
)
return vector.apply(v, math.round)
end
function vector.apply(v, func)
function vector.ceil(v)
return vector.apply(v, math.ceil)
end
function vector.sign(v, tolerance)
return vector.apply(v, math.sign, tolerance)
end
function vector.abs(v)
return vector.apply(v, math.abs)
end
function vector.apply(v, func, ...)
return fast_new(
func(v.x),
func(v.y),
func(v.z)
func(v.x, ...),
func(v.y, ...),
func(v.z, ...)
)
end
@ -375,6 +384,26 @@ function vector.in_area(pos, min, max)
(pos.z >= min.z) and (pos.z <= max.z)
end
function vector.random_direction()
-- Generate a random direction of unit length, via rejection sampling
local x, y, z, l2
repeat -- expected less than two attempts on average (volume sphere vs. cube)
x, y, z = math.random() * 2 - 1, math.random() * 2 - 1, math.random() * 2 - 1
l2 = x*x + y*y + z*z
until l2 <= 1 and l2 >= 1e-6
-- normalize
local l = math.sqrt(l2)
return fast_new(x/l, y/l, z/l)
end
function vector.random_in_area(min, max)
return fast_new(
math.random(min.x, max.x),
math.random(min.y, max.y),
math.random(min.z, max.z)
)
end
if rawget(_G, "core") and core.set_read_vector and core.set_push_vector then
local function read_vector(v)
return v.x, v.y, v.z

View file

@ -23,6 +23,8 @@ core.add_node = core.set_node
-- we don't deal with metadata currently
core.swap_node = core.set_node
core.bulk_swap_node = core.bulk_set_node
function core.remove_node(pos)
return core.vmanip:set_node_at(pos, {name="air"})
end

View file

@ -19,7 +19,7 @@
local BASE_SPACING = 0.1
local function get_scroll_btn_width()
return core.settings:get_bool("enable_touch") and 0.8 or 0.5
return core.settings:get_bool("touch_gui") and 0.8 or 0.5
end
local function buttonbar_formspec(self)
@ -28,10 +28,8 @@ local function buttonbar_formspec(self)
end
local formspec = {
"style_type[box;noclip=true]",
string.format("box[%f,%f;%f,%f;%s]", self.pos.x, self.pos.y, self.size.x,
self.size.y, self.bgcolor),
"style_type[box;noclip=false]",
}
local btn_size = self.size.y - 2*BASE_SPACING
@ -71,7 +69,7 @@ local function buttonbar_formspec(self)
y = self.pos.y + BASE_SPACING,
}
table.insert(formspec, string.format("image_button[%f,%f;%f,%f;%s;%s;%s;true;false]tooltip[%s;%s]",
table.insert(formspec, string.format("image_button[%f,%f;%f,%f;%s;%s;%s;false;false]tooltip[%s;%s]",
btn_pos.x, btn_pos.y, btn_size, btn_size, btn.image, btn.name,
btn.caption, btn.name, btn.tooltip))
end
@ -86,9 +84,6 @@ local function buttonbar_formspec(self)
y = self.pos.y + BASE_SPACING,
}
table.insert(formspec, string.format("style[%s,%s;noclip=true]",
self.btn_prev_name, self.btn_next_name))
table.insert(formspec, string.format("button[%f,%f;%f,%f;%s;<]",
btn_prev_pos.x, btn_prev_pos.y, get_scroll_btn_width(), btn_size,
self.btn_prev_name))
@ -102,14 +97,24 @@ local function buttonbar_formspec(self)
end
local function buttonbar_buttonhandler(self, fields)
if fields[self.btn_prev_name] and self.cur_page > 1 then
self.cur_page = self.cur_page - 1
return true
if fields[self.btn_prev_name] then
if self.cur_page > 1 then
self.cur_page = self.cur_page - 1
return true
elseif self.cur_page == 1 then
self.cur_page = self.num_pages
return true
end
end
if fields[self.btn_next_name] and self.cur_page < self.num_pages then
self.cur_page = self.cur_page + 1
return true
if fields[self.btn_next_name] then
if self.cur_page < self.num_pages then
self.cur_page = self.cur_page + 1
return true
elseif self.cur_page == self.num_pages then
self.cur_page = 1
return true
end
end
for _, btn in ipairs(self.buttons) do

View file

@ -66,11 +66,22 @@ local function get_formspec(self)
local content, prepend = tab.get_formspec(self, tab.name, tab.tabdata, tab.tabsize)
local tsize = tab.tabsize or { width = self.width, height = self.height }
local ENABLE_TOUCH = core.settings:get_bool("enable_touch")
local orig_tsize = tab.tabsize or { width = self.width, height = self.height }
local tsize = { width = orig_tsize.width, height = orig_tsize.height }
tsize.height = tsize.height
+ TABHEADER_H -- tabheader included in formspec size
+ (ENABLE_TOUCH and GAMEBAR_OFFSET_TOUCH or GAMEBAR_OFFSET_DESKTOP)
+ GAMEBAR_H -- gamebar included in formspec size
if self.parent == nil and not prepend then
prepend = string.format("size[%f,%f,%s]", tsize.width, tsize.height,
dump(self.fixed_size))
local anchor_pos = TABHEADER_H + orig_tsize.height / 2
prepend = prepend .. ("anchor[0.5,%f]"):format(anchor_pos / tsize.height)
if tab.formspec_version then
prepend = ("formspec_version[%d]"):format(tab.formspec_version) .. prepend
end
@ -78,12 +89,15 @@ local function get_formspec(self)
local end_button_size = 0.75
local tab_header_size = { width = tsize.width, height = 0.85 }
local tab_header_size = { width = tsize.width, height = TABHEADER_H }
if self.end_button then
tab_header_size.width = tab_header_size.width - end_button_size - 0.1
end
local formspec = (prepend or "") .. self:tab_header(tab_header_size) .. content
local formspec = (prepend or "")
formspec = formspec .. ("bgcolor[;neither]container[0,%f]box[0,0;%f,%f;#0000008C]"):format(
TABHEADER_H, orig_tsize.width, orig_tsize.height)
formspec = formspec .. self:tab_header(tab_header_size) .. content
if self.end_button then
formspec = formspec ..
@ -98,6 +112,8 @@ local function get_formspec(self)
self.end_button.name)
end
formspec = formspec .. "container_end[]"
return formspec
end

View file

@ -221,6 +221,7 @@ core.register_chatcommand("haspriv", {
return true, S("No online player has the \"@1\" privilege.",
param)
else
table.sort(players_with_priv)
return true, S("Players online with the \"@1\" privilege: @2",
param,
table.concat(players_with_priv, ", "))

View file

@ -0,0 +1,31 @@
local F = core.formspec_escape
local S = core.get_translator("__builtin")
function core.show_death_screen(player, _reason)
local fs = {
"formspec_version[1]",
"size[11,5.5,true]",
"bgcolor[#320000b4;true]",
"label[4.85,1.35;", F(S("You died")), "]",
"button_exit[4,3;3,0.5;btn_respawn;", F(S("Respawn")), "]",
}
core.show_formspec(player:get_player_name(), "__builtin:death", table.concat(fs, ""))
end
core.register_on_dieplayer(function(player, reason)
core.show_death_screen(player, reason)
end)
core.register_on_joinplayer(function(player)
if player:get_hp() == 0 then
core.show_death_screen(player, nil)
end
end)
core.register_on_player_receive_fields(function(player, formname, fields)
if formname == "__builtin:death" and fields.quit and player:get_hp() == 0 then
player:respawn()
core.log("action", player:get_player_name() .. " respawns at " ..
player:get_pos():to_string())
end
end)

View file

@ -42,6 +42,8 @@ core.features = {
node_interaction_actor = true,
moveresult_new_pos = true,
override_item_remove_fields = true,
hotbar_hud_element = true,
bulk_lbms = true,
}
function core.has_feature(arg)

View file

@ -251,11 +251,31 @@ register_builtin_hud_element("minimap", {
position = {x = 1, y = 0},
alignment = {x = -1, y = 1},
offset = {x = -10, y = 10},
size = {x = 256, y = 256},
size = {x = 0, y = -25},
},
show_elem = function(player, flags)
local proto_ver = core.get_player_information(player:get_player_name()).protocol_version
-- Don't add a minimap for clients which already have it hardcoded in C++.
return flags.minimap and
core.get_player_information(player:get_player_name()).protocol_version >= 44
return flags.minimap and proto_ver >= 44
end,
update_def = function(player, elem_def)
local proto_ver = core.get_player_information(player:get_player_name()).protocol_version
-- Only use percentage when the client supports it.
elem_def.size = proto_ver >= 45 and {x = 0, y = -25} or {x = 256, y = 256}
end,
})
--- Hotbar
register_builtin_hud_element("hotbar", {
elem_def = {
type = "hotbar",
position = {x = 0.5, y = 1},
direction = 0,
alignment = {x = 0, y = -1},
offset = {x = 0, y = -4}, -- Extra padding below.
},
show_elem = function(player, flags)
return flags.hotbar
end,
})

View file

@ -38,6 +38,7 @@ dofile(gamepath .. "forceloading.lua")
dofile(gamepath .. "hud.lua")
dofile(gamepath .. "knockback.lua")
dofile(gamepath .. "async.lua")
dofile(gamepath .. "death_screen.lua")
core.after(0, builtin_shared.cache_content_ids)

View file

@ -6,14 +6,14 @@ local S = core.get_translator("__builtin")
-- Misc. API functions
--
-- @spec core.kick_player(String, String) :: Boolean
function core.kick_player(player_name, reason)
-- @spec core.kick_player(String, String, Boolean) :: Boolean
function core.kick_player(player_name, reason, reconnect)
if type(reason) == "string" then
reason = "Kicked: " .. reason
else
reason = "Kicked."
end
return core.disconnect_player(player_name, reason)
return core.disconnect_player(player_name, reason, reconnect)
end
function core.check_player_privs(name, ...)
@ -272,3 +272,54 @@ function core.get_globals_to_transfer()
}
return all
end
do
local function valid_object_iterator(objects)
local i = 0
local function next_valid_object()
i = i + 1
local obj = objects[i]
if obj == nil then
return
end
if obj:is_valid() then
return obj
end
return next_valid_object()
end
return next_valid_object
end
function core.objects_inside_radius(center, radius)
return valid_object_iterator(core.get_objects_inside_radius(center, radius))
end
function core.objects_in_area(min_pos, max_pos)
return valid_object_iterator(core.get_objects_in_area(min_pos, max_pos))
end
end
--
-- Helper for LBM execution, called from C++
--
function core.run_lbm(id, pos_list, dtime_s)
local lbm = core.registered_lbms[id]
assert(lbm, "Entry with given id not found in registered_lbms table")
core.set_last_run_mod(lbm.mod_origin)
if lbm.bulk_action then
return lbm.bulk_action(pos_list, dtime_s)
end
-- emulate non-bulk LBMs
local expect = core.get_node(pos_list[1]).name
-- engine guarantees that
-- 1) all nodes are the same content type
-- 2) the list is up-to-date when we're called
assert(expect ~= "ignore")
for _, pos in ipairs(pos_list) do
local n = core.get_node(pos)
if n.name == expect then -- might have been changed by previous call
lbm.action(pos, n, dtime_s)
end
end
end

View file

@ -105,7 +105,12 @@ function core.register_lbm(spec)
-- Add to core.registered_lbms
check_modname_prefix(spec.name)
check_node_list(spec.nodenames, "nodenames")
assert(type(spec.action) == "function", "Required field 'action' of type function")
local have = spec.action ~= nil
local have_bulk = spec.bulk_action ~= nil
assert(not have or type(spec.action) == "function", "Field 'action' must be a function")
assert(not have_bulk or type(spec.bulk_action) == "function", "Field 'bulk_action' must be a function")
assert(have ~= have_bulk, "Either 'action' or 'bulk_action' must be present")
core.registered_lbms[#core.registered_lbms + 1] = spec
spec.mod_origin = core.get_current_modname() or "??"
end

View file

@ -42,6 +42,7 @@ local scriptdir = core.get_builtin_path()
local commonpath = scriptdir .. "common" .. DIR_DELIM
local asyncpath = scriptdir .. "async" .. DIR_DELIM
dofile(commonpath .. "math.lua")
dofile(commonpath .. "vector.lua")
dofile(commonpath .. "strict.lua")
dofile(commonpath .. "serialize.lua")

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Вы загінулі
Respawn=Адрадзіцца

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Умряхте
Respawn=Прераждане

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Has mort
Respawn=Reaparèixer

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Zemřel jsi
Respawn=Oživit

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Buest ti farw
Respawn=Atgyfodi

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Du døde
Respawn=Genopstå

View file

@ -244,3 +244,5 @@ A total of @1 sample(s) were taken.=Es wurden insgesamt @1 Datenpunkt(e) aufgeze
The output is limited to '@1'.=Die Ausgabe ist beschränkt auf „@1“.
Saving of profile failed: @1=Speichern des Profils fehlgeschlagen: @1
Profile saved to @1=Profil abgespeichert nach @1
You died=Sie sind gestorben
Respawn=Wiederbeleben

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Πέθανες
Respawn=Επανεμφάνηση

View file

@ -244,3 +244,5 @@ A total of @1 sample(s) were taken.=Sume @1 ekzemplero(j) konserviĝis.
The output is limited to '@1'.=La eligo estas limigita al «@1».
Saving of profile failed: @1=Konservado de profilo malsukcesis: @1
Profile saved to @1=Profilo konservita al @1
You died=Vi mortis
Respawn=Renaskiĝi

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Has muerto
Respawn=Reaparecer

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Said surma
Respawn=Ärka ellu

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Hil zara
Respawn=Birsortu

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Kuolit
Respawn=Synny uudelleen

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Namatay ka
Respawn=Mag-respawn

View file

@ -0,0 +1,248 @@
# textdomain: __builtin
Invalid parameters (see /help @1).=Paramètres invalides (voir /help @1).
Too many arguments, try using just /help <command>=Trop de paramètres, essayez /help <command>
Available commands: @1=Commandes disponibles : @1
Use '/help <cmd>' to get more information, or '/help all' to list everything.=Essayez '/help <cmd>' pour obtenir plus d'informations, ou '/help all' pour tout lister.
Available commands:=Commandes disponibles :
Command not available: @1=Commande non disponible : @1
[all | privs | <cmd>] [-t]=[all | privs | <cmd>] [-t]
Get help for commands or list privileges (-t: output in chat)=Obtenir de l'aide pour les commandes ou pour lister les privilèges (-t : affichage dans le tchat)
Available privileges:=Privilèges disponibles :
Command=Commande
Parameters=Paramètres
For more information, click on any entry in the list.=Pour plus d'informations, cliquez sur une entrée dans la liste.
Double-click to copy the entry to the chat history.=Double-cliquez pour copier une entrée dans l'historique du tchat.
Command: @1 @2=Commande : @1 @2
Available commands: (see also: /help <cmd>)=Commandes disponibles : (voir aussi : /help <cmd>)
Close=Fermer
Privilege=Privilège
Description=Description
Empty command.=Commande vide.
Invalid command: @1=Commande invalide : @1
Invalid command usage.=Usage invalide de la commande.
(@1 s)= (@1 s)
Command execution took @1 s=L'exécution de la commande a pris @1 s.
You don't have permission to run this command (missing privileges: @1).=Vous n'avez pas la permission d'exécuter cette commande (privilèges manquants : @1)
Unable to get position of player @1.=Impossible d'obtenir la position du joueur @1.
Incorrect area format. Expected: (x1,y1,z1) (x2,y2,z2)=Format incorrect de la zone. Demandé : (x1, y1, z1) (x2, y2, z2)
<action>=<action>
Show chat action (e.g., '/me orders a pizza' displays '<player name> orders a pizza')=Affiche une action de tchat (ex : '/me commande une pizza' affichage '<joueur> commande une pizza')
Show the name of the server owner=Affiche le nom du propriétaire du serveur
The administrator of this server is @1.=L'administrateur de ce serveur est @1.
There's no administrator named in the config file.=Il n'y a pas d'administrateur indiqué dans le fichier de configuration.
@1 does not have any privileges.=@1 ne possède aucun privilège.
Privileges of @1: @2=Privilège(s) de @1 : @2
[<name>]=[<nom>]
Show privileges of yourself or another player=Affiche vos privilèges ou ceux d'un autre joueur.
Player @1 does not exist.=Le joueur @1 n'existe pas.
<privilege>=<privilège>
Return list of all online players with privilege=Renvoie la liste de tous les joueurs en ligne avec un privilège.
Invalid parameters (see /help haspriv).=Paramètres invalides (voir /help haspriv)
Unknown privilege!=Privilège inconnu !
No online player has the "@1" privilege.=Aucun joueur en ligne avant le privilège « @1 »
Players online with the "@1" privilege: @2=Joueurs en ligne avec le privilège « @1 » : @2
Your privileges are insufficient.=Vos privilèges sont insuffisants.
Your privileges are insufficient. '@1' only allows you to grant: @2=Vos privilèges sont insuffisants. '@1' vous autorise seulement d'accorder : @2
Unknown privilege: @1=Privilège inconnu : @1
@1 granted you privileges: @2=@1 vous a accordé les privilèges : @2
<name> (<privilege> [, <privilege2> [<...>]] | all)=<nom> (<privilège> [, <privilège2> [<...>]] | all)
Give privileges to player=Accorder le privilège au joueur
Invalid parameters (see /help grant).=Paramètres invalides (voir /help grant)
<privilege> [, <privilege2> [<...>]] | all=<privilège> [, <privilège2> [<...>]] | all
Grant privileges to yourself=Accorder des privilèges à vous-même
Invalid parameters (see /help grantme).=Paramètres invalides (voir /help grantme)
Your privileges are insufficient. '@1' only allows you to revoke: @2=Vos privilèges sont insuffisants. '@1' vous autorise seulement à révoquer : @2
Note: Cannot revoke in singleplayer: @1=Note : Impossible de révoquer en solo : @1
Note: Cannot revoke from admin: @1=Note : Impossible de révoquer à l'administrateur : @1
No privileges were revoked.=Aucun privilège n'a été révoqué.
@1 revoked privileges from you: @2=@1 vous a révoqué le privilège : @2
Remove privileges from player=Révoquer les privilèges au joueur
Invalid parameters (see /help revoke).=Paramètres invalides (voir /help revoke).
Revoke privileges from yourself=Révoquer des privilèges à vous-même
Invalid parameters (see /help revokeme).=Paramètres invalides (voir /help revokeme).
<name> <password>=<nom> <mot de passe>
Set player's password (sent unencrypted, thus insecure)=Voir le mot de passe d'un joueur (envoyé non crypté, soit non sécurisé)
Name field required.=Le champ « nom » est requis.
Your password was cleared by @1.=Votre mot de passe a été effacé par @1.
Password of player "@1" cleared.=Mot de passe du joueur « @1 » effacé.
Your password was set by @1.=Votre mot de passe a été défini par @1.
Password of player "@1" set.=Mot de passe « @1 » défini.
<name>=<nom>
Set empty password for a player=Définir un mot de passe pour un joueur
Reload authentication data=Recharger les données d'authentification
Done.=Fait.
Failed.=Échoué.
Remove a player's data=Supprimer les données d'un joueur
Player "@1" removed.=Joueur « @1 » supprimé.
No such player "@1" to remove.=Aucun joueur « @1 » à supprimer.
Player "@1" is connected, cannot remove.=Le joueur « @1 » est connecté, impossible de supprimer.
Unhandled remove_player return code @1.=La commande remove_player non gérée a retourné le code @1.
Cannot teleport out of map bounds!=Impossible de téléporter en dehors des limites de la carte !
Cannot get player with name @1.=Impossible d'obtenir le joueur @1.
Cannot teleport, @1 is attached to an object!=Impossible de téléporter, @1 est lié à un objet !
Teleporting @1 to @2.=Téléportation de @1 vers @2.
One does not teleport to oneself.=Impossible de se téléporter vers soi-même.
Cannot get teleportee with name @1.=Impossible d'obtenir le téléporté @1.
Cannot get target player with name @1.=Impossible d'obtenir le joueur cible @1.
Teleporting @1 to @2 at @3.=Téléportation de @1 vers @2 à @3.
<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>=<X>, <Y>, <Z> | <vers_nom> | <nom> <X>, <Y>, <Z> | <nom> <vers_nom>
Teleport to position or player=Se téléporter vers une position ou un joueur.
You don't have permission to teleport other players (missing privilege: @1).=Vous n'avez pas la permission de téléporter des joueurs (privilège manquant : @1).
([-n] <name> <value>) | <name>=([-n] <nom> <valeur>) | <nom>
Set or read server configuration setting=Définir ou lire un paramètre de configuration du serveur.
Failed. Cannot modify secure settings. Edit the settings file manually.=Échoué. Impossible de modifier les paramètres sécurisés. Éditez le fichier manuellement.
Failed. Use '/set -n <name> <value>' to create a new setting.=Échoué. Utilisez '/set -n <nom> <valeur>' pour créer un nouveau paramètre.
@1 @= @2=@1 @= @2
<not set>=<non défini>
Invalid parameters (see /help set).=Paramètres invalides (voir /help set).
Finished emerging @1 blocks in @2ms.=Fini de générer @1 blocks en @2 ms.
emergeblocks update: @1/@2 blocks emerged (@3%)=Mise à jour de emergeblocks : @1/@2 de blocs générés (@3%)
(here [<radius>]) | (<pos1> <pos2>)=(here [<rayon>]) | (<pos1> <pos1>)
Load (or, if nonexistent, generate) map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)=Charger (ou, si inexistant, générer), des blocs contenus dans la zone de pos1 à pos2 (<pos1> et <pos2> doivent être entre parenthèses)
Started emerge of area ranging from @1 to @2.=Début de la génération de la zone de @1 à @2.
Delete map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)=Supprimer les blocs contenus dans la zone de pos1 à pos2 (<pos1> et <pos2> doivent être entre parenthèses)
Successfully cleared area ranging from @1 to @2.=La zone de @1 à @2 a été nettoyée avec succès.
Failed to clear one or more blocks in area.=Le nettoyage d'un ou plusieurs blocs dans la zone a echoué.
Resets lighting in the area between pos1 and pos2 (<pos1> and <pos2> must be in parentheses)=Réinitialiser l'éclairage dans la zone de pos1 à pos2 (<pos1> et <pos2> doivent être entre parenthèses)
Successfully reset light in the area ranging from @1 to @2.=L'éclairage dans la zone de @1 à @2 a été réinitialisé avec succès.
Failed to load one or more blocks in area.=Le chargement d'un ou plusieurs blocs dans la zone a échoué.
List mods installed on the server=Liste les modules installés sur le serveur.
No mods installed.=Aucun module installé.
Cannot give an empty item.=Impossible de donner un objet vide.
Cannot give an unknown item.=Impossible de donner un objet inconnu.
Giving 'ignore' is not allowed.=Donner 'ignore' n'est pas autorisé.
@1 is not a known player.=Le joueur @1 est inconnu.
@1 partially added to inventory.=@1 été partiellement rajouté à l'inventaire.
@1 could not be added to inventory.=@1 n'a pas pu être rajouté à l'inventaire.
@1 added to inventory.=@1 a été rajouté à l'inventaire.
@1 partially added to inventory of @2.=@1 a été partiellement rajouté à l'inventaire de @2.
@1 could not be added to inventory of @2.=@1 n'a pas pu être rajouté à l'inventaire de @2.
@1 added to inventory of @2.=@1 a été rajouté à l'inventaire de @2.
<name> <ItemString> [<count> [<wear>]]=<nom> <CodeObjet> [<nombre> [<usure>]]
Give item to player=Donner un objet à un joueur
Name and ItemString required.=Le nom et le code de l'objet sont requis
<ItemString> [<count> [<wear>]]=<CodeObjet> [<nombre> [<usure>]]
Give item to yourself=Donner un objet à vous-même
ItemString required.=Code objet requis.
<EntityName> [<X>,<Y>,<Z>]=<NomEntité> [<X>, <Y>, <Z>]
Spawn entity at given (or your) position=Faire apparaître une entité à une position donnée (ou la vôtre)
EntityName required.=Nom de l'entité requis.
Unable to spawn entity, player is nil.=Impossible de faire apparaître l'entité, le joueur est inexistant.
Cannot spawn an unknown entity.=Impossible de faire apparaître une entité inconnue.
Invalid parameters (@1).=Paramètres invalides (@1).
@1 spawned.=@1 a apparu.
@1 failed to spawn.=@1 a échoué à apparaître.
Destroy item in hand=Détruire l'objet dans la main
Unable to pulverize, no player.=Impossible de détruire, pas de joueur.
Unable to pulverize, no item in hand.=Impossible de détruire, pas d'objet dans la main.
An item was pulverized.=Un objet a été détruit.
[<range>] [<seconds>] [<limit>]=[<rayon>] [<secondes>] [<limite>]
Check who last touched a node or a node near it within the time specified by <seconds>. Default: range @= 0, seconds @= 86400 @= 24h, limit @= 5. Set <seconds> to inf for no time limit=Vérifier qui a le dernier touché un nœud ou un autre aux environs dans le temps spécifié par <secondes>. Par défaut : rayon @= 0, secondes @= 86400 @= 24h, limite @= 5. Définissez <secondes> à inf pour aucune limite de temps.
Rollback functions are disabled.=Les fonctions retour sont désactivées.
That limit is too high!=Cette limite est trop grande !
Checking @1 ...=Vérification de @1 ...
Nobody has touched the specified location in @1 seconds.=Personne n'as touché la position spécificée dans les dernières @1 secondes.
@1 @2 @3 -> @4 @5 seconds ago.=@1 @2 @3 -> @4 il y a @5 secondes.
Punch a node (range@=@1, seconds@=@2, limit@=@3).=Taper un nœud (rayon @= @1, secondes @= @2, limite @= @3).
(<name> [<seconds>]) | (:<actor> [<seconds>])=(<nom> [<secondes>]) | (:<acteur> [<secondes>])
Revert actions of a player. Default for <seconds> is 60. Set <seconds> to inf for no time limit=Annuler les actions d'un joueur. La valeur par défaut de <secondes> est 60. Définissez <secondes> à inf pour aucune limite de temps.
Invalid parameters. See /help rollback and /help rollback_check.=Paramètres invalides. Voir /help rollback et /help rollback_check.
Reverting actions of player '@1' since @2 seconds.=Annuler les actions du joueur '@1' depuis @2 secondes.
Reverting actions of @1 since @2 seconds.=Annuler les actions de @1 depuis @2 secondes.
(log is too long to show)=(le journal est trop long à afficher)
Reverting actions succeeded.=Les actions ont été annulées avec succès.
Reverting actions FAILED.=L'annulation des actions a échoué.
Show server status=Afficher le statut du serveur.
This command was disabled by a mod or game.=Cette commande a été désactivée par un module ou un jeu.
[<0..23>:<0..59> | <0..24000>]=[<0..23>:<0..59> | <0.24000>]
Show or set time of day=Afficher ou définir l'heure du jour.
Current time is @1:@2.=L'heure actuelle est @1:@2.
You don't have permission to run this command (missing privilege: @1).=Vous n'avez pas la permission d'exécuter cette commande (privilège manquant : @1)
Invalid time (must be between 0 and 24000).=Heure invalide (doit être comprise entre 0 et 24000).
Time of day changed.=L'heure du jour a changé.
Invalid hour (must be between 0 and 23 inclusive).=Heure invalide (doit être comprise entre 0 et 23 inclus).
Invalid minute (must be between 0 and 59 inclusive).=Minute invalide (doit être comprise entre 0 et 59 inclus).
Show day count since world creation=Afficher le nombre de jours écoulés depuis la création du monde.
Current day is @1.=Le jour actuel est @1.
[<delay_in_seconds> | -1] [-r] [<message>]=[<délai_en_secondes> | -1] [-r] [<message>]
Shutdown server (-1 cancels a delayed shutdown, -r allows players to reconnect)=Éteindre le serveur (-1 annule une extinction programmée, -r autorise les joueurs à se reconnecter)
Server shutting down (operator request).=Extinction du serveur (requête de l'opérateur).
Ban the IP of a player or show the ban list=Bannir l'IP d'un joueur ou affiche la liste des bans.
The ban list is empty.=La liste des bans est vide.
Ban list: @1=Liste de bans : @1
You cannot ban players in singleplayer!=Vous ne pouvez pas bannir des joueurs en solo !
Player is not online.=Le joueur n'est pas en ligne.
Failed to ban player.=Le bannissement du joueur a échoué.
Banned @1.=@1 a été banni.
<name> | <IP_address>=<nom> | <adresse_IP>
Remove IP ban belonging to a player/IP=Rétablir un IP appartenant à un joueur ou une adresse IP.
Failed to unban player/IP.=Le rétablissement du joueur ou de l'adresse IP a échoué.
Unbanned @1.=@1 a été rétabli.
<name> [<reason>]=<nom> [<motif>]
Kick a player=Expulser un joueur
Failed to kick player @1.=L'expulsion du joueur @1 a échoué.
Kicked @1.=@1 a été expulsé.
[full | quick]=[full | quick]
Clear all objects in world=Nettoyer tous les objets dans le monde
Invalid usage, see /help clearobjects.=Usage invalide, voir /help clearobjects.
Clearing all objects. This may take a long time. You may experience a timeout. (by @1)=Nettoyage de tous les objects. Cela peut prendre du temps. Une inactivité peut surveni (par @1).
Cleared all objects.=Tous les objets ont été nettoyés.
<name> <message>=<nom> <message>
Send a direct message to a player=Envoyer un message privé à un joueur.
Invalid usage, see /help msg.=Usage invalide, voir /help msg.
The player @1 is not online.=Le joueur @1 n'est pas en ligne.
DM from @1: @2=Message privé de @1 : @2
Message sent.=Message privé envoyé.
Get the last login time of a player or yourself=Obtenir l'horodatage de la dernière connexion d'un joueur ou de vous-même.
@1's last login time was @2.=@1 s'est connecté pour la dernière fois au @2.
@1's last login time is unknown.=L'horodatage de la dernière connexion de @1 est inconnu.
Clear the inventory of yourself or another player=Vider votre inventaire ou celui d'un autre joueur.
You don't have permission to clear another player's inventory (missing privilege: @1).=Vous n'avez pas la permission de vider l'inventaire d'un autre joueur (privilège manquant : @1).
@1 cleared your inventory.=@1 a vidé votre inventaire.
Cleared @1's inventory.=L'inventaire de @1 a été vidé.
Player must be online to clear inventory!=Le joueur doit être en ligne pour pouvoir vider son inventaire.
Players can't be killed, damage has been disabled.=Les joueurs ne peuvent pas être tués, les dommages ont été désactivés.
Player @1 is not online.=Le joueur @1 n'est pas en ligne.
You are already dead.=Vous êtes déjà mort.
@1 is already dead.=@1 est déjà mort.
@1 has been killed.=@1 a été tué.
Kill player or yourself=Tuer un joueur ou vous-même.
@1 joined the game.=@1 a rejoint la partie.
@1 left the game.=@1 a quitté la partie.
@1 left the game (timed out).=@1 a quitté la partie (inactivité).
(no description)=(sans description)
Can interact with things and modify the world=Peut interagir avec des éléments ou modifier le monde.
Can speak in chat=Peut écrire dans le tchat.
Can modify basic privileges (@1)=Peut modifier les privilèges basiques (@1)
Can modify privileges=Peut modifier les privilèges
Can teleport self=Peut se téléporter
Can teleport other players=Peut téléporter d'autres joueurs
Can set the time of day using /time=Peut définir l'heure du jour avec /time
Can do server maintenance stuff=Peut effectuer des tâches de maintenance du serveur
Can bypass node protection in the world=Peut outrepasser la protection des nœuds dans le monde.
Can ban and unban players=Peut bannir et rétablir des joueurs.
Can kick players=Peut expulser des joueurs.
Can use /give and /giveme=Peut utiliser /give et /giveme
Can use /setpassword and /clearpassword=Peut utiliser /setpassword et /clearpassword
Can use fly mode=Peut utiliser le mode vol
Can use fast mode=Peut utiliser le mode rapide
Can fly through solid nodes using noclip mode=Peut voler à travers des nœuds solides en utilisant le mode de collisions désactivées.
Can use the rollback functionality=Peut utiliser la fonctionnalité de retour
Can enable wireframe=Peut activer la vue fil de fer
Unknown Item=Objet inconnu
Air=Air
Ignore=Ignorer
You can't place 'ignore' nodes!=Vous ne pouvez pas placé de nœuds 'ignorés' !
print [<filter>] | dump [<filter>] | save [<format> [<filter>]] | reset=print [<filtre>] | dump [<filtre>] | save [<format> [<filtre>]] | reset
Handle the profiler and profiling data=Traiter le profileur et les données de profilage
Statistics written to action log.=Les statistiques sont écrites dans les journaux d'actions.
Statistics were reset.=Les statistiques ont été réinitialisées.
Usage: @1=Usage : @1
Format can be one of txt, csv, lua, json, json_pretty (structures may be subject to change).=Le format peut être txt, csv, lua, json ou json_pretty (les structures sont sujettes au changement).
Values below show absolute/relative times spend per server step by the instrumented function.=Les valeurs inférieures affichent les temps absolu et relatif dépensés par étape du serveur par la fonction utilisée.
A total of @1 sample(s) were taken.=@1 échantillons ont été collectés.
The output is limited to '@1'.=La sortie est limitée à '@1'.
Saving of profile failed: @1=La sauvegarde du profil a échoué : @1
Profile saved to @1=Le profil a été sauvegardé dans @1
You died=Vous êtes mort
Respawn=Réapparaître

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Fuair tú bás
Respawn=Athsceith

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Morreches
Respawn=Reaparecer

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Meghaltál
Respawn=Újraéledés

View file

@ -244,3 +244,5 @@ A total of @1 sample(s) were taken.=Total @1 sampel yang diambil.
The output is limited to '@1'.=Keluaran dibatasi ke '@1'.
Saving of profile failed: @1=Penyimpanan profil gagal: @1
Profile saved to @1=Profil disimpan ke @1
You died=Anda mati
Respawn=Bangkit kembali

View file

@ -245,3 +245,5 @@ A total of @1 sample(s) were taken.=Son stati ottenuti campioni per un totale di
The output is limited to '@1'.=L'output è limitato a '@1'.
Saving of profile failed: @1=Errore nel salvare il profilo: @1
Profile saved to @1=Profilo salvato in @1
You died=Sei morto
Respawn=Rinasci

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=死んでしまった
Respawn=リスポーン

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=.i do morsi
Respawn=tolcanci

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Panjenengan pejah
Respawn=Bangkit Malilh

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=사망했습니다
Respawn=리스폰

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Кулінныд
Respawn=Ловзьыны

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Сиз өлдүңүз.
Respawn=Кайтадан жаралуу

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Jūs numirėte
Respawn=Prisikelti

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Jūs nomirāt
Respawn=Atdzīvoties

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=尔死矣
Respawn=复生

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Та үхсэн
Respawn=Дахин төрөх

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=तू मेलास
Respawn=पुनर्जन्म

View file

@ -244,3 +244,5 @@ A total of @1 sample(s) were taken.=Sebanyak @1 sampel telah diambil secara kese
The output is limited to '@1'.=Output dihadkan kepada '@1'.
Saving of profile failed: @1=Penyimpanan profil telah gagal: @1
Profile saved to @1=Profil telah disimpan ke @1
You died=Anda telah meninggal
Respawn=Jelma semula

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Du døde
Respawn=Gjenoppstå

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Je bent gestorven
Respawn=Herboren worden

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Du døydde
Respawn=Kom opp att

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Setz mòrt·a
Respawn=Tornar

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Nie żyjesz
Respawn=Wróć do gry

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Você morreu
Respawn=Renascer

View file

@ -0,0 +1,248 @@
# textdomain: __builtin
Invalid parameters (see /help @1).=Parâmetros inválidos (veja /help @1).
Too many arguments, try using just /help <command>=Muitos argumentos, tente usar apenas /help <comando>
Available commands: @1=Comandos disponíveis: @1
Use '/help <cmd>' to get more information, or '/help all' to list everything.=Use '/help <cmd>' para obter mais informações, ou '/help all' para listar tudo.
Available commands:=Comandos disponíveis:
Command not available: @1=Comando não disponível: @1
[all | privs | <cmd>] [-t]=[all | privs | <cmd>] [-t]
Get help for commands or list privileges (-t: output in chat)=Obtenha ajuda para comandos ou liste privilégios (-t: saída no chat)
Available privileges:=Privilégios disponíveis:
Command=Comando
Parameters=Parâmetros
For more information, click on any entry in the list.=Para mais informações, clique em qualquer entrada na lista.
Double-click to copy the entry to the chat history.=Clique duas vezes para copiar a entrada para o histórico do chat.
Command: @1 @2=Comando: @1 @2
Available commands: (see also: /help <cmd>)=Comandos disponíveis: (veja também: /help <cmd>)
Close=Fechar
Privilege=Privilégio
Description=Descrição
Empty command.=Comando vazio.
Invalid command: @1=Comando inválido: @1
Invalid command usage.=Uso de comando inválido.
(@1 s)= (@1 s)
Command execution took @1 s=A execução do comando levou @1 s
You don't have permission to run this command (missing privileges: @1).=Você não tem permissão para executar este comando (privilégios faltando: @1).
Unable to get position of player @1.=Incapaz de obter a posição do jogador @1.
Incorrect area format. Expected: (x1,y1,z1) (x2,y2,z2)=Formato de área incorreto. Esperado: (x1,y1,z1) (x2,y2,z2)
<action>=<ação>
Show chat action (e.g., '/me orders a pizza' displays '<player name> orders a pizza')=Mostra a ação do chat (por exemplo, '/me orders a pizza' exibe '<nome do jogador> pede uma pizza')
Show the name of the server owner=Mostra o nome do dono do servidor
The administrator of this server is @1.=O administrador deste servidor é @1.
There's no administrator named in the config file.=Não há administrador nomeado no arquivo de configuração.
@1 does not have any privileges.=@1 não tem nenhum privilégio.
Privileges of @1: @2=Privilégios de @1: @2
[<name>]=[<nome>]
Show privileges of yourself or another player=Mostrar privilégios seus ou de outro jogador
Player @1 does not exist.=O jogador @1 não existe.
<privilege>=<privilégio>
Return list of all online players with privilege=Retornar lista de todos os jogadores online com privilégio
Invalid parameters (see /help haspriv).=Parâmetros inválidos (veja /help haspriv).
Unknown privilege!=Privilégio desconhecido!
No online player has the "@1" privilege.=Nenhum jogador online tem o privilégio "@1".
Players online with the "@1" privilege: @2=Jogadores online com o privilégio "@1": @2
Your privileges are insufficient.=Seus privilégios são insuficientes.
Your privileges are insufficient. '@1' only allows you to grant: @2=Seus privilégios são insuficientes. '@1' só permite que você conceda: @2
Unknown privilege: @1=Privilégio desconhecido: @1
@1 granted you privileges: @2=@1 concedeu-lhe privilégios: @2
<name> (<privilege> [, <privilege2> [<...>]] | all)=<nome> (<privilégio> [, <privilégio2> [<...>]] | all)
Give privileges to player=Conceder privilégios ao jogador
Invalid parameters (see /help grant).=Parâmetros inválidos (veja /help grant).
<privilege> [, <privilege2> [<...>]] | all=<privilégio> [, <privilégio2> [<...>]] | all
Grant privileges to yourself=Concede privilégios a você mesmo
Invalid parameters (see /help grantme).=Parâmetros inválidos (veja /help grantme).
Your privileges are insufficient. '@1' only allows you to revoke: @2=Seus privilégios são insuficientes. '@1' só permite que você revogue: @2
Note: Cannot revoke in singleplayer: @1=Nota: Não é possível revogar em singleplayer: @1
Note: Cannot revoke from admin: @1=Nota: Não é possível revogar do administrador: @1
No privileges were revoked.=Nenhum privilégio foi revogado.
@1 revoked privileges from you: @2=@1 revogou seus privilégios: @2
Remove privileges from player=Remover privilégios do jogador
Invalid parameters (see /help revoke).=Parâmetros inválidos (veja /help revoke).
Revoke privileges from yourself=Revogar privilégios de si mesmo
Invalid parameters (see /help revokeme).=Parâmetros inválidos (veja /help revokeme).
<name> <password>=<nome> <senha>
Set player's password (sent unencrypted, thus insecure)=Definir a senha do jogador (enviada sem criptografia, portanto insegura)
Name field required.=Campo de nome obrigatório.
Your password was cleared by @1.=Sua senha foi limpa por @1.
Password of player "@1" cleared.=Senha do jogador "@1" limpa.
Your password was set by @1.=Sua senha foi definida por @1.
Password of player "@1" set.=Senha do jogador "@1" definida.
<name>=<nome>
Set empty password for a player=Definir senha vazia para um jogador
Reload authentication data=Recarregar dados de autenticação
Done.=Pronto.
Failed.=Erro.
Remove a player's data=Remover dados de um jogador
Player "@1" removed.=Jogador "@1" removido.
No such player "@1" to remove.=Não existe tal jogador "@1" para remover.
Player "@1" is connected, cannot remove.=Jogador "@1" está conectado, não pode ser removido.
Unhandled remove_player return code @1.=Código de retorno remove_player não tratado @1.
Cannot teleport out of map bounds!=Não é possível teleportar para fora dos limites do mapa!
Cannot get player with name @1.=Não é possível obter jogador com o nome @1.
Cannot teleport, @1 is attached to an object!=Não é possível teleportar, @1 está anexado a um objeto!
Teleporting @1 to @2.=Teleportando @1 para @2.
One does not teleport to oneself.=Não tem como se teletransportar para você mesmo.
Cannot get teleportee with name @1.=Não é possível teletransportar com o nome @1.
Cannot get target player with name @1.=Não é possível obter jogador alvo com o nome @1.
Teleporting @1 to @2 at @3.=Teleportando @1 para @2 em @3.
<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>=<X>,<Y>,<Z> | <para_nome> | <nome> <X>,<Y>,<Z> | <nome> <para_nome>
Teleport to position or player=Teleportar para posição ou um jogador
You don't have permission to teleport other players (missing privilege: @1).=Você não tem permissão para teleportar outros jogadores (privilégio faltando: @1).
([-n] <name> <value>) | <name>=([-n] <nome> <valor>) | <nome>
Set or read server configuration setting=Definir ou ler configuração do servidor
Failed. Cannot modify secure settings. Edit the settings file manually.=Falha. Não é possível modificar configurações seguras. Edite o arquivo de configurações manualmente.
Failed. Use '/set -n <name> <value>' to create a new setting.=Falhou. Use '/set -n <nome> <valor>' para criar uma nova configuração.
@1 @= @2=@1 @= @2
<not set>=<não definido>
Invalid parameters (see /help set).=Parâmetros inválidos (veja /help set).
Finished emerging @1 blocks in @2ms.=Finalizada a emergência de @1 blocos em @2ms.
emergeblocks update: @1/@2 blocks emerged (@3%)=atualização de emergeblocks: @1/@2 blocos emergidos (@3%)
(here [<radius>]) | (<pos1> <pos2>)=(aqui [<raio>]) | (<pos1> <pos2>)
Load (or, if nonexistent, generate) map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)=Carregar (ou, se inexistente, gerar) blocos de mapa contidos na área pos1 a pos2 (<pos1> e <pos2> devem estar entre parênteses)
Started emerge of area ranging from @1 to @2.=Iniciada o surgimento de áreas que vão de @1 a @2.
Delete map blocks contained in area pos1 to pos2 (<pos1> and <pos2> must be in parentheses)=Excluir blocos de mapa contidos na área pos1 a pos2 (<pos1> e <pos2> devem estar entre parênteses)
Successfully cleared area ranging from @1 to @2.=Área limpa com sucesso variando de @1 a @2.
Failed to clear one or more blocks in area.=Falha ao limpar um ou mais blocos na área.
Resets lighting in the area between pos1 and pos2 (<pos1> and <pos2> must be in parentheses)=Redefine a iluminação na área entre pos1 e pos2 (<pos1> e <pos2> devem estar entre parênteses)
Successfully reset light in the area ranging from @1 to @2.=Iluminação redefinida com sucesso na área variando de @1 a @2.
Failed to load one or more blocks in area.=Falha ao carregar um ou mais blocos na área.
List mods installed on the server=Listar mods instalados no servidor
No mods installed.=Sem mods instalados.
Cannot give an empty item.=Não é possível dar um item vazio.
Cannot give an unknown item.=Não é possível dar um item desconhecido.
Giving 'ignore' is not allowed.=Não é permitido dar 'ignore'.
@1 is not a known player.=@1 não é um jogador conhecido.
@1 partially added to inventory.=@1 parcialmente adicionado ao inventário.
@1 could not be added to inventory.=@1 não pôde ser adicionado ao inventário.
@1 added to inventory.=@1 adicionado ao inventário.
@1 partially added to inventory of @2.=@1 parcialmente adicionado ao inventário de @2.
@1 could not be added to inventory of @2.=@1 não pôde ser adicionado ao inventário de @2.
@1 added to inventory of @2.=@1 adicionado ao inventário de @2.
<name> <ItemString> [<count> [<wear>]]=<nome> <ItemString> [<quantidade> [<desgaste>]]
Give item to player=Dar item ao jogador
Name and ItemString required.=Nome e ItemString são obrigatórios.
<ItemString> [<count> [<wear>]]=<ItemString> [<quantidade> [<desgaste>]]
Give item to yourself=Dar item a si mesmo
ItemString required.=ItemString é obrigatório.
<EntityName> [<X>,<Y>,<Z>]=<NomeDaEntidade> [<X>,<Y>,<Z>]
Spawn entity at given (or your) position=Gerar entidade na posição fornecida (ou na sua)
EntityName required.=NomeDaEntidade é obrigatório.
Unable to spawn entity, player is nil.=Não é possível gerar a entidade, jogador é nulo.
Cannot spawn an unknown entity.=Não é possível gerar uma entidade desconhecida.
Invalid parameters (@1).=Parâmetros inválidos (@1).
@1 spawned.=@1 gerado.
@1 failed to spawn.=Falha ao gerar @1.
Destroy item in hand=Destruir item na mão
Unable to pulverize, no player.=Incapaz de pulverizar, sem jogador.
Unable to pulverize, no item in hand.=Incapaz de pulverizar, sem item na mão.
An item was pulverized.=Um item foi pulverizado.
[<range>] [<seconds>] [<limit>]=[<alcance>] [<segundos>] [<limite>]
Check who last touched a node or a node near it within the time specified by <seconds>. Default: range @= 0, seconds @= 86400 @= 24h, limit @= 5. Set <seconds> to inf for no time limit=Verificar quem tocou pela última vez um nó ou um nó próximo dentro do tempo especificado por <segundos>. Padrão: alcance @= 0, segundos @= 86400 @= 24h, limite @= 5. Defina <segundos> como inf para sem limite de tempo
Rollback functions are disabled.=Funções de rollback estão desativadas.
That limit is too high!=Esse limite é muito alto!
Checking @1 ...=Verificando @1 ...
Nobody has touched the specified location in @1 seconds.=Ninguém tocou a localização especificada em @1 segundos.
@1 @2 @3 -> @4 @5 seconds ago.=@1 @2 @3 -> @4 @5 segundos atrás.
Punch a node (range@=@1, seconds@=@2, limit@=@3).=Golpeie um nó (alcance@=@1, segundos@=@2, limite@=@3).
(<name> [<seconds>]) | (:<actor> [<seconds>])=(<nome> [<segundos>]) | (:<ator> [<segundos>])
Revert actions of a player. Default for <seconds> is 60. Set <seconds> to inf for no time limit=Reverter ações de um jogador. O padrão para <segundos> é 60. Defina <segundos> como inf para sem limite de tempo
Invalid parameters. See /help rollback and /help rollback_check.=Parâmetros inválidos. Veja /help rollback e /help rollback_check.
Reverting actions of player '@1' since @2 seconds.=Revertendo ações do jogador '@1' desde @2 segundos.
Reverting actions of @1 since @2 seconds.=Revertendo ações de @1 desde @2 segundos.
(log is too long to show)=O log é muito longo para mostrar
Reverting actions succeeded.=Ações revertidas com sucesso.
Reverting actions FAILED.=Reversão de ações FALHOU.
Show server status=Mostrar status do servidor
This command was disabled by a mod or game.=Este comando foi desativado por um mod ou jogo.
[<0..23>:<0..59> | <0..24000>]=[<0..23>:<0..59> | <0..24000>]
Show or set time of day=Mostrar ou definir hora do dia
Current time is @1:@2.=A hora atual é @1:@2.
You don't have permission to run this command (missing privilege: @1).=Você não tem permissão para executar este comando (privilégio faltando: @1).
Invalid time (must be between 0 and 24000).=Hora inválida (deve estar entre 0 e 24000).
Time of day changed.=Hora do dia alterada.
Invalid hour (must be between 0 and 23 inclusive).=Hora inválida (deve estar entre 0 e 23 inclusivo).
Invalid minute (must be between 0 and 59 inclusive).=Minuto inválido (deve estar entre 0 e 59 inclusivo).
Show day count since world creation=Mostrar contagem de dias desde a criação do mundo
Current day is @1.=O dia atual é @1.
[<delay_in_seconds> | -1] [-r] [<message>]=[<atraso_em_segundos> | -1] [-r] [<mensagem>]
Shutdown server (-1 cancels a delayed shutdown, -r allows players to reconnect)=Desligar servidor (-1 cancela o desligamento adiado, -r permite que os jogadores se reconectem)
Server shutting down (operator request).=Servidor desligando (solicitação do operador).
Ban the IP of a player or show the ban list=Banir o IP de um jogador ou mostrar a lista de banimentos
The ban list is empty.=A lista de banimentos está vazia.
Ban list: @1=Lista de banimentos: @1
You cannot ban players in singleplayer!=Você não pode banir jogadores em singleplayer!
Player is not online.=Jogador não está online.
Failed to ban player.=Falha ao banir jogador.
Banned @1.=Banido @1.
<name> | <IP_address>=<nome> | <endereço_IP>
Remove IP ban belonging to a player/IP=Remover banimento de IP pertencente a um jogador/IP
Failed to unban player/IP.=Falha ao desbanir jogador/IP.
Unbanned @1.=Desbanido @1.
<name> [<reason>]=<nome> [<motivo>]
Kick a player=Expulsar um jogador
Failed to kick player @1.=Falha ao expulsar jogador @1.
Kicked @1.=Expulso @1.
[full | quick]=[full | quick]
Clear all objects in world=Limpar todos os objetos no mundo
Invalid usage, see /help clearobjects.=Uso inválido, veja /help clearobjects.
Clearing all objects. This may take a long time. You may experience a timeout. (by @1)=Limpeza de todos os objetos. Isso pode levar muito tempo. Você pode experimentar um tempo limite. (por @1)
Cleared all objects.=Todos os objetos foram limpos.
<name> <message>=<nome> <mensagem>
Send a direct message to a player=Enviar uma mensagem direta a um jogador
Invalid usage, see /help msg.=Uso inválido, veja /help msg.
The player @1 is not online.=O jogador @1 não está online.
DM from @1: @2=DM de @1: @2
Message sent.=Mensagem enviada.
Get the last login time of a player or yourself=Pegue o último horário de login de um jogador ou de você mesmo
@1's last login time was @2.=O último login de @1 foi às @2.
@1's last login time is unknown.=O último login de @1 é desconhecido.
Clear the inventory of yourself or another player=Limpar o inventário de você mesmo ou de outro jogador
You don't have permission to clear another player's inventory (missing privilege: @1).=Você não tem permissão para limpar o inventário de outro jogador (privilégio faltando: @1).
@1 cleared your inventory.=@1 limpou seu inventário.
Cleared @1's inventory.=Inventário de @1 limpo.
Player must be online to clear inventory!=O jogador deve estar online para limpar o inventário!
Players can't be killed, damage has been disabled.=Jogadores não podem ser mortos, o dano foi desativado.
Player @1 is not online.=Jogador @1 não está online.
You are already dead.=Você já está morto.
@1 is already dead.=@1 já está morto.
@1 has been killed.=@1 foi morto.
Kill player or yourself=Matar jogador ou a si mesmo
@1 joined the game.=@1 entrou no jogo.
@1 left the game.=@1 saiu do jogo.
@1 left the game (timed out).=@1 saiu do jogo (tempo esgotado)
(no description)=(sem descrição)
Can interact with things and modify the world=Pode interagir com as coisas e modificar o mundo
Can speak in chat=Pode falar no chat
Can modify basic privileges (@1)=Pode modificar privilégios básicos (@1)
Can modify privileges=Pode modificar privilégios
Can teleport self=Pode se teletransportar
Can teleport other players=Pode teletransportar outros jogadores
Can set the time of day using /time=Pode definir a hora do dia usando /time
Can do server maintenance stuff=Pode realizar tarefas de manutenção do servidor
Can bypass node protection in the world=Pode ignorar a proteção de nós no mundo
Can ban and unban players=Pode banir e desbanir jogadores
Can kick players=Pode chutar jogadores
Can use /give and /giveme=Pode usar /give e /giveme
Can use /setpassword and /clearpassword=Pode usar /setpassword e /clearpassword
Can use fly mode=Pode usar o modo voar
Can use fast mode=Pode usar o modo rápido
Can fly through solid nodes using noclip mode=Pode voar através de nós sólidos usando o modo noclip
Can use the rollback functionality=Pode usar a funcionalidade de reversão
Can enable wireframe=Pode ativar wireframe
Unknown Item=Item desconhecido
Air=Ar
Ignore=Ignorar
You can't place 'ignore' nodes!=Você não pode colocar nós 'ignorar'!
print [<filter>] | dump [<filter>] | save [<format> [<filter>]] | reset=print [<filtro>] | dump [<filtro>] | save [<formato> [<filtro>]] | reset
Handle the profiler and profiling data=Lidar com o criador de perfil e os dados de criação de perfil
Statistics written to action log.=Estatísticas salvas no log de ações.
Statistics were reset.=As estatísticas foram redefinidas.
Usage: @1=Uso: @1
Format can be one of txt, csv, lua, json, json_pretty (structures may be subject to change).=O formato pode ser txt, csv, lua, json, json_pretty (as estruturas podem estar sujeitas a alterações).
Values below show absolute/relative times spend per server step by the instrumented function.=Os valores abaixo mostram os tempos absolutos/relativos gastos por etapa do servidor pela função instrumentada.
A total of @1 sample(s) were taken.=Um total de @1 amostra(s) foi coletada.
The output is limited to '@1'.=A saída é limitada a '@1'.
Saving of profile failed: @1=Falha ao salvar o perfil: @1
Profile saved to @1=Perfil salvo em @1
You died=Você morreu
Respawn=Reviver

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Ai murit
Respawn=Reînviere

View file

@ -244,3 +244,5 @@ A total of @1 sample(s) were taken.=Всего было взято @1 образ
The output is limited to '@1'.=Вывод ограничен значением '@1'.
Saving of profile failed: @1=Не удалось сохранить данные профилирования: @1
Profile saved to @1=Данные профилирования сохранены в @1
You died=Вы умерли
Respawn=Возродиться

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Zomrel si
Respawn=Oživiť

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Umrl si
Respawn=Ponovno oživi

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Умро си
Respawn=Врати се у живот

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Umro/la si.
Respawn=Vrati se u zivot

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Du dog
Respawn=Återuppstå

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Umekufa.
Respawn=Respawn

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=sina moli
Respawn=o kama sin

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Öldün
Respawn=Yeniden Canlan

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Сез үлдегез
Respawn=Тергезелергә

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Ви загинули
Respawn=Відродитися

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=Bạn đã bị chết
Respawn=Hồi sinh

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=您已死亡
Respawn=重生

View file

@ -0,0 +1,3 @@
# textdomain: __builtin
You died=您已死亡
Respawn=重生

View file

@ -133,6 +133,8 @@ local function start_install(package, reason)
conf:set("release", package.release)
conf:write()
end
pkgmgr.reload_by_type(package.type)
end
end
@ -146,7 +148,6 @@ local function start_install(package, reason)
start_install(next.package, next.reason)
end
ui.update()
end
@ -181,14 +182,26 @@ function contentdb.get_package_by_id(id)
end
local function get_raw_dependencies(package)
if package.type ~= "mod" then
return {}
end
if package.raw_deps then
return package.raw_deps
-- Create a coroutine from `fn` and provide results to `callback` when complete (dead).
-- Returns a resumer function.
local function make_callback_coroutine(fn, callback)
local co = coroutine.create(fn)
local function resumer(...)
local ok, result = coroutine.resume(co, ...)
if not ok then
error(result)
elseif coroutine.status(co) == "dead" then
callback(result)
end
end
return resumer
end
local function get_raw_dependencies_async(package)
local url_fmt = "/api/packages/%s/dependencies/?only_hard=1&protocol_version=%s&engine_version=%s"
local version = core.get_version()
local base_url = core.settings:get("contentdb_url")
@ -197,11 +210,25 @@ local function get_raw_dependencies(package)
local http = core.get_http_api()
local response = http.fetch_sync({ url = url })
if not response.succeeded then
core.log("error", "Unable to fetch dependencies for " .. package.url_part)
return
return nil
end
return core.parse_json(response.data) or {}
end
local function get_raw_dependencies_co(package, resumer)
if package.type ~= "mod" then
return {}
end
if package.raw_deps then
return package.raw_deps
end
local data = core.parse_json(response.data) or {}
core.handle_async(get_raw_dependencies_async, package, resumer)
local data = coroutine.yield()
if not data then
return nil
end
for id, raw_deps in pairs(data) do
local package2 = contentdb.package_by_id[id:lower()]
@ -222,8 +249,8 @@ local function get_raw_dependencies(package)
end
function contentdb.has_hard_deps(package)
local raw_deps = get_raw_dependencies(package)
local function has_hard_deps_co(package, resumer)
local raw_deps = get_raw_dependencies_co(package, resumer)
if not raw_deps then
return nil
end
@ -238,8 +265,14 @@ function contentdb.has_hard_deps(package)
end
function contentdb.has_hard_deps(package, callback)
local resumer = make_callback_coroutine(has_hard_deps_co, callback)
resumer(package, resumer)
end
-- Recursively resolve dependencies, given the installed mods
local function resolve_dependencies_2(raw_deps, installed_mods, out)
local function resolve_dependencies_2_co(raw_deps, installed_mods, out, resumer)
local function resolve_dep(dep)
-- Check whether it's already installed
if installed_mods[dep.name] then
@ -289,9 +322,9 @@ local function resolve_dependencies_2(raw_deps, installed_mods, out)
local result = resolve_dep(dep)
out[dep.name] = result
if result and result.package and not result.installed then
local raw_deps2 = get_raw_dependencies(result.package)
local raw_deps2 = get_raw_dependencies_co(result.package, resumer)
if raw_deps2 then
resolve_dependencies_2(raw_deps2, installed_mods, out)
resolve_dependencies_2_co(raw_deps2, installed_mods, out, resumer)
end
end
end
@ -301,11 +334,10 @@ local function resolve_dependencies_2(raw_deps, installed_mods, out)
end
-- Resolve dependencies for a package, calls the recursive version.
function contentdb.resolve_dependencies(package, game)
local function resolve_dependencies_co(package, game, resumer)
assert(game)
local raw_deps = get_raw_dependencies(package)
local raw_deps = get_raw_dependencies_co(package, resumer)
local installed_mods = {}
local mods = {}
@ -319,7 +351,7 @@ function contentdb.resolve_dependencies(package, game)
end
local out = {}
if not resolve_dependencies_2(raw_deps, installed_mods, out) then
if not resolve_dependencies_2_co(raw_deps, installed_mods, out, resumer) then
return nil
end
@ -336,6 +368,13 @@ function contentdb.resolve_dependencies(package, game)
end
-- Resolve dependencies for a package, calls the recursive version.
function contentdb.resolve_dependencies(package, game, callback)
local resumer = make_callback_coroutine(resolve_dependencies_co, callback)
resumer(package, game, resumer)
end
local function fetch_pkgs(params)
local version = core.get_version()
local base_url = core.settings:get("contentdb_url")
@ -427,8 +466,9 @@ end
function contentdb.update_paths()
pkgmgr.load_all()
local mod_hash = {}
pkgmgr.refresh_globals()
for _, mod in pairs(pkgmgr.global_mods:get_list()) do
local cdb_id = pkgmgr.get_contentdb_id(mod)
if cdb_id then
@ -437,7 +477,6 @@ function contentdb.update_paths()
end
local game_hash = {}
pkgmgr.update_gamelist()
for _, game in pairs(pkgmgr.games) do
local cdb_id = pkgmgr.get_contentdb_id(game)
if cdb_id then
@ -446,7 +485,7 @@ function contentdb.update_paths()
end
local txp_hash = {}
for _, txp in pairs(pkgmgr.get_texture_packs()) do
for _, txp in pairs(pkgmgr.texture_packs) do
local cdb_id = pkgmgr.get_contentdb_id(txp)
if cdb_id then
txp_hash[contentdb.aliases[cdb_id] or cdb_id] = txp

View file

@ -63,21 +63,12 @@ local function install_or_update_package(this, package)
end
local function on_confirm()
local has_hard_deps = contentdb.has_hard_deps(package)
if has_hard_deps then
local dlg = create_install_dialog(package)
dlg:set_parent(this)
this:hide()
dlg:show()
elseif has_hard_deps == nil then
local dlg = messagebox("error_checking_deps",
fgettext("Error getting dependencies for package"))
dlg:set_parent(this)
this:hide()
dlg:show()
else
contentdb.queue_download(package, package.path and contentdb.REASON_UPDATE or contentdb.REASON_NEW)
end
local dlg = create_install_dialog(package)
dlg:set_parent(this)
this:hide()
dlg:show()
dlg:load_deps()
end
if package.type == "mod" and #pkgmgr.games == 0 then
@ -190,7 +181,7 @@ local function get_info_formspec(text)
return table.concat({
"formspec_version[6]",
"size[15.75,9.5]",
core.settings:get_bool("enable_touch") and "padding[0.01,0.01]" or "position[0.5,0.55]",
core.settings:get_bool("touch_gui") and "padding[0.01,0.01]" or "position[0.5,0.55]",
"label[4,4.35;", text, "]",
"container[0,", H - 0.8 - 0.375, "]",
@ -221,7 +212,7 @@ local function get_formspec(dlgdata)
local formspec = {
"formspec_version[6]",
"size[15.75,9.5]",
core.settings:get_bool("enable_touch") and "padding[0.01,0.01]" or "position[0.5,0.55]",
core.settings:get_bool("touch_gui") and "padding[0.01,0.01]" or "position[0.5,0.55]",
"style[status,downloading,queued;border=false]",
@ -472,7 +463,7 @@ end
local function handle_events(event)
if event == "DialogShow" then
-- On touchscreen, don't show the "MINETEST" header behind the dialog.
mm_game_theme.set_engine(core.settings:get_bool("enable_touch"))
mm_game_theme.set_engine(core.settings:get_bool("touch_gui"))
-- If ContentDB is already loaded, auto-install packages here.
do_auto_install()

View file

@ -15,7 +15,31 @@
--with this program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
local function is_still_visible(dlg)
local this = ui.find_by_name("install_dialog")
return this == dlg and not dlg.hidden
end
local function get_loading_formspec()
local TOUCH_GUI = core.settings:get_bool("touch_gui")
local w = TOUCH_GUI and 14 or 7
local formspec = {
"formspec_version[3]",
"size[", w, ",9.05]",
TOUCH_GUI and "padding[0.01,0.01]" or "position[0.5,0.55]",
"label[3,4.525;", fgettext("Loading..."), "]",
}
return table.concat(formspec)
end
local function get_formspec(data)
if not data.has_hard_deps_ready then
return get_loading_formspec()
end
local selected_game, selected_game_idx = pkgmgr.find_by_gameid(core.settings:get("menu_last_game"))
if not selected_game_idx then
selected_game_idx = 1
@ -27,15 +51,35 @@ local function get_formspec(data)
game_list[i] = core.formspec_escape(game.title)
end
if not data.deps_ready[selected_game_idx] and
not data.deps_loading[selected_game_idx] then
data.deps_loading[selected_game_idx] = true
contentdb.resolve_dependencies(data.package, selected_game, function(deps)
if not is_still_visible(data.dlg) then
return
end
data.deps_ready[selected_game_idx] = deps
ui.update()
end)
end
-- The value of `data.deps_ready[selected_game_idx]` may have changed
-- since the last if statement since `contentdb.resolve_dependencies`
-- calls the callback immediately if the dependencies are already cached.
if not data.deps_ready[selected_game_idx] then
return get_loading_formspec()
end
local package = data.package
local will_install_deps = data.will_install_deps
local deps_to_install = 0
local deps_not_found = 0
data.dependencies = contentdb.resolve_dependencies(package, selected_game)
data.deps_chosen = data.deps_ready[selected_game_idx]
local formatted_deps = {}
for _, dep in pairs(data.dependencies) do
for _, dep in pairs(data.deps_chosen) do
formatted_deps[#formatted_deps + 1] = "#fff"
formatted_deps[#formatted_deps + 1] = core.formspec_escape(dep.name)
if dep.installed then
@ -66,18 +110,18 @@ local function get_formspec(data)
message_bg = mt_color_orange
end
local ENABLE_TOUCH = core.settings:get_bool("enable_touch")
local TOUCH_GUI = core.settings:get_bool("touch_gui")
local w = ENABLE_TOUCH and 14 or 7
local w = TOUCH_GUI and 14 or 7
local padded_w = w - 2*0.375
local dropdown_w = ENABLE_TOUCH and 10.2 or 4.25
local dropdown_w = TOUCH_GUI and 10.2 or 4.25
local button_w = (padded_w - 0.25) / 3
local button_pad = button_w / 2
local formspec = {
"formspec_version[3]",
"size[", w, ",9.05]",
ENABLE_TOUCH and "padding[0.01,0.01]" or "position[0.5,0.55]",
TOUCH_GUI and "padding[0.01,0.01]" or "position[0.5,0.55]",
"style[title;border=false]",
"box[0,0;", w, ",0.8;#3333]",
"button[0,0;", w, ",0.8;title;", fgettext("Install $1", package.title) , "]",
@ -128,7 +172,7 @@ local function handle_submit(this, fields)
contentdb.queue_download(data.package, contentdb.REASON_NEW)
if data.will_install_deps then
for _, dep in pairs(data.dependencies) do
for _, dep in pairs(data.deps_chosen) do
if not dep.is_optional and not dep.installed and dep.package then
contentdb.queue_download(dep.package, contentdb.REASON_DEPENDENCY)
end
@ -153,10 +197,50 @@ local function handle_submit(this, fields)
end
local function load_deps(dlg)
local package = dlg.data.package
contentdb.has_hard_deps(package, function(result)
if not is_still_visible(dlg) then
return
end
if result == nil then
local parent = dlg.parent
dlg:delete()
local dlg2 = messagebox("error_checking_deps",
fgettext("Error getting dependencies for package $1", package.url_part))
dlg2:set_parent(parent)
parent:hide()
dlg2:show()
elseif result == false then
contentdb.queue_download(package, package.path and contentdb.REASON_UPDATE or contentdb.REASON_NEW)
dlg:delete()
else
assert(result == true)
dlg.data.has_hard_deps_ready = true
end
ui.update()
end)
end
function create_install_dialog(package)
local dlg = dialog_create("install_dialog", get_formspec, handle_submit, nil)
dlg.data.dependencies = nil
dlg.data.deps_chosen = nil
dlg.data.package = package
dlg.data.will_install_deps = true
dlg.data.has_hard_deps_ready = false
dlg.data.deps_ready = {}
dlg.data.deps_loading = {}
dlg.load_deps = load_deps
-- `get_formspec` needs to access `dlg` to check whether it's still open.
-- It doesn't suffice to check that any "install_dialog" instance is open
-- via `ui.find_by_name`, it's necessary to check for this exact instance.
dlg.data.dlg = dlg
return dlg
end

View file

@ -110,7 +110,7 @@ pkgmgr = {}
-- @param modpack Currently processing modpack or nil/"" if none (recursion)
function pkgmgr.get_mods(path, virtual_path, listing, modpack)
local mods = core.get_dir_list(path, true)
local added = {}
for _, name in ipairs(mods) do
if name:sub(1, 1) ~= "." then
local mod_path = path .. DIR_DELIM .. name
@ -120,6 +120,7 @@ function pkgmgr.get_mods(path, virtual_path, listing, modpack)
parent_dir = path,
}
listing[#listing + 1] = toadd
added[#added + 1] = toadd
-- Get config file
local mod_conf
@ -150,8 +151,6 @@ function pkgmgr.get_mods(path, virtual_path, listing, modpack)
toadd.virtual_path = mod_virtual_path
toadd.type = "mod"
pkgmgr.update_translations({ toadd })
-- Check modpack.txt
-- Note: modpack.conf is already checked above
local modpackfile = io.open(mod_path .. DIR_DELIM .. "modpack.txt")
@ -171,6 +170,8 @@ function pkgmgr.get_mods(path, virtual_path, listing, modpack)
end
end
pkgmgr.update_translations(added)
if not modpack then
-- Sort all when the recursion is done
table.sort(listing, function(a, b)
@ -180,12 +181,13 @@ function pkgmgr.get_mods(path, virtual_path, listing, modpack)
end
--------------------------------------------------------------------------------
function pkgmgr.get_texture_packs()
function pkgmgr.reload_texture_packs()
local txtpath = core.get_texturepath()
local txtpath_system = core.get_texturepath_share()
local retval = {}
load_texture_packs(txtpath, retval)
-- on portable versions these two paths coincide. It avoids loading the path twice
if txtpath ~= txtpath_system then
load_texture_packs(txtpath_system, retval)
@ -197,11 +199,13 @@ function pkgmgr.get_texture_packs()
return a.title:lower() < b.title:lower()
end)
return retval
pkgmgr.texture_packs = retval
end
--------------------------------------------------------------------------------
function pkgmgr.get_all()
pkgmgr.load_all()
local result = {}
for _, mod in pairs(pkgmgr.global_mods:get_list()) do
@ -210,7 +214,7 @@ function pkgmgr.get_all()
for _, game in pairs(pkgmgr.games) do
result[#result + 1] = game
end
for _, txp in pairs(pkgmgr.get_texture_packs()) do
for _, txp in pairs(pkgmgr.texture_packs) do
result[#result + 1] = txp
end
@ -288,7 +292,7 @@ end
function pkgmgr.render_packagelist(render_list, use_technical_names, with_icon)
if not render_list then
if not pkgmgr.global_mods then
pkgmgr.refresh_globals()
pkgmgr.reload_global_mods()
end
render_list = pkgmgr.global_mods
end
@ -549,6 +553,7 @@ function pkgmgr.get_worldconfig(worldpath)
end
--------------------------------------------------------------------------------
-- Caller is responsible for reloading content types (see reload_by_type)
function pkgmgr.install_dir(expected_type, path, basename, targetpath)
assert(type(expected_type) == "string")
assert(type(path) == "string")
@ -615,12 +620,6 @@ function pkgmgr.install_dir(expected_type, path, basename, targetpath)
fgettext_ne("Failed to install $1 to $2", basename, targetpath)
end
if basefolder.type == "game" then
pkgmgr.update_gamelist()
else
pkgmgr.refresh_globals()
end
return targetpath, nil
end
@ -742,7 +741,7 @@ function pkgmgr.comparemod(elem1,elem2)
end
--------------------------------------------------------------------------------
function pkgmgr.refresh_globals()
function pkgmgr.reload_global_mods()
local function is_equal(element,uid) --uid match
if element.name == uid then
return true
@ -774,7 +773,7 @@ function pkgmgr.get_game_mods(gamespec, retval)
end
--------------------------------------------------------------------------------
function pkgmgr.update_gamelist()
function pkgmgr.reload_games()
pkgmgr.games = core.get_games()
table.sort(pkgmgr.games, function(a, b)
return a.title:lower() < b.title:lower()
@ -782,6 +781,32 @@ function pkgmgr.update_gamelist()
pkgmgr.update_translations(pkgmgr.games)
end
--------------------------------------------------------------------------------
function pkgmgr.reload_by_type(type)
if type == "game" then
pkgmgr.reload_games()
elseif type == "txp" then
pkgmgr.reload_texture_packs()
elseif type == "mod" or type == "modpack" then
pkgmgr.reload_global_mods()
else
error("Unknown package type: " .. type)
end
end
--------------------------------------------------------------------------------
function pkgmgr.load_all()
if not pkgmgr.global_mods then
pkgmgr.reload_global_mods()
end
if not pkgmgr.games then
pkgmgr.reload_games()
end
if not pkgmgr.texture_packs then
pkgmgr.reload_texture_packs()
end
end
--------------------------------------------------------------------------------
function pkgmgr.update_translations(list)
for _, item in ipairs(list) do
@ -831,4 +856,4 @@ end
--------------------------------------------------------------------------------
-- read initial data
--------------------------------------------------------------------------------
pkgmgr.update_gamelist()
pkgmgr.reload_games()

View file

@ -46,6 +46,9 @@ local function reset()
function core.get_texturepath()
return txp_dir
end
function core.get_texturepath_share()
return txp_dir
end
function core.get_modpath()
return mods_dir
end
@ -59,13 +62,6 @@ local function reset()
setfenv(loadfile("builtin/common/misc_helpers.lua"), env)()
setfenv(loadfile("builtin/mainmenu/content/pkgmgr.lua"), env)()
function env.pkgmgr.update_gamelist()
table.insert(calls, { "update_gamelist" })
end
function env.pkgmgr.refresh_globals()
table.insert(calls, { "refresh_globals" })
end
function env.assert_calls(list)
assert.are.same(list, calls)
end
@ -113,7 +109,6 @@ describe("install_dir", function()
env.assert_calls({
{ "delete_dir", mods_dir .. "/mymod" },
{ "copy_dir", "/tmp/123", mods_dir .. "/mymod", false },
{ "refresh_globals" },
})
end)
@ -129,7 +124,6 @@ describe("install_dir", function()
env.assert_calls({
{ "delete_dir", mods_dir .. "/mymod" },
{ "copy_dir", "/tmp/123", mods_dir .. "/mymod", false },
{ "refresh_globals" },
})
end)
@ -145,7 +139,6 @@ describe("install_dir", function()
env.assert_calls({
{ "delete_dir", games_dir .. "/mygame" },
{ "copy_dir", "/tmp/123", games_dir .. "/mygame", false },
{ "update_gamelist" },
})
end)
@ -161,7 +154,6 @@ describe("install_dir", function()
env.assert_calls({
{ "delete_dir", mods_dir .. "/123" },
{ "copy_dir", "/tmp/123", mods_dir .. "/123", false },
{ "refresh_globals" },
})
end)
@ -188,7 +180,6 @@ describe("install_dir", function()
env.assert_calls({
{ "delete_dir", "/tmp/alt-target" },
{ "copy_dir", "/tmp/123", "/tmp/alt-target", false },
{ "refresh_globals" },
})
end)
@ -238,6 +229,5 @@ describe("install_dir", function()
path, message = env.pkgmgr.install_dir("txp", "/tmp/123", "name", nil)
assert.is._not._nil(path)
assert.is._nil(message)
end)
end)

View file

@ -31,7 +31,7 @@ local cache_file_path = core.get_cache_path() .. DIR_DELIM .. "cdb" .. DIR_DELIM
local has_fetched = false
local latest_releases
do
if check_cache_age("cdb_updates_last_checked", 3 * 3600) then
if check_cache_age("cdb_updates_last_checked", 24 * 3600) then
local f = io.open(cache_file_path, "r")
local data = ""
if f then
@ -72,9 +72,6 @@ end
local function has_packages_from_cdb()
pkgmgr.refresh_globals()
pkgmgr.update_gamelist()
for _, content in pairs(pkgmgr.get_all()) do
if pkgmgr.get_contentdb_id(content) then
return true
@ -127,9 +124,6 @@ function update_detector.get_all()
return {}
end
pkgmgr.refresh_globals()
pkgmgr.update_gamelist()
local ret = {}
local all_content = pkgmgr.get_all()
for _, content in ipairs(all_content) do

View file

@ -0,0 +1,85 @@
{
"#": "https://github.com/orgs/minetest/teams/engine/members",
"core_developers": [
"Perttu Ahola (celeron55) <celeron55@gmail.com> [Project founder]",
"sfan5 <sfan5@live.de>",
"ShadowNinja <shadowninja@minetest.net>",
"Nathanaëlle Courant (Nore/Ekdohibs) <nore@mesecons.net>",
"Loic Blot (nerzhul/nrz) <loic.blot@unix-experience.fr>",
"Andrew Ward (rubenwardy) <rw@rubenwardy.com>",
"Krock/SmallJoker <mk939@ymail.com>",
"Lars Hofhansl <larsh@apache.org>",
"v-rob <robinsonvincent89@gmail.com>",
"Desour/DS",
"srifqi",
"Gregor Parzefall (grorp)",
"Lars Müller (luatic)"
],
"previous_core_developers": [
"BlockMen",
"Maciej Kasatkin (RealBadAngel) [RIP]",
"Lisa Milne (darkrose) <lisa@ltmnet.com>",
"proller",
"Ilya Zhuravlev (xyz) <xyz@minetest.net>",
"PilzAdam <pilzadam@minetest.net>",
"est31 <MTest31@outlook.com>",
"kahrl <kahrl@gmx.net>",
"Ryan Kwolek (kwolekr) <kwolekr@minetest.net>",
"sapier",
"Zeno",
"Auke Kok (sofar) <sofar@foo-projects.org>",
"Aaron Suen <warr1024@gmail.com>",
"paramat",
"Pierre-Yves Rollo <dev@pyrollo.com>",
"hecks",
"Jude Melton-Houghton (TurkeyMcMac) [RIP]",
"Hugues Ross <hugues.ross@gmail.com>",
"Dmitry Kostenko (x2048) <codeforsmile@gmail.com>"
],
"#": "Currently only https://github.com/orgs/minetest/teams/triagers/members",
"core_team": [
"Zughy [Issue triager]",
"wsor [Issue triager]",
"Hugo Locurcio (Calinou) [Issue triager]"
],
"#": "For updating active/previous contributors, see the script in ./util/gather_git_credits.py",
"contributors": [
"cx384",
"numzero",
"AFCMS",
"sfence",
"Wuzzy",
"ROllerozxa",
"JosiahWI",
"OgelGames",
"David Heidelberg",
"1F616EMO",
"HybridDog",
"Bradley Pierce (Thresher)",
"savilli",
"Stvk imension",
"y5nw",
"chmodsayshello",
"jordan4ibanez",
"superfloh247"
],
"previous_contributors": [
"Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net> [Minetest logo]",
"red-001 <red-001@outlook.ie>",
"Giuseppe Bilotta",
"HybridDog",
"ClobberXD",
"Dániel Juhász (juhdanad) <juhdanad@gmail.com>",
"MirceaKitsune <mirceakitsune@gmail.com>",
"Jean-Patrick Guerrero (kilbith)",
"MoNTE48",
"Constantin Wenger (SpeedProg)",
"Ciaran Gultnieks (CiaranG)",
"Paul Ouellette (pauloue)",
"stujones11",
"Rogier <rogier777@gmail.com>",
"Gregory Currie (gregorycu)",
"JacobF",
"Jeija <jeija@mesecons.net>"
]
}

View file

@ -126,7 +126,7 @@ local function get_formspec(data)
local retval =
"size[11.5,7.5,true]" ..
"label[0.5,0;" .. fgettext("World:") .. "]" ..
"label[1.75,0;" .. data.worldspec.name .. "]"
"label[1.75,0;" .. core.formspec_escape(data.worldspec.name) .. "]"
if mod.is_modpack or mod.type == "game" then
local info = core.formspec_escape(

View file

@ -37,11 +37,7 @@ local function delete_content_buttonhandler(this, fields)
gamedata.errormessage = fgettext_ne("pkgmgr: failed to delete \"$1\"", this.data.content.path)
end
if this.data.content.type == "game" then
pkgmgr.update_gamelist()
else
pkgmgr.refresh_globals()
end
pkgmgr.reload_by_type(this.data.content.type)
else
gamedata.errormessage = fgettext_ne("pkgmgr: invalid path \"$1\"", this.data.content.path)
end

View file

@ -45,7 +45,7 @@ local function rename_modpack_buttonhandler(this, fields)
local oldpath = this.data.mod.path
local targetpath = this.data.mod.parent_dir .. DIR_DELIM .. fields["te_modpack_name"]
os.rename(oldpath, targetpath)
pkgmgr.refresh_globals()
pkgmgr.reload_global_mods()
pkgmgr.selected_mod = pkgmgr.global_mods:get_current_index(
pkgmgr.global_mods:raw_index_by_uid(fields["te_modpack_name"]))

View file

@ -23,6 +23,13 @@ mt_color_dark_green = "#25C191"
mt_color_orange = "#FF8800"
mt_color_red = "#FF3300"
MAIN_TAB_W = 15.5
MAIN_TAB_H = 7.1
TABHEADER_H = 0.85
GAMEBAR_H = 1.25
GAMEBAR_OFFSET_DESKTOP = 0.375
GAMEBAR_OFFSET_TOUCH = 0.15
local menupath = core.get_mainmenu_path()
local basepath = core.get_builtin_path()
defaulttexturedir = core.get_texturepath_share() .. DIR_DELIM .. "base" ..
@ -89,7 +96,7 @@ local function init_globals()
mm_game_theme.set_engine() -- This is just a fallback.
-- Create main tabview
local tv_main = tabview_create("maintab", {x = 15.5, y = 7.1}, {x = 0, y = 0})
local tv_main = tabview_create("maintab", {x = MAIN_TAB_W, y = MAIN_TAB_H}, {x = 0, y = 0})
tv_main:set_autosave_tab(true)
tv_main:add(tabs.local_game)

View file

@ -306,17 +306,36 @@ function make.flags(setting)
"label[0,0.1;" .. get_label(setting) .. "]",
}
local value = core.settings:get(setting.name) or setting.default
self.resettable = core.settings:has(setting.name)
checkboxes = {}
for _, name in ipairs(value:split(",")) do
name = name:trim()
if name:sub(1, 2) == "no" then
checkboxes[name:sub(3)] = false
elseif name ~= "" then
checkboxes[name] = true
for _, name in ipairs(setting.possible) do
checkboxes[name] = false
end
local function apply_flags(flag_string, what)
local prefixed_flags = {}
for _, name in ipairs(flag_string:split(",")) do
prefixed_flags[name:trim()] = true
end
for _, name in ipairs(setting.possible) do
local enabled = prefixed_flags[name]
local disabled = prefixed_flags["no" .. name]
if enabled and disabled then
core.log("warning", "Flag " .. name .. " in " .. what .. " " ..
setting.name .. " both enabled and disabled, ignoring")
elseif enabled then
checkboxes[name] = true
elseif disabled then
checkboxes[name] = false
end
end
end
-- First apply the default, which is necessary since flags
-- which are not overridden may be missing from the value.
apply_flags(setting.default, "default for setting")
local value = core.settings:get(setting.name)
if value then
apply_flags(value, "setting")
end
local columns = math.max(math.floor(avail_w / 2.5), 1)
@ -325,18 +344,16 @@ function make.flags(setting)
local y = 0.55
for _, possible in ipairs(setting.possible) do
if possible:sub(1, 2) ~= "no" then
if x >= avail_w then
x = 0
y = y + 0.5
end
local is_checked = checkboxes[possible]
fs[#fs + 1] = ("checkbox[%f,%f;%s;%s;%s]"):format(
x, y, setting.name .. "_" .. possible,
core.formspec_escape(possible), tostring(is_checked))
x = x + column_width
if x >= avail_w then
x = 0
y = y + 0.5
end
local is_checked = checkboxes[possible]
fs[#fs + 1] = ("checkbox[%f,%f;%s;%s;%s]"):format(
x, y, setting.name .. "_" .. possible,
core.formspec_escape(possible), tostring(is_checked))
x = x + column_width
end
return table.concat(fs, ""), y + 0.25
@ -355,12 +372,10 @@ function make.flags(setting)
if changed then
local values = {}
for _, name in ipairs(setting.possible) do
if name:sub(1, 2) ~= "no" then
if checkboxes[name] then
table.insert(values, name)
else
table.insert(values, "no" .. name)
end
if checkboxes[name] then
table.insert(values, name)
else
table.insert(values, "no" .. name)
end
end

View file

@ -22,16 +22,27 @@ local component_funcs = dofile(core.get_mainmenu_path() .. DIR_DELIM ..
local shadows_component = dofile(core.get_mainmenu_path() .. DIR_DELIM ..
"settings" .. DIR_DELIM .. "shadows_component.lua")
local full_settings = settingtypes.parse_config_file(false, true)
local loaded = false
local full_settings
local info_icon_path = core.formspec_escape(defaulttexturedir .. "settings_info.png")
local reset_icon_path = core.formspec_escape(defaulttexturedir .. "settings_reset.png")
local all_pages = {}
local page_by_id = {}
local filtered_pages = all_pages
local filtered_page_by_id = page_by_id
local function get_setting_info(name)
for _, entry in ipairs(full_settings) do
if entry.type ~= "category" and entry.name == name then
return entry
end
end
return nil
end
local function add_page(page)
assert(type(page.id) == "string")
assert(type(page.title) == "string")
@ -46,49 +57,6 @@ local function add_page(page)
end
local change_keys = {
query_text = "Controls",
requires = {
keyboard_mouse = true,
},
get_formspec = function(self, avail_w)
local btn_w = math.min(avail_w, 3)
return ("button[0,0;%f,0.8;btn_change_keys;%s]"):format(btn_w, fgettext("Controls")), 0.8
end,
on_submit = function(self, fields)
if fields.btn_change_keys then
core.show_keys_menu()
end
end,
}
add_page({
id = "accessibility",
title = fgettext_ne("Accessibility"),
content = {
"language",
{ heading = fgettext_ne("General") },
"font_size",
"chat_font_size",
"gui_scaling",
"hud_scaling",
"show_nametag_backgrounds",
{ heading = fgettext_ne("Chat") },
"console_height",
"console_alpha",
"console_color",
{ heading = fgettext_ne("Controls") },
"autojump",
"safe_dig_and_place",
{ heading = fgettext_ne("Movement") },
"arm_inertia",
"view_bobbing_amount",
"fall_bobbing_amount",
},
})
local function load_settingtypes()
local page = nil
local section = nil
@ -129,94 +97,134 @@ local function load_settingtypes()
end
end
end
load_settingtypes()
table.insert(page_by_id.controls_keyboard_and_mouse.content, 1, change_keys)
do
local content = page_by_id.graphics_and_audio_shaders.content
local idx = table.indexof(content, "enable_dynamic_shadows")
table.insert(content, idx, shadows_component)
end
local function get_setting_info(name)
for _, entry in ipairs(full_settings) do
if entry.type ~= "category" and entry.name == name then
return entry
end
local function load()
if loaded then
return
end
loaded = true
full_settings = settingtypes.parse_config_file(false, true)
local change_keys = {
query_text = "Controls",
requires = {
touch_controls = false,
},
get_formspec = function(self, avail_w)
local btn_w = math.min(avail_w, 3)
return ("button[0,0;%f,0.8;btn_change_keys;%s]"):format(btn_w, fgettext("Controls")), 0.8
end,
on_submit = function(self, fields)
if fields.btn_change_keys then
core.show_keys_menu()
end
end,
}
add_page({
id = "accessibility",
title = fgettext_ne("Accessibility"),
content = {
"language",
{ heading = fgettext_ne("General") },
"font_size",
"chat_font_size",
"gui_scaling",
"hud_scaling",
"show_nametag_backgrounds",
{ heading = fgettext_ne("Chat") },
"console_height",
"console_alpha",
"console_color",
{ heading = fgettext_ne("Controls") },
"autojump",
"safe_dig_and_place",
{ heading = fgettext_ne("Movement") },
"arm_inertia",
"view_bobbing_amount",
"fall_bobbing_amount",
},
})
load_settingtypes()
table.insert(page_by_id.controls_keyboard_and_mouse.content, 1, change_keys)
do
local content = page_by_id.graphics_and_audio_shaders.content
local idx = table.indexof(content, "enable_dynamic_shadows")
table.insert(content, idx, shadows_component)
end
return nil
-- These must not be translated, as they need to show in the local
-- language no matter the user's current language.
-- This list must be kept in sync with src/unsupported_language_list.txt.
get_setting_info("language").option_labels = {
[""] = fgettext_ne("(Use system language)"),
--ar = " [ar]", blacklisted
be = "Беларуская [be]",
bg = "Български [bg]",
ca = "Català [ca]",
cs = "Česky [cs]",
cy = "Cymraeg [cy]",
da = "Dansk [da]",
de = "Deutsch [de]",
--dv = " [dv]", blacklisted
el = "Ελληνικά [el]",
en = "English [en]",
eo = "Esperanto [eo]",
es = "Español [es]",
et = "Eesti [et]",
eu = "Euskara [eu]",
fi = "Suomi [fi]",
fil = "Wikang Filipino [fil]",
fr = "Français [fr]",
gd = "Gàidhlig [gd]",
gl = "Galego [gl]",
--he = " [he]", blacklisted
--hi = " [hi]", blacklisted
hu = "Magyar [hu]",
id = "Bahasa Indonesia [id]",
it = "Italiano [it]",
ja = "日本語 [ja]",
jbo = "Lojban [jbo]",
kk = "Қазақша [kk]",
--kn = " [kn]", blacklisted
ko = "한국어 [ko]",
ky = "Kırgızca / Кыргызча [ky]",
lt = "Lietuvių [lt]",
lv = "Latviešu [lv]",
mn = "Монгол [mn]",
mr = "मराठी [mr]",
ms = "Bahasa Melayu [ms]",
--ms_Arab = " [ms_Arab]", blacklisted
nb = "Norsk Bokmål [nb]",
nl = "Nederlands [nl]",
nn = "Norsk Nynorsk [nn]",
oc = "Occitan [oc]",
pl = "Polski [pl]",
pt = "Português [pt]",
pt_BR = "Português do Brasil [pt_BR]",
ro = "Română [ro]",
ru = "Русский [ru]",
sk = "Slovenčina [sk]",
sl = "Slovenščina [sl]",
sr_Cyrl = "Српски [sr_Cyrl]",
sr_Latn = "Srpski (Latinica) [sr_Latn]",
sv = "Svenska [sv]",
sw = "Kiswahili [sw]",
--th = " [th]", blacklisted
tr = "Türkçe [tr]",
tt = "Tatarça [tt]",
uk = "Українська [uk]",
vi = "Tiếng Việt [vi]",
zh_CN = "中文 (简体) [zh_CN]",
zh_TW = "正體中文 (繁體) [zh_TW]",
}
end
-- These must not be translated, as they need to show in the local
-- language no matter the user's current language.
-- This list must be kept in sync with src/unsupported_language_list.txt.
get_setting_info("language").option_labels = {
[""] = fgettext_ne("(Use system language)"),
--ar = " [ar]", blacklisted
be = "Беларуская [be]",
bg = "Български [bg]",
ca = "Català [ca]",
cs = "Česky [cs]",
cy = "Cymraeg [cy]",
da = "Dansk [da]",
de = "Deutsch [de]",
--dv = " [dv]", blacklisted
el = "Ελληνικά [el]",
en = "English [en]",
eo = "Esperanto [eo]",
es = "Español [es]",
et = "Eesti [et]",
eu = "Euskara [eu]",
fi = "Suomi [fi]",
fil = "Wikang Filipino [fil]",
fr = "Français [fr]",
gd = "Gàidhlig [gd]",
gl = "Galego [gl]",
--he = " [he]", blacklisted
--hi = " [hi]", blacklisted
hu = "Magyar [hu]",
id = "Bahasa Indonesia [id]",
it = "Italiano [it]",
ja = "日本語 [ja]",
jbo = "Lojban [jbo]",
kk = "Қазақша [kk]",
--kn = " [kn]", blacklisted
ko = "한국어 [ko]",
ky = "Kırgızca / Кыргызча [ky]",
lt = "Lietuvių [lt]",
lv = "Latviešu [lv]",
mn = "Монгол [mn]",
mr = "मराठी [mr]",
ms = "Bahasa Melayu [ms]",
--ms_Arab = " [ms_Arab]", blacklisted
nb = "Norsk Bokmål [nb]",
nl = "Nederlands [nl]",
nn = "Norsk Nynorsk [nn]",
oc = "Occitan [oc]",
pl = "Polski [pl]",
pt = "Português [pt]",
pt_BR = "Português do Brasil [pt_BR]",
ro = "Română [ro]",
ru = "Русский [ru]",
sk = "Slovenčina [sk]",
sl = "Slovenščina [sl]",
sr_Cyrl = "Српски [sr_Cyrl]",
sr_Latn = "Srpski (Latinica) [sr_Latn]",
sv = "Svenska [sv]",
sw = "Kiswahili [sw]",
--th = " [th]", blacklisted
tr = "Türkçe [tr]",
tt = "Tatarça [tt]",
uk = "Українська [uk]",
vi = "Tiếng Việt [vi]",
zh_CN = "中文 (简体) [zh_CN]",
zh_TW = "正體中文 (繁體) [zh_TW]",
}
-- See if setting matches keywords
local function get_setting_match_weight(entry, query_keywords)
local setting_score = 0
@ -316,8 +324,6 @@ local function check_requirements(name, requires)
local special = {
android = PLATFORM == "Android",
desktop = PLATFORM ~= "Android",
touchscreen_gui = core.settings:get_bool("enable_touch"),
keyboard_mouse = not core.settings:get_bool("enable_touch"),
shaders_support = shaders_support,
shaders = core.settings:get_bool("enable_shaders") and shaders_support,
opengl = video_driver == "opengl",
@ -449,13 +455,13 @@ local function get_formspec(dialogdata)
local extra_h = 1 -- not included in tabsize.height
local tabsize = {
width = core.settings:get_bool("enable_touch") and 16.5 or 15.5,
height = core.settings:get_bool("enable_touch") and (10 - extra_h) or 12,
width = core.settings:get_bool("touch_gui") and 16.5 or 15.5,
height = core.settings:get_bool("touch_gui") and (10 - extra_h) or 12,
}
local scrollbar_w = core.settings:get_bool("enable_touch") and 0.6 or 0.4
local scrollbar_w = core.settings:get_bool("touch_gui") and 0.6 or 0.4
local left_pane_width = core.settings:get_bool("enable_touch") and 4.5 or 4.25
local left_pane_width = core.settings:get_bool("touch_gui") and 4.5 or 4.25
local left_pane_padding = 0.25
local search_width = left_pane_width + scrollbar_w - (0.75 * 2)
@ -469,7 +475,7 @@ local function get_formspec(dialogdata)
local fs = {
"formspec_version[6]",
"size[", tostring(tabsize.width), ",", tostring(tabsize.height + extra_h), "]",
core.settings:get_bool("enable_touch") and "padding[0.01,0.01]" or "",
core.settings:get_bool("touch_gui") and "padding[0.01,0.01]" or "",
"bgcolor[#0000]",
-- HACK: this is needed to allow resubmitting the same formspec
@ -644,15 +650,15 @@ local function buttonhandler(this, fields)
write_settings_early()
end
-- enable_touch is a checkbox in a setting component. We handle this
-- touch_controls is a checkbox in a setting component. We handle this
-- setting differently so we can hide/show pages using the next if-statement
if fields.enable_touch ~= nil then
local value = core.is_yes(fields.enable_touch)
core.settings:set_bool("enable_touch", value)
if fields.touch_controls ~= nil then
local value = core.is_yes(fields.touch_controls)
core.settings:set_bool("touch_controls", value)
write_settings_early()
end
if fields.show_advanced ~= nil or fields.enable_touch ~= nil then
if fields.show_advanced ~= nil or fields.touch_controls ~= nil then
local suggested_page_id = update_filtered_pages(dialogdata.query)
dialogdata.components = nil
@ -734,6 +740,7 @@ end
function create_settings_dlg()
load()
local dlg = dialog_create("dlg_settings", get_formspec, buttonhandler, eventhandler)
dlg.data.page_id = update_filtered_pages("")

View file

@ -439,9 +439,9 @@ function settingtypes.parse_config_file(read_all, parse_mods)
end
-- Parse mods
pkgmgr.load_all()
local mods_category_initialized = false
local mods = {}
pkgmgr.get_mods(core.get_modpath(), "mods", mods)
local mods = pkgmgr.global_mods:get_list()
table.sort(mods, function(a, b) return a.name < b.name end)
for _, mod in ipairs(mods) do

View file

@ -15,90 +15,6 @@
--with this program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-- https://github.com/orgs/minetest/teams/engine/members
local core_developers = {
"Perttu Ahola (celeron55) <celeron55@gmail.com> [Project founder]",
"sfan5 <sfan5@live.de>",
"ShadowNinja <shadowninja@minetest.net>",
"Nathanaëlle Courant (Nore/Ekdohibs) <nore@mesecons.net>",
"Loic Blot (nerzhul/nrz) <loic.blot@unix-experience.fr>",
"Andrew Ward (rubenwardy) <rw@rubenwardy.com>",
"Krock/SmallJoker <mk939@ymail.com>",
"Lars Hofhansl <larsh@apache.org>",
"v-rob <robinsonvincent89@gmail.com>",
"Desour/DS",
"srifqi",
"Gregor Parzefall (grorp)",
}
-- currently only https://github.com/orgs/minetest/teams/triagers/members
local core_team = {
"Zughy [Issue triager]",
"wsor [Issue triager]",
"Hugo Locurcio (Calinou) [Issue triager]",
}
-- For updating active/previous contributors, see the script in ./util/gather_git_credits.py
local active_contributors = {
"Wuzzy [Features, translations, documentation]",
"numzero [Optimizations, work on OpenGL driver]",
"ROllerozxa [Bugfixes, Mainmenu]",
"Lars Müller [Bugfixes]",
"AFCMS [Documentation]",
"savilli [Bugfixes]",
"fluxionary [Bugfixes]",
"Bradley Pierce (Thresher) [Documentation]",
"Stvk imension [Android]",
"JosiahWI [Code cleanups]",
"OgelGames [UI, Bugfixes]",
"ndren [Bugfixes]",
"Abdou-31 [Documentation]",
}
local previous_core_developers = {
"BlockMen",
"Maciej Kasatkin (RealBadAngel) [RIP]",
"Lisa Milne (darkrose) <lisa@ltmnet.com>",
"proller",
"Ilya Zhuravlev (xyz) <xyz@minetest.net>",
"PilzAdam <pilzadam@minetest.net>",
"est31 <MTest31@outlook.com>",
"kahrl <kahrl@gmx.net>",
"Ryan Kwolek (kwolekr) <kwolekr@minetest.net>",
"sapier",
"Zeno",
"Auke Kok (sofar) <sofar@foo-projects.org>",
"Aaron Suen <warr1024@gmail.com>",
"paramat",
"Pierre-Yves Rollo <dev@pyrollo.com>",
"hecks",
"Jude Melton-Houghton (TurkeyMcMac) [RIP]",
"Hugues Ross <hugues.ross@gmail.com>",
"Dmitry Kostenko (x2048) <codeforsmile@gmail.com>",
}
local previous_contributors = {
"Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net> [Minetest logo]",
"red-001 <red-001@outlook.ie>",
"Giuseppe Bilotta",
"HybridDog",
"ClobberXD",
"Dániel Juhász (juhdanad) <juhdanad@gmail.com>",
"MirceaKitsune <mirceakitsune@gmail.com>",
"Jean-Patrick Guerrero (kilbith)",
"MoNTE48",
"Constantin Wenger (SpeedProg)",
"Ciaran Gultnieks (CiaranG)",
"Paul Ouellette (pauloue)",
"stujones11",
"Rogier <rogier777@gmail.com>",
"Gregory Currie (gregorycu)",
"JacobF",
"Jeija <jeija@mesecons.net>",
}
local function prepare_credits(dest, source)
local string = table.concat(source, "\n") .. "\n"
@ -114,6 +30,13 @@ local function prepare_credits(dest, source)
table.insert(dest, string)
end
local function get_credits()
local f = assert(io.open(core.get_mainmenu_path() .. "/credits.json"))
local json = core.parse_json(f:read("*all"))
f:close()
return json
end
return {
name = "about",
caption = fgettext("About"),
@ -127,30 +50,32 @@ return {
"<tag name=gray color=#aaa>",
}
local credits = get_credits()
table.insert_all(hypertext, {
"<heading>", fgettext_ne("Core Developers"), "</heading>\n",
})
prepare_credits(hypertext, core_developers)
prepare_credits(hypertext, credits.core_developers)
table.insert_all(hypertext, {
"\n",
"<heading>", fgettext_ne("Core Team"), "</heading>\n",
})
prepare_credits(hypertext, core_team)
prepare_credits(hypertext, credits.core_team)
table.insert_all(hypertext, {
"\n",
"<heading>", fgettext_ne("Active Contributors"), "</heading>\n",
})
prepare_credits(hypertext, active_contributors)
prepare_credits(hypertext, credits.contributors)
table.insert_all(hypertext, {
"\n",
"<heading>", fgettext_ne("Previous Core Developers"), "</heading>\n",
})
prepare_credits(hypertext, previous_core_developers)
prepare_credits(hypertext, credits.previous_core_developers)
table.insert_all(hypertext, {
"\n",
"<heading>", fgettext_ne("Previous Contributors"), "</heading>\n",
})
prepare_credits(hypertext, previous_contributors)
prepare_credits(hypertext, credits.previous_contributors)
hypertext = table.concat(hypertext):sub(1, -2)

View file

@ -29,16 +29,11 @@ end
local packages_raw, packages
local function update_packages()
if not pkgmgr.global_mods then
pkgmgr.refresh_globals()
end
if not pkgmgr.games then
pkgmgr.update_gamelist()
end
pkgmgr.load_all()
packages_raw = {}
table.insert_all(packages_raw, pkgmgr.games)
table.insert_all(packages_raw, pkgmgr.get_texture_packs())
table.insert_all(packages_raw, pkgmgr.texture_packs)
table.insert_all(packages_raw, pkgmgr.global_mods:get_list())
local function get_data()
@ -207,6 +202,7 @@ local function handle_doubleclick(pkg)
core.settings:set("texture_path", pkg.path)
end
packages = nil
pkgmgr.reload_texture_packs()
mm_game_theme.init()
mm_game_theme.set_engine()
@ -271,6 +267,7 @@ local function handle_buttons(tabview, fields, tabname, tabdata)
core.settings:set("texture_path", txp_path)
packages = nil
pkgmgr.reload_texture_packs()
mm_game_theme.init()
mm_game_theme.set_engine()
@ -283,7 +280,7 @@ end
return {
name = "content",
caption = function()
local update_count = update_detector.get_count()
local update_count = core.settings:get_bool("contentdb_enable_updates_indicator") and update_detector.get_count() or 0
if update_count == 0 then
return fgettext("Content")
else

View file

@ -92,10 +92,16 @@ function singleplayer_refresh_gamebar()
end
end
local ENABLE_TOUCH = core.settings:get_bool("enable_touch")
local gamebar_pos_y = MAIN_TAB_H
+ TABHEADER_H -- tabheader included in formspec size
+ (ENABLE_TOUCH and GAMEBAR_OFFSET_TOUCH or GAMEBAR_OFFSET_DESKTOP)
local btnbar = buttonbar_create(
"game_button_bar",
core.settings:get_bool("enable_touch") and {x = 0, y = 7.25} or {x = 0, y = 7.475},
{x = 15.5, y = 1.25},
{x = 0, y = gamebar_pos_y},
{x = MAIN_TAB_W, y = GAMEBAR_H},
"#000000",
game_buttonbar_button_handler)

View file

@ -217,8 +217,9 @@ local function init()
-- Wrap register_lbm() to automatically instrument lbms.
local orig_register_lbm = core.register_lbm
core.register_lbm = function(spec)
spec.action = instrument {
func = spec.action,
local k = spec.bulk_action ~= nil and "bulk_action" or "action"
spec[k] = instrument {
func = spec[k],
class = "LBM",
label = spec.label or spec.name,
}

View file

@ -61,7 +61,7 @@
#
# # This is a comment
# #
# # Requires: shaders, enable_dynamic_shadows, !touchscreen_gui
# # Requires: shaders, enable_dynamic_shadows, !touch_controls
# name (Readable name) type type_args
#
# A requirement can be the name of a boolean setting or an engine-defined value.
@ -72,7 +72,6 @@
# * shaders_support (a video driver that supports shaders, may not be enabled)
# * shaders (both enable_shaders and shaders_support)
# * desktop / android
# * touchscreen_gui / keyboard_mouse
# * opengl / gles
# * You can negate any requirement by prepending with !
#
@ -92,7 +91,7 @@ camera_smoothing (Camera smoothing) float 0.0 0.0 0.99
# Smooths rotation of camera when in cinematic mode, 0 to disable. Enter cinematic mode by using the key set in Controls.
#
# Requires: keyboard_mouse
# Requires: !touch_controls
cinematic_camera_smoothing (Camera smoothing in cinematic mode) float 0.7 0.0 0.99
# If enabled, you can place nodes at the position (feet + eye level) where you stand.
@ -113,12 +112,12 @@ always_fly_fast (Always fly fast) bool true
# The time in seconds it takes between repeated node placements when holding
# the place button.
#
# Requires: keyboard_mouse
repeat_place_time (Place repetition interval) float 0.25 0.15 2.0
# Requires: !touch_controls
repeat_place_time (Place repetition interval) float 0.25 0.16 2.0
# The minimum time in seconds it takes between digging nodes when holding
# the dig button.
repeat_dig_time (Dig repetition interval) float 0.15 0.15 2.0
repeat_dig_time (Minimum dig repetition interval) float 0.0 0.0 2.0
# Automatically jump up single-node obstacles.
autojump (Automatic jumping) bool false
@ -132,63 +131,63 @@ safe_dig_and_place (Safe digging and placing) bool false
# Invert vertical mouse movement.
#
# Requires: keyboard_mouse
# Requires: !touch_controls
invert_mouse (Invert mouse) bool false
# Mouse sensitivity multiplier.
#
# Requires: keyboard_mouse
# Requires: !touch_controls
mouse_sensitivity (Mouse sensitivity) float 0.2 0.001 10.0
# Enable mouse wheel (scroll) for item selection in hotbar.
#
# Requires: keyboard_mouse
# Requires: !touch_controls
enable_hotbar_mouse_wheel (Hotbar: Enable mouse wheel for selection) bool true
# Invert mouse wheel (scroll) direction for item selection in hotbar.
#
# Requires: keyboard_mouse
# Requires: !touch_controls
invert_hotbar_mouse_wheel (Hotbar: Invert mouse wheel direction) bool false
[*Touchscreen]
# Enables touchscreen mode, allowing you to play the game with a touchscreen.
enable_touch (Enable touchscreen) bool true
# Enables the touchscreen controls, allowing you to play the game with a touchscreen.
touch_controls (Enable touchscreen controls) bool true
# Touchscreen sensitivity multiplier.
#
# Requires: touchscreen_gui
# Requires: touch_controls
touchscreen_sensitivity (Touchscreen sensitivity) float 0.2 0.001 10.0
# The length in pixels after which a touch interaction is considered movement.
#
# Requires: touchscreen_gui
# Requires: touch_controls
touchscreen_threshold (Movement threshold) int 20 0 100
# The delay in milliseconds after which a touch interaction is considered a long tap.
#
# Requires: touchscreen_gui
# Requires: touch_controls
touch_long_tap_delay (Threshold for long taps) int 400 100 1000
# Use crosshair to select object instead of whole screen.
# If enabled, a crosshair will be shown and will be used for selecting object.
#
# Requires: touchscreen_gui
# Requires: touch_controls
touch_use_crosshair (Use crosshair for touch screen) bool false
# Fixes the position of virtual joystick.
# If disabled, virtual joystick will center to first-touch's position.
#
# Requires: touchscreen_gui
# Requires: touch_controls
fixed_virtual_joystick (Fixed virtual joystick) bool false
# Use virtual joystick to trigger "Aux1" button.
# If enabled, virtual joystick will also tap "Aux1" button when out of main circle.
#
# Requires: touchscreen_gui
# Requires: touch_controls
virtual_joystick_triggers_aux1 (Virtual joystick triggers Aux1 button) bool false
# The gesture for for punching players/entities.
# The gesture for punching players/entities.
# This can be overridden by games and mods.
#
# * short_tap
@ -198,7 +197,7 @@ virtual_joystick_triggers_aux1 (Virtual joystick triggers Aux1 button) bool fals
# Known from the classic Minetest mobile controls.
# Combat is more or less impossible.
#
# Requires: touchscreen_gui
# Requires: touch_controls
touch_punch_gesture (Punch gesture) enum short_tap short_tap,long_tap
@ -404,6 +403,11 @@ enable_clouds (Clouds) bool true
# Requires: enable_clouds
enable_3d_clouds (3D clouds) bool true
# Use smooth cloud shading.
#
# Requires: enable_3d_clouds, enable_clouds
soft_clouds (Soft clouds) bool false
[**Filtering and Antialiasing]
# Use mipmaps when scaling textures. May slightly increase performance,
@ -506,6 +510,11 @@ water_wave_length (Waving liquids wavelength) float 20.0 0.1
# Requires: shaders, enable_waving_water
water_wave_speed (Waving liquids wave speed) float 5.0
# When enabled, liquid reflections are simulated.
#
# Requires: shaders, enable_waving_water, enable_dynamic_shadows
enable_water_reflections (Liquid reflections) bool false
[**Dynamic shadows]
# Set to true to enable Shadow Mapping.
@ -705,6 +714,18 @@ enable_volumetric_auroras (Volumetric Auroras) bool false
# Requires: shaders, enable_dynamic_shadows
enable_bumpmaps (Bump maps) bool false
[**Other Effects]
# Simulate translucency when looking at foliage in the sunlight.
#
# Requires: shaders, enable_dynamic_shadows
enable_translucent_foliage (Translucent foliage) bool false
# Apply specular shading to nodes.
#
# Requires: shaders, enable_dynamic_shadows
enable_node_specular (Node specular) bool false
[*Audio]
# Volume of all sounds.
@ -728,6 +749,10 @@ language (Language) enum ,be,bg,ca,cs,da,de,el,en,eo,es,et,eu,fi,fr,gd,gl,hu,i
[**GUI]
# When enabled, the GUI is optimized to be more usable on touchscreens.
# Whether this is enabled by default depends on your hardware form-factor.
touch_gui (Optimize GUI for touchscreens) bool false
# Scale GUI by a user specified value.
# Use a nearest-neighbor-anti-alias filter to scale the GUI.
# This will smooth over some of the rough edges, and blend
@ -735,6 +760,9 @@ language (Language) enum ,be,bg,ca,cs,da,de,el,en,eo,es,et,eu,fi,fr,gd,gl,hu,i
# edge pixels when images are scaled by non-integer sizes.
gui_scaling (GUI scaling) float 1.0 0.5 20
# Enables smooth scrolling.
smooth_scrolling (Smooth scrolling) bool true
# Enables animation of inventory items.
inventory_items_animations (Inventory items animations) bool false
@ -773,6 +801,12 @@ hud_scaling (HUD scaling) float 1.0 0.5 20
# Mods may still set a background.
show_nametag_backgrounds (Show name tag backgrounds by default) bool true
# Whether to show the client debug info (has the same effect as hitting F5).
show_debug (Show debug info) bool false
# Radius to use when the block bounds HUD feature is set to near blocks.
show_block_bounds_radius_near (Block bounds HUD radius) int 4 0 1000
[**Chat]
# Maximum number of recent chat messages to show
@ -807,6 +841,10 @@ chat_font_size (Chat font size) int 0 0 72
# The URL for the content repository
contentdb_url (ContentDB URL) string https://content.minetest.net
# If enabled and you have ContentDB packages installed, Minetest may contact ContentDB to
# check for package updates when opening the mainmenu.
contentdb_enable_updates_indicator (Enable updates available indicator on content tab) bool true
# Comma-separated list of flags to hide in the content repository.
# "nonfree" can be used to hide packages which do not qualify as 'free software',
# as defined by the Free Software Foundation.
@ -834,7 +872,7 @@ serverlist_url (Serverlist URL) string servers.minetest.net
# If disabled, new accounts will be registered automatically when logging in.
enable_split_login_register (Enable split login/register) bool true
# URL to JSON file which provides information about the newest Minetest release
# URL to JSON file which provides information about the newest Minetest release.
# If this is empty the engine will never check for updates.
update_information_url (Update information URL) string https://www.minetest.net/release_info.json
@ -862,6 +900,9 @@ server_url (Server URL) string https://minetest.net
# Automatically report to the serverlist.
server_announce (Announce server) bool false
# Send names of online players to the serverlist. If disabled only the player count is revealed.
server_announce_send_players (Send player names to the server list) bool true
# Announce to this serverlist.
serverlist_url (Serverlist URL) string servers.minetest.net
@ -1051,7 +1092,7 @@ mapgen_limit (Map generation limit) int 31007 0 31007
# Global map generation attributes.
# In Mapgen v6 the 'decorations' flag controls all decorations except trees
# and jungle grass, in all other mapgens this flag controls all decorations.
mg_flags (Mapgen flags) flags caves,dungeons,light,decorations,biomes,ores caves,dungeons,light,decorations,biomes,ores,nocaves,nodungeons,nolight,nodecorations,nobiomes,noores
mg_flags (Mapgen flags) flags caves,dungeons,light,decorations,biomes,ores caves,dungeons,light,decorations,biomes,ores
[*Biome API]
@ -1070,7 +1111,7 @@ mg_biome_np_humidity_blend (Humidity blend noise) noise_params_2d 0, 1.5, (8, 8,
[*Mapgen V5]
# Map generation attributes specific to Mapgen v5.
mgv5_spflags (Mapgen V5 specific flags) flags caverns caverns,nocaverns
mgv5_spflags (Mapgen V5 specific flags) flags caverns caverns
# Controls width of tunnels, a smaller value creates wider tunnels.
# Value >= 10.0 completely disables generation of tunnels and avoids the
@ -1144,7 +1185,7 @@ mgv5_np_dungeons (Dungeon noise) noise_params_3d 0.9, 0.5, (500, 500, 500), 0, 2
# When the 'snowbiomes' flag is enabled jungles are automatically enabled and
# the 'jungles' flag is ignored.
# The 'temples' flag disables generation of desert temples. Normal dungeons will appear instead.
mgv6_spflags (Mapgen V6 specific flags) flags jungles,biomeblend,mudflow,snowbiomes,noflat,trees,temples jungles,biomeblend,mudflow,snowbiomes,flat,trees,temples,nojungles,nobiomeblend,nomudflow,nosnowbiomes,noflat,notrees,notemples
mgv6_spflags (Mapgen V6 specific flags) flags jungles,biomeblend,mudflow,snowbiomes,noflat,trees,temples jungles,biomeblend,mudflow,snowbiomes,flat,trees,temples
# Deserts occur when np_biome exceeds this value.
# When the 'snowbiomes' flag is enabled, this is ignored.
@ -1200,7 +1241,7 @@ mgv6_np_apple_trees (Apple trees noise) noise_params_2d 0, 1, (100, 100, 100), 3
# 'ridges': Rivers.
# 'floatlands': Floating land masses in the atmosphere.
# 'caverns': Giant caves deep underground.
mgv7_spflags (Mapgen V7 specific flags) flags mountains,ridges,nofloatlands,caverns mountains,ridges,floatlands,caverns,nomountains,noridges,nofloatlands,nocaverns
mgv7_spflags (Mapgen V7 specific flags) flags mountains,ridges,nofloatlands,caverns mountains,ridges,floatlands,caverns
# Y of mountain density gradient zero level. Used to shift mountains vertically.
mgv7_mount_zero_level (Mountain zero level) int 0 -31000 31000
@ -1334,7 +1375,7 @@ mgv7_np_dungeons (Dungeon noise) noise_params_3d 0.9, 0.5, (500, 500, 500), 0, 2
[*Mapgen Carpathian]
# Map generation attributes specific to Mapgen Carpathian.
mgcarpathian_spflags (Mapgen Carpathian specific flags) flags caverns,norivers caverns,rivers,nocaverns,norivers
mgcarpathian_spflags (Mapgen Carpathian specific flags) flags caverns,norivers caverns,rivers
# Defines the base ground level.
mgcarpathian_base_level (Base ground level) float 12.0
@ -1443,7 +1484,7 @@ mgcarpathian_np_dungeons (Dungeon noise) noise_params_3d 0.9, 0.5, (500, 500, 50
# 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,nocaverns lakes,hills,caverns,nolakes,nohills,nocaverns
mgflat_spflags (Mapgen Flat specific flags) flags nolakes,nohills,nocaverns lakes,hills,caverns
# Y of flat ground.
mgflat_ground_level (Ground level) int 8 -31000 31000
@ -1527,7 +1568,7 @@ mgflat_np_dungeons (Dungeon noise) noise_params_3d 0.9, 0.5, (500, 500, 500), 0,
# 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
mgfractal_spflags (Mapgen Fractal specific flags) flags terrain terrain
# Controls width of tunnels, a smaller value creates wider tunnels.
# Value >= 10.0 completely disables generation of tunnels and avoids the
@ -1661,7 +1702,7 @@ mgfractal_np_dungeons (Dungeon noise) noise_params_3d 0.9, 0.5, (500, 500, 500),
# 'vary_river_depth': If enabled, low humidity and high heat causes rivers
# to become shallower and occasionally dry.
# 'altitude_dry': Reduces humidity with altitude.
mgvalleys_spflags (Mapgen Valleys specific flags) flags altitude_chill,humid_rivers,vary_river_depth,altitude_dry altitude_chill,humid_rivers,vary_river_depth,altitude_dry,noaltitude_chill,nohumid_rivers,novary_river_depth,noaltitude_dry
mgvalleys_spflags (Mapgen Valleys specific flags) flags altitude_chill,humid_rivers,vary_river_depth,altitude_dry altitude_chill,humid_rivers,vary_river_depth,altitude_dry
# The vertical distance over which heat drops by 20 if 'altitude_chill' is
# enabled. Also, the vertical distance over which humidity drops by 10 if
@ -1876,11 +1917,11 @@ shader_path (Shader path) path
# The rendering back-end.
# Note: A restart is required after changing this!
# OpenGL is the default for desktop, and OGLES2 for Android.
# Shaders are supported by everything but OGLES1.
video_driver (Video driver) enum ,opengl,opengl3,ogles1,ogles2
video_driver (Video driver) enum ,opengl,opengl3,ogles2
# Distance in nodes at which transparency depth sorting is enabled
# Use this to limit the performance impact of transparency depth sorting
# Distance in nodes at which transparency depth sorting is enabled.
# Use this to limit the performance impact of transparency depth sorting.
# Set to 0 to disable it entirely.
transparency_sorting_distance (Transparency Sorting Distance) int 16 0 128
# Radius of cloud area stated in number of 64 node cloud squares.
@ -2040,9 +2081,6 @@ client_unload_unused_data_timeout (Mapblock unload timeout) float 600.0 0.0
# Set to -1 for unlimited amount.
client_mapblock_limit (Mapblock limit) int 7500 -1 2147483647
# Whether to show the client debug info (has the same effect as hitting F5).
show_debug (Show debug info) bool false
# Maximum number of blocks that are simultaneously sent per client.
# The maximum total count is calculated dynamically:
# max_total = ceil((#clients + max_users) * per_client / 4)
@ -2052,9 +2090,8 @@ max_simultaneous_block_sends_per_client (Maximum simultaneous block sends per cl
# This determines how long they are slowed down after placing or removing a node.
full_block_send_enable_min_time_from_building (Delay in sending blocks after building) float 2.0 0.0
# Maximum number of packets sent per send step, if you have a slow connection
# try reducing it, but don't reduce it to a number below double of targeted
# client number.
# Maximum number of packets sent per send step in the low-level networking code.
# You generally don't need to change this, however busy servers may benefit from a higher number.
max_packets_per_iteration (Max. packets per iteration) int 1024 1 65535
# Compression level to use when sending mapblocks to the client.
@ -2230,9 +2267,6 @@ curl_file_download_timeout (cURL file download timeout) int 300000 5000 21474836
[**Miscellaneous]
# Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k screens.
screen_dpi (DPI) int 72 1
# Adjust the detected display density, used for scaling UI elements.
display_density_factor (Display Density Scaling Factor) float 1 0.5 5.0