summaryrefslogtreecommitdiff
path: root/builtin/game
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/game')
-rw-r--r--builtin/game/auth.lua6
-rw-r--r--builtin/game/chatcommands.lua244
-rw-r--r--builtin/game/deprecated.lua21
-rw-r--r--builtin/game/falling.lua50
-rw-r--r--builtin/game/features.lua2
-rw-r--r--builtin/game/forceloading.lua2
-rw-r--r--builtin/game/init.lua4
-rw-r--r--builtin/game/item.lua53
-rw-r--r--builtin/game/item_entity.lua33
-rw-r--r--builtin/game/misc.lua93
-rw-r--r--builtin/game/register.lua8
-rw-r--r--builtin/game/statbars.lua10
-rw-r--r--builtin/game/static_spawn.lua4
13 files changed, 286 insertions, 244 deletions
diff --git a/builtin/game/auth.lua b/builtin/game/auth.lua
index 46fe3d342..8cb4ebf57 100644
--- a/builtin/game/auth.lua
+++ b/builtin/game/auth.lua
@@ -106,7 +106,7 @@ core.builtin_auth_handler = {
end
end
-- For the admin, give everything
- elseif name == core.setting_get("name") then
+ elseif name == core.settings:get("name") then
for priv, def in pairs(core.registered_privileges) do
privileges[priv] = true
end
@@ -125,7 +125,7 @@ core.builtin_auth_handler = {
core.log('info', "Built-in authentication handler adding player '"..name.."'")
core.auth_table[name] = {
password = password,
- privileges = core.string_to_privs(core.setting_get("default_privs")),
+ privileges = core.string_to_privs(core.settings:get("default_privs")),
last_login = os.time(),
}
save_auth_file()
@@ -148,7 +148,7 @@ core.builtin_auth_handler = {
if not core.auth_table[name] then
core.builtin_auth_handler.create_auth(name,
core.get_password_hash(name,
- core.setting_get("default_password")))
+ core.settings:get("default_password")))
end
core.auth_table[name].privileges = privileges
core.notify_authentication_modified(name)
diff --git a/builtin/game/chatcommands.lua b/builtin/game/chatcommands.lua
index 2bd93855b..3dfc29ffa 100644
--- a/builtin/game/chatcommands.lua
+++ b/builtin/game/chatcommands.lua
@@ -1,27 +1,28 @@
--- Minetest: builtin/chatcommands.lua
+-- Minetest: builtin/game/chatcommands.lua
--
-- Chat command handler
--
-core.chatcommands = {}
-function core.register_chatcommand(cmd, def)
- def = def or {}
- def.params = def.params or ""
- def.description = def.description or ""
- def.privs = def.privs or {}
- def.mod_origin = core.get_current_modname() or "??"
- core.chatcommands[cmd] = def
-end
+core.chatcommands = core.registered_chatcommands -- BACKWARDS COMPATIBILITY
core.register_on_chat_message(function(name, message)
+ if message:sub(1,1) ~= "/" then
+ return
+ end
+
local cmd, param = string.match(message, "^/([^ ]+) *(.*)")
- if not param then
- param = ""
+ if not cmd then
+ core.chat_send_player(name, "-!- Empty command")
+ return true
end
- local cmd_def = core.chatcommands[cmd]
+
+ param = param or ""
+
+ local cmd_def = core.registered_chatcommands[cmd]
if not cmd_def then
- return false
+ core.chat_send_player(name, "-!- Invalid command: " .. cmd)
+ return true
end
local has_privs, missing_privs = core.check_player_privs(name, cmd_def.privs)
if has_privs then
@@ -38,7 +39,7 @@ core.register_on_chat_message(function(name, message)
return true -- Handled chat message
end)
-if core.setting_getbool("profiler.load") then
+if core.settings:get_bool("profiler.load") then
-- Run after register_chatcommand and its register_on_chat_message
-- Before any chattcommands that should be profiled
profiler.init_chatcommand()
@@ -70,7 +71,8 @@ end
--
core.register_chatcommand("me", {
params = "<action>",
- description = "chat action (eg. /me orders a pizza)",
+ description = "Display chat action (e.g., '/me orders a pizza' displays"
+ .. " '<player name> orders a pizza')",
privs = {shout=true},
func = function(name, param)
core.chat_send_all("* " .. name .. " " .. param)
@@ -80,7 +82,7 @@ core.register_chatcommand("me", {
core.register_chatcommand("admin", {
description = "Show the name of the server owner",
func = function(name)
- local admin = minetest.setting_get("name")
+ local admin = minetest.settings:get("name")
if admin then
return true, "The administrator of this server is "..admin.."."
else
@@ -89,64 +91,9 @@ core.register_chatcommand("admin", {
end,
})
-core.register_chatcommand("help", {
- privs = {},
- params = "[all/privs/<cmd>]",
- description = "Get help for commands or list privileges",
- func = function(name, param)
- local function format_help_line(cmd, def)
- local msg = core.colorize("#00ffff", "/"..cmd)
- if def.params and def.params ~= "" then
- msg = msg .. " " .. def.params
- end
- if def.description and def.description ~= "" then
- msg = msg .. ": " .. def.description
- end
- return msg
- end
- if param == "" then
- local msg = ""
- local cmds = {}
- for cmd, def in pairs(core.chatcommands) do
- if core.check_player_privs(name, def.privs) then
- cmds[#cmds + 1] = cmd
- end
- end
- table.sort(cmds)
- return true, "Available commands: " .. table.concat(cmds, " ") .. "\n"
- .. "Use '/help <cmd>' to get more information,"
- .. " or '/help all' to list everything."
- elseif param == "all" then
- local cmds = {}
- for cmd, def in pairs(core.chatcommands) do
- if core.check_player_privs(name, def.privs) then
- cmds[#cmds + 1] = format_help_line(cmd, def)
- end
- end
- table.sort(cmds)
- return true, "Available commands:\n"..table.concat(cmds, "\n")
- elseif param == "privs" then
- local privs = {}
- for priv, def in pairs(core.registered_privileges) do
- privs[#privs + 1] = priv .. ": " .. def.description
- end
- table.sort(privs)
- return true, "Available privileges:\n"..table.concat(privs, "\n")
- else
- local cmd = param
- local def = core.chatcommands[cmd]
- if not def then
- return false, "Command not available: "..cmd
- else
- return true, format_help_line(cmd, def)
- end
- end
- end,
-})
-
core.register_chatcommand("privs", {
params = "<name>",
- description = "print out privileges of player",
+ description = "Print privileges of player",
func = function(caller, param)
param = param:trim()
local name = (param ~= "" and param or caller)
@@ -161,8 +108,8 @@ local function handle_grant_command(caller, grantname, grantprivstr)
if not (caller_privs.privs or caller_privs.basic_privs) then
return false, "Your privileges are insufficient."
end
-
- if not core.auth_table[grantname] then
+
+ if not core.get_auth_handler().get_auth(grantname) then
return false, "Player " .. grantname .. " does not exist."
end
local grantprivs = core.string_to_privs(grantprivstr)
@@ -172,7 +119,7 @@ local function handle_grant_command(caller, grantname, grantprivstr)
local privs = core.get_player_privs(grantname)
local privs_unknown = ""
local basic_privs =
- core.string_to_privs(core.setting_get("basic_privs") or "interact,shout")
+ core.string_to_privs(core.settings:get("basic_privs") or "interact,shout")
for priv, _ in pairs(grantprivs) do
if not basic_privs[priv] and not caller_privs.privs then
return false, "Your privileges are insufficient."
@@ -204,7 +151,7 @@ core.register_chatcommand("grant", {
local grantname, grantprivstr = string.match(param, "([^ ]+) (.+)")
if not grantname or not grantprivstr then
return false, "Invalid parameters (see /help grant)"
- end
+ end
return handle_grant_command(name, grantname, grantprivstr)
end,
})
@@ -215,7 +162,7 @@ core.register_chatcommand("grantme", {
func = function(name, param)
if param == "" then
return false, "Invalid parameters (see /help grantme)"
- end
+ end
return handle_grant_command(name, name, param)
end,
})
@@ -232,13 +179,13 @@ core.register_chatcommand("revoke", {
local revoke_name, revoke_priv_str = string.match(param, "([^ ]+) (.+)")
if not revoke_name or not revoke_priv_str then
return false, "Invalid parameters (see /help revoke)"
- elseif not core.auth_table[revoke_name] then
+ elseif not core.get_auth_handler().get_auth(revoke_name) then
return false, "Player " .. revoke_name .. " does not exist."
end
local revoke_privs = core.string_to_privs(revoke_priv_str)
local privs = core.get_player_privs(revoke_name)
local basic_privs =
- core.string_to_privs(core.setting_get("basic_privs") or "interact,shout")
+ core.string_to_privs(core.settings:get("basic_privs") or "interact,shout")
for priv, _ in pairs(revoke_privs) do
if not basic_privs[priv] and
not core.check_player_privs(name, {privs=true}) then
@@ -269,7 +216,7 @@ core.register_chatcommand("revoke", {
core.register_chatcommand("setpassword", {
params = "<name> <password>",
- description = "set given password",
+ description = "Set player's password",
privs = {password=true},
func = function(name, param)
local toname, raw_password = string.match(param, "^([^ ]+) +(.+)$")
@@ -307,7 +254,7 @@ core.register_chatcommand("setpassword", {
core.register_chatcommand("clearpassword", {
params = "<name>",
- description = "set empty password",
+ description = "Set empty password",
privs = {password=true},
func = function(name, param)
local toname = param
@@ -324,7 +271,7 @@ core.register_chatcommand("clearpassword", {
core.register_chatcommand("auth_reload", {
params = "",
- description = "reload authentication data",
+ description = "Reload authentication data",
privs = {server=true},
func = function(name, param)
local done = core.auth_reload()
@@ -332,9 +279,34 @@ core.register_chatcommand("auth_reload", {
end,
})
+core.register_chatcommand("remove_player", {
+ params = "<name>",
+ description = "Remove player data",
+ privs = {server=true},
+ func = function(name, param)
+ local toname = param
+ if toname == "" then
+ return false, "Name field required"
+ end
+
+ local rc = core.remove_player(toname)
+
+ if rc == 0 then
+ core.log("action", name .. " removed player data of " .. toname .. ".")
+ return true, "Player \"" .. toname .. "\" removed."
+ elseif rc == 1 then
+ return true, "No such player \"" .. toname .. "\" to remove."
+ elseif rc == 2 then
+ return true, "Player \"" .. toname .. "\" is connected, cannot remove."
+ end
+
+ return false, "Unhandled remove_player return code " .. rc .. ""
+ end,
+})
+
core.register_chatcommand("teleport", {
params = "<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>",
- description = "teleport to given position",
+ description = "Teleport to player or position",
privs = {teleport=true},
func = function(name, param)
-- Returns (pos, true) if found, otherwise (pos, false)
@@ -365,7 +337,7 @@ core.register_chatcommand("teleport", {
p.y = tonumber(p.y)
p.z = tonumber(p.z)
if p.x and p.y and p.z then
- local lm = tonumber(minetest.setting_get("map_generation_limit") or 31000)
+ local lm = 31000
if p.x < -lm or p.x > lm or p.y < -lm or p.y > lm or p.z < -lm or p.z > lm then
return false, "Cannot teleport out of map bounds!"
end
@@ -442,25 +414,25 @@ core.register_chatcommand("teleport", {
core.register_chatcommand("set", {
params = "[-n] <name> <value> | <name>",
- description = "set or read server configuration setting",
+ description = "Set or read server configuration setting",
privs = {server=true},
func = function(name, param)
local arg, setname, setvalue = string.match(param, "(-[n]) ([^ ]+) (.+)")
if arg and arg == "-n" and setname and setvalue then
- core.setting_set(setname, setvalue)
+ core.settings:set(setname, setvalue)
return true, setname .. " = " .. setvalue
end
local setname, setvalue = string.match(param, "([^ ]+) (.+)")
if setname and setvalue then
- if not core.setting_get(setname) then
+ if not core.settings:get(setname) then
return false, "Failed. Use '/set -n <name> <value>' to create a new setting."
end
- core.setting_set(setname, setvalue)
+ core.settings:set(setname, setvalue)
return true, setname .. " = " .. setvalue
end
local setname = string.match(param, "([^ ]+)")
if setname then
- local setvalue = core.setting_get(setname)
+ local setvalue = core.settings:get(setname)
if not setvalue then
setvalue = "<not set>"
end
@@ -497,7 +469,7 @@ end
core.register_chatcommand("emergeblocks", {
params = "(here [radius]) | (<pos1> <pos2>)",
- description = "starts loading (or generating, if inexistent) map blocks "
+ description = "Load (or, if nonexistent, generate) map blocks "
.. "contained in area pos1 to pos2",
privs = {server=true},
func = function(name, param)
@@ -523,7 +495,7 @@ core.register_chatcommand("emergeblocks", {
core.register_chatcommand("deleteblocks", {
params = "(here [radius]) | (<pos1> <pos2>)",
- description = "delete map blocks contained in area pos1 to pos2",
+ description = "Delete map blocks contained in area pos1 to pos2",
privs = {server=true},
func = function(name, param)
local p1, p2 = parse_range_str(name, param)
@@ -540,6 +512,25 @@ core.register_chatcommand("deleteblocks", {
end,
})
+core.register_chatcommand("fixlight", {
+ params = "(here [radius]) | (<pos1> <pos2>)",
+ description = "Resets lighting in the area between pos1 and pos2",
+ privs = {server = true},
+ func = function(name, param)
+ local p1, p2 = parse_range_str(name, param)
+ if p1 == false then
+ return false, p2
+ end
+
+ if core.fix_light(p1, p2) then
+ return true, "Successfully reset light in the area ranging from " ..
+ core.pos_to_string(p1, 1) .. " to " .. core.pos_to_string(p2, 1)
+ else
+ return false, "Failed to load one or more blocks in area"
+ end
+ end,
+})
+
core.register_chatcommand("mods", {
params = "",
description = "List mods installed on the server",
@@ -587,7 +578,7 @@ end
core.register_chatcommand("give", {
params = "<name> <ItemString>",
- description = "give item to player",
+ description = "Give item to player",
privs = {give=true},
func = function(name, param)
local toname, itemstring = string.match(param, "^([^ ]+) +(.+)$")
@@ -600,7 +591,7 @@ core.register_chatcommand("give", {
core.register_chatcommand("giveme", {
params = "<ItemString>",
- description = "give item to yourself",
+ description = "Give item to yourself",
privs = {give=true},
func = function(name, param)
local itemstring = string.match(param, "(.+)$")
@@ -671,12 +662,12 @@ end)
core.register_chatcommand("rollback_check", {
params = "[<range>] [<seconds>] [limit]",
- description = "Check who has last touched a node or near it,"
- .. " max. <seconds> ago (default range=0,"
- .. " seconds=86400=24h, limit=5)",
+ description = "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",
privs = {rollback=true},
func = function(name, param)
- if not core.setting_getbool("enable_rollback_recording") then
+ if not core.settings:get_bool("enable_rollback_recording") then
return false, "Rollback functions are disabled."
end
local range, seconds, limit =
@@ -724,10 +715,10 @@ core.register_chatcommand("rollback_check", {
core.register_chatcommand("rollback", {
params = "<player name> [<seconds>] | :<actor> [<seconds>]",
- description = "revert actions of a player; default for <seconds> is 60",
+ description = "Revert actions of a player. Default for <seconds> is 60",
privs = {rollback=true},
func = function(name, param)
- if not core.setting_getbool("enable_rollback_recording") then
+ if not core.settings:get_bool("enable_rollback_recording") then
return false, "Rollback functions are disabled."
end
local target_name, seconds = string.match(param, ":([^ ]+) *(%d*)")
@@ -769,7 +760,7 @@ core.register_chatcommand("status", {
core.register_chatcommand("time", {
params = "<0..23>:<0..59> | <0..24000>",
- description = "set time of day",
+ description = "Set time of day",
privs = {},
func = function(name, param)
if param == "" then
@@ -815,12 +806,21 @@ core.register_chatcommand("days", {
})
core.register_chatcommand("shutdown", {
- description = "shutdown server",
+ description = "Shutdown server",
+ params = "[delay_in_seconds (non-negative number, or -1 to cancel)] [reconnect] [message]",
privs = {server=true},
func = function(name, param)
- core.log("action", name .. " shuts down server")
- core.request_shutdown()
- core.chat_send_all("*** Server shutting down (operator request).")
+ local delay, reconnect, message = param:match("([^ ][-]?[0-9]+)([^ ]+)(.*)")
+ message = message or ""
+
+ if delay ~= "" then
+ delay = tonumber(param) or 0
+ else
+ delay = 0
+ core.log("action", name .. " shuts down server")
+ core.chat_send_all("*** Server shutting down (operator request).")
+ end
+ core.request_shutdown(message:trim(), core.is_yes(reconnect), delay)
end,
})
@@ -846,7 +846,7 @@ core.register_chatcommand("ban", {
core.register_chatcommand("unban", {
params = "<name/ip>",
- description = "remove IP ban",
+ description = "Remove IP ban",
privs = {ban=true},
func = function(name, param)
if not core.unban_player_or_ip(param) then
@@ -859,7 +859,7 @@ core.register_chatcommand("unban", {
core.register_chatcommand("kick", {
params = "<name> [reason]",
- description = "kick a player",
+ description = "Kick a player",
privs = {kick=true},
func = function(name, param)
local tokick, reason = param:match("([^ ]+) (.+)")
@@ -878,7 +878,7 @@ core.register_chatcommand("kick", {
core.register_chatcommand("clearobjects", {
params = "[full|quick]",
- description = "clear all objects in world",
+ description = "Clear all objects in world",
privs = {server=true},
func = function(name, param)
local options = {}
@@ -938,3 +938,31 @@ core.register_chatcommand("last-login", {
return false, "Last login time is unknown"
end,
})
+
+core.register_chatcommand("clearinv", {
+ params = "[name]",
+ description = "Clear the inventory of yourself or another player",
+ func = function(name, param)
+ local player
+ if param and param ~= "" and param ~= name then
+ if not core.check_player_privs(name, {server=true}) then
+ return false, "You don't have permission"
+ .. " to run this command (missing privilege: server)"
+ end
+ player = core.get_player_by_name(param)
+ core.chat_send_player(param, name.." cleared your inventory.")
+ else
+ player = core.get_player_by_name(name)
+ end
+
+ if player then
+ player:get_inventory():set_list("main", {})
+ player:get_inventory():set_list("craft", {})
+ player:get_inventory():set_list("craftpreview", {})
+ core.log("action", name.." clears "..player:get_player_name().."'s inventory")
+ return true, "Cleared "..player:get_player_name().."'s inventory."
+ else
+ return false, "Player must be online to clear inventory!"
+ end
+ end,
+})
diff --git a/builtin/game/deprecated.lua b/builtin/game/deprecated.lua
index cd1cf5e2d..1a9a96f2a 100644
--- a/builtin/game/deprecated.lua
+++ b/builtin/game/deprecated.lua
@@ -49,3 +49,24 @@ setmetatable(core.env, {
function core.rollback_get_last_node_actor(pos, range, seconds)
return core.rollback_get_node_actions(pos, range, seconds, 1)[1]
end
+
+--
+-- core.setting_*
+--
+
+local settings = core.settings
+
+local function setting_proxy(name)
+ return function(...)
+ core.log("deprecated", "WARNING: minetest.setting_* "..
+ "functions are deprecated. "..
+ "Use methods on the minetest.settings object.")
+ return settings[name](settings, ...)
+ end
+end
+
+core.setting_set = setting_proxy("set")
+core.setting_get = setting_proxy("get")
+core.setting_setbool = setting_proxy("set_bool")
+core.setting_getbool = setting_proxy("get_bool")
+core.setting_save = setting_proxy("write")
diff --git a/builtin/game/falling.lua b/builtin/game/falling.lua
index 4696ce481..b1beb1ab0 100644
--- a/builtin/game/falling.lua
+++ b/builtin/game/falling.lua
@@ -18,9 +18,11 @@ core.register_entity(":__builtin:falling_node", {
},
node = {},
+ meta = {},
- set_node = function(self, node)
+ set_node = function(self, node, meta)
self.node = node
+ self.meta = meta or {}
self.object:set_properties({
is_visible = true,
textures = {node.name},
@@ -28,15 +30,21 @@ core.register_entity(":__builtin:falling_node", {
end,
get_staticdata = function(self)
- return core.serialize(self.node)
+ local ds = {
+ node = self.node,
+ meta = self.meta,
+ }
+ return core.serialize(ds)
end,
on_activate = function(self, staticdata)
self.object:set_armor_groups({immortal = 1})
- local node = core.deserialize(staticdata)
- if node then
- self:set_node(node)
+ local ds = core.deserialize(staticdata)
+ if ds and ds.node then
+ self:set_node(ds.node, ds.meta)
+ elseif ds then
+ self:set_node(ds)
elseif staticdata ~= "" then
self:set_node({name = staticdata})
end
@@ -83,7 +91,7 @@ core.register_entity(":__builtin:falling_node", {
-- it's drops
if n2.name ~= "air" and (not nd or nd.liquidtype == "none") then
core.remove_node(np)
- if nd.buildable_to == false then
+ if nd and nd.buildable_to == false then
-- Add dropped items
local drops = core.get_node_drops(n2.name, "")
for _, dropped_item in pairs(drops) do
@@ -98,6 +106,10 @@ core.register_entity(":__builtin:falling_node", {
-- Create node and remove entity
if core.registered_nodes[self.node.name] then
core.add_node(np, self.node)
+ if self.meta then
+ local meta = core.get_meta(np)
+ meta:from_table(self.meta)
+ end
end
self.object:remove()
core.check_for_falling(np)
@@ -111,11 +123,25 @@ core.register_entity(":__builtin:falling_node", {
end
})
-local function spawn_falling_node(p, node)
+local function spawn_falling_node(p, node, meta)
local obj = core.add_entity(p, "__builtin:falling_node")
if obj then
+ obj:get_luaentity():set_node(node, meta)
+ end
+end
+
+function core.spawn_falling_node(pos)
+ local node = core.get_node(pos)
+ if node.name == "air" or node.name == "ignore" then
+ return false
+ end
+ local obj = core.add_entity(pos, "__builtin:falling_node")
+ if obj then
obj:get_luaentity():set_node(node)
+ core.remove_node(pos)
+ return true
end
+ return false
end
local function drop_attached_node(p)
@@ -134,7 +160,8 @@ end
function builtin_shared.check_attached_node(p, n)
local def = core.registered_nodes[n.name]
local d = {x = 0, y = 0, z = 0}
- if def.paramtype2 == "wallmounted" then
+ if def.paramtype2 == "wallmounted" or
+ def.paramtype2 == "colorwallmounted" then
-- The fallback vector here is in case 'wallmounted to dir' is nil due
-- to voxelmanip placing a wallmounted node without resetting a
-- pre-existing param2 value that is out-of-range for wallmounted.
@@ -174,8 +201,13 @@ function core.check_single_for_falling(p)
(not d_bottom.walkable or d_bottom.buildable_to) then
n.level = core.get_node_level(p)
+ local meta = core.get_meta(p)
+ local metatable = {}
+ if meta ~= nil then
+ metatable = meta:to_table()
+ end
core.remove_node(p)
- spawn_falling_node(p, n)
+ spawn_falling_node(p, n, metatable)
return true
end
end
diff --git a/builtin/game/features.lua b/builtin/game/features.lua
index 2aad458da..ef85fbbc3 100644
--- a/builtin/game/features.lua
+++ b/builtin/game/features.lua
@@ -9,6 +9,8 @@ core.features = {
no_legacy_abms = true,
texture_names_parens = true,
area_store_custom_ids = true,
+ add_entity_with_staticdata = true,
+ no_chat_message_prediction = true,
}
function core.has_feature(arg)
diff --git a/builtin/game/forceloading.lua b/builtin/game/forceloading.lua
index 8a05de36c..7c5537e85 100644
--- a/builtin/game/forceloading.lua
+++ b/builtin/game/forceloading.lua
@@ -40,7 +40,7 @@ function core.forceload_block(pos, transient)
elseif other_table[hash] ~= nil then
relevant_table[hash] = 1
else
- if total_forceloaded >= (tonumber(core.setting_get("max_forceloaded_blocks")) or 16) then
+ if total_forceloaded >= (tonumber(core.settings:get("max_forceloaded_blocks")) or 16) then
return false
end
total_forceloaded = total_forceloaded+1
diff --git a/builtin/game/init.lua b/builtin/game/init.lua
index b5e2f7cca..e2635f07a 100644
--- a/builtin/game/init.lua
+++ b/builtin/game/init.lua
@@ -13,15 +13,17 @@ dofile(gamepath.."constants.lua")
assert(loadfile(gamepath.."item.lua"))(builtin_shared)
dofile(gamepath.."register.lua")
-if core.setting_getbool("profiler.load") then
+if core.settings:get_bool("profiler.load") then
profiler = dofile(scriptpath.."profiler"..DIR_DELIM.."init.lua")
end
+dofile(commonpath .. "after.lua")
dofile(gamepath.."item_entity.lua")
dofile(gamepath.."deprecated.lua")
dofile(gamepath.."misc.lua")
dofile(gamepath.."privileges.lua")
dofile(gamepath.."auth.lua")
+dofile(commonpath .. "chatcommands.lua")
dofile(gamepath.."chatcommands.lua")
dofile(gamepath.."static_spawn.lua")
dofile(gamepath.."detached_inventory.lua")
diff --git a/builtin/game/item.lua b/builtin/game/item.lua
index bf456a4e0..e36745f93 100644
--- a/builtin/game/item.lua
+++ b/builtin/game/item.lua
@@ -109,7 +109,7 @@ local facedir_to_dir_map = {
1, 4, 3, 2,
}
function core.facedir_to_dir(facedir)
- return facedir_to_dir[facedir_to_dir_map[facedir]]
+ return facedir_to_dir[facedir_to_dir_map[facedir % 32]]
end
function core.dir_to_wallmounted(dir)
@@ -144,11 +144,20 @@ local wallmounted_to_dir = {
{x = 0, y = 0, z = -1},
}
function core.wallmounted_to_dir(wallmounted)
- return wallmounted_to_dir[wallmounted]
+ return wallmounted_to_dir[wallmounted % 8]
+end
+
+function core.dir_to_yaw(dir)
+ return -math.atan2(dir.x, dir.z)
+end
+
+function core.yaw_to_dir(yaw)
+ return {x = -math.sin(yaw), y = 0, z = math.cos(yaw)}
end
function core.get_node_drops(nodename, toolname)
- local drop = ItemStack({name=nodename}):get_definition().drop
+ local def = core.registered_nodes[nodename]
+ local drop = def and def.drop
if drop == nil then
-- default drop
return {nodename}
@@ -197,7 +206,6 @@ function core.get_node_drops(nodename, toolname)
end
function core.item_place_node(itemstack, placer, pointed_thing, param2)
- local item = itemstack:peek_item()
local def = itemstack:get_definition()
if def.type ~= "node" or pointed_thing.type ~= "node" then
return itemstack, false
@@ -207,20 +215,21 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
local oldnode_under = core.get_node_or_nil(under)
local above = pointed_thing.above
local oldnode_above = core.get_node_or_nil(above)
+ local playername = placer:get_player_name()
if not oldnode_under or not oldnode_above then
- core.log("info", placer:get_player_name() .. " tried to place"
+ core.log("info", playername .. " tried to place"
.. " node in unloaded position " .. core.pos_to_string(above))
return itemstack, false
end
- local olddef_under = ItemStack({name=oldnode_under.name}):get_definition()
+ local olddef_under = core.registered_nodes[oldnode_under.name]
olddef_under = olddef_under or core.nodedef_default
- local olddef_above = ItemStack({name=oldnode_above.name}):get_definition()
+ local olddef_above = core.registered_nodes[oldnode_above.name]
olddef_above = olddef_above or core.nodedef_default
if not olddef_above.buildable_to and not olddef_under.buildable_to then
- core.log("info", placer:get_player_name() .. " tried to place"
+ core.log("info", playername .. " tried to place"
.. " node in invalid position " .. core.pos_to_string(above)
.. ", replacing " .. oldnode_above.name)
return itemstack, false
@@ -235,17 +244,17 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
place_to = {x = under.x, y = under.y, z = under.z}
end
- if core.is_protected(place_to, placer:get_player_name()) and
+ if core.is_protected(place_to, playername) and
not minetest.check_player_privs(placer, "protection_bypass") then
- core.log("action", placer:get_player_name()
+ core.log("action", playername
.. " tried to place " .. def.name
.. " at protected position "
.. core.pos_to_string(place_to))
- core.record_protection_violation(place_to, placer:get_player_name())
+ core.record_protection_violation(place_to, playername)
return itemstack
end
- core.log("action", placer:get_player_name() .. " places node "
+ core.log("action", playername .. " places node "
.. def.name .. " at " .. core.pos_to_string(place_to))
local oldnode = core.get_node(place_to)
@@ -254,7 +263,8 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
-- Calculate direction for wall mounted stuff like torches and signs
if def.place_param2 ~= nil then
newnode.param2 = def.place_param2
- elseif def.paramtype2 == 'wallmounted' and not param2 then
+ elseif (def.paramtype2 == "wallmounted" or
+ def.paramtype2 == "colorwallmounted") and not param2 then
local dir = {
x = under.x - above.x,
y = under.y - above.y,
@@ -262,7 +272,8 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
}
newnode.param2 = core.dir_to_wallmounted(dir)
-- Calculate the direction for furnaces and chests and stuff
- elseif def.paramtype2 == 'facedir' and not param2 then
+ elseif (def.paramtype2 == "facedir" or
+ def.paramtype2 == "colorfacedir") and not param2 then
local placer_pos = placer:getpos()
if placer_pos then
local dir = {
@@ -300,7 +311,6 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
end
-- Run script hook
- local _, callback
for _, callback in ipairs(core.registered_on_placenodes) do
-- Deepcopy pos, node and pointed_thing because callback can modify them
local place_to_copy = {x=place_to.x, y=place_to.y, z=place_to.z}
@@ -441,8 +451,9 @@ function core.handle_node_drops(pos, drops, digger)
end
function core.node_dig(pos, node, digger)
- local def = ItemStack({name=node.name}):get_definition()
- if not def.diggable or (def.can_dig and not def.can_dig(pos,digger)) then
+ local def = core.registered_nodes[node.name]
+ if def and (not def.diggable or
+ (def.can_dig and not def.can_dig(pos, digger))) then
core.log("info", digger:get_player_name() .. " tried to dig "
.. node.name .. " which is not diggable "
.. core.pos_to_string(pos))
@@ -467,12 +478,12 @@ function core.node_dig(pos, node, digger)
local wdef = wielded:get_definition()
local tp = wielded:get_tool_capabilities()
- local dp = core.get_dig_params(def.groups, tp)
+ local dp = core.get_dig_params(def and def.groups, tp)
if wdef and wdef.after_use then
wielded = wdef.after_use(wielded, digger, node, dp) or wielded
else
-- Wear out tool
- if not core.setting_getbool("creative_mode") then
+ if not core.settings:get_bool("creative_mode") then
wielded:add_wear(dp.wear)
if wielded:get_count() == 0 and wdef.sound and wdef.sound.breaks then
core.sound_play(wdef.sound.breaks, {pos = pos, gain = 0.5})
@@ -485,7 +496,7 @@ function core.node_dig(pos, node, digger)
core.handle_node_drops(pos, drops, digger)
local oldmetadata = nil
- if def.after_dig_node then
+ if def and def.after_dig_node then
oldmetadata = core.get_meta(pos):to_table()
end
@@ -493,7 +504,7 @@ function core.node_dig(pos, node, digger)
core.remove_node(pos)
-- Run callback
- if def.after_dig_node then
+ if def and def.after_dig_node then
-- Copy pos and node because callback can modify them
local pos_copy = {x=pos.x, y=pos.y, z=pos.z}
local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
diff --git a/builtin/game/item_entity.lua b/builtin/game/item_entity.lua
index be158c119..c0e36be2d 100644
--- a/builtin/game/item_entity.lua
+++ b/builtin/game/item_entity.lua
@@ -14,7 +14,7 @@ end
-- If item_entity_ttl is not set, enity will have default life time
-- Setting it to -1 disables the feature
-local time_to_live = tonumber(core.setting_get("item_entity_ttl"))
+local time_to_live = tonumber(core.settings:get("item_entity_ttl"))
if not time_to_live then
time_to_live = 900
end
@@ -53,6 +53,8 @@ core.register_entity(":__builtin:item", {
if itemtable then
itemname = stack:to_table().name
end
+ -- Backwards compatibility: old clients use the texture
+ -- to get the type of the item
local item_texture = nil
local item_type = ""
if core.registered_items[itemname] then
@@ -66,6 +68,7 @@ core.register_entity(":__builtin:item", {
visual_size = {x = s, y = s},
collisionbox = {-c, -c, -c, c, c, c},
automatic_rotate = math.pi * 0.5,
+ wield_item = itemstring,
}
self.object:set_properties(prop)
end,
@@ -101,31 +104,39 @@ core.register_entity(":__builtin:item", {
self:set_item(self.itemstring)
end,
+ -- moves items from this stack to an other stack
try_merge_with = function(self, own_stack, object, obj)
+ -- other item's stack
local stack = ItemStack(obj.itemstring)
- if own_stack:get_name() == stack:get_name() and stack:get_free_space() > 0 then
+ -- only merge if items are the same
+ if own_stack:get_name() == stack:get_name() and
+ own_stack:get_meta() == stack:get_meta() and
+ own_stack:get_wear() == stack:get_wear() and
+ stack:get_free_space() > 0 then
local overflow = false
local count = stack:get_count() + own_stack:get_count()
local max_count = stack:get_stack_max()
if count > max_count then
overflow = true
+ stack:set_count(max_count)
count = count - max_count
+ own_stack:set_count(count)
else
self.itemstring = ''
+ stack:set_count(count)
end
local pos = object:getpos()
pos.y = pos.y + (count - stack:get_count()) / max_count * 0.15
object:moveto(pos, false)
local s, c
- local max_count = stack:get_stack_max()
- local name = stack:get_name()
if not overflow then
- obj.itemstring = name .. " " .. count
+ obj.itemstring = stack:to_string()
s = 0.2 + 0.1 * (count / max_count)
c = s
object:set_properties({
visual_size = {x = s, y = s},
- collisionbox = {-c, -c, -c, c, c, c}
+ collisionbox = {-c, -c, -c, c, c, c},
+ wield_item = obj.itemstring
})
self.object:remove()
-- merging succeeded
@@ -133,18 +144,20 @@ core.register_entity(":__builtin:item", {
else
s = 0.4
c = 0.3
+ obj.itemstring = stack:to_string()
object:set_properties({
visual_size = {x = s, y = s},
- collisionbox = {-c, -c, -c, c, c, c}
+ collisionbox = {-c, -c, -c, c, c, c},
+ wield_item = obj.itemstring
})
- obj.itemstring = name .. " " .. max_count
s = 0.2 + 0.1 * (count / max_count)
c = s
+ self.itemstring = own_stack:to_string()
self.object:set_properties({
visual_size = {x = s, y = s},
- collisionbox = {-c, -c, -c, c, c, c}
+ collisionbox = {-c, -c, -c, c, c, c},
+ wield_item = self.itemstring
})
- self.itemstring = name .. " " .. count
end
end
-- merging didn't succeed
diff --git a/builtin/game/misc.lua b/builtin/game/misc.lua
index 7caa9e7ba..bfe407b9d 100644
--- a/builtin/game/misc.lua
+++ b/builtin/game/misc.lua
@@ -4,50 +4,6 @@
-- Misc. API functions
--
-local jobs = {}
-local time = 0.0
-local last = core.get_us_time() / 1000000
-
-core.register_globalstep(function(dtime)
- local new = core.get_us_time() / 1000000
- if new > last then
- time = time + (new - last)
- else
- -- Overflow, we may lose a little bit of time here but
- -- only 1 tick max, potentially running timers slightly
- -- too early.
- time = time + new
- end
- last = new
-
- if #jobs < 1 then
- return
- end
-
- -- Iterate backwards so that we miss any new timers added by
- -- a timer callback, and so that we don't skip the next timer
- -- in the list if we remove one.
- for i = #jobs, 1, -1 do
- local job = jobs[i]
- if time >= job.expire then
- core.set_last_run_mod(job.mod_origin)
- job.func(unpack(job.arg))
- table.remove(jobs, i)
- end
- end
-end)
-
-function core.after(after, func, ...)
- assert(tonumber(after) and type(func) == "function",
- "Invalid core.after invocation")
- jobs[#jobs + 1] = {
- func = func,
- expire = time + after,
- arg = {...},
- mod_origin = core.get_last_run_mod()
- }
-end
-
function core.check_player_privs(name, ...)
local arg_type = type(name)
if (arg_type == "userdata" or arg_type == "table") and
@@ -56,11 +12,11 @@ function core.check_player_privs(name, ...)
elseif arg_type ~= "string" then
error("Invalid core.check_player_privs argument type: " .. arg_type, 2)
end
-
+
local requested_privs = {...}
local player_privs = core.get_player_privs(name)
local missing_privileges = {}
-
+
if type(requested_privs[1]) == "table" then
-- We were provided with a table like { privA = true, privB = true }.
for priv, value in pairs(requested_privs[1]) do
@@ -76,11 +32,11 @@ function core.check_player_privs(name, ...)
end
end
end
-
+
if #missing_privileges > 0 then
return false, missing_privileges
end
-
+
return true, ""
end
@@ -114,6 +70,10 @@ function core.get_connected_players()
return temp_table
end
+function minetest.player_exists(name)
+ return minetest.get_auth_handler().get_auth(name) ~= nil
+end
+
-- Returns two position vectors representing a box of `radius` in each
-- direction centered around the player corresponding to `player_name`
function core.get_player_radius_area(player_name, radius)
@@ -161,7 +121,7 @@ function core.get_node_group(name, group)
end
function core.setting_get_pos(name)
- local value = core.setting_get(name)
+ local value = core.settings:get(name)
if not value then
return nil
end
@@ -210,38 +170,11 @@ function core.http_add_fetch(httpenv)
return httpenv
end
-if minetest.setting_getbool("disable_escape_sequences") then
-
- function core.get_color_escape_sequence(color)
- return ""
- end
-
- function core.get_background_escape_sequence(color)
- return ""
- end
-
- function core.colorize(color, message)
- return message
- end
-
-else
-
- local ESCAPE_CHAR = string.char(0x1b)
- function core.get_color_escape_sequence(color)
- return ESCAPE_CHAR .. "(c@" .. color .. ")"
- end
-
- function core.get_background_escape_sequence(color)
- return ESCAPE_CHAR .. "(b@" .. color .. ")"
- end
-
- function core.colorize(color, message)
- return core.get_color_escape_sequence(color) .. message .. core.get_color_escape_sequence("#ffffff")
- end
-
-end
-
function core.close_formspec(player_name, formname)
return minetest.show_formspec(player_name, formname, "")
end
+function core.cancel_shutdown_requests()
+ core.request_shutdown("", false, -1)
+end
+
diff --git a/builtin/game/register.lua b/builtin/game/register.lua
index 90f095e9f..ec6f28097 100644
--- a/builtin/game/register.lua
+++ b/builtin/game/register.lua
@@ -331,8 +331,8 @@ core.register_item(":unknown", {
core.register_node(":air", {
description = "Air (you hacker you!)",
- inventory_image = "unknown_node.png",
- wield_image = "unknown_node.png",
+ inventory_image = "air.png",
+ wield_image = "air.png",
drawtype = "airlike",
paramtype = "light",
sunlight_propagates = true,
@@ -348,8 +348,8 @@ core.register_node(":air", {
core.register_node(":ignore", {
description = "Ignore (you hacker you!)",
- inventory_image = "unknown_node.png",
- wield_image = "unknown_node.png",
+ inventory_image = "ignore.png",
+ wield_image = "ignore.png",
drawtype = "airlike",
paramtype = "none",
sunlight_propagates = false,
diff --git a/builtin/game/statbars.lua b/builtin/game/statbars.lua
index 61a8b9077..6aa106140 100644
--- a/builtin/game/statbars.lua
+++ b/builtin/game/statbars.lua
@@ -1,3 +1,5 @@
+-- cache setting
+local enable_damage = core.settings:get_bool("enable_damage")
local health_bar_definition =
{
@@ -42,9 +44,8 @@ local function initialize_builtin_statbars(player)
player:hud_set_flags(player:hud_get_flags())
end
- if player:hud_get_flags().healthbar and
- core.is_yes(core.setting_get("enable_damage")) then
- if hud_ids[name].id_healthbar == nil then
+ if player:hud_get_flags().healthbar and enable_damage then
+ if hud_ids[name].id_healthbar == nil then
health_bar_definition.number = player:get_hp()
hud_ids[name].id_healthbar = player:hud_add(health_bar_definition)
end
@@ -56,8 +57,7 @@ local function initialize_builtin_statbars(player)
end
if (player:get_breath() < 11) then
- if player:hud_get_flags().breathbar and
- core.is_yes(core.setting_get("enable_damage")) then
+ if player:hud_get_flags().breathbar and enable_damage then
if hud_ids[name].id_breathbar == nil then
hud_ids[name].id_breathbar = player:hud_add(breath_bar_definition)
end
diff --git a/builtin/game/static_spawn.lua b/builtin/game/static_spawn.lua
index 100334226..b1157b42e 100644
--- a/builtin/game/static_spawn.lua
+++ b/builtin/game/static_spawn.lua
@@ -1,10 +1,10 @@
-- Minetest: builtin/static_spawn.lua
local function warn_invalid_static_spawnpoint()
- if core.setting_get("static_spawnpoint") and
+ if core.settings:get("static_spawnpoint") and
not core.setting_get_pos("static_spawnpoint") then
core.log("error", "The static_spawnpoint setting is invalid: \""..
- core.setting_get("static_spawnpoint").."\"")
+ core.settings:get("static_spawnpoint").."\"")
end
end