protector-configurator mod by nikaru

This commit is contained in:
Vitaliy Olkhin 2024-02-25 14:41:23 +05:00 committed by Koldun
commit 881bb329b3
Signed by: Koldun
GPG Key ID: 53DE683337F5D25F
15 changed files with 569 additions and 0 deletions

95
help.lua Normal file
View 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
View 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")

View 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 writers 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
View File

@ -0,0 +1,3 @@
name = protector_configurator
description = Add protector configurator for Protector Redo
depends = default

250
terminal.lua Normal file
View 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"}
}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 B

193
writer.lua Normal file
View 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 writers 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"}
}
})