Configuration & entity support

master
Lars Mueller 2020-12-20 14:53:13 +01:00
parent 6f6b80198a
commit 0c06c640c1
4 changed files with 59 additions and 17 deletions

View File

@ -1,8 +1,12 @@
# Disable Build Where They Stand # Disable Build Where They Stand
Disables placing blocks at places where they would collide with a player. Disables placing blocks at places where they would collide with a player (or entity).
## About ## About
No dependencies. Licensed under the MIT License. Written by Lars Mueller aka LMD or appguru(eu). No dependencies. Licensed under the MIT License. Written by Lars Mueller aka LMD or appguru(eu).
## Usage
Enable & probably configure it. Note: Uses the new modlib configuration system.

View File

@ -1,6 +1,7 @@
local visualize_box local modname = minetest.get_current_modname()
-- uncomment for testing: local conf = modlib.mod.configuration()
-- visualize_box = loadfile(minetest.get_modpath(minetest.get_current_modname()) .. "/test.lua")() _G[modname].conf = conf
local visualize_box = loadfile(minetest.get_modpath(modname) .. "/test.lua")()
local function aabb_collision(box, other_box, diff) local function aabb_collision(box, other_box, diff)
for index, coord in pairs{"x", "y", "z"} do for index, coord in pairs{"x", "y", "z"} do
@ -162,18 +163,29 @@ local function get_node_collisionboxes(node, pos)
return boxes return boxes
end end
minetest.register_on_placenode(function(pos, newnode, _, oldnode) minetest.register_on_placenode(function(pos, newnode, _player, oldnode)
for _, player in pairs(minetest.get_connected_players()) do local entities, search_radius = conf.entities, conf.search_radius
if vector.distance(player:get_pos(), pos) <= 10 then local objects = entities and minetest.get_objects_inside_radius(pos, search_radius) or minetest.get_connected_players()
-- HACK imposes a restriction on player & node collisionbox size for performance for index, object in pairs(objects) do
local collisionbox_player = player:get_properties().collisionbox if entities then
local diff = vector.subtract(player:get_pos(), pos) if not (object:is_player() or object:get_properties().physical) then
for _, collisionbox in pairs(get_node_collisionboxes(newnode, pos)) do objects[index] = nil
if visualize_box then visualize_box(pos, collisionbox) end end
if aabb_collision(collisionbox_player, collisionbox, diff) then else
minetest.set_node(pos, oldnode) if vector.distance(object:get_pos(), pos) > search_radius then
return true objects[index] = nil
end end
end
end
for _, object in pairs(objects) do
local collisionbox_player = object:get_properties().collisionbox
local diff = vector.subtract(object:get_pos(), pos)
for _, collisionbox in pairs(get_node_collisionboxes(newnode, pos)) do
if conf.test then visualize_box(pos, collisionbox) end
if aabb_collision(collisionbox_player, collisionbox, diff) then
-- TODO tell player why they can't build
minetest.set_node(pos, oldnode)
return true
end end
end end
end end

View File

@ -1,2 +1,3 @@
name = disable_build_where_they_stand name = disable_build_where_they_stand
description = Disables placing blocks at places where they would collide with a player description = Disables placing blocks at places where they would collide with a player (or entity)
depends = modlib

25
schema.lua Normal file
View File

@ -0,0 +1,25 @@
return {
type = "table",
entries = {
entities = {
type = "boolean",
description = "Also check for entities standing there",
default = true
},
search_radius = {
type = "number",
description = "Search radius for entities & players",
values = set,
range = {min_exclusive = 0, max = 100},
int = false,
infinity = false,
nan = false,
default = 10
},
test = {
description = "Enable debug mode (visualization of boxes)",
type = "boolean",
default = false
}
}
}