forked from minetest-mods/areas
250 lines
7.7 KiB
Lua
250 lines
7.7 KiB
Lua
|
|
||
|
-- I could depend on WorldEdit for this, but you need to have the 'worldedit'
|
||
|
-- permission to use those commands and you don't have /area_pos{1,2} [x y z|x,y,z]
|
||
|
-- Since this is mostly copied from WorldEdit it is licensed under the AGPL.
|
||
|
|
||
|
areas.marker1 = {}
|
||
|
areas.marker2 = {}
|
||
|
areas.set_pos = {}
|
||
|
areas.pos1 = {}
|
||
|
areas.pos2 = {}
|
||
|
|
||
|
minetest.register_chatcommand("select_area", {
|
||
|
params = "<id>",
|
||
|
description = "Select a area by id.",
|
||
|
privs = {},
|
||
|
func = function(name, param)
|
||
|
local id = tonumber(param)
|
||
|
if not id then
|
||
|
minetest.chat_send_player(name, "Invalid usage, see /help select_area.")
|
||
|
end
|
||
|
|
||
|
for k, area in pairs(areas.areas) do
|
||
|
if area.id == id then
|
||
|
areas:setPos1(name, area.pos1)
|
||
|
areas:setPos2(name, area.pos2)
|
||
|
minetest.chat_send_player(name, "Area "..tostring(id).." selected.")
|
||
|
return
|
||
|
end
|
||
|
end
|
||
|
minetest.chat_send_player(name, "The area "..tostring(id).." does not exist.")
|
||
|
end})
|
||
|
|
||
|
minetest.register_chatcommand("area_pos1", {
|
||
|
params = "[X Y Z|X,Y,Z]",
|
||
|
description = "Set area protection region position 1 to the player's location or the one specified",
|
||
|
privs = {},
|
||
|
func = function(name, param)
|
||
|
local pos = {}
|
||
|
local found, _, x, y, z = param:find("^(-?%d+)[%s%,]+(-?%d+)[%s%,]+(-?%d+)$")
|
||
|
if found then
|
||
|
pos = {x=tonumber(x), y=tonumber(y), z=tonumber(z)}
|
||
|
elseif param == "" then
|
||
|
player = minetest.get_player_by_name(name)
|
||
|
if player then
|
||
|
pos = player:getpos()
|
||
|
else
|
||
|
minetest.chat_send_player(name, "Unable to get position")
|
||
|
return
|
||
|
end
|
||
|
else
|
||
|
minetest.chat_send_player(name, "Invalid usage, see /help no_pos1")
|
||
|
end
|
||
|
pos.x, pos.y, pos.z = math.floor(pos.x + 0.5), math.floor(pos.y + 0.5), math.floor(pos.z + 0.5)
|
||
|
areas:setPos1(name, pos)
|
||
|
minetest.chat_send_player(name, "Area position 1 set to " .. minetest.pos_to_string(pos))
|
||
|
end,
|
||
|
})
|
||
|
|
||
|
minetest.register_chatcommand("area_pos2", {
|
||
|
params = "[X Y Z|X,Y,Z]",
|
||
|
description = "Set area protection region position 2 to the player's location or the one specified",
|
||
|
privs = {},
|
||
|
func = function(name, param)
|
||
|
local pos = {}
|
||
|
local found, _, x, y, z = param:find("^(-?%d+)[%s%,]+(-?%d+)[%s%,]+(-?%d+)$")
|
||
|
if found then
|
||
|
pos = {x=tonumber(x), y=tonumber(y), z=tonumber(z)}
|
||
|
elseif param == "" then
|
||
|
player = minetest.get_player_by_name(name)
|
||
|
if player then
|
||
|
pos = player:getpos()
|
||
|
else
|
||
|
minetest.chat_send_player(name, "Unable to get position")
|
||
|
return
|
||
|
end
|
||
|
else
|
||
|
minetest.chat_send_player(name, "Invalid usage, see /help no_pos2")
|
||
|
end
|
||
|
pos.x, pos.y, pos.z = math.floor(pos.x + 0.5), math.floor(pos.y + 0.5), math.floor(pos.z + 0.5)
|
||
|
areas:setPos2(name, pos)
|
||
|
minetest.chat_send_player(name, "Area position 2 set to " .. minetest.pos_to_string(pos))
|
||
|
end,
|
||
|
})
|
||
|
|
||
|
|
||
|
minetest.register_chatcommand("area_pos", {
|
||
|
params = "set/set1/set2/get",
|
||
|
description = "Set area protection region, position 1, or position 2 by punching nodes, or display the region",
|
||
|
privs = {},
|
||
|
func = function(name, param)
|
||
|
if param == "set" then -- Set both area positions
|
||
|
areas.set_pos[name] = "pos1"
|
||
|
minetest.chat_send_player(name, "Select positions by punching two nodes")
|
||
|
elseif param == "set1" then -- Set area position 1
|
||
|
areas.set_pos[name] = "pos1only"
|
||
|
minetest.chat_send_player(name, "Select position 1 by punching a node")
|
||
|
elseif param == "set2" then -- Set area position 2
|
||
|
areas.set_pos[name] = "pos2"
|
||
|
minetest.chat_send_player(name, "Select position 2 by punching a node")
|
||
|
elseif param == "get" then -- Display current area positions
|
||
|
if areas.pos1[name] ~= nil then
|
||
|
minetest.chat_send_player(name, "Position 1: " .. minetest.pos_to_string(areas.pos1[name]))
|
||
|
else
|
||
|
minetest.chat_send_player(name, "Position 1 not set")
|
||
|
end
|
||
|
if areas.pos2[name] ~= nil then
|
||
|
minetest.chat_send_player(name, "Position 2: " .. minetest.pos_to_string(areas.pos2[name]))
|
||
|
else
|
||
|
minetest.chat_send_player(name, "Position 2 not set")
|
||
|
end
|
||
|
else
|
||
|
minetest.chat_send_player(name, "Unknown subcommand: " .. param)
|
||
|
end
|
||
|
end,
|
||
|
})
|
||
|
|
||
|
function areas:getPos1(playerName)
|
||
|
return areas.pos1[playerName]
|
||
|
end
|
||
|
|
||
|
function areas:getPos2(playerName)
|
||
|
return areas.pos2[playerName]
|
||
|
end
|
||
|
|
||
|
function areas:setPos1(playerName, pos)
|
||
|
areas.pos1[playerName] = pos
|
||
|
areas.markPos1(playerName)
|
||
|
end
|
||
|
|
||
|
function areas:setPos2(playerName, pos)
|
||
|
areas.pos2[playerName] = pos
|
||
|
areas.markPos2(playerName)
|
||
|
end
|
||
|
|
||
|
|
||
|
minetest.register_on_punchnode(function(pos, node, puncher)
|
||
|
local name = puncher:get_player_name()
|
||
|
if name ~= "" and areas.set_pos[name] ~= nil then --currently setting position
|
||
|
if areas.set_pos[name] == "pos1" then --setting position 1
|
||
|
areas.pos1[name] = pos
|
||
|
areas.markPos1(name)
|
||
|
areas.set_pos[name] = "pos2" --set position 2 on the next invocation
|
||
|
minetest.chat_send_player(name, "Position 1 set to " .. minetest.pos_to_string(pos))
|
||
|
elseif areas.set_pos[name] == "pos1only" then --setting position 1 only
|
||
|
areas.pos1[name] = pos
|
||
|
areas.markPos1(name)
|
||
|
areas.set_pos[name] = nil --finished setting positions
|
||
|
minetest.chat_send_player(name, "Position 1 set to " .. minetest.pos_to_string(pos))
|
||
|
elseif areas.set_pos[name] == "pos2" then --setting position 2
|
||
|
areas.pos2[name] = pos
|
||
|
areas.markPos2(name)
|
||
|
areas.set_pos[name] = nil --finished setting positions
|
||
|
minetest.chat_send_player(name, "Position 2 set to " .. minetest.pos_to_string(pos))
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
-- Modifies positions `pos1` and `pos2` so that each component of `pos1`
|
||
|
-- is less than or equal to its corresponding component of `pos2`,
|
||
|
-- returning two new positions
|
||
|
function areas:sortPos(pos1, pos2)
|
||
|
if pos1.x > pos2.x then
|
||
|
pos2.x, pos1.x = pos1.x, pos2.x
|
||
|
end
|
||
|
if pos1.y > pos2.y then
|
||
|
pos2.y, pos1.y = pos1.y, pos2.y
|
||
|
end
|
||
|
if pos1.z > pos2.z then
|
||
|
pos2.z, pos1.z = pos1.z, pos2.z
|
||
|
end
|
||
|
return pos1, pos2
|
||
|
end
|
||
|
|
||
|
-- Rounds a position to the nearest integer
|
||
|
function areas:roundPos(pos)
|
||
|
pos.x = math.floor(pos.x+0.5)
|
||
|
pos.y = math.floor(pos.y+0.5)
|
||
|
pos.z = math.floor(pos.z+0.5)
|
||
|
return pos
|
||
|
end
|
||
|
|
||
|
-- Marks area position 1
|
||
|
areas.markPos1 = function(name)
|
||
|
local pos = areas.pos1[name]
|
||
|
if areas.marker1[name] ~= nil then -- Marker already exists
|
||
|
areas.marker1[name]:remove() -- Remove marker
|
||
|
areas.marker1[name] = nil
|
||
|
end
|
||
|
if pos ~= nil then -- Add marker
|
||
|
areas.marker1[name] = minetest.add_entity(pos, "areas:pos1")
|
||
|
areas.marker1[name]:get_luaentity().active = true
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Marks area position 2
|
||
|
areas.markPos2 = function(name)
|
||
|
local pos = areas.pos2[name]
|
||
|
if areas.marker2[name] ~= nil then -- Marker already exists
|
||
|
areas.marker2[name]:remove() -- Remove marker
|
||
|
areas.marker2[name] = nil
|
||
|
end
|
||
|
if pos ~= nil then -- Add marker
|
||
|
areas.marker2[name] = minetest.add_entity(pos, "areas:pos2")
|
||
|
areas.marker2[name]:get_luaentity().active = true
|
||
|
end
|
||
|
end
|
||
|
|
||
|
minetest.register_entity("areas:pos1", {
|
||
|
initial_properties = {
|
||
|
visual = "cube",
|
||
|
visual_size = {x=1.1, y=1.1},
|
||
|
textures = {"areas_pos1.png", "areas_pos1.png",
|
||
|
"areas_pos1.png", "areas_pos1.png",
|
||
|
"areas_pos1.png", "areas_pos1.png"},
|
||
|
collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55},
|
||
|
},
|
||
|
on_step = function(self, dtime)
|
||
|
if self.active == nil then
|
||
|
self.object:remove()
|
||
|
end
|
||
|
end,
|
||
|
on_punch = function(self, hitter)
|
||
|
self.object:remove()
|
||
|
local name = hitter:get_player_name()
|
||
|
areas.marker1[name] = nil
|
||
|
end,
|
||
|
})
|
||
|
|
||
|
minetest.register_entity("areas:pos2", {
|
||
|
initial_properties = {
|
||
|
visual = "cube",
|
||
|
visual_size = {x=1.1, y=1.1},
|
||
|
textures = {"areas_pos2.png", "areas_pos2.png",
|
||
|
"areas_pos2.png", "areas_pos2.png",
|
||
|
"areas_pos2.png", "areas_pos2.png"},
|
||
|
collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55},
|
||
|
},
|
||
|
on_step = function(self, dtime)
|
||
|
if self.active == nil then
|
||
|
self.object:remove()
|
||
|
end
|
||
|
end,
|
||
|
on_punch = function(self, hitter)
|
||
|
self.object:remove()
|
||
|
local name = hitter:get_player_name()
|
||
|
areas.marker2[name] = nil
|
||
|
end,
|
||
|
})
|
||
|
|