-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathdigicode.lua
163 lines (147 loc) · 4.82 KB
/
digicode.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
--------------
-- Digicode --
--------------
local has_mesecons = minetest.get_modpath("mesecons")
local secret_code = "1234"
local allowed_chars = "0123456789"
local code_length = 4
local digicode_context = {}
-- after_place_node, use by digicode and palm_scanner
-- placer is a player object
local function set_owner(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name())
meta:set_string("code", secret_code)
end
local function toggle_digicode(pos)
local node = minetest.get_node(pos)
local name = node.name
if name == "scifi_nodes:digicode_off" then
minetest.swap_node(pos, {name="scifi_nodes:digicode_on", param2=node.param2})
mesecon.receptor_on(pos, scifi_nodes.get_switch_rules(node.param2))
minetest.get_node_timer(pos):start(2)
elseif name == "scifi_nodes:digicode_on" then
minetest.swap_node(pos, {name="scifi_nodes:digicode_off", param2=node.param2})
mesecon.receptor_off(pos, scifi_nodes.get_switch_rules(node.param2))
end
end
local function code_is_valid(code)
local valid = false
if type(code) == "string" and #code == code_length then
valid = true
end
for i=1, #code do
if not string.find(allowed_chars, string.sub(code,i,i)) then
valid = false
end
end
return valid
end
local function update_code(pos, code)
local meta = minetest.get_meta(pos)
meta:set_string("code", code)
end
local function show_digicode_formspec(pos, _, player)
local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner")
local current_code = meta:get_string("code")
local current_player = player:get_player_name()
-- Gathering datas that will be used by callback function
digicode_context[current_player] = {code = current_code, pos = pos}
if current_player == owner then
minetest.show_formspec(current_player, "digicode_formspec",
"size[6,3]"..
"field[1,1;3,1;code;Code;]".. -- type, position, size, name, label
"button_exit[1,2;2,1;change;Change code]"..
"button_exit[3,2;2,1;open;Open door]")
else
minetest.show_formspec(current_player, "digicode_formspec",
"size[6,3]"..
"field[2,1;3,1;code;Code;]"..
"button_exit[2,2;3,1;open;Open door]")
end
end
-- Process datas from digicode_formspec
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "digicode_formspec" then
return false
end
local sounds = {"scifi_nodes_scanner_granted","scifi_nodes_scanner_refused",
"scifi_nodes_digicode_granted","scifi_nodes_digicode_refused"
}
local sound_index
-- We have the right formspec so we can proceed it.
-- Let's retrieve the datas we need :
local context = digicode_context[player:get_player_name()]
if fields.change and code_is_valid(fields.code) then
update_code(context.pos, fields.code)
sound_index = 1
elseif
fields.change and not code_is_valid(fields.code) then
sound_index = 2
elseif
fields.open and fields.code == context.code then
toggle_digicode(context.pos)
sound_index = 3
elseif
fields.open and fields.code ~= context.code then
sound_index = 4
end
-- play sound at context position
minetest.sound_play(sounds[sound_index], {
pos = context.pos,
max_hear_distance = 10
})
context[player:get_player_name()] = nil -- we don't need it anymore
end)
minetest.register_node("scifi_nodes:digicode_on", {
description = "Digicode",
sunlight_propagates = true,
buildable_to = false,
tiles = {"scifi_nodes_digicode_on.png",},
inventory_image = "scifi_nodes_digicode_on.png",
wield_image = "scifi_nodes_digicode_on.png",
drawtype = "signlike",
node_box = {type = "wallmounted",},
selection_box = {type = "wallmounted",},
paramtype = "light",
paramtype2 = "wallmounted",
light_source = 5,
groups = {cracky=1, oddly_breakable_by_hand=1, not_in_creative_inventory=1, mesecon_needs_receiver = 1},
is_ground_content = false,
drop = "scifi_nodes:digicode_off",
mesecons = {
receptor = {
state = (has_mesecons and mesecon.state.on)
}
},
on_timer = toggle_digicode,
sounds = scifi_nodes.node_sound_metal_defaults(),
})
minetest.register_node("scifi_nodes:digicode_off", {
description = "Digicode",
tiles = {"scifi_nodes_digicode_off.png",},
inventory_image = "scifi_nodes_digicode_off.png",
wield_image = "scifi_nodes_digicode_off.png",
drawtype = "signlike",
sunlight_propagates = true,
buildable_to = false,
node_box = {type = "wallmounted",},
selection_box = {type = "wallmounted",},
paramtype = "light",
paramtype2 = "wallmounted",
groups = {cracky=1, oddly_breakable_by_hand=1, mesecon_needs_receiver = 1},
is_ground_content = false,
mesecons = {
receptor = {
state = (has_mesecons and mesecon.state.off)
}
},
after_place_node = set_owner,
on_rightclick = show_digicode_formspec,
sounds = scifi_nodes.node_sound_metal_defaults(),
})
minetest.register_craft({
output = "scifi_nodes:digicode_off 2",
recipe = {{"mesecons_switch:mesecon_switch_off", "scifi_nodes:grey", ""}}
})