aboutsummaryrefslogtreecommitdiff
path: root/builtin/game
diff options
context:
space:
mode:
authorElias Fleckenstein <eliasfleckenstein@web.de>2021-09-19 20:56:13 +0200
committerElias Fleckenstein <eliasfleckenstein@web.de>2021-09-19 20:56:13 +0200
commitc8900e169a1ddceec07a449f1ae7c4322ff02036 (patch)
tree5156605fb473d25786426eb6876ba2e7d3b7507b /builtin/game
parent950d2c9b3e10cbace9236e820c8119d1abb9e01f (diff)
parente0529da5c84f224c380e6d5e063392cb01f85683 (diff)
downloaddragonfireclient-c8900e169a1ddceec07a449f1ae7c4322ff02036.tar.xz
Merge branch 'master' of https://github.com/minetest/minetest
Diffstat (limited to 'builtin/game')
-rw-r--r--builtin/game/auth.lua7
-rw-r--r--builtin/game/chat.lua82
-rw-r--r--builtin/game/falling.lua70
-rw-r--r--builtin/game/features.lua2
-rw-r--r--builtin/game/forceloading.lua9
-rw-r--r--builtin/game/init.lua2
-rw-r--r--builtin/game/item.lua105
-rw-r--r--builtin/game/misc.lua63
-rw-r--r--builtin/game/privileges.lua7
-rw-r--r--builtin/game/register.lua1
-rw-r--r--builtin/game/voxelarea.lua14
11 files changed, 228 insertions, 134 deletions
diff --git a/builtin/game/auth.lua b/builtin/game/auth.lua
index fc061666c..e7d502bb3 100644
--- a/builtin/game/auth.lua
+++ b/builtin/game/auth.lua
@@ -87,6 +87,10 @@ core.builtin_auth_handler = {
core.settings:get("default_password")))
end
+ auth_entry.privileges = privileges
+
+ core_auth.save(auth_entry)
+
-- Run grant callbacks
for priv, _ in pairs(privileges) do
if not auth_entry.privileges[priv] then
@@ -100,9 +104,6 @@ core.builtin_auth_handler = {
core.run_priv_callbacks(name, priv, nil, "revoke")
end
end
-
- auth_entry.privileges = privileges
- core_auth.save(auth_entry)
core.notify_authentication_modified(name)
end,
reload = function()
diff --git a/builtin/game/chat.lua b/builtin/game/chat.lua
index 0bd12c25f..99296f782 100644
--- a/builtin/game/chat.lua
+++ b/builtin/game/chat.lua
@@ -212,9 +212,14 @@ core.register_chatcommand("haspriv", {
table.insert(players_with_priv, player_name)
end
end
- return true, S("Players online with the \"@1\" privilege: @2",
- param,
- table.concat(players_with_priv, ", "))
+ if #players_with_priv == 0 then
+ return true, S("No online player has the \"@1\" privilege.",
+ param)
+ else
+ return true, S("Players online with the \"@1\" privilege: @2",
+ param,
+ table.concat(players_with_priv, ", "))
+ end
end
})
@@ -250,11 +255,11 @@ local function handle_grant_command(caller, grantname, grantprivstr)
if privs_unknown ~= "" then
return false, privs_unknown
end
+ core.set_player_privs(grantname, privs)
for priv, _ in pairs(grantprivs) do
-- call the on_grant callbacks
core.run_priv_callbacks(grantname, priv, caller, "grant")
end
- core.set_player_privs(grantname, privs)
core.log("action", caller..' granted ('..core.privs_to_string(grantprivs, ', ')..') privileges to '..grantname)
if grantname ~= caller then
core.chat_send_player(grantname,
@@ -354,13 +359,13 @@ local function handle_revoke_command(caller, revokename, revokeprivstr)
end
local revokecount = 0
+
+ core.set_player_privs(revokename, privs)
for priv, _ in pairs(revokeprivs) do
-- call the on_revoke callbacks
core.run_priv_callbacks(revokename, priv, caller, "revoke")
revokecount = revokecount + 1
end
-
- core.set_player_privs(revokename, privs)
local new_privs = core.get_player_privs(revokename)
if revokecount == 0 then
@@ -499,10 +504,10 @@ core.register_chatcommand("remove_player", {
-- pos may be a non-integer position
local function find_free_position_near(pos)
local tries = {
- {x=1, y=0, z=0},
- {x=-1, y=0, z=0},
- {x=0, y=0, z=1},
- {x=0, y=0, z=-1},
+ vector.new( 1, 0, 0),
+ vector.new(-1, 0, 0),
+ vector.new( 0, 0, 1),
+ vector.new( 0, 0, -1),
}
for _, d in ipairs(tries) do
local p = vector.add(pos, d)
@@ -737,7 +742,12 @@ core.register_chatcommand("mods", {
description = S("List mods installed on the server"),
privs = {},
func = function(name, param)
- return true, table.concat(core.get_modnames(), ", ")
+ local mods = core.get_modnames()
+ if #mods == 0 then
+ return true, S("No mods installed.")
+ else
+ return true, table.concat(core.get_modnames(), ", ")
+ end
end,
})
@@ -1053,24 +1063,58 @@ core.register_chatcommand("days", {
end
})
+local function parse_shutdown_param(param)
+ local delay, reconnect, message
+ local one, two, three
+ one, two, three = param:match("^(%S+) +(%-r) +(.*)")
+ if one and two and three then
+ -- 3 arguments: delay, reconnect and message
+ return one, two, three
+ end
+ -- 2 arguments
+ one, two = param:match("^(%S+) +(.*)")
+ if one and two then
+ if tonumber(one) then
+ delay = one
+ if two == "-r" then
+ reconnect = two
+ else
+ message = two
+ end
+ elseif one == "-r" then
+ reconnect, message = one, two
+ end
+ return delay, reconnect, message
+ end
+ -- 1 argument
+ one = param:match("(.*)")
+ if tonumber(one) then
+ delay = one
+ elseif one == "-r" then
+ reconnect = one
+ else
+ message = one
+ end
+ return delay, reconnect, message
+end
+
core.register_chatcommand("shutdown", {
- params = S("[<delay_in_seconds> | -1] [reconnect] [<message>]"),
- description = S("Shutdown server (-1 cancels a delayed shutdown)"),
+ params = S("[<delay_in_seconds> | -1] [-r] [<message>]"),
+ description = S("Shutdown server (-1 cancels a delayed shutdown, -r allows players to reconnect)"),
privs = {server=true},
func = function(name, param)
- local delay, reconnect, message
- delay, param = param:match("^%s*(%S+)(.*)")
- if param then
- reconnect, param = param:match("^%s*(%S+)(.*)")
+ local delay, reconnect, message = parse_shutdown_param(param)
+ local bool_reconnect = reconnect == "-r"
+ if not message then
+ message = ""
end
- message = param and param:match("^%s*(.+)") or ""
delay = tonumber(delay) or 0
if delay == 0 then
core.log("action", name .. " shuts down server")
core.chat_send_all("*** "..S("Server shutting down (operator request)."))
end
- core.request_shutdown(message:trim(), core.is_yes(reconnect), delay)
+ core.request_shutdown(message:trim(), bool_reconnect, delay)
return true
end,
})
diff --git a/builtin/game/falling.lua b/builtin/game/falling.lua
index 2cc0d8fac..29cb56aae 100644
--- a/builtin/game/falling.lua
+++ b/builtin/game/falling.lua
@@ -39,7 +39,7 @@ local gravity = tonumber(core.settings:get("movement_gravity")) or 9.81
core.register_entity(":__builtin:falling_node", {
initial_properties = {
visual = "item",
- visual_size = {x = SCALE, y = SCALE, z = SCALE},
+ visual_size = vector.new(SCALE, SCALE, SCALE),
textures = {},
physical = true,
is_visible = false,
@@ -96,7 +96,7 @@ core.register_entity(":__builtin:falling_node", {
local vsize
if def.visual_scale then
local s = def.visual_scale
- vsize = {x = s, y = s, z = s}
+ vsize = vector.new(s, s, s)
end
self.object:set_properties({
is_visible = true,
@@ -111,15 +111,21 @@ core.register_entity(":__builtin:falling_node", {
itemstring = core.itemstring_with_palette(itemstring, node.param2)
end
-- FIXME: solution needed for paramtype2 == "leveled"
- local vsize
- if def.visual_scale then
- local s = def.visual_scale * SCALE
- vsize = {x = s, y = s, z = s}
+ -- Calculate size of falling node
+ local s = {}
+ s.x = (def.visual_scale or 1) * SCALE
+ s.y = s.x
+ s.z = s.x
+ -- Compensate for wield_scale
+ if def.wield_scale then
+ s.x = s.x / def.wield_scale.x
+ s.y = s.y / def.wield_scale.y
+ s.z = s.z / def.wield_scale.z
end
self.object:set_properties({
is_visible = true,
wield_item = itemstring,
- visual_size = vsize,
+ visual_size = s,
glow = def.light_source,
})
end
@@ -158,7 +164,8 @@ core.register_entity(":__builtin:falling_node", {
if euler then
self.object:set_rotation(euler)
end
- elseif (def.paramtype2 == "wallmounted" or def.paramtype2 == "colorwallmounted" or def.drawtype == "signlike") then
+ elseif (def.drawtype ~= "plantlike" and def.drawtype ~= "plantlike_rooted" and
+ (def.paramtype2 == "wallmounted" or def.paramtype2 == "colorwallmounted" or def.drawtype == "signlike")) then
local rot = node.param2 % 8
if (def.drawtype == "signlike" and def.paramtype2 ~= "wallmounted" and def.paramtype2 ~= "colorwallmounted") then
-- Change rotation to "floor" by default for non-wallmounted paramtype2
@@ -227,7 +234,7 @@ core.register_entity(":__builtin:falling_node", {
on_activate = function(self, staticdata)
self.object:set_armor_groups({immortal = 1})
- self.object:set_acceleration({x = 0, y = -gravity, z = 0})
+ self.object:set_acceleration(vector.new(0, -gravity, 0))
local ds = core.deserialize(staticdata)
if ds and ds.node then
@@ -303,7 +310,7 @@ core.register_entity(":__builtin:falling_node", {
if self.floats then
local pos = self.object:get_pos()
- local bcp = vector.round({x = pos.x, y = pos.y - 0.7, z = pos.z})
+ local bcp = pos:offset(0, -0.7, 0):round()
local bcn = core.get_node(bcp)
local bcd = core.registered_nodes[bcn.name]
@@ -344,13 +351,12 @@ core.register_entity(":__builtin:falling_node", {
-- TODO: this hack could be avoided in the future if objects
-- could choose who to collide with
local vel = self.object:get_velocity()
- self.object:set_velocity({
- x = vel.x,
- y = player_collision.old_velocity.y,
- z = vel.z
- })
- self.object:set_pos(vector.add(self.object:get_pos(),
- {x = 0, y = -0.5, z = 0}))
+ self.object:set_velocity(vector.new(
+ vel.x,
+ player_collision.old_velocity.y,
+ vel.z
+ ))
+ self.object:set_pos(self.object:get_pos():offset(0, -0.5, 0))
end
return
elseif bcn.name == "ignore" then
@@ -430,7 +436,7 @@ local function drop_attached_node(p)
if def and def.preserve_metadata then
local oldmeta = core.get_meta(p):to_table().fields
-- Copy pos and node because the callback can modify them.
- local pos_copy = {x=p.x, y=p.y, z=p.z}
+ local pos_copy = vector.new(p)
local node_copy = {name=n.name, param1=n.param1, param2=n.param2}
local drop_stacks = {}
for k, v in pairs(drops) do
@@ -455,14 +461,14 @@ end
function builtin_shared.check_attached_node(p, n)
local def = core.registered_nodes[n.name]
- local d = {x = 0, y = 0, z = 0}
+ local d = vector.new()
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.
-- The fallback vector corresponds to param2 = 0.
- d = core.wallmounted_to_dir(n.param2) or {x = 0, y = 1, z = 0}
+ d = core.wallmounted_to_dir(n.param2) or vector.new(0, 1, 0)
else
d.y = -1
end
@@ -482,7 +488,7 @@ end
function core.check_single_for_falling(p)
local n = core.get_node(p)
if core.get_item_group(n.name, "falling_node") ~= 0 then
- local p_bottom = {x = p.x, y = p.y - 1, z = p.z}
+ local p_bottom = vector.offset(p, 0, -1, 0)
-- Only spawn falling node if node below is loaded
local n_bottom = core.get_node_or_nil(p_bottom)
local d_bottom = n_bottom and core.registered_nodes[n_bottom.name]
@@ -521,17 +527,17 @@ end
-- Down first as likely case, but always before self. The same with sides.
-- Up must come last, so that things above self will also fall all at once.
local check_for_falling_neighbors = {
- {x = -1, y = -1, z = 0},
- {x = 1, y = -1, z = 0},
- {x = 0, y = -1, z = -1},
- {x = 0, y = -1, z = 1},
- {x = 0, y = -1, z = 0},
- {x = -1, y = 0, z = 0},
- {x = 1, y = 0, z = 0},
- {x = 0, y = 0, z = 1},
- {x = 0, y = 0, z = -1},
- {x = 0, y = 0, z = 0},
- {x = 0, y = 1, z = 0},
+ vector.new(-1, -1, 0),
+ vector.new( 1, -1, 0),
+ vector.new( 0, -1, -1),
+ vector.new( 0, -1, 1),
+ vector.new( 0, -1, 0),
+ vector.new(-1, 0, 0),
+ vector.new( 1, 0, 0),
+ vector.new( 0, 0, 1),
+ vector.new( 0, 0, -1),
+ vector.new( 0, 0, 0),
+ vector.new( 0, 1, 0),
}
function core.check_for_falling(p)
diff --git a/builtin/game/features.lua b/builtin/game/features.lua
index 8f0604448..583ef5092 100644
--- a/builtin/game/features.lua
+++ b/builtin/game/features.lua
@@ -20,6 +20,8 @@ core.features = {
direct_velocity_on_players = true,
use_texture_alpha_string_modes = true,
degrotate_240_steps = true,
+ abm_min_max_y = true,
+ dynamic_add_media_table = true,
}
function core.has_feature(arg)
diff --git a/builtin/game/forceloading.lua b/builtin/game/forceloading.lua
index e1e00920c..8043e5dea 100644
--- a/builtin/game/forceloading.lua
+++ b/builtin/game/forceloading.lua
@@ -86,12 +86,6 @@ local function read_file(filename)
return core.deserialize(t) or {}
end
-local function write_file(filename, table)
- local f = io.open(filename, "w")
- f:write(core.serialize(table))
- f:close()
-end
-
blocks_forceloaded = read_file(wpath.."/force_loaded.txt")
for _, __ in pairs(blocks_forceloaded) do
total_forceloaded = total_forceloaded + 1
@@ -106,7 +100,8 @@ end)
-- persists the currently forceloaded blocks to disk
local function persist_forceloaded_blocks()
- write_file(wpath.."/force_loaded.txt", blocks_forceloaded)
+ local data = core.serialize(blocks_forceloaded)
+ core.safe_file_write(wpath.."/force_loaded.txt", data)
end
-- periodical forceload persistence
diff --git a/builtin/game/init.lua b/builtin/game/init.lua
index 1d62be019..bb007fabd 100644
--- a/builtin/game/init.lua
+++ b/builtin/game/init.lua
@@ -7,8 +7,6 @@ local gamepath = scriptpath .. "game".. DIR_DELIM
-- not exposed to outer context
local builtin_shared = {}
-dofile(commonpath .. "vector.lua")
-
dofile(gamepath .. "constants.lua")
assert(loadfile(gamepath .. "item.lua"))(builtin_shared)
dofile(gamepath .. "register.lua")
diff --git a/builtin/game/item.lua b/builtin/game/item.lua
index c4d93abd6..92818b177 100644
--- a/builtin/game/item.lua
+++ b/builtin/game/item.lua
@@ -70,12 +70,12 @@ end
-- Table of possible dirs
local facedir_to_dir = {
- {x= 0, y=0, z= 1},
- {x= 1, y=0, z= 0},
- {x= 0, y=0, z=-1},
- {x=-1, y=0, z= 0},
- {x= 0, y=-1, z= 0},
- {x= 0, y=1, z= 0},
+ vector.new( 0, 0, 1),
+ vector.new( 1, 0, 0),
+ vector.new( 0, 0, -1),
+ vector.new(-1, 0, 0),
+ vector.new( 0, -1, 0),
+ vector.new( 0, 1, 0),
}
-- Mapping from facedir value to index in facedir_to_dir.
local facedir_to_dir_map = {
@@ -114,12 +114,12 @@ end
-- table of dirs in wallmounted order
local wallmounted_to_dir = {
- [0] = {x = 0, y = 1, z = 0},
- {x = 0, y = -1, z = 0},
- {x = 1, y = 0, z = 0},
- {x = -1, y = 0, z = 0},
- {x = 0, y = 0, z = 1},
- {x = 0, y = 0, z = -1},
+ [0] = vector.new( 0, 1, 0),
+ vector.new( 0, -1, 0),
+ vector.new( 1, 0, 0),
+ vector.new(-1, 0, 0),
+ vector.new( 0, 0, 1),
+ vector.new( 0, 0, -1),
}
function core.wallmounted_to_dir(wallmounted)
return wallmounted_to_dir[wallmounted % 8]
@@ -130,7 +130,7 @@ function core.dir_to_yaw(dir)
end
function core.yaw_to_dir(yaw)
- return {x = -math.sin(yaw), y = 0, z = math.cos(yaw)}
+ return vector.new(-math.sin(yaw), 0, math.cos(yaw))
end
function core.is_colored_paramtype(ptype)
@@ -153,6 +153,18 @@ function core.strip_param2_color(param2, paramtype2)
return param2
end
+local function has_all_groups(tbl, required_groups)
+ if type(required_groups) == "string" then
+ return (tbl[required_groups] or 0) ~= 0
+ end
+ for _, group in ipairs(required_groups) do
+ if (tbl[group] or 0) == 0 then
+ return false
+ end
+ end
+ return true
+end
+
function core.get_node_drops(node, toolname)
-- Compatibility, if node is string
local nodename = node
@@ -192,7 +204,7 @@ function core.get_node_drops(node, toolname)
if item.rarity ~= nil then
good_rarity = item.rarity < 1 or math.random(item.rarity) == 1
end
- if item.tools ~= nil then
+ if item.tools ~= nil or item.tool_groups ~= nil then
good_tool = false
end
if item.tools ~= nil and toolname then
@@ -207,6 +219,27 @@ function core.get_node_drops(node, toolname)
end
end
end
+ if item.tool_groups ~= nil and toolname then
+ local tooldef = core.registered_items[toolname]
+ if tooldef ~= nil and type(tooldef.groups) == "table" then
+ if type(item.tool_groups) == "string" then
+ -- tool_groups can be a string which specifies the required group
+ good_tool = core.get_item_group(toolname, item.tool_groups) ~= 0
+ else
+ -- tool_groups can be a list of sufficient requirements.
+ -- i.e. if any item in the list can be satisfied then the tool is good
+ assert(type(item.tool_groups) == "table")
+ for _, required_groups in ipairs(item.tool_groups) do
+ -- required_groups can be either a string (a single group),
+ -- or an array of strings where all must be in tooldef.groups
+ good_tool = has_all_groups(tooldef.groups, required_groups)
+ if good_tool then
+ break
+ end
+ end
+ end
+ end
+ end
if good_rarity and good_tool then
got_count = got_count + 1
for _, add_item in ipairs(item.items) do
@@ -268,12 +301,12 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2,
end
-- Place above pointed node
- local place_to = {x = above.x, y = above.y, z = above.z}
+ local place_to = vector.new(above)
-- If node under is buildable_to, place into it instead (eg. snow)
if olddef_under.buildable_to then
log("info", "node under is buildable to")
- place_to = {x = under.x, y = under.y, z = under.z}
+ place_to = vector.new(under)
end
if core.is_protected(place_to, playername) then
@@ -293,22 +326,14 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2,
newnode.param2 = def.place_param2
elseif (def.paramtype2 == "wallmounted" or
def.paramtype2 == "colorwallmounted") and not param2 then
- local dir = {
- x = under.x - above.x,
- y = under.y - above.y,
- z = under.z - above.z
- }
+ local dir = vector.subtract(under, above)
newnode.param2 = core.dir_to_wallmounted(dir)
-- Calculate the direction for furnaces and chests and stuff
elseif (def.paramtype2 == "facedir" or
def.paramtype2 == "colorfacedir") and not param2 then
local placer_pos = placer and placer:get_pos()
if placer_pos then
- local dir = {
- x = above.x - placer_pos.x,
- y = above.y - placer_pos.y,
- z = above.z - placer_pos.z
- }
+ local dir = vector.subtract(above, placer_pos)
newnode.param2 = core.dir_to_facedir(dir)
log("info", "facedir: " .. newnode.param2)
end
@@ -362,7 +387,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2,
-- Run callback
if def.after_place_node and not prevent_after_place then
-- Deepcopy place_to and pointed_thing because callback can modify it
- local place_to_copy = {x=place_to.x, y=place_to.y, z=place_to.z}
+ local place_to_copy = vector.new(place_to)
local pointed_thing_copy = copy_pointed_thing(pointed_thing)
if def.after_place_node(place_to_copy, placer, itemstack,
pointed_thing_copy) then
@@ -373,7 +398,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2,
-- Run script hook
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}
+ local place_to_copy = vector.new(place_to)
local newnode_copy = {name=newnode.name, param1=newnode.param1, param2=newnode.param2}
local oldnode_copy = {name=oldnode.name, param1=oldnode.param1, param2=oldnode.param2}
local pointed_thing_copy = copy_pointed_thing(pointed_thing)
@@ -519,11 +544,11 @@ function core.handle_node_drops(pos, drops, digger)
for _, dropped_item in pairs(drops) do
local left = give_item(dropped_item)
if not left:is_empty() then
- local p = {
- x = pos.x + math.random()/2-0.25,
- y = pos.y + math.random()/2-0.25,
- z = pos.z + math.random()/2-0.25,
- }
+ local p = vector.offset(pos,
+ math.random()/2-0.25,
+ math.random()/2-0.25,
+ math.random()/2-0.25
+ )
core.add_item(p, left)
end
end
@@ -582,7 +607,7 @@ function core.node_dig(pos, node, digger)
if def and def.preserve_metadata then
local oldmeta = core.get_meta(pos):to_table().fields
-- Copy pos and node because the callback can modify them.
- local pos_copy = {x=pos.x, y=pos.y, z=pos.z}
+ local pos_copy = vector.new(pos)
local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
local drop_stacks = {}
for k, v in pairs(drops) do
@@ -614,7 +639,7 @@ function core.node_dig(pos, node, digger)
-- Run callback
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 pos_copy = vector.new(pos)
local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
def.after_dig_node(pos_copy, node_copy, oldmetadata, digger)
end
@@ -627,7 +652,7 @@ function core.node_dig(pos, node, digger)
end
-- Copy pos and node because callback can modify them
- local pos_copy = {x=pos.x, y=pos.y, z=pos.z}
+ local pos_copy = vector.new(pos)
local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
callback(pos_copy, node_copy, digger)
end
@@ -670,7 +695,7 @@ core.nodedef_default = {
groups = {},
inventory_image = "",
wield_image = "",
- wield_scale = {x=1,y=1,z=1},
+ wield_scale = vector.new(1, 1, 1),
stack_max = default_stack_max,
usable = false,
liquids_pointable = false,
@@ -729,7 +754,7 @@ core.craftitemdef_default = {
groups = {},
inventory_image = "",
wield_image = "",
- wield_scale = {x=1,y=1,z=1},
+ wield_scale = vector.new(1, 1, 1),
stack_max = default_stack_max,
liquids_pointable = false,
tool_capabilities = nil,
@@ -748,7 +773,7 @@ core.tooldef_default = {
groups = {},
inventory_image = "",
wield_image = "",
- wield_scale = {x=1,y=1,z=1},
+ wield_scale = vector.new(1, 1, 1),
stack_max = 1,
liquids_pointable = false,
tool_capabilities = nil,
@@ -767,7 +792,7 @@ core.noneitemdef_default = { -- This is used for the hand and unknown items
groups = {},
inventory_image = "",
wield_image = "",
- wield_scale = {x=1,y=1,z=1},
+ wield_scale = vector.new(1, 1, 1),
stack_max = default_stack_max,
liquids_pointable = false,
tool_capabilities = nil,
diff --git a/builtin/game/misc.lua b/builtin/game/misc.lua
index fcb86146d..63d64817c 100644
--- a/builtin/game/misc.lua
+++ b/builtin/game/misc.lua
@@ -119,13 +119,12 @@ end
function core.get_position_from_hash(hash)
- local pos = {}
- pos.x = (hash % 65536) - 32768
+ local x = (hash % 65536) - 32768
hash = math.floor(hash / 65536)
- pos.y = (hash % 65536) - 32768
+ local y = (hash % 65536) - 32768
hash = math.floor(hash / 65536)
- pos.z = (hash % 65536) - 32768
- return pos
+ local z = (hash % 65536) - 32768
+ return vector.new(x, y, z)
end
@@ -215,7 +214,7 @@ function core.is_area_protected(minp, maxp, player_name, interval)
local y = math.floor(yf + 0.5)
for xf = minp.x, maxp.x, d.x do
local x = math.floor(xf + 0.5)
- local pos = {x = x, y = y, z = z}
+ local pos = vector.new(x, y, z)
if core.is_protected(pos, player_name) then
return pos
end
@@ -270,24 +269,44 @@ function core.cancel_shutdown_requests()
end
--- Callback handling for dynamic_add_media
+-- Used for callback handling with dynamic_add_media
+core.dynamic_media_callbacks = {}
-local dynamic_add_media_raw = core.dynamic_add_media_raw
-core.dynamic_add_media_raw = nil
-function core.dynamic_add_media(filepath, callback)
- local ret = dynamic_add_media_raw(filepath)
- if ret == false then
- return ret
+
+-- PNG encoder safety wrapper
+
+local o_encode_png = core.encode_png
+function core.encode_png(width, height, data, compression)
+ if type(width) ~= "number" then
+ error("Incorrect type for 'width', expected number, got " .. type(width))
end
- if callback == nil then
- core.log("deprecated", "Calling minetest.dynamic_add_media without "..
- "a callback is deprecated and will stop working in future versions.")
- else
- -- At the moment async loading is not actually implemented, so we
- -- immediately call the callback ourselves
- for _, name in ipairs(ret) do
- callback(name)
+ if type(height) ~= "number" then
+ error("Incorrect type for 'height', expected number, got " .. type(height))
+ end
+
+ local expected_byte_count = width * height * 4
+
+ if type(data) ~= "table" and type(data) ~= "string" then
+ error("Incorrect type for 'height', expected table or string, got " .. type(height))
+ end
+
+ local data_length = type(data) == "table" and #data * 4 or string.len(data)
+
+ if data_length ~= expected_byte_count then
+ error(string.format(
+ "Incorrect length of 'data', width and height imply %d bytes but %d were provided",
+ expected_byte_count,
+ data_length
+ ))
+ end
+
+ if type(data) == "table" then
+ local dataBuf = {}
+ for i = 1, #data do
+ dataBuf[i] = core.colorspec_to_bytes(data[i])
end
+ data = table.concat(dataBuf)
end
- return true
+
+ return o_encode_png(width, height, data, compression or 6)
end
diff --git a/builtin/game/privileges.lua b/builtin/game/privileges.lua
index 1d3efb525..97681655e 100644
--- a/builtin/game/privileges.lua
+++ b/builtin/game/privileges.lua
@@ -97,10 +97,13 @@ core.register_privilege("rollback", {
description = S("Can use the rollback functionality"),
give_to_singleplayer = false,
})
+core.register_privilege("basic_debug", {
+ description = S("Can view more debug info that might give a gameplay advantage"),
+ give_to_singleplayer = false,
+})
core.register_privilege("debug", {
- description = S("Allows enabling various debug options that may affect gameplay"),
+ description = S("Can enable wireframe"),
give_to_singleplayer = false,
- give_to_admin = true,
})
core.register_can_bypass_userlimit(function(name, ip)
diff --git a/builtin/game/register.lua b/builtin/game/register.lua
index c07535855..56e40c75c 100644
--- a/builtin/game/register.lua
+++ b/builtin/game/register.lua
@@ -610,6 +610,7 @@ core.registered_on_modchannel_message, core.register_on_modchannel_message = mak
core.registered_on_player_inventory_actions, core.register_on_player_inventory_action = make_registration()
core.registered_allow_player_inventory_actions, core.register_allow_player_inventory_action = make_registration()
core.registered_on_rightclickplayers, core.register_on_rightclickplayer = make_registration()
+core.registered_on_liquid_transformed, core.register_on_liquid_transformed = make_registration()
--
-- Compatibility for on_mapgen_init()
diff --git a/builtin/game/voxelarea.lua b/builtin/game/voxelarea.lua
index 724761414..64436bf1a 100644
--- a/builtin/game/voxelarea.lua
+++ b/builtin/game/voxelarea.lua
@@ -1,6 +1,6 @@
VoxelArea = {
- MinEdge = {x=1, y=1, z=1},
- MaxEdge = {x=0, y=0, z=0},
+ MinEdge = vector.new(1, 1, 1),
+ MaxEdge = vector.new(0, 0, 0),
ystride = 0,
zstride = 0,
}
@@ -19,11 +19,11 @@ end
function VoxelArea:getExtent()
local MaxEdge, MinEdge = self.MaxEdge, self.MinEdge
- return {
- x = MaxEdge.x - MinEdge.x + 1,
- y = MaxEdge.y - MinEdge.y + 1,
- z = MaxEdge.z - MinEdge.z + 1,
- }
+ return vector.new(
+ MaxEdge.x - MinEdge.x + 1,
+ MaxEdge.y - MinEdge.y + 1,
+ MaxEdge.z - MinEdge.z + 1
+ )
end
function VoxelArea:getVolume()