diff options
author | Paramat <paramat@users.noreply.github.com> | 2018-01-23 18:04:58 +0000 |
---|---|---|
committer | Loïc Blot <nerzhul@users.noreply.github.com> | 2018-01-23 19:04:58 +0100 |
commit | 01bc817fe0a59e2e2b20c26d395c5b989c5156c9 (patch) | |
tree | 9434f2ddfeb8da51ee07eac41fe8bc4dba341141 /builtin/game/misc.lua | |
parent | 0425c6b8c888d0ccdf09a371a7415c8b3cb055a3 (diff) | |
download | minetest-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/game/misc.lua')
-rw-r--r-- | builtin/game/misc.lua | 66 |
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 - |