protector-configurator mod by nikaru
95
help.lua
Normal file
@ -0,0 +1,95 @@
|
||||
local modname = "protector_configurator"
|
||||
local S = minetest.get_translator(modname)
|
||||
|
||||
|
||||
protector_configurator = {}
|
||||
|
||||
|
||||
function protector_configurator:get_cords(meta)
|
||||
local cords = meta:get_string("cords")
|
||||
if cords == "" then
|
||||
return nil
|
||||
end
|
||||
local cords_t = {}
|
||||
for i, cord in pairs(cords:split(" ")) do
|
||||
local pos = minetest.string_to_pos(cord)
|
||||
if pos then table.insert(cords_t, pos) end
|
||||
end
|
||||
return cords_t
|
||||
end
|
||||
|
||||
|
||||
function protector_configurator:check_owner(username, pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta:get_string("owner") ~= username then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function protector_configurator:cords2strings(cords)
|
||||
local cords_t = {}
|
||||
for i, cord in pairs(cords) do
|
||||
local cord = minetest.pos_to_string(cord)
|
||||
if cord then table.insert(cords_t, cord) end
|
||||
end
|
||||
return cords_t
|
||||
end
|
||||
|
||||
|
||||
function protector_configurator:add_cord(meta, cord)
|
||||
local cords = self:get_cords(meta)
|
||||
if not cords then
|
||||
cords = {}
|
||||
end
|
||||
for i, cord_ in pairs(cords) do
|
||||
if cord_ == cord then return end
|
||||
end
|
||||
table.insert(cords, cord)
|
||||
meta:set_string("cords", table.concat(self:cords2strings(cords), " "))
|
||||
end
|
||||
|
||||
|
||||
function protector_configurator:add_cords(meta, new_cords)
|
||||
local cords = self:get_cords(meta)
|
||||
if not cords or #cords == 0 then
|
||||
meta:set_string("cords", table.concat(self:cords2strings(new_cords), " "))
|
||||
return
|
||||
end
|
||||
local max_idx = #cords
|
||||
|
||||
for i, new_cord in pairs(new_cords) do
|
||||
local f = false
|
||||
for i, cord in pairs(cords) do
|
||||
if new_cord == cord then f = true break end
|
||||
end
|
||||
if not f then table.insert(cords, new_cord) end
|
||||
end
|
||||
meta:set_string("cords", table.concat(self:cords2strings(cords), " "))
|
||||
end
|
||||
|
||||
|
||||
function protector_configurator:del_cord_by_index(meta, index)
|
||||
local cords = self:get_cords(meta)
|
||||
if not cords then return end
|
||||
if index > #cords then return end
|
||||
table.remove(cords, index)
|
||||
meta:set_string("cords", table.concat(self:cords2strings(cords), " "))
|
||||
end
|
||||
|
||||
|
||||
function protector_configurator:list2textlist(list, x, y, w, h, name)
|
||||
if x then x = tostring(x) else x = 1 end
|
||||
if y then y = tostring(y) else y = 0 end
|
||||
if w then w = tostring(w) else w = 5 end
|
||||
if h then h = tostring(h) else h = 7 end
|
||||
if name then name = tostring(name) else name = "text_list" end
|
||||
|
||||
local str = string.format('textlist[%s,%s;%s,%s;%s;', x, y, w, h, name)
|
||||
for i, elem in pairs(list) do
|
||||
str = str .. minetest.formspec_escape(tostring(elem)) .. ','
|
||||
end
|
||||
local str = str:sub(1, #str - 1) .. ";1]"
|
||||
return str
|
||||
end
|
6
init.lua
Normal file
@ -0,0 +1,6 @@
|
||||
local modname = "protector_configurator"
|
||||
local modpath = minetest.get_modpath(modname)
|
||||
|
||||
dofile(modpath .. "/help.lua")
|
||||
dofile(modpath .. "/terminal.lua")
|
||||
dofile(modpath .. "/writer.lua")
|
22
locale/protector_configurator.ru.tr
Normal file
@ -0,0 +1,22 @@
|
||||
# textdomain: protector_configurator
|
||||
|
||||
protect writer=записыватель защиты
|
||||
LMB on the terminal to insert coordinates from the protect writer into the terminal=ЛКМ по терминалу для вставки коородинат из записывателя защиты в терминал
|
||||
or=или
|
||||
LMB on the protector block to add coordinates to the protect writer’s list=ЛКМ по блоку защиты для добавления координат в список записывателя защиты
|
||||
and=и
|
||||
shift + RMB to copy coordinates from the terminal to protect writer=shift + ПКМ для копирования координат из терминала в записыватель защиты
|
||||
no coordinates have been set=не установлено ни одной координаты
|
||||
clear all=очистить все
|
||||
delete=удалить
|
||||
add=добавить
|
||||
you can't add this protector!=вы не можете добавить этот блок защиты!
|
||||
you do not own this terminal!=вы не являетесь владельцем этого терминала!
|
||||
added coordinates:=добавлены координаты:
|
||||
coordinates added to terminal=координаты добавлены в терминал
|
||||
no players have been set=не установлен ни один игрок
|
||||
set members=установить участников
|
||||
add members=добавить участников
|
||||
protector terminal=терминал защиты
|
||||
coordinates copied to writer=координаты скопированы в записыватель защиты
|
||||
exit=выход
|
3
mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = protector_configurator
|
||||
description = Add protector configurator for Protector Redo
|
||||
depends = default
|
250
terminal.lua
Normal file
@ -0,0 +1,250 @@
|
||||
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"}
|
||||
}
|
||||
})
|
||||
|
BIN
textures/minetest_ptotector_controller_left_clear.png
Normal file
After Width: | Height: | Size: 250 B |
BIN
textures/minetest_ptotector_controller_top_clear.png
Normal file
After Width: | Height: | Size: 218 B |
BIN
textures/protector_configurator_terminal_back.png
Normal file
After Width: | Height: | Size: 475 B |
BIN
textures/protector_configurator_terminal_down.png
Normal file
After Width: | Height: | Size: 236 B |
BIN
textures/protector_configurator_terminal_front.png
Normal file
After Width: | Height: | Size: 580 B |
BIN
textures/protector_configurator_terminal_left.png
Normal file
After Width: | Height: | Size: 288 B |
BIN
textures/protector_configurator_terminal_right.png
Normal file
After Width: | Height: | Size: 276 B |
BIN
textures/protector_configurator_terminal_top.png
Normal file
After Width: | Height: | Size: 249 B |
BIN
textures/protector_configurator_writer.png
Normal file
After Width: | Height: | Size: 311 B |
193
writer.lua
Normal file
@ -0,0 +1,193 @@
|
||||
local modname = "protector_configurator"
|
||||
local S = minetest.get_translator(modname)
|
||||
|
||||
local context = {}
|
||||
|
||||
|
||||
local writer_formspec = function(itemstack, player)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
local player = player:get_player_name()
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
|
||||
local meta = itemstack:get_meta()
|
||||
|
||||
local cords = protector_configurator:get_cords(meta)
|
||||
|
||||
-- if coordinates are not set, we will display information about this instead of coordinates
|
||||
local textlist = ""
|
||||
if not cords then
|
||||
textlist = protector_configurator:list2textlist({S("no coordinates have been set")})
|
||||
else
|
||||
textlist = protector_configurator:list2textlist(protector_configurator:cords2strings(cords))
|
||||
end
|
||||
|
||||
local formspec = 'size[8,8]'
|
||||
.. textlist
|
||||
.. "button[1,7;2,1;delete;" .. S("delete") .. "]"
|
||||
.. "button[3,7;3,1;clear;" .. S("clear all") .. "]"
|
||||
.. "button_exit[6,7;2,1;exit;" .. S("exit") .. "]"
|
||||
|
||||
minetest.show_formspec(player, modname .. ":writer_formspec", formspec)
|
||||
end
|
||||
|
||||
|
||||
local function use_with_protecotr(itemstack, username, pos)
|
||||
local meta = itemstack:get_meta()
|
||||
protector_configurator:add_cord(meta, pos)
|
||||
|
||||
minetest.chat_send_player(username, S("added coordinates:") .. " "
|
||||
.. minetest.pos_to_string(pos))
|
||||
|
||||
return itemstack
|
||||
end
|
||||
|
||||
|
||||
local function use_with_terminal(itemstack, username, pos)
|
||||
local terminal_meta = minetest.get_meta(pos)
|
||||
local writer_meta = itemstack:get_meta()
|
||||
|
||||
local writer_cords = protector_configurator:get_cords(writer_meta)
|
||||
if not writer_cords then return end
|
||||
|
||||
protector_configurator:add_cords(terminal_meta, writer_cords)
|
||||
|
||||
minetest.chat_send_player(username, S("coordinates added to terminal") )
|
||||
|
||||
terminal_meta:set_string("formspec", protector_configurator:terminal_formspec(terminal_meta))
|
||||
return itemstack
|
||||
end
|
||||
|
||||
|
||||
local function on_use_writer(itemstack, user, pointed_thing)
|
||||
if not user or pointed_thing.type ~= "node" then
|
||||
return
|
||||
end
|
||||
local username = user:get_player_name()
|
||||
if not username then
|
||||
return
|
||||
end
|
||||
|
||||
local pos = pointed_thing.under
|
||||
local nodename = minetest.get_node(pos).name
|
||||
|
||||
if nodename == "protector:protect" or nodename == "protector:protect2" then
|
||||
if protector_configurator:check_owner(username, pos) then -- add protector cords
|
||||
return use_with_protecotr(itemstack, username, pos)
|
||||
else -- cant add protector
|
||||
minetest.chat_send_player(username, S("you can't add this protector!"))
|
||||
end
|
||||
elseif nodename == modname .. ":terminal" then
|
||||
if protector_configurator:check_owner(username, pos) then -- add cords to terminal
|
||||
return use_with_terminal(itemstack, username, pos)
|
||||
else -- cant add cords to terminal
|
||||
minetest.chat_send_player(username, S("you do not own this terminal!"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function copy_to_writer(pos, itemstack)
|
||||
local terminal_meta = minetest.get_meta(pos)
|
||||
local writer_meta = itemstack:get_meta()
|
||||
|
||||
writer_meta:set_string("cords", terminal_meta:get_string("cords"))
|
||||
return itemstack
|
||||
end
|
||||
|
||||
|
||||
local function on_place(itemstack, placer, pointed_thing)
|
||||
if not placer then return end
|
||||
local name = placer:get_player_name()
|
||||
|
||||
if pointed_thing.type == "node" then
|
||||
local node = minetest.get_node(pointed_thing.under).name
|
||||
print("node")
|
||||
print(node)
|
||||
if node ~= modname .. ":terminal" then
|
||||
writer_formspec(itemstack, placer)
|
||||
return
|
||||
end
|
||||
if protector_configurator:check_owner(name, pointed_thing.under) then
|
||||
minetest.chat_send_player(name, S("coordinates copied to writer"))
|
||||
return copy_to_writer(pointed_thing.under, itemstack)
|
||||
else
|
||||
minetest.chat_send_player(name, S("you do not own this terminal!"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
minetest.register_craftitem(modname .. ":writer", {
|
||||
|
||||
description = S("protect writer") .. "\n"
|
||||
.. S("LMB on the protector block to add coordinates to the protect writer’s list") .. "\n"
|
||||
.. S("or") .. " " .. S("LMB on the terminal to insert coordinates from the protect writer into the terminal") .. "\n"
|
||||
.. S("and") .. " " .. S("shift + RMB to copy coordinates from the terminal to protect writer"),
|
||||
|
||||
stack_max = 1,
|
||||
|
||||
inventory_image = modname .. "_writer.png",
|
||||
|
||||
on_place = on_place,
|
||||
|
||||
on_secondary_use = writer_formspec,
|
||||
|
||||
on_use = on_use_writer
|
||||
})
|
||||
|
||||
-----for formspec-----
|
||||
|
||||
local function clear_writer(player, item)
|
||||
if not player then return end
|
||||
local meta = item:get_meta()
|
||||
meta:set_string("cords", "")
|
||||
player:set_wielded_item(item)
|
||||
end
|
||||
|
||||
local function textlist_work(player, field)
|
||||
if not player then return end
|
||||
local t = field:split(":")
|
||||
if t[1] ~= "CHG" then return end
|
||||
context[player:get_player_name()] = tonumber(t[2])
|
||||
end
|
||||
|
||||
local function delete(player, item)
|
||||
if not player or not item then return end
|
||||
local name = player:get_player_name()
|
||||
|
||||
local idx = context[name]
|
||||
if not idx then idx = 1 end
|
||||
|
||||
local meta = item:get_meta()
|
||||
protector_configurator:del_cord_by_index(meta, idx)
|
||||
|
||||
player:set_wielded_item(item)
|
||||
context[name] = nil
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname ~= "protector_configurator:writer_formspec" then return end
|
||||
local item = player:get_wielded_item()
|
||||
if not item then return end
|
||||
if item:get_name() ~= modname .. ":writer" then return end
|
||||
|
||||
if fields.clear then clear_writer(player, item)
|
||||
elseif fields.text_list then textlist_work(player, fields.text_list)
|
||||
elseif fields.delete then delete(player, item) end
|
||||
|
||||
if not fields.exit then writer_formspec(item, player) end
|
||||
end)
|
||||
|
||||
minetest.register_craft({
|
||||
output = modname .. ":writer",
|
||||
|
||||
recipe = {
|
||||
{"default:mese_crystal"},
|
||||
{"default:steel_ingot"},
|
||||
{"default:stick"}
|
||||
}
|
||||
})
|