Add electronic locks

master
HimbeerserverDE 2020-10-01 16:31:02 +02:00
parent f3af2a7bf7
commit 306eee992b
15 changed files with 552 additions and 8 deletions

346
controllers.lua Normal file
View File

@ -0,0 +1,346 @@
realdoors.connection_rules = {
{x = 0, y = 0, z = -1},
{x = 1, y = 0, z = 0},
{x = -1, y = 0, z = 0},
{x = 0, y = 0, z = 1},
{x = 1, y = 1, z = 0},
{x = 1, y = -1, z = 0},
{x = -1, y = 1, z = 0},
{x = -1, y = -1, z = 0},
{x = 0, y = 1, z = 1},
{x = 0, y = -1, z = 1},
{x = 0, y = 1, z = -1},
{x = 0, y = -1, z = -1},
{x = 0, y = -1, z = 0},
{x = 0, y = 0, z = -2},
{x = 2, y = 0, z = 0},
{x = -2, y = 0, z = 0},
{x = 0, y = 0, z = 2},
{x = 2, y = 2, z = 0},
{x = 2, y = -2, z = 0},
{x = -2, y = 2, z = 0},
{x = -2, y = -2, z = 0},
{x = 0, y = 2, z = 2},
{x = 0, y = -2, z = 2},
{x = 0, y = 2, z = -2},
{x = 0, y = -2, z = -2},
{x = 0, y = -2, z = 0},
}
realdoors.keyswitch_formspec = "size[10,3]" ..
"list[context;keyslot;1,1;1,1]" ..
"button[3,1;3,1;trigger;Use key]" ..
"list[current_player;main;1,2;9,1]"
realdoors.cardreader_formspec = "size[13,3]" ..
"list[context;cardslot;1,1;1,1]" ..
"button[3,1;3,1;trigger;Use keycard]" ..
"list[context;cardslot;7,1;1,1;1]" ..
"button[9,1;3,1;cardset;Change card]" ..
"list[current_player;main;1,2;9,1]"
realdoors.codepad_formspec = "size[5,6]" ..
"button[1,2;1,1;one;1]button[2,2;1,1;two;2]button[3,2;1,1;three;3]" ..
"button[1,3;1,1;four;4]button[2,3;1,1;five;5]button[3,3;1,1;six;6]" ..
"button[1,4;1,1;seven;7]button[2,4;1,1;eight;8]button[3,4;1,1;nine;9]" ..
"button[1,5;1,1;clear;C]button[2,5;1,1;zero;0]button[3,5;1,1;submit;E]"
realdoors.keyswitch_formspec_handler = function(pos, fields, sender)
local meta = minetest.get_meta(pos)
if not fields.trigger then return end
local inv = minetest.get_inventory({type = "node", pos = pos})
local keystack = inv:get_stack("keyslot", 1)
if keystack:get_name() ~= "realdoors:key" then return end
local key = keystack:get_meta():get_string("shape")
if meta:get_string("key") == "" then
meta:set_string("key", key)
minetest.chat_send_player(sender:get_player_name(), "This switch has been linked to key " .. key)
return
end
if key == meta:get_string("key") then
mesecon.receptor_on(pos, realdoors.connection_rules)
minetest.after(1, realdoors.keyswitch_formspec_handler_2, pos)
else
minetest.chat_send_player(sender:get_player_name(), "Your key does not match the lock")
end
end
realdoors.keyswitch_formspec_handler_2 = function(pos)
mesecon.receptor_off(pos, realdoors.connection_rules)
end
realdoors.cardreader_formspec_handler = function(pos, fields, sender)
local meta = minetest.get_meta(pos)
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")
if fields.cardset then
local newstack = inv:get_stack("cardslot", 2)
if newstack:get_name() ~= "realdoors:card" then return end
if key == meta:get_string("key") then
meta:set_string("key", newstack:get_meta():get_string("id"))
minetest.chat_send_player(sender:get_player_name(), "This reader has been linked to card " .. key)
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
if not fields.trigger then return end
if meta:get_string("key") == "" then
meta:set_string("key", key)
minetest.chat_send_player(sender:get_player_name(), "This reader has been linked to card " .. key)
minetest.sound_play("lockbeep_ok", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
return
end
if key == meta:get_string("key") then
mesecon.receptor_on(pos, realdoors.connection_rules)
minetest.sound_play("lockbeep_ok", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
minetest.after(1, realdoors.cardreader_formspec_handler_2, pos)
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.cardreader_formspec_handler_2 = function(pos)
mesecon.receptor_off(pos, realdoors.connection_rules)
end
realdoors.codepad_formspec_handler = function(pos, fields, sender)
local meta = minetest.get_meta(pos)
local entered = meta:get_string("entered")
local numberstrings = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}
for i = 0, 9 do
if fields[numberstrings[i + 1]] then
entered = entered .. tostring(i)
minetest.sound_play("lockbeep_keypress", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
end
end
if fields.clear then
if meta:get_string("setup") == "auth" or meta:get_string("setup") == "menu" then meta:set_string("setup", "no") end
minetest.sound_play("lockbeep_keypress", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
entered = ""
end
if fields.submit then
if entered == "" and meta:get_string("setup") ~= "auth" and meta:get_string("setup") ~= "menu" then
meta:set_string("setup", "auth")
minetest.sound_play("lockbeep_keypress", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
elseif meta:get_string("setup") == "auth" then
if meta:get_string("code") == "" or entered == meta:get_string("code") then
meta:set_string("setup", "menu")
minetest.sound_play("lockbeep_ok", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
else
minetest.sound_play("lockbeep_error", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
end
elseif meta:get_string("setup") == "menu" then
meta:set_string("code", entered)
meta:set_string("setup", "no")
minetest.sound_play("lockbeep_ok", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
elseif meta:get_string("code") == "" or entered == meta:get_string("code") then
mesecon.receptor_on(pos, realdoors.connection_rules)
minetest.sound_play("lockbeep_ok", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
minetest.after(1, realdoors.codepad_formspec_handler_2, pos)
else
minetest.sound_play("lockbeep_error", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
end
entered = ""
end
meta:set_string("entered", entered)
end
realdoors.codepad_formspec_handler_2 = function(pos)
mesecon.receptor_off(pos, realdoors.connection_rules)
end
minetest.register_node("realdoors:keyswitch", {
description = "Key switch",
drawtype = "nodebox",
tiles = {"keyswitch.png"},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = false,
node_box = {
type = "fixed",
fixed = {
{-0.1, -0.1, 0.4, 0.1, 0.1, 0.5},
},
},
groups = {snappy = 1},
on_construct = function(pos)
minetest.get_meta(pos):set_string("formspec", realdoors.keyswitch_formspec)
local inv = minetest.get_inventory({type = "node", pos = pos})
inv:set_size("keyslot", 1)
end,
on_receive_fields = function(pos, formname, fields, sender)
realdoors.keyswitch_formspec_handler(pos, fields, sender)
end,
mesecons = {
receptor = {
state = mesecon.state.off,
rules = realdoors.connection_rules,
},
},
})
minetest.register_node("realdoors:cardreader", {
description = "Keycard reader",
drawtype = "nodebox",
tiles = {"keycardreader.png"},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = false,
node_box = {
type = "fixed",
fixed = {
{-0.1, -0.125, 0.4, 0.1, 0.125, 0.5},
},
},
groups = {snappy = 1},
on_construct = function(pos)
minetest.get_meta(pos):set_string("formspec", realdoors.cardreader_formspec)
local inv = minetest.get_inventory({type = "node", pos = pos})
inv:set_size("cardslot", 2)
end,
on_receive_fields = function(pos, formname, fields, sender)
realdoors.cardreader_formspec_handler(pos, fields, sender)
end,
mesecons = {
receptor = {
state = mesecon.state.off,
rules = realdoors.connection_rules,
},
},
})
minetest.register_node("realdoors:codepad", {
description = "Codepad",
drawtype = "nodebox",
tiles = {"codepad.png"},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = false,
node_box = {
type = "fixed",
fixed = {
{-0.1, -0.125, 0.4, 0.1, 0.125, 0.5},
},
},
groups = {snappy = 1},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", realdoors.codepad_formspec)
meta:mark_as_private("entered")
meta:mark_as_private("code")
end,
on_receive_fields = function(pos, formname, fields, sender)
realdoors.codepad_formspec_handler(pos, fields, sender)
end,
mesecons = {
receptor = {
state = mesecon.state.off,
rules = realdoors.connection_rules,
},
},
})
minetest.register_node("realdoors:toggler", {
description = "Door toggler",
drawtype = "nodebox",
tiles = {"toggler.png"},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = false,
node_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
},
},
groups = {snappy = 1},
on_construct = function(pos)
minetest.get_meta(pos):set_string("formspec", "field[doorpos;Door position;${door}]")
end,
on_receive_fields = function(pos, formname, fields, sender)
local name = sender:get_player_name()
if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass = true}) then
minetest.record_protection_violation(pos, name)
return
end
if fields.doorpos then
minetest.get_meta(pos):set_string("door", fields.doorpos)
end
end,
mesecons = {
effector = {
rules = realdoors.connection_rules,
action_on = function(pos, node)
local doorpos = minetest.string_to_pos(minetest.get_meta(pos):get_string("door"))
if not doorpos then return end
realdoors.toggle(doorpos)
end,
action_off = function(pos, node)
local doorpos = minetest.string_to_pos(minetest.get_meta(pos):get_string("door"))
if not doorpos then return end
realdoors.toggle(doorpos)
end,
},
},
})
minetest.log("verbose", "[realdoors] Loaded controllers.lua v" .. realdoors.v)

191
electronic.lua Normal file
View File

@ -0,0 +1,191 @@
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;cardset;Change card]" ..
"button[1,3;3,1;close;Close door]" ..
"list[current_player;main;1,2;9,1]"
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")
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.cardset then
local newstack = inv:get_stack("cardslot", 2)
if newstack:get_name() ~= "realdoors:card" then return end
if key == meta:get_string("key") then
meta:set_string("key", newstack:get_meta():get_string("id"))
minetest.chat_send_player(sender:get_player_name(), "This door has been linked to card " .. 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 valid")
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(), "This door has been linked to card " .. key)
minetest.sound_play("lockbeep_ok", {
pos = pos,
max_hear_distance = 8,
gain = 4.0,
})
return
end
if key == meta:get_string("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)

View File

@ -4,6 +4,8 @@ realdoors.v = "0.1"
local mp = minetest.get_modpath(minetest.get_current_modname())
dofile(mp .. "/mechanical.lua")
dofile(mp .. "/electronic.lua")
dofile(mp .. "/controllers.lua")
dofile(mp .. "/nodes.lua")

View File

@ -40,10 +40,6 @@ realdoors.mechanical_formspec_handler = function(pos, fields, sender)
end
end
realdoors.show_mechanical_formspec = function(name)
minetest.show_formspec(name, "realdoors_mechanical", realdoors.mechanical_formspec)
end
realdoors.register_mechanical = function(def)
minetest.register_node("realdoors:door_" .. def.name .. "_a", {
description = def.desc .. " (left)",
@ -121,9 +117,11 @@ realdoors.toggle = function(pos)
local meta = minetest.get_meta(pos)
local open = false
if meta:get_string("state") == "open" then open = true end
local def = realdoors.mechanical_defs[node.name:gsub("realdoors:door_", ""):gsub("_a", ""):gsub("_b", "")]
local align = node.name:gsub("realdoors:door_", ""):gsub(def.name, ""):gsub("_", "")
local newname = "realdoors:door_" .. def.name
local def = realdoors.mechanical_defs[node.name:gsub("realdoors:door_", ""):gsub("realdoors:edoor_", ""):gsub("_a", ""):gsub("_b", "")]
local align = node.name:gsub("realdoors:door_", ""):gsub("realdoors:edoor_", ""):gsub(def.name, ""):gsub("_", "")
local elec = ""
if node.name:find("realdoors:edoor_", nil, true) then elec = "e" end
local newname = "realdoors:" .. elec .. "door_" .. def.name
if align == "a" then
newname = newname .. "_b"
else

View File

@ -1,3 +1,3 @@
name = realdoors
description = Adds realistic door locks
depends = default
depends = default, mesecons, digilines

View File

@ -5,4 +5,11 @@ realdoors.register_mechanical({
tex_inv = "doors_item_wood.png",
})
realdoors.register_electronic({
name = "wood",
desc = "Electronically locked wooden door",
tex = "doors_door_wood.png",
tex_inv = "doors_item_wood.png",
})
minetest.log("verbose", "[realdoors] Loaded nodes.lua v" .. realdoors.v)

BIN
sounds/lockbeep_error.ogg Normal file

Binary file not shown.

Binary file not shown.

BIN
sounds/lockbeep_ok.ogg Normal file

Binary file not shown.

BIN
textures/card_blank.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

BIN
textures/codepad.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

BIN
textures/keycardreader.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

BIN
textures/keyswitch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

BIN
textures/realdoors_card.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

BIN
textures/toggler.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B