areas/pos.lua

283 lines
7.8 KiB
Lua
Raw Normal View History

2013-09-03 01:16:14 +02:00
-- I could depend on WorldEdit for this, but you need to have the 'worldedit'
2013-09-03 07:33:08 +02:00
-- permission to use those commands and you don't have
2013-11-15 01:11:20 +01:00
-- /area_pos{1,2} [X Y Z|X,Y,Z].
-- Since this is mostly copied from WorldEdit it is mostly
-- licensed under the AGPL. (select_area is a exception)
2013-09-03 01:16:14 +02:00
areas.marker1 = {}
areas.marker2 = {}
areas.set_pos = {}
areas.pos1 = {}
areas.pos2 = {}
minetest.register_chatcommand("select_area", {
2014-05-29 17:04:37 +02:00
params = "<ID>",
2013-09-03 01:16:14 +02:00
description = "Select a area by id.",
func = function(name, param)
local id = tonumber(param)
if not id then
2014-05-29 17:04:37 +02:00
return false, "Invalid usage, see /help select_area."
2013-09-03 01:16:14 +02:00
end
if not areas.areas[id] then
2014-05-29 17:04:37 +02:00
return false, "The area "..id.." does not exist."
2013-09-03 01:16:14 +02:00
end
areas:setPos1(name, areas.areas[id].pos1)
areas:setPos2(name, areas.areas[id].pos2)
2014-05-29 17:04:37 +02:00
return true, "Area "..id.." selected."
end,
})
2013-09-03 01:16:14 +02:00
minetest.register_chatcommand("area_pos1", {
params = "[X Y Z|X,Y,Z]",
2013-09-03 07:33:08 +02:00
description = "Set area protection region position 1 to your"
.." location or the one specified",
2013-09-03 01:16:14 +02:00
privs = {},
func = function(name, param)
local pos = nil
2013-09-03 07:33:08 +02:00
local found, _, x, y, z = param:find(
2013-11-15 01:15:26 +01:00
"^(-?%d+)[, ](-?%d+)[, ](-?%d+)$")
2013-09-03 01:16:14 +02:00
if found then
pos = {x=tonumber(x), y=tonumber(y), z=tonumber(z)}
elseif param == "" then
2014-05-29 17:04:37 +02:00
local player = minetest.get_player_by_name(name)
2013-09-03 01:16:14 +02:00
if player then
pos = player:getpos()
else
2014-05-29 17:04:37 +02:00
return false, "Unable to get position."
2013-09-03 01:16:14 +02:00
end
else
2014-05-29 17:04:37 +02:00
return false, "Invalid usage, see /help area_pos1."
2013-09-03 01:16:14 +02:00
end
2013-09-03 07:33:08 +02:00
pos = vector.round(pos)
2013-09-03 01:16:14 +02:00
areas:setPos1(name, pos)
2014-05-29 17:04:37 +02:00
return true, "Area position 1 set to "
..minetest.pos_to_string(pos)
2013-09-03 01:16:14 +02:00
end,
})
minetest.register_chatcommand("area_pos2", {
params = "[X Y Z|X,Y,Z]",
2013-09-03 07:33:08 +02:00
description = "Set area protection region position 2 to your"
.." location or the one specified",
2013-09-03 01:16:14 +02:00
func = function(name, param)
local pos = nil
2013-09-03 07:33:08 +02:00
local found, _, x, y, z = param:find(
2013-11-15 01:15:26 +01:00
"^(-?%d+)[, ](-?%d+)[, ](-?%d+)$")
2013-09-03 01:16:14 +02:00
if found then
pos = {x=tonumber(x), y=tonumber(y), z=tonumber(z)}
elseif param == "" then
2014-05-29 17:04:37 +02:00
local player = minetest.get_player_by_name(name)
2013-09-03 01:16:14 +02:00
if player then
pos = player:getpos()
else
2014-05-29 17:04:37 +02:00
return false, "Unable to get position."
2013-09-03 01:16:14 +02:00
end
else
2014-05-29 17:04:37 +02:00
return false, "Invalid usage, see /help area_pos2."
2013-09-03 01:16:14 +02:00
end
2013-09-03 07:33:08 +02:00
pos = vector.round(pos)
2013-09-03 01:16:14 +02:00
areas:setPos2(name, pos)
2014-05-29 17:04:37 +02:00
return true, "Area position 2 set to "
..minetest.pos_to_string(pos)
2013-09-03 01:16:14 +02:00
end,
})
minetest.register_chatcommand("area_pos", {
params = "set/set1/set2/get",
2013-09-03 07:33:08 +02:00
description = "Set area protection region, position 1, or position 2"
.." by punching nodes, or display the region",
2013-09-03 01:16:14 +02:00
func = function(name, param)
if param == "set" then -- Set both area positions
areas.set_pos[name] = "pos1"
2014-05-29 17:04:37 +02:00
return true, "Select positions by punching two nodes."
2013-09-03 01:16:14 +02:00
elseif param == "set1" then -- Set area position 1
areas.set_pos[name] = "pos1only"
2014-05-29 17:04:37 +02:00
return true, "Select position 1 by punching a node."
2013-09-03 01:16:14 +02:00
elseif param == "set2" then -- Set area position 2
areas.set_pos[name] = "pos2"
2014-05-29 17:04:37 +02:00
return true, "Select position 2 by punching a node."
2013-09-03 01:16:14 +02:00
elseif param == "get" then -- Display current area positions
2014-05-29 17:04:37 +02:00
local pos1str, pos2str = "Position 1: ", "Position 2: "
if areas.pos1[name] then
pos1str = pos1str..minetest.pos_to_string(areas.pos1[name])
2013-09-03 01:16:14 +02:00
else
2014-05-29 17:04:37 +02:00
pos1str = pos1str.."<not set>"
2013-09-03 01:16:14 +02:00
end
2014-05-29 17:04:37 +02:00
if areas.pos2[name] then
pos2str = pos2str..minetest.pos_to_string(areas.pos2[name])
2013-09-03 01:16:14 +02:00
else
2014-05-29 17:04:37 +02:00
pos2str = pos2str.."<not set>"
2013-09-03 01:16:14 +02:00
end
2014-05-29 17:04:37 +02:00
return true, pos1str.."\n"..pos2str
2013-09-03 01:16:14 +02:00
else
2014-05-29 17:04:37 +02:00
return false, "Unknown subcommand: "..param
2013-09-03 01:16:14 +02:00
end
end,
})
function areas.useWorldedit(playerName)
2016-01-10 21:51:15 +01:00
if worldedit then
2016-01-10 19:56:11 +01:00
if nil == playerName then
return true;
elseif minetest.check_player_privs(playerName, {worldedit = true}) then
return true;
end
end
2016-01-10 21:51:15 +01:00
return false;
end
function areas:getPos(playerName)
2016-01-10 21:51:15 +01:00
local pos1, pos2 = nil, nil;
if areas.useWorldedit(playerName) then
2016-01-10 21:51:15 +01:00
pos1, pos2 = worldedit.pos1[playerName], worldedit.pos2[playerName];
else
2016-01-10 21:51:15 +01:00
pos1, pos2 = areas.pos1[playerName], areas.pos2[playerName];
end
if not (pos1 and pos2) then
return nil
end
-- Copy positions so that the area table doesn't contain multiple
-- references to the same position.
pos1, pos2 = vector.new(pos1), vector.new(pos2)
return areas:sortPos(pos1, pos2)
2013-09-03 01:16:14 +02:00
end
function areas:setPos1(playerName, pos)
if areas.useWorldedit(playerName) then
worldedit.pos1[playerName] = pos;
worldedit.mark_pos1(name);
else
areas.pos1[playerName] = pos
areas.markPos1(playerName)
end
2013-09-03 01:16:14 +02:00
end
function areas:setPos2(playerName, pos)
if areas.useWorldedit(playerName) then
worldedit.pos2[playerName] = pos;
worldedit.mark_pos2(name);
else
areas.pos2[playerName] = pos
areas.markPos2(playerName)
end
2013-09-03 01:16:14 +02:00
end
minetest.register_on_punchnode(function(pos, node, puncher)
local name = puncher:get_player_name()
2013-09-03 07:33:08 +02:00
-- Currently setting position
if name ~= "" and areas.set_pos[name] then
if areas.set_pos[name] == "pos1" then
2013-09-03 01:16:14 +02:00
areas.pos1[name] = pos
areas.markPos1(name)
2013-09-03 07:33:08 +02:00
areas.set_pos[name] = "pos2"
minetest.chat_send_player(name,
"Position 1 set to "
..minetest.pos_to_string(pos))
elseif areas.set_pos[name] == "pos1only" then
2013-09-03 01:16:14 +02:00
areas.pos1[name] = pos
areas.markPos1(name)
2013-09-03 07:33:08 +02:00
areas.set_pos[name] = nil
minetest.chat_send_player(name,
"Position 1 set to "
..minetest.pos_to_string(pos))
elseif areas.set_pos[name] == "pos2" then
2013-09-03 01:16:14 +02:00
areas.pos2[name] = pos
areas.markPos2(name)
2013-09-03 07:33:08 +02:00
areas.set_pos[name] = nil
minetest.chat_send_player(name,
"Position 2 set to "
..minetest.pos_to_string(pos))
2013-09-03 01:16:14 +02:00
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`,
2014-07-12 22:37:54 +02:00
-- returning the two positions.
2013-09-03 01:16:14 +02:00
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
-- 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,
})