251 lines
7.0 KiB
Lua
251 lines
7.0 KiB
Lua
modname = "protector_configurator"
|
|
local S = minetest.get_translator(modname)
|
|
|
|
local context_cords = {}
|
|
local context_players = {}
|
|
|
|
|
|
function protector_configurator:terminal_formspec(meta)
|
|
|
|
local cords = protector_configurator:get_cords(meta)
|
|
if cords then
|
|
cords = protector_configurator:cords2strings(cords)
|
|
else
|
|
cords = {S("no coordinates have been set")}
|
|
end
|
|
|
|
local players = meta:get_string("players")
|
|
if players ~= "" then
|
|
players = players:split(" ")
|
|
else
|
|
players = {S("no players have been set")}
|
|
end
|
|
|
|
local cordslist = protector_configurator:list2textlist(cords, 11, 0, 5, 7, "cords")
|
|
|
|
local playerslist = protector_configurator:list2textlist(players, 0, 0, 5, 7, "players")
|
|
|
|
local formspec = "size[16,8]"
|
|
.. cordslist
|
|
.. "button[11,7;2,1;delete_cord;" .. S("delete") .. "]"
|
|
.. "button[13,7;3,1;clear_cords;" .. S("clear all") .. "]"
|
|
.. playerslist
|
|
.. "button[0,7;2,1;delete_player;" .. S("delete") .. "]"
|
|
.. "button[2,7;3,1;clear_players;" .. S("clear all") .. "]"
|
|
.. "field[5.5,0.5;3,1;input_name;add player(s):;]"
|
|
.. "field_close_on_enter[input_name;false]"
|
|
.. "button[8.5,0.2;2,1;add;" .. S("add") .. "]"
|
|
.. "button[6,3;4.5,1;set_members;" .. S("set members") .."(=)]"
|
|
.. "button[6,4;4.5,1;add_members;" .. S("add members") .."(+)]"
|
|
.. "field_enter_after_edit[input_name;true]"
|
|
|
|
return formspec
|
|
end
|
|
|
|
|
|
local function check_can_configure(pos, owner)
|
|
local nodename = minetest.get_node(pos).name
|
|
if nodename == "ignore" then return "ignore" end
|
|
if nodename ~= "protector:protect" and nodename ~= "protector:protect2" then return "cant" end
|
|
|
|
local protect_owner = minetest.get_meta(pos):get_string("owner")
|
|
|
|
if protect_owner ~= owner then return "cant" end
|
|
return "can"
|
|
end
|
|
|
|
|
|
local function update_cords(meta, cords, to_del)
|
|
for i, del_cord in pairs(to_del) do
|
|
for j, cord in pairs(cords) do
|
|
if cord == del_cord then table.remove(cords, j) break end
|
|
end
|
|
end
|
|
meta:set_string("cords", table.concat(protector_configurator:cords2strings(cords), " "))
|
|
end
|
|
|
|
|
|
local function xor_add(list1, list2)
|
|
for i, elem2 in pairs(list2) do
|
|
local f = false
|
|
for j, elem1 in pairs(list1) do
|
|
if elem1 == elem2 then f = true break end
|
|
end
|
|
if not f then table.insert(list1, elem2) end
|
|
end
|
|
return list1
|
|
end
|
|
|
|
|
|
local function set_members(meta, mode)
|
|
local mode = mode or "set"
|
|
local players = meta:get_string("players")
|
|
local cords = protector_configurator:get_cords(meta)
|
|
if not cords then return end
|
|
|
|
local owner = meta:get_string("owner")
|
|
local to_del = {}
|
|
|
|
for i, cord in pairs(cords) do
|
|
local result = check_can_configure(cord, owner)
|
|
|
|
if result == "cant" then -- remove coordinates from the list if the block is not available to this player or is deleted
|
|
table.insert(to_del, cord)
|
|
elseif result == "can" then
|
|
|
|
local protector_meta = minetest.get_meta(cord)
|
|
|
|
if mode == "set" then -- if set members
|
|
protector_meta:set_string("members", players)
|
|
elseif mode == "add" then -- if you add members to those already added earlier
|
|
local members = protector_meta:get_string("members")
|
|
if members == "" then members = players
|
|
else members = table.concat(xor_add(members:split(" "), players:split(" ")), " ") end
|
|
protector_meta:set_string("members", members)
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
update_cords(meta, cords, to_del)
|
|
end
|
|
|
|
|
|
local function add_player(meta, name)
|
|
local players = meta:get_string("players")
|
|
|
|
if players == "" then
|
|
players = {}
|
|
else
|
|
players = players:split(" ")
|
|
end
|
|
|
|
for i, name in pairs(name:split(" ")) do
|
|
local f = false
|
|
for i, player in pairs(players) do
|
|
if player == name then f = true break end
|
|
end
|
|
if not f then table.insert(players, minetest.formspec_escape(name)) end
|
|
end
|
|
meta:set_string("players", table.concat(players, " "))
|
|
end
|
|
|
|
----for formspec----
|
|
local function context_work(name, field, context)
|
|
local t = field:split(":")
|
|
if t[1] ~= "CHG" then return end
|
|
context[name] = tonumber(t[2])
|
|
end
|
|
|
|
|
|
local function delete_cord(name, meta)
|
|
local idx = context_cords[name]
|
|
if not idx then idx = 1 end
|
|
|
|
protector_configurator:del_cord_by_index(meta, idx)
|
|
|
|
context_cords[name] = nil
|
|
end
|
|
|
|
local function delete_player(name, meta)
|
|
local idx = context_players[name]
|
|
if not idx then idx = 1 end
|
|
|
|
local players = meta:get_string("players")
|
|
if players == "" then
|
|
return
|
|
else
|
|
players = players:split(" ")
|
|
end
|
|
if idx > #players then return end
|
|
|
|
table.remove(players, idx)
|
|
|
|
meta:set_string("players", table.concat(players, " "))
|
|
context_players[name] = nil
|
|
end
|
|
|
|
|
|
local function on_receive_fields(pos, formname, fields, player)
|
|
if not player then return end
|
|
if not protector_configurator:check_owner(player:get_player_name(), pos) then return end
|
|
|
|
local name = player:get_player_name()
|
|
local meta = minetest.get_meta(pos)
|
|
|
|
--input_name should be processed later by set_members and add_members
|
|
if fields.cords then context_work(name, fields.cords, context_cords)
|
|
elseif fields.players then context_work(name, fields.players, context_players)
|
|
elseif fields.delete_cord then delete_cord(name, meta)
|
|
elseif fields.delete_player then delete_player(name, meta)
|
|
elseif fields.clear_cords then meta:set_string("cords", "")
|
|
elseif fields.clear_players then meta:set_string("players", "")
|
|
elseif fields.set_members then set_members(meta)
|
|
elseif fields.add_members then set_members(meta, "add")
|
|
elseif fields.input_name then add_player(meta, fields.input_name) end
|
|
|
|
meta:set_string("formspec", protector_configurator:terminal_formspec(meta))
|
|
end
|
|
|
|
|
|
minetest.register_node(modname .. ":terminal", {
|
|
description = S("protector terminal"),
|
|
|
|
stack_max = 1,
|
|
|
|
drawtype = "nodebox",
|
|
|
|
groups = {cracky=3, stone=1},
|
|
|
|
paramtype2 = "facedir",
|
|
|
|
tiles = {
|
|
"protector_configurator_terminal_top.png",
|
|
"protector_configurator_terminal_down.png",
|
|
"protector_configurator_terminal_right.png",
|
|
"protector_configurator_terminal_left.png",
|
|
"protector_configurator_terminal_back.png",
|
|
"protector_configurator_terminal_front.png"
|
|
},
|
|
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {-0.375, -0.5, 0.5, 0.375, 0.375, 0.25}
|
|
--12 / 14 / 2 = 0.375,
|
|
--4 / 16 = 0.25,
|
|
},
|
|
|
|
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
|
local meta = minetest.get_meta(pos)
|
|
local item_meta = itemstack:get_meta()
|
|
meta:set_string("owner", placer:get_player_name())
|
|
|
|
meta:set_string("cords", item_meta:get_string("cords"))
|
|
meta:set_string("players", item_meta:get_string("players"))
|
|
|
|
meta:set_string("formspec", protector_configurator:terminal_formspec(meta))
|
|
end,
|
|
|
|
preserve_metadata = function(pos, oldnode, oldmeta, drops)
|
|
if #drops < 1 then return end
|
|
|
|
local item_meta = drops[1]:get_meta()
|
|
|
|
if oldmeta.cords then item_meta:set_string("cords", oldmeta.cords) end
|
|
if oldmeta.players then item_meta:set_string("players", oldmeta.players) end
|
|
end,
|
|
|
|
on_receive_fields = on_receive_fields
|
|
})
|
|
|
|
minetest.register_craft({
|
|
output = modname .. ":terminal",
|
|
|
|
recipe = {
|
|
{"default:steelblock", "", "default:steelblock"},
|
|
{"default:mese_crystal", "default:steel_ingot", "default:mese_crystal"},
|
|
{"default:steelblock", "default:gold_ingot", "default:steelblock"}
|
|
}
|
|
})
|
|
|