aboutsummaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
authorParamat <paramat@users.noreply.github.com>2018-01-23 18:04:58 +0000
committerLoïc Blot <nerzhul@users.noreply.github.com>2018-01-23 19:04:58 +0100
commit01bc817fe0a59e2e2b20c26d395c5b989c5156c9 (patch)
tree9434f2ddfeb8da51ee07eac41fe8bc4dba341141 /builtin
parent0425c6b8c888d0ccdf09a371a7415c8b3cb055a3 (diff)
downloadminetest-01bc817fe0a59e2e2b20c26d395c5b989c5156c9.tar.gz
minetest-01bc817fe0a59e2e2b20c26d395c5b989c5156c9.tar.bz2
minetest-01bc817fe0a59e2e2b20c26d395c5b989c5156c9.zip
Intersects_protection(): Move from Minetest Game to builtin (#6952)
A useful function that applies 'core.is_protected()' to a 3D lattice of points evenly spaced throughout a defined volume, with a parameter for the maximum spacing of points.
Diffstat (limited to 'builtin')
-rw-r--r--builtin/game/misc.lua66
1 files changed, 65 insertions, 1 deletions
diff --git a/builtin/game/misc.lua b/builtin/game/misc.lua
index 39ef9b461..79ca40217 100644
--- a/builtin/game/misc.lua
+++ b/builtin/game/misc.lua
@@ -40,14 +40,17 @@ function core.check_player_privs(name, ...)
return true, ""
end
+
local player_list = {}
+
function core.send_join_message(player_name)
if not minetest.is_singleplayer() then
core.chat_send_all("*** " .. player_name .. " joined the game.")
end
end
+
function core.send_leave_message(player_name, timed_out)
local announcement = "*** " .. player_name .. " left the game."
if timed_out then
@@ -56,18 +59,21 @@ function core.send_leave_message(player_name, timed_out)
core.chat_send_all(announcement)
end
+
core.register_on_joinplayer(function(player)
local player_name = player:get_player_name()
player_list[player_name] = player
core.send_join_message(player_name)
end)
+
core.register_on_leaveplayer(function(player, timed_out)
local player_name = player:get_player_name()
player_list[player_name] = nil
core.send_leave_message(player_name, timed_out)
end)
+
function core.get_connected_players()
local temp_table = {}
for index, value in pairs(player_list) do
@@ -78,12 +84,15 @@ 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)
local player = core.get_player_by_name(player_name)
if player == nil then
@@ -101,10 +110,12 @@ function core.get_player_radius_area(player_name, radius)
return p1, p2
end
+
function core.hash_node_position(pos)
return (pos.z+32768)*65536*65536 + (pos.y+32768)*65536 + pos.x+32768
end
+
function core.get_position_from_hash(hash)
local pos = {}
pos.x = (hash%65536) - 32768
@@ -115,6 +126,7 @@ function core.get_position_from_hash(hash)
return pos
end
+
function core.get_item_group(name, group)
if not core.registered_items[name] or not
core.registered_items[name].groups[group] then
@@ -123,11 +135,13 @@ function core.get_item_group(name, group)
return core.registered_items[name].groups[group]
end
+
function core.get_node_group(name, group)
core.log("deprecated", "Deprecated usage of get_node_group, use get_item_group instead")
return core.get_item_group(name, group)
end
+
function core.setting_get_pos(name)
local value = core.settings:get(name)
if not value then
@@ -136,17 +150,64 @@ function core.setting_get_pos(name)
return core.string_to_pos(value)
end
+
-- To be overriden by protection mods
+
function core.is_protected(pos, name)
return false
end
+
function core.record_protection_violation(pos, name)
for _, func in pairs(core.registered_on_protection_violation) do
func(pos, name)
end
end
+
+-- Checks if specified volume intersects a protected volume
+
+function core.intersects_protection(minp, maxp, player_name, interval)
+ -- 'interval' is the largest allowed interval for the 3D lattice of checks.
+
+ -- Compute the optimal float step 'd' for each axis so that all corners and
+ -- borders are checked. 'd' will be smaller or equal to 'interval'.
+ -- Subtracting 1e-4 ensures that the max co-ordinate will be reached by the
+ -- for loop (which might otherwise not be the case due to rounding errors).
+
+ -- Default to 4
+ interval = interval or 4
+ local d = {}
+
+ for _, c in pairs({"x", "y", "z"}) do
+ if maxp[c] > minp[c] then
+ d[c] = (maxp[c] - minp[c]) /
+ math.ceil((maxp[c] - minp[c]) / interval) - 1e-4
+ elseif maxp[c] == minp[c] then
+ d[c] = 1 -- Any value larger than 0 to avoid division by zero
+ else -- maxp[c] < minp[c], print error and treat as protection intersected
+ minetest.log("error", "maxp < minp in 'minetest.intersects_protection()'")
+ return true
+ end
+ end
+
+ for zf = minp.z, maxp.z, d.z do
+ local z = math.floor(zf + 0.5)
+ for yf = minp.y, maxp.y, d.y do
+ local y = math.floor(yf + 0.5)
+ for xf = minp.x, maxp.x, d.x do
+ local x = math.floor(xf + 0.5)
+ if core.is_protected({x = x, y = y, z = z}, player_name) then
+ return true
+ end
+ end
+ end
+ end
+
+ return false
+end
+
+
local raillike_ids = {}
local raillike_cur_id = 0
function core.raillike_group(name)
@@ -159,7 +220,9 @@ function core.raillike_group(name)
return id
end
+
-- HTTP callback interface
+
function core.http_add_fetch(httpenv)
httpenv.fetch = function(req, callback)
local handle = httpenv.fetch_async(req)
@@ -178,11 +241,12 @@ function core.http_add_fetch(httpenv)
return httpenv
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
-