realdoors/electronic.lua

258 lines
7.3 KiB
Lua

realdoors.electronic_defs = {}
realdoors.electronic_formspec = "size[16,4]" ..
"list[context;cardslot;1,1;1,1]" ..
"button[3,1;3,1;cardcheck;Use keycard]" ..
"list[context;cardslot;7,1;1,1;1]" ..
"button[9,1;3,1;carddup;Copy card]" ..
"button[13,1;3,1;cardadd;Add card]" ..
"button[13,2;3,1;cardrm;Remove card]" ..
"button[13,3;3,1;cardrst;Remove all cards]" ..
"button[1,3;3,1;close;Close door]" ..
"list[current_player;main;1,2;9,1]"
function table_contains(t, e)
for _, v in ipairs(t) do
if v == e then
return true
end
end
return false
end
function table_remove(t, e)
for k, v in ipairs(t) do
if v == e then
t[k] = nil
end
end
return t
end
realdoors.electronic_formspec_handler = function(pos, fields, sender)
local meta = minetest.get_meta(pos)
if fields.close then
if meta:get_string("state") == "open" then
realdoors.toggle(pos)
end
end
local inv = minetest.get_inventory({type = "node", pos = pos})
local cardstack = inv:get_stack("cardslot", 1)
if cardstack:get_name() ~= "realdoors:card" then return end
local key = cardstack:get_meta():get_string("id")
local reqkeys = minetest.deserialize(meta:get_string("keys")) or {}
if fields.carddup then
local dupstack = inv:get_stack("cardslot", 2)
if dupstack:get_name() ~= "realdoors:card_blank" then return end
dupstack:set_name("realdoors:card")
dupstack:get_meta():set_string("id", key)
inv:set_stack("cardslot", 2, dupstack)
return
end
if fields.cardadd then
local newstack = inv:get_stack("cardslot", 2)
if newstack:get_name() ~= "realdoors:card" then return end
if key == meta:get_string("key") then
table.insert(reqkeys, newstack:get_meta():get_string("id"))
meta:set_string("keys", minetest.serialize(reqkeys))
minetest.chat_send_player(sender:get_player_name(), "The following card has been added: " .. newstack:get_meta():get_string("id"))
minetest.sound_play("lockbeep_ok", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
else
minetest.chat_send_player(sender:get_player_name(), "Your keycard is not the correct master card")
minetest.sound_play("lockbeep_error", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
end
return
end
if fields.cardrm then
local newstack = inv:get_stack("cardslot", 2)
if newstack:get_name() ~= "realdoors:card" then return end
if key == meta:get_string("key") then
reqkeys = table_remove(reqkeys, newstack:get_meta():get_string("id"))
meta:set_string("keys", minetest.serialize(reqkeys))
minetest.chat_send_player(sender:get_player_name(), "The following card has been removed: " .. newstack:get_meta():get_string("id"))
minetest.sound_play("lockbeep_ok", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
else
minetest.chat_send_player(sender:get_player_name(), "Your keycard is not the correct master card")
minetest.sound_play("lockbeep_error", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
end
return
end
if fields.cardrst then
if key == meta:get_string("key") then
reqkeys = {}
meta:set_string("keys", minetest.serialize(reqkeys))
minetest.chat_send_player(sender:get_player_name(), "All cards except for the master card have been removed")
minetest.sound_play("lockbeep_ok", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
else
minetest.chat_send_player(sender:get_player_name(), "Your keycard is not the correct master card")
minetest.sound_play("lockbeep_error", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
end
return
end
if not fields.cardcheck then return end
if meta:get_string("key") == "" then
meta:set_string("key", key)
minetest.chat_send_player(sender:get_player_name(), "The following card is now the master card: " .. key)
minetest.sound_play("lockbeep_ok", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
return
end
if table_contains(reqkeys, key) then
realdoors.toggle(pos)
minetest.sound_play("lockbeep_ok", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
else
minetest.chat_send_player(sender:get_player_name(), "Your keycard is not valid")
minetest.sound_play("lockbeep_error", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
end
end
realdoors.register_electronic = function(def)
minetest.register_node("realdoors:edoor_" .. def.name .. "_a", {
description = def.desc .. " (left)",
drawtype = "mesh",
tiles = {def.tex},
inventory_image = def.tex_inv,
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = false,
selection_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 1.5, -0.375},
},
},
collision_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 1.5, -0.375},
},
},
mesh = "realdoor_a.obj",
sounds = default.node_sound_wood_defaults(),
groups = {snappy = 3},
on_construct = function(pos)
minetest.get_meta(pos):set_string("state", "closed")
local inv = minetest.get_inventory({type = "node", pos = pos})
inv:set_size("cardslot", 2)
minetest.get_meta(pos):set_string("formspec", realdoors.electronic_formspec)
end,
on_receive_fields = function(pos, formname, fields, sender)
realdoors.electronic_formspec_handler(pos, fields, sender)
end,
})
minetest.register_node("realdoors:edoor_" .. def.name .. "_b", {
description = def.desc .. " (right)",
drawtype = "mesh",
tiles = {def.tex},
inventory_image = def.tex_inv,
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = false,
selection_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 1.5, -0.375},
},
},
collision_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 1.5, -0.375},
},
},
mesh = "realdoor_b.obj",
sounds = default.node_sound_wood_defaults(),
groups = {snappy = 3},
on_construct = function(pos)
minetest.get_meta(pos):set_string("state", "closed")
local inv = minetest.get_inventory({type = "node", pos = pos})
inv:set_size("cardslot", 2)
minetest.get_meta(pos):set_string("formspec", realdoors.electronic_formspec)
end,
on_receive_fields = function(pos, formname, fields, sender)
realdoors.electronic_formspec_handler(pos, fields, sender)
end,
})
realdoors.electronic_defs[def.name] = def
end
realdoors.init_card = function(itemstack, id)
if not id then
math.randomseed(os.clock())
id = math.random(111111111, 999999999)
end
local meta = itemstack:get_meta()
meta:set_string("id", tostring(id))
return itemstack
end
minetest.register_craftitem("realdoors:card_blank", {
description = "Blank keycard",
inventory_image = "card_blank.png",
})
minetest.register_craftitem("realdoors:card", {
description = "Keycard",
inventory_image = "realdoors_card.png",
})
minetest.register_craft({
type = "shaped",
output = "realdoors:card_blank",
recipe = {
{"default:paper"},
{"default:mese_crystal"},
{"default:paper"},
},
})
minetest.register_craft({
type = "shapeless",
output = "realdoors:card",
recipe = {"realdoors:card_blank", "default:mese_crystal"},
})
minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
if itemstack:get_name() ~= "realdoors:card" then return end
return realdoors.init_card(itemstack)
end)
minetest.log("verbose", "[realdoors] Loaded electronic.lua v" .. realdoors.v)