Locked repeaters: Update receptor after unlock
[MineClone/MineClone2.git] / mods / ITEMS / REDSTONE / mesecons_delayer / init.lua
blobefdbb939b619769afcc235c78db47c13c27fa1fc
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 -- Functions that are called after the delay time
26 local delayer_activate = function(pos, node)
27 local def = minetest.registered_nodes[node.name]
28 local time = def.delayer_time
29 minetest.swap_node(pos, {name=def.delayer_onstate, param2=node.param2})
30 mesecon.queue:add_action(pos, "receptor_on", {delayer_get_output_rules(node)}, time, nil)
32 -- Lock repeater
33 local r = delayer_get_output_rules(node)[1]
34 local lpos = vector.add(pos, r)
35 local lnode = minetest.get_node(lpos)
36 local ldef = minetest.registered_nodes[lnode.name]
37 local g = minetest.get_item_group(lnode.name, "redstone_repeater")
38 if g >= 1 and g <= 4 then
39 local lrs = delayer_get_input_rules(lnode)
40 local fail = false
41 for _, lr in pairs(lrs) do
42 if lr.x == r.x or lr.z == r.z then
43 fail = true
44 break
45 end
46 end
47 if not fail then
48 minetest.swap_node(lpos, {name=ldef.delayer_lockstate, param2=lnode.param2})
49 end
50 end
51 end
53 local delayer_deactivate = function(pos, node)
54 local def = minetest.registered_nodes[node.name]
55 local time = def.delayer_time
56 minetest.swap_node(pos, {name=def.delayer_offstate, param2=node.param2})
57 mesecon.queue:add_action(pos, "receptor_off", {delayer_get_output_rules(node)}, time, nil)
59 -- Unlock repeater
60 local r = delayer_get_output_rules(node)[1]
61 local lpos = vector.add(pos, r)
62 local lnode = minetest.get_node(lpos)
63 local ldef = minetest.registered_nodes[lnode.name]
64 local g = minetest.get_item_group(lnode.name, "redstone_repeater")
65 if g == 5 then
66 local lrs = delayer_get_input_rules(lnode)
67 local fail = false
68 for _, lr in pairs(lrs) do
69 if lr.x == r.x or lr.z == r.z then
70 fail = true
71 break
72 end
73 end
74 if not fail then
75 if mesecon.is_powered(lpos) then
76 minetest.swap_node(lpos, {name="mesecons_delayer:delayer_on_1", param2=lnode.param2})
77 mesecon.queue:add_action(lpos, "receptor_on", {delayer_get_output_rules(lnode)}, ldef.delayer_time, nil)
78 else
79 minetest.swap_node(lpos, {name="mesecons_delayer:delayer_off_1", param2=lnode.param2})
80 mesecon.queue:add_action(lpos, "receptor_off", {delayer_get_output_rules(lnode)}, ldef.delayer_time, nil)
81 end
82 end
83 end
84 end
86 -- Register the 2 (states) x 4 (delay times) delayers
88 for i = 1, 4 do
89 local groups = {}
90 if i == 1 then
91 groups = {dig_immediate=3,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,attached_node=1,redstone_repeater=i}
92 else
93 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}
94 end
96 local delaytime
97 if i == 1 then delaytime = 0.1
98 elseif i == 2 then delaytime = 0.2
99 elseif i == 3 then delaytime = 0.3
100 elseif i == 4 then delaytime = 0.4
103 local boxes
104 if i == 1 then
105 boxes = {
106 { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
107 { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
108 { -1/16, -6/16, 0/16, 1/16, -1/16, 2/16}, -- moved torch
110 elseif i == 2 then
111 boxes = {
112 { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
113 { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
114 { -1/16, -6/16, -2/16, 1/16, -1/16, 0/16}, -- moved torch
116 elseif i == 3 then
117 boxes = {
118 { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
119 { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
120 { -1/16, -6/16, -4/16, 1/16, -1/16, -2/16}, -- moved torch
122 elseif i == 4 then
123 boxes = {
124 { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
125 { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
126 { -1/16, -6/16, -6/16, 1/16, -1/16, -4/16}, -- moved torch
130 local help, longdesc, usagehelp, icon
131 if i == 1 then
132 help = true
133 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."
134 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."
135 icon = "mesecons_delayer_item.png"
136 else
137 help = false
140 local on_rotate
141 if minetest.get_modpath("screwdriver") then
142 on_rotate = screwdriver.disallow
145 minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), {
146 description = "Redstone Repeater",
147 inventory_image = icon,
148 wield_image = icon,
149 _doc_items_create_entry = help,
150 _doc_items_longdesc = longdesc,
151 _doc_items_usagehelp = usagehelp,
152 drawtype = "nodebox",
153 tiles = {
154 "mesecons_delayer_off.png",
155 "mcl_stairs_stone_slab_top.png",
156 "mesecons_delayer_sides_off.png",
157 "mesecons_delayer_sides_off.png",
158 "mesecons_delayer_ends_off.png",
159 "mesecons_delayer_ends_off.png",
161 wield_image = "mesecons_delayer_off.png",
162 walkable = true,
163 selection_box = {
164 type = "fixed",
165 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
167 collision_box = {
168 type = "fixed",
169 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
171 node_box = {
172 type = "fixed",
173 fixed = boxes
175 groups = groups,
176 paramtype = "light",
177 paramtype2 = "facedir",
178 sunlight_propagates = false,
179 is_ground_content = false,
180 drop = 'mesecons_delayer:delayer_off_1',
181 on_rightclick = function (pos, node)
182 if node.name=="mesecons_delayer:delayer_off_1" then
183 minetest.swap_node(pos, {name="mesecons_delayer:delayer_off_2", param2=node.param2})
184 elseif node.name=="mesecons_delayer:delayer_off_2" then
185 minetest.swap_node(pos, {name="mesecons_delayer:delayer_off_3", param2=node.param2})
186 elseif node.name=="mesecons_delayer:delayer_off_3" then
187 minetest.swap_node(pos, {name="mesecons_delayer:delayer_off_4", param2=node.param2})
188 elseif node.name=="mesecons_delayer:delayer_off_4" then
189 minetest.swap_node(pos, {name="mesecons_delayer:delayer_off_1", param2=node.param2})
191 end,
192 delayer_time = delaytime,
193 delayer_onstate = "mesecons_delayer:delayer_on_"..tostring(i),
194 delayer_lockstate = "mesecons_delayer:delayer_off_locked",
195 sounds = mcl_sounds.node_sound_stone_defaults(),
196 mesecons = {
197 receptor =
199 state = mesecon.state.off,
200 rules = delayer_get_output_rules
202 effector =
204 rules = delayer_get_input_rules,
205 action_on = delayer_activate
208 on_rotate = on_rotate,
212 minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), {
213 description = "Redstone Repeater (Powered)",
214 _doc_items_create_entry = false,
215 drawtype = "nodebox",
216 tiles = {
217 "mesecons_delayer_on.png",
218 "mcl_stairs_stone_slab_top.png",
219 "mesecons_delayer_sides_on.png",
220 "mesecons_delayer_sides_on.png",
221 "mesecons_delayer_ends_on.png",
222 "mesecons_delayer_ends_on.png",
224 walkable = true,
225 selection_box = {
226 type = "fixed",
227 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
229 collision_box = {
230 type = "fixed",
231 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
233 node_box = {
234 type = "fixed",
235 fixed = boxes
237 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},
238 paramtype = "light",
239 paramtype2 = "facedir",
240 sunlight_propagates = false,
241 is_ground_content = false,
242 drop = 'mesecons_delayer:delayer_off_1',
243 on_rightclick = function (pos, node)
244 if node.name=="mesecons_delayer:delayer_on_1" then
245 minetest.swap_node(pos, {name="mesecons_delayer:delayer_on_2",param2=node.param2})
246 elseif node.name=="mesecons_delayer:delayer_on_2" then
247 minetest.swap_node(pos, {name="mesecons_delayer:delayer_on_3",param2=node.param2})
248 elseif node.name=="mesecons_delayer:delayer_on_3" then
249 minetest.swap_node(pos, {name="mesecons_delayer:delayer_on_4",param2=node.param2})
250 elseif node.name=="mesecons_delayer:delayer_on_4" then
251 minetest.swap_node(pos, {name="mesecons_delayer:delayer_on_1",param2=node.param2})
253 end,
254 delayer_time = delaytime,
255 delayer_offstate = "mesecons_delayer:delayer_off_"..tostring(i),
256 delayer_lockstate = "mesecons_delayer:delayer_on_locked",
257 sounds = mcl_sounds.node_sound_stone_defaults(),
258 mesecons = {
259 receptor =
261 state = mesecon.state.on,
262 rules = delayer_get_output_rules
264 effector =
266 rules = delayer_get_input_rules,
267 action_off = delayer_deactivate
270 on_rotate = on_rotate,
276 -- Locked repeater
278 minetest.register_node("mesecons_delayer:delayer_off_locked", {
279 description = "Redstone Repeater (Locked)",
280 inventory_image = icon,
281 wield_image = icon,
282 _doc_items_create_entry = false,
283 drawtype = "nodebox",
284 -- FIXME: Textures of torch and the lock bar overlap. Nodeboxes are (sadly) not suitable for this.
285 -- So this needs to be turned into a mesh.
286 tiles = {
287 "mesecons_delayer_locked_off.png",
288 "mcl_stairs_stone_slab_top.png",
289 "mesecons_delayer_sides_locked_off.png",
290 "mesecons_delayer_sides_locked_off.png",
291 "mesecons_delayer_front_locked_off.png",
292 "mesecons_delayer_end_locked_off.png",
294 wield_image = "mesecons_delayer_locked_off.png",
295 walkable = true,
296 selection_box = {
297 type = "fixed",
298 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
300 collision_box = {
301 type = "fixed",
302 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
304 node_box = {
305 type = "fixed",
306 fixed = {
307 { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
308 { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
309 { -6/16, -6/16, 0/16, 6/16, -4/16, 2/16}, -- lock
312 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},
313 paramtype = "light",
314 paramtype2 = "facedir",
315 sunlight_propagates = false,
316 is_ground_content = false,
317 drop = 'mesecons_delayer:delayer_off_1',
318 delayer_time = 0.1,
319 sounds = mcl_sounds.node_sound_stone_defaults(),
320 mesecons = {
321 receptor =
323 state = mesecon.state.off,
324 rules = delayer_get_output_rules
326 effector =
328 rules = delayer_get_input_rules,
331 on_rotate = on_rotate,
334 minetest.register_node("mesecons_delayer:delayer_on_locked", {
335 description = "Redstone Repeater (Locked, Powered)",
336 _doc_items_create_entry = false,
337 drawtype = "nodebox",
338 tiles = {
339 "mesecons_delayer_locked_on.png",
340 "mcl_stairs_stone_slab_top.png",
341 "mesecons_delayer_sides_locked_on.png",
342 "mesecons_delayer_sides_locked_on.png",
343 "mesecons_delayer_front_locked_on.png",
344 "mesecons_delayer_end_locked_on.png",
346 walkable = true,
347 selection_box = {
348 type = "fixed",
349 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
351 collision_box = {
352 type = "fixed",
353 fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
355 node_box = {
356 type = "fixed",
357 fixed = {
358 { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab
359 { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch
360 { -6/16, -6/16, 0/16, 6/16, -4/16, 2/16}, -- lock
363 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},
364 paramtype = "light",
365 paramtype2 = "facedir",
366 sunlight_propagates = false,
367 is_ground_content = false,
368 drop = 'mesecons_delayer:delayer_off_1',
369 delayer_time = 0.1,
370 sounds = mcl_sounds.node_sound_stone_defaults(),
371 mesecons = {
372 receptor =
374 state = mesecon.state.on,
375 rules = delayer_get_output_rules
377 effector =
379 rules = delayer_get_input_rules,
382 on_rotate = on_rotate,
385 minetest.register_craft({
386 output = "mesecons_delayer:delayer_off_1",
387 recipe = {
388 {"mesecons_torch:mesecon_torch_on", "mesecons:redstone", "mesecons_torch:mesecon_torch_on"},
389 {"mcl_core:stone","mcl_core:stone", "mcl_core:stone"},
393 -- Add entry aliases for the Help
394 if minetest.get_modpath("doc") then
395 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_off_2")
396 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_off_3")
397 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_off_4")
398 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_off_locked")
399 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_on_1")
400 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_on_2")
401 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_on_3")
402 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_on_4")
403 doc.add_entry_alias("nodes", "mesecons_delayer:delayer_off_1", "nodes", "mesecons_delayer:delayer_on_locked")