Update repeater lock after dig
[MineClone/MineClone2.git] / mods / ITEMS / REDSTONE / mesecons_delayer / init.lua
blobba63590232f67633550525b1425803736f405c21
1 -- Function that get the input/output rules of the delayer
2 local delayer_get_output_rules = function(node)
3 local rules = {{x = -1, y = 0, z = 0, spread=true}}
4 for i = 0, node.param2 do
5 rules = mesecon.rotate_rules_left(rules)
6 end
7 return rules
8 end
10 local delayer_get_input_rules = function(node)
11 local rules = {{x = 1, y = 0, z = 0}}
12 for i = 0, node.param2 do
13 rules = mesecon.rotate_rules_left(rules)
14 end
15 return rules
16 end
18 local delayer_get_all_rules = function(node)
19 local orules = delayer_get_output_rules(node)
20 local irules = delayer_get_input_rules(node)
21 return mesecon.mergetables(orules, irules)
22 end
24 local check_lock_repeater = function(pos, node)
25 -- Check the repeater at pos and look if there is
26 -- a repeater in its facing direction and sideways.
27 -- If yes, lock the second repeater.
28 local r = delayer_get_output_rules(node)[1]
29 local lpos = vector.add(pos, r)
30 local lnode = minetest.get_node(lpos)
31 local ldef = minetest.registered_nodes[lnode.name]
32 local g = minetest.get_item_group(lnode.name, "redstone_repeater")
33 if g >= 1 and g <= 4 then
34 local lrs = delayer_get_input_rules(lnode)
35 local fail = false
36 for _, lr in pairs(lrs) do
37 if lr.x == r.x or lr.z == r.z then
38 fail = true
39 break
40 end
41 end
42 if not fail then
43 minetest.swap_node(lpos, {name=ldef.delayer_lockstate, param2=lnode.param2})
44 return true
45 end
46 end
47 return false
48 end
50 local check_unlock_repeater = function(pos, node)
51 -- Unlock repeater
52 local r = delayer_get_output_rules(node)[1]
53 local lpos = vector.add(pos, r)
54 local lnode = minetest.get_node(lpos)
55 local ldef = minetest.registered_nodes[lnode.name]
56 local g = minetest.get_item_group(lnode.name, "redstone_repeater")
57 if g == 5 then
58 local lrs = delayer_get_input_rules(lnode)
59 local fail = false
60 for _, lr in pairs(lrs) do
61 if lr.x == r.x or lr.z == r.z then
62 fail = true
63 break
64 end
65 end
66 if not fail then
67 if mesecon.is_powered(lpos) then
68 minetest.swap_node(lpos, {name="mesecons_delayer:delayer_on_1", param2=lnode.param2})
69 mesecon.queue:add_action(lpos, "receptor_on", {delayer_get_output_rules(lnode)}, ldef.delayer_time, nil)
70 else
71 minetest.swap_node(lpos, {name="mesecons_delayer:delayer_off_1", param2=lnode.param2})
72 mesecon.queue:add_action(lpos, "receptor_off", {delayer_get_output_rules(lnode)}, ldef.delayer_time, nil)
73 end
74 return true
75 end
76 end
77 return false
78 end
80 -- Functions that are called after the delay time
81 local delayer_activate = function(pos, node)
82 local def = minetest.registered_nodes[node.name]
83 local time = def.delayer_time
84 minetest.swap_node(pos, {name=def.delayer_onstate, param2=node.param2})
85 mesecon.queue:add_action(pos, "receptor_on", {delayer_get_output_rules(node)}, time, nil)
87 check_lock_repeater(pos, node)
88 end
90 local delayer_deactivate = function(pos, node)
91 local def = minetest.registered_nodes[node.name]
92 local time = def.delayer_time
93 minetest.swap_node(pos, {name=def.delayer_offstate, param2=node.param2})
94 mesecon.queue:add_action(pos, "receptor_off", {delayer_get_output_rules(node)}, time, nil)
96 check_unlock_repeater(pos, node)
97 end
99 -- Register the 2 (states) x 4 (delay times) delayers
101 for i = 1, 4 do
102 local groups = {}
103 if i == 1 then
104 groups = {dig_immediate=3,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,attached_node=1,redstone_repeater=i}
105 else
106 groups = {dig_immediate=3,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,attached_node=1,redstone_repeater=i,not_in_creative_inventory=1}
109 local delaytime
110 if i == 1 then delaytime = 0.1
111 elseif i == 2 then delaytime = 0.2
112 elseif i == 3 then delaytime = 0.3
113 elseif i == 4 then delaytime = 0.4
116 local boxes
117 if i == 1 then
118 boxes = {
119 { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
120 { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
121 { -1/16, -6/16, 0/16, 1/16, -1/16, 2/16}, -- moved torch
123 elseif i == 2 then
124 boxes = {
125 { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
126 { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
127 { -1/16, -6/16, -2/16, 1/16, -1/16, 0/16}, -- moved torch
129 elseif i == 3 then
130 boxes = {
131 { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
132 { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
133 { -1/16, -6/16, -4/16, 1/16, -1/16, -2/16}, -- moved torch
135 elseif i == 4 then
136 boxes = {
137 { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
138 { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
139 { -1/16, -6/16, -6/16, 1/16, -1/16, -4/16}, -- moved torch
143 local help, longdesc, usagehelp, icon
144 if i == 1 then
145 help = true
146 longdesc = "Redstone repeaters are versatile redstone components which delay redstone signals and only allow redstone signals to travel through one direction. The delay of the signal is indicated by the redstone torches and is between 0.1 and 0.4 seconds long."
147 usagehelp = "To power a redstone repeater, send a signal in “arrow” direction. To change the delay, rightclick the redstone repeater. The delay is changed in steps of 0.1 seconds."
148 icon = "mesecons_delayer_item.png"
149 else
150 help = false
153 local on_rotate
154 if minetest.get_modpath("screwdriver") then
155 on_rotate = screwdriver.disallow
158 minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), {
159 description = "Redstone Repeater",
160 inventory_image = icon,
161 wield_image = icon,
162 _doc_items_create_entry = help,
163 _doc_items_longdesc = longdesc,
164 _doc_items_usagehelp = usagehelp,
165 drawtype = "nodebox",
166 tiles = {
167 "mesecons_delayer_off.png",
168 "mcl_stairs_stone_slab_top.png",
169 "mesecons_delayer_sides_off.png",
170 "mesecons_delayer_sides_off.png",
171 "mesecons_delayer_ends_off.png",
172 "mesecons_delayer_ends_off.png",
174 wield_image = "mesecons_delayer_off.png",
175 walkable = true,
176 selection_box = {
177 type = "fixed",
178 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
180 collision_box = {
181 type = "fixed",
182 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
184 node_box = {
185 type = "fixed",
186 fixed = boxes
188 groups = groups,
189 paramtype = "light",
190 paramtype2 = "facedir",
191 sunlight_propagates = false,
192 is_ground_content = false,
193 drop = 'mesecons_delayer:delayer_off_1',
194 on_rightclick = function (pos, node)
195 if node.name=="mesecons_delayer:delayer_off_1" then
196 minetest.swap_node(pos, {name="mesecons_delayer:delayer_off_2", param2=node.param2})
197 elseif node.name=="mesecons_delayer:delayer_off_2" then
198 minetest.swap_node(pos, {name="mesecons_delayer:delayer_off_3", param2=node.param2})
199 elseif node.name=="mesecons_delayer:delayer_off_3" then
200 minetest.swap_node(pos, {name="mesecons_delayer:delayer_off_4", param2=node.param2})
201 elseif node.name=="mesecons_delayer:delayer_off_4" then
202 minetest.swap_node(pos, {name="mesecons_delayer:delayer_off_1", param2=node.param2})
204 end,
205 delayer_time = delaytime,
206 delayer_onstate = "mesecons_delayer:delayer_on_"..tostring(i),
207 delayer_lockstate = "mesecons_delayer:delayer_off_locked",
208 sounds = mcl_sounds.node_sound_stone_defaults(),
209 mesecons = {
210 receptor =
212 state = mesecon.state.off,
213 rules = delayer_get_output_rules
215 effector =
217 rules = delayer_get_input_rules,
218 action_on = delayer_activate
221 on_rotate = on_rotate,
225 minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), {
226 description = "Redstone Repeater (Powered)",
227 _doc_items_create_entry = false,
228 drawtype = "nodebox",
229 tiles = {
230 "mesecons_delayer_on.png",
231 "mcl_stairs_stone_slab_top.png",
232 "mesecons_delayer_sides_on.png",
233 "mesecons_delayer_sides_on.png",
234 "mesecons_delayer_ends_on.png",
235 "mesecons_delayer_ends_on.png",
237 walkable = true,
238 selection_box = {
239 type = "fixed",
240 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
242 collision_box = {
243 type = "fixed",
244 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
246 node_box = {
247 type = "fixed",
248 fixed = boxes
250 groups = {dig_immediate = 3, dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1, attached_node=1, redstone_repeater=i, not_in_creative_inventory = 1},
251 paramtype = "light",
252 paramtype2 = "facedir",
253 sunlight_propagates = false,
254 is_ground_content = false,
255 drop = 'mesecons_delayer:delayer_off_1',
256 on_rightclick = function (pos, node)
257 if node.name=="mesecons_delayer:delayer_on_1" then
258 minetest.swap_node(pos, {name="mesecons_delayer:delayer_on_2",param2=node.param2})
259 elseif node.name=="mesecons_delayer:delayer_on_2" then
260 minetest.swap_node(pos, {name="mesecons_delayer:delayer_on_3",param2=node.param2})
261 elseif node.name=="mesecons_delayer:delayer_on_3" then
262 minetest.swap_node(pos, {name="mesecons_delayer:delayer_on_4",param2=node.param2})
263 elseif node.name=="mesecons_delayer:delayer_on_4" then
264 minetest.swap_node(pos, {name="mesecons_delayer:delayer_on_1",param2=node.param2})
266 end,
267 after_dig_node = function(pos, oldnode, oldmetadata, digger)
268 check_unlock_repeater(pos, oldnode)
269 end,
270 delayer_time = delaytime,
271 delayer_offstate = "mesecons_delayer:delayer_off_"..tostring(i),
272 delayer_lockstate = "mesecons_delayer:delayer_on_locked",
273 sounds = mcl_sounds.node_sound_stone_defaults(),
274 mesecons = {
275 receptor =
277 state = mesecon.state.on,
278 rules = delayer_get_output_rules
280 effector =
282 rules = delayer_get_input_rules,
283 action_off = delayer_deactivate
286 on_rotate = on_rotate,
292 -- Locked repeater
294 minetest.register_node("mesecons_delayer:delayer_off_locked", {
295 description = "Redstone Repeater (Locked)",
296 inventory_image = icon,
297 wield_image = icon,
298 _doc_items_create_entry = false,
299 drawtype = "nodebox",
300 -- FIXME: Textures of torch and the lock bar overlap. Nodeboxes are (sadly) not suitable for this.
301 -- So this needs to be turned into a mesh.
302 tiles = {
303 "mesecons_delayer_locked_off.png",
304 "mcl_stairs_stone_slab_top.png",
305 "mesecons_delayer_sides_locked_off.png",
306 "mesecons_delayer_sides_locked_off.png",
307 "mesecons_delayer_front_locked_off.png",
308 "mesecons_delayer_end_locked_off.png",
310 wield_image = "mesecons_delayer_locked_off.png",
311 walkable = true,
312 selection_box = {
313 type = "fixed",
314 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
316 collision_box = {
317 type = "fixed",
318 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
320 node_box = {
321 type = "fixed",
322 fixed = {
323 { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
324 { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
325 { -6/16, -6/16, 0/16, 6/16, -4/16, 2/16}, -- lock
328 groups = {dig_immediate = 3, dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1, attached_node=1, redstone_repeater=5, not_in_creative_inventory = 1},
329 paramtype = "light",
330 paramtype2 = "facedir",
331 sunlight_propagates = false,
332 is_ground_content = false,
333 drop = 'mesecons_delayer:delayer_off_1',
334 delayer_time = 0.1,
335 sounds = mcl_sounds.node_sound_stone_defaults(),
336 mesecons = {
337 receptor =
339 state = mesecon.state.off,
340 rules = delayer_get_output_rules
342 effector =
344 rules = delayer_get_input_rules,
347 on_rotate = on_rotate,
350 minetest.register_node("mesecons_delayer:delayer_on_locked", {
351 description = "Redstone Repeater (Locked, Powered)",
352 _doc_items_create_entry = false,
353 drawtype = "nodebox",
354 tiles = {
355 "mesecons_delayer_locked_on.png",
356 "mcl_stairs_stone_slab_top.png",
357 "mesecons_delayer_sides_locked_on.png",
358 "mesecons_delayer_sides_locked_on.png",
359 "mesecons_delayer_front_locked_on.png",
360 "mesecons_delayer_end_locked_on.png",
362 walkable = true,
363 selection_box = {
364 type = "fixed",
365 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
367 collision_box = {
368 type = "fixed",
369 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
371 node_box = {
372 type = "fixed",
373 fixed = {
374 { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
375 { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
376 { -6/16, -6/16, 0/16, 6/16, -4/16, 2/16}, -- lock
379 after_dig_node = function(pos, oldnode, oldmetadata, digger)
380 check_unlock_repeater(pos, oldnode)
381 end,
382 groups = {dig_immediate = 3, dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1, attached_node=1, redstone_repeater=5, not_in_creative_inventory = 1},
383 paramtype = "light",
384 paramtype2 = "facedir",
385 sunlight_propagates = false,
386 is_ground_content = false,
387 drop = 'mesecons_delayer:delayer_off_1',
388 delayer_time = 0.1,
389 sounds = mcl_sounds.node_sound_stone_defaults(),
390 mesecons = {
391 receptor =
393 state = mesecon.state.on,
394 rules = delayer_get_output_rules
396 effector =
398 rules = delayer_get_input_rules,
401 on_rotate = on_rotate,
404 minetest.register_craft({
405 output = "mesecons_delayer:delayer_off_1",
406 recipe = {
407 {"mesecons_torch:mesecon_torch_on", "mesecons:redstone", "mesecons_torch:mesecon_torch_on"},
408 {"mcl_core:stone","mcl_core:stone", "mcl_core:stone"},
412 -- Add entry aliases for the Help
413 if minetest.get_modpath("doc") then
414 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_off_2")
415 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_off_3")
416 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_off_4")
417 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_off_locked")
418 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_on_1")
419 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_on_2")
420 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_on_3")
421 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_on_4")
422 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_on_locked")