]> git.lizzy.rs Git - Crafter.git/blob - mods/redstone/piston.lua
Allow rightclicking a piston to change it's direction
[Crafter.git] / mods / redstone / piston.lua
1 local minetest,math,ipairs,vector,table = minetest,math,ipairs,vector,table
2 --exclude certain mods and nodes from being pushed and pulled to stop glitches
3 local registered_nodes
4 minetest.register_on_mods_loaded(function()
5         registered_nodes  = minetest.registered_nodes
6 end)
7
8 local excluded_mods = {utility=true,craftingtable=true,buildtest=true,sign=true,bed=true}
9 local excluded_nodes = {
10         ["redstone:piston_on"]=true,
11         ["redstone:sticky_piston_on"]=true,
12         ["redstone:actuator"]=true,
13         ["redstone:sticky_actuator"]=true,
14         ["redstone:inverter_on"]=true,
15         ["redstone:inverter_off"]=true,
16         ["redstone:torch_wall"]=true,
17         ["redstone:torch_floor"]=true,
18         ["redstone:lever_on"]=true,
19         ["redstone:lever_off"]=true,
20         ["redstone:button_on"]=true,
21         ["redstone:button_off"]=true,
22 }
23 for i = 0,8 do
24         excluded_nodes["redstone:dust_"..i] = true
25 end
26 for i = 0,7 do
27         excluded_nodes["redstone:repeater_on_"..i] = true
28         excluded_nodes["redstone:repeater_off_"..i] = true
29 end
30 for i = 0,9 do
31         excluded_nodes["redstone:comparator_"..i] = true
32 end
33 for i = 0,9 do
34         excluded_nodes["redstone:pressure_plate_"..i] = true
35 end
36 for i = 0,1 do
37         excluded_nodes["redstone:ore_"..i] = true
38 end
39
40
41 --[[
42 ███████╗██╗   ██╗███╗   ██╗ ██████╗████████╗██╗ ██████╗ ███╗   ██╗
43 ██╔════╝██║   ██║████╗  ██║██╔════╝╚══██╔══╝██║██╔═══██╗████╗  ██║
44 █████╗  ██║   ██║██╔██╗ ██║██║        ██║   ██║██║   ██║██╔██╗ ██║
45 ██╔══╝  ██║   ██║██║╚██╗██║██║        ██║   ██║██║   ██║██║╚██╗██║
46 ██║     ╚██████╔╝██║ ╚████║╚██████╗   ██║   ██║╚██████╔╝██║ ╚████║
47 ╚═╝      ╚═════╝ ╚═╝  ╚═══╝ ╚═════╝   ╚═╝   ╚═╝ ╚═════╝ ╚═╝  ╚═══╝
48 ]]
49
50 --this is how the piston pushes nodes
51 local move_index
52 local space
53 local index_pos
54 local node
55 local param2
56 local def
57 local push
58 local index
59 local function push_nodes(pos,dir)
60         move_index = {}
61         space = false
62         for i = 1,30 do
63                 index_pos = vector.add(vector.multiply(dir,i),pos)
64                 node = minetest.get_node(index_pos)
65                 param2 = node.param2
66                 def = minetest.registered_nodes[node.name]
67                 name = node.name
68                 push = ((excluded_mods[def.mod_origin] ~= true) and (excluded_nodes[name] ~= true))
69                 if push and name ~= "air" then
70                         index = {}
71                         index.pos = index_pos
72                         index.name = name
73                         index.param2 = param2
74                         table.insert(move_index,index)
75                 elseif name == "air" then
76                         space = true
77                         break
78                 else
79                         space = false
80                         break
81                 end             
82         end
83
84         --check if room to move and objects in log
85         if space == true and next(move_index) then
86                 if table.getn(move_index) == 1 and minetest.get_item_group(move_index[1].name, "falling_node") > 0 then
87                         for i = 1,table.getn(move_index) do
88                                 move_index[i].pos = vector.add(move_index[i].pos,dir)
89                                 minetest.set_node(move_index[i].pos,{name="air"})
90
91                                 local obj = minetest.add_entity(vector.add(move_index[i].pos,dir), "__builtin:falling_node")
92                                 obj:get_luaentity():set_node({name=move_index[i].name})
93                                 obj:set_velocity(vector.multiply(dir,19))
94                         end
95                 else
96                         for i = 1,table.getn(move_index) do
97                                 if move_index[i] then
98                                         if move_index[i].pos then
99                                                 move_index[i].pos = vector.add(move_index[i].pos,dir)
100                                                 minetest.set_node(move_index[i].pos,move_index[i])
101                                                 minetest.check_for_falling(move_index[i].pos)
102                                         end
103                                 end
104                         end
105                 end
106         end
107         return(space)
108 end
109
110 --this is the logic of the piston
111 local facedir
112 local dir
113 local piston_location
114 local worked
115 local function actuator_arm_function(pos)
116         --this is where the piston activates
117         facedir = minetest.get_node(pos).param2
118         dir = minetest.facedir_to_dir(facedir)
119         piston_location = vector.add(pos,dir)
120         worked = push_nodes(pos,dir)
121         local node = minetest.get_node(vector.add(pos,dir)).name
122         
123         if worked == true then
124                 --push player
125                 if node == "air" then
126                         for _,object in ipairs(minetest.get_objects_inside_radius(piston_location, 2)) do
127
128                                 if object:is_player() and object:get_hp() > 0 then
129                                         local pos2 = object:get_pos()
130                                         local compare = vector.subtract(pos2,piston_location)
131                                         local real_y = compare.y
132                                         compare = vector.abs(compare)
133                                         --piston pointing up
134                                         if dir.y == 1 then
135                                                 if compare.y <= 0.5 and compare.x < 0.8 and compare.z < 0.8 then
136                                                         object:move_to(vector.add(dir,pos2))
137                                                         object:add_player_velocity(vector.multiply(dir,20))
138                                                 end
139                                         --piston sideways
140                                         elseif dir.x ~=0 or dir.z ~= 0 then
141                                                 if real_y <= 0.5 and real_y >= -1.6 and compare.x < 0.8 and compare.z < 0.8 then
142                                                         object:move_to(vector.add(dir,pos2))
143                                                         object:add_player_velocity(vector.multiply(dir,19))
144                                                 end
145                                         end
146                                 elseif not object:is_player() and object:get_luaentity().name == "__builtin:falling_node" then
147                                         local pos2 = object:get_pos()
148                                         local compare = vector.subtract(pos2,piston_location)
149                                         local real_y = compare.y
150                                         compare = vector.abs(compare)
151                                         if compare.y <= 1.5 and compare.x <= 1.5 and compare.z <= 1.5 then
152                                                 object:move_to(vector.add(dir,pos2))
153                                                 object:add_velocity(vector.multiply(dir,20))
154                                         end
155                                 elseif not object:is_player() and object:get_luaentity().name == "__builtin:item" then
156                                         local pos2 = object:get_pos()
157                                         local compare = vector.subtract(pos2,piston_location)
158                                         local real_y = compare.y
159                                         compare = vector.abs(compare)
160                                         if compare.y <= 1 and compare.x <= 1 and compare.z <= 1 then
161                                                 object:move_to(vector.add(dir,pos2))
162                                                 object:add_velocity(vector.multiply(dir,20))
163                                                 object:get_luaentity().poll_timer = 0
164                                         end
165                                 end
166                         end
167                 end
168                 minetest.sound_play("piston", {pos=pos,pitch=math.random(85,100)/100})
169                 minetest.set_node(piston_location,{name="redstone:actuator",param2=facedir})
170                 minetest.swap_node(pos,{name="redstone:piston_on",param2=facedir})
171
172                 redstone.inject(pos,{
173                         name = "redstone:piston_on",
174                         activator = true,
175                 })
176                 redstone.update(pos)
177         end
178 end
179
180
181 --[[
182  ██████╗ ███████╗███████╗
183 ██╔═══██╗██╔════╝██╔════╝
184 ██║   ██║█████╗  █████╗  
185 ██║   ██║██╔══╝  ██╔══╝  
186 ╚██████╔╝██║     ██║     
187  ╚═════╝ ╚═╝     ╚═╝     
188 ]]
189
190
191 minetest.register_node("redstone:piston_off", {
192     description = "Piston",
193     tiles = {"redstone_piston.png","redstone_piston.png^[transformR180","redstone_piston.png^[transformR270","redstone_piston.png^[transformR90","wood.png","stone.png"},
194     paramtype2 = "facedir",
195     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1,redstone_activation=1},
196     sounds = main.stoneSound(),
197     drop = "redstone:piston_off",
198     paramtype = "light",
199         sunlight_propagates = true,
200         --reverse the direction to face the player
201         on_construct = function(pos)
202                 redstone.inject(pos,{
203                         name = "redstone:piston_off",
204                         activator = true,
205                 })
206                 redstone.update(pos)
207         end,
208         on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
209                 local look = clicker:get_look_dir()
210                 look = vector.multiply(look,-1)
211                 local dir = minetest.dir_to_facedir(look, true)
212                 minetest.swap_node(pos,{name="redstone:piston_off",param2=dir})
213         end,
214     after_place_node = function(pos, placer, itemstack, pointed_thing)
215                 local look = placer:get_look_dir()
216                 look = vector.multiply(look,-1)
217                 local dir = minetest.dir_to_facedir(look, true)
218                 minetest.swap_node(pos,{name="redstone:piston_off",param2=dir})
219         end,
220         after_destruct = function(pos, oldnode)
221                 redstone.inject(pos,nil)
222     end,
223 })
224
225
226 redstone.register_activator({
227         name = "redstone:piston_off",
228         activate = function(pos)
229                 minetest.after(0,function()
230                         actuator_arm_function(pos)
231                 end)
232         end
233 })
234
235 minetest.register_lbm({
236         name = "redstone:piston_off",
237         nodenames = {"redstone:piston_off"},
238         run_at_every_load = true,
239         action = function(pos)
240                 redstone.inject(pos,{
241                         name = "redstone:piston_off",
242                         activator = true,
243                 })
244                 --redstone needs to warm up
245                 minetest.after(0,function()
246                         redstone.update(pos)
247                 end)
248         end,
249 })
250
251
252 --[[
253  ██████╗ ███╗   ██╗
254 ██╔═══██╗████╗  ██║
255 ██║   ██║██╔██╗ ██║
256 ██║   ██║██║╚██╗██║
257 ╚██████╔╝██║ ╚████║
258  ╚═════╝ ╚═╝  ╚═══╝
259 ]]
260
261 minetest.register_node("redstone:piston_on", {
262     description = "Piston",
263     tiles = {"redstone_piston.png","redstone_piston.png^[transformR180","redstone_piston.png^[transformR270","redstone_piston.png^[transformR90","stone.png","stone.png"},
264     drawtype = "nodebox",
265     paramtype = "light",
266     paramtype2 = "facedir",
267     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1,redstone_activation=1},
268     sounds = main.stoneSound(),
269     drop = "redstone:piston_off",
270     node_box = {
271                 type = "fixed",
272                 fixed = {
273                                 --left front bottom right back top
274                                 {-0.5, -0.5,  -0.5, 0.5,  0.5, 3/16},
275                         },
276                 },
277     after_destruct = function(pos, oldnode)
278                 local facedir = oldnode.param2
279                 local dir = minetest.facedir_to_dir(facedir)
280                 local piston_location = vector.add(pos,dir)
281                 minetest.remove_node(piston_location)
282                 redstone.inject(pos,nil)
283     end,
284 })
285
286 minetest.register_lbm({
287         name = "redstone:piston_on",
288         nodenames = {"redstone:piston_on"},
289         run_at_every_load = true,
290         action = function(pos)
291                 redstone.inject(pos,{
292                         name = "redstone:piston_on",
293                         activator = true,
294                 })
295                 --redstone needs to warm up
296                 minetest.after(0,function()
297                         redstone.update(pos)
298                 end)
299         end,
300 })
301
302 redstone.register_activator({
303         name = "redstone:piston_on",
304         deactivate = function(pos)
305                 --this is where the piston deactivates
306                 local facedir = minetest.get_node(pos).param2
307                 local dir = minetest.facedir_to_dir(facedir)
308                 local piston_location = vector.add(pos,dir)
309                 minetest.remove_node(piston_location)
310                 minetest.swap_node(pos,{name="redstone:piston_off",param2=facedir})
311                 piston_location.y = piston_location.y + 1
312                 minetest.sound_play("piston", {pos=pos,pitch=math.random(85,100)/100})
313                 redstone.inject(pos,{
314                         name = "redstone:piston_off",
315                         activator = true,
316                 })
317         end
318 })
319
320
321 --[[
322  █████╗ ██████╗ ███╗   ███╗
323 ██╔══██╗██╔══██╗████╗ ████║
324 ███████║██████╔╝██╔████╔██║
325 ██╔══██║██╔══██╗██║╚██╔╝██║
326 ██║  ██║██║  ██║██║ ╚═╝ ██║
327 ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝     ╚═╝
328 ]]
329
330
331
332 minetest.register_node("redstone:actuator", {
333     description = "Piston Actuator",
334     tiles = {"wood.png"},
335     drawtype = "nodebox",
336     paramtype = "light",
337     paramtype2 = "facedir",
338     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1},
339     sounds = main.stoneSound(),
340     drop = "redstone:piston_off",
341     node_box = {
342                 type = "fixed",
343                 fixed = {
344                                 --left front bottom right back top
345                                 {-0.5, -0.5,  0.2, 0.5,  0.5, 0.5}, --mover
346                                 {-0.15, -0.15,  -0.9, 0.15,  0.15, 0.5}, --actuator
347                         },
348                 },
349         after_destruct = function(pos, oldnode)
350                 local facedir = oldnode.param2
351                 local dir = minetest.facedir_to_dir(facedir)
352                 dir = vector.multiply(dir,-1)
353                 local piston_location = vector.add(pos,dir)
354                 minetest.remove_node(piston_location)
355     end,
356 })
357
358
359
360
361
362 --[[
363 ███████╗████████╗██╗ ██████╗██╗  ██╗██╗   ██╗    ██████╗ ██╗███████╗████████╗ ██████╗ ███╗   ██╗    ██████╗ ███████╗ ██████╗ ██╗███╗   ██╗███████╗
364 ██╔════╝╚══██╔══╝██║██╔════╝██║ ██╔╝╚██╗ ██╔╝    ██╔══██╗██║██╔════╝╚══██╔══╝██╔═══██╗████╗  ██║    ██╔══██╗██╔════╝██╔════╝ ██║████╗  ██║██╔════╝
365 ███████╗   ██║   ██║██║     █████╔╝  ╚████╔╝     ██████╔╝██║███████╗   ██║   ██║   ██║██╔██╗ ██║    ██████╔╝█████╗  ██║  ███╗██║██╔██╗ ██║███████╗
366 ╚════██║   ██║   ██║██║     ██╔═██╗   ╚██╔╝      ██╔═══╝ ██║╚════██║   ██║   ██║   ██║██║╚██╗██║    ██╔══██╗██╔══╝  ██║   ██║██║██║╚██╗██║╚════██║
367 ███████║   ██║   ██║╚██████╗██║  ██╗   ██║       ██║     ██║███████║   ██║   ╚██████╔╝██║ ╚████║    ██████╔╝███████╗╚██████╔╝██║██║ ╚████║███████║
368 ╚══════╝   ╚═╝   ╚═╝ ╚═════╝╚═╝  ╚═╝   ╚═╝       ╚═╝     ╚═╝╚══════╝   ╚═╝    ╚═════╝ ╚═╝  ╚═══╝    ╚═════╝ ╚══════╝ ╚═════╝ ╚═╝╚═╝  ╚═══╝╚══════╝
369 ]]--
370
371
372
373
374
375
376
377 --[[
378 ███████╗██╗   ██╗███╗   ██╗ ██████╗████████╗██╗ ██████╗ ███╗   ██╗
379 ██╔════╝██║   ██║████╗  ██║██╔════╝╚══██╔══╝██║██╔═══██╗████╗  ██║
380 █████╗  ██║   ██║██╔██╗ ██║██║        ██║   ██║██║   ██║██╔██╗ ██║
381 ██╔══╝  ██║   ██║██║╚██╗██║██║        ██║   ██║██║   ██║██║╚██╗██║
382 ██║     ╚██████╔╝██║ ╚████║╚██████╗   ██║   ██║╚██████╔╝██║ ╚████║
383 ╚═╝      ╚═════╝ ╚═╝  ╚═══╝ ╚═════╝   ╚═╝   ╚═╝ ╚═════╝ ╚═╝  ╚═══╝
384 ]]
385
386
387 --this is how the piston pushes nodes
388 local move_index
389 local space
390 local index_pos
391 local node
392 local param2
393 local def
394 local push
395 local index
396 local function sticky_push_nodes(pos,dir)
397         move_index = {}
398         space = false
399         for i = 1,30 do
400                 index_pos = vector.add(vector.multiply(dir,i),pos)
401                 node = minetest.get_node(index_pos)
402                 param2 = node.param2
403                 def = minetest.registered_nodes[node.name]
404                 name = node.name
405                 push = ((excluded_mods[def.mod_origin] ~= true) and (excluded_nodes[name] ~= true))
406                 if push and name ~= "air" then
407                         index = {}
408                         index.pos = index_pos
409                         index.name = name
410                         index.param2 = param2
411                         table.insert(move_index,index)
412                 elseif name == "air" then
413                         space = true
414                         break
415                 else
416                         space = false
417                         break
418                 end             
419         end
420
421         --check if room to move and objects in log
422         if space == true and next(move_index) then
423                 for i = 1,table.getn(move_index) do
424                         move_index[i].pos = vector.add(move_index[i].pos,dir)
425                         minetest.set_node(move_index[i].pos,move_index[i])
426                         minetest.check_for_falling(move_index[i].pos)
427                 end
428         end
429         return(space)
430 end
431
432 --this is the logic of the piston
433 local facedir
434 local dir
435 local piston_location
436 local worked
437 local function sticky_actuator_arm_function(pos)
438         --this is where the piston activates
439         facedir = minetest.get_node(pos).param2
440         dir = minetest.facedir_to_dir(facedir)
441         piston_location = vector.add(pos,dir)
442         worked = sticky_push_nodes(pos,dir)
443         local node = minetest.get_node(vector.add(pos,dir)).name
444         
445         if worked == true then
446                 --push player
447                 if node == "air" then
448                         for _,object in ipairs(minetest.get_objects_inside_radius(piston_location, 2)) do
449
450                                 if object:is_player() and object:get_hp() > 0 then
451                                         local pos2 = object:get_pos()
452                                         local compare = vector.subtract(pos2,piston_location)
453                                         local real_y = compare.y
454                                         compare = vector.abs(compare)
455                                         --piston pointing up
456                                         if dir.y == 1 then
457                                                 if compare.y <= 0.5 and compare.x < 0.8 and compare.z < 0.8 then
458                                                         object:move_to(vector.add(dir,pos2))
459                                                 end
460                                         --piston sideways
461                                         elseif dir.x ~=0 or dir.z ~= 0 then
462                                                 if real_y <= 0.5 and real_y >= -1.6 and compare.x < 0.8 and compare.z < 0.8 then
463                                                         object:move_to(vector.add(dir,pos2))
464                                                 end
465                                         end
466                                 elseif not object:is_player() and object:get_luaentity().name == "__builtin:falling_node" then
467                                         local pos2 = object:get_pos()
468                                         local compare = vector.subtract(pos2,piston_location)
469                                         local real_y = compare.y
470                                         compare = vector.abs(compare)
471                                         if compare.y <= 1.5 and compare.x <= 1.5 and compare.z <= 1.5 then
472                                                 object:move_to(vector.add(dir,pos2))
473                                         end
474                                 elseif not object:is_player() and object:get_luaentity().name == "__builtin:item" then
475                                         local pos2 = object:get_pos()
476                                         local compare = vector.subtract(pos2,piston_location)
477                                         local real_y = compare.y
478                                         compare = vector.abs(compare)
479                                         if compare.y <= 1 and compare.x <= 1 and compare.z <= 1 then
480                                                 object:move_to(vector.add(dir,pos2))
481                                                 object:get_luaentity().poll_timer = 0
482                                         end
483                                 end
484                         end
485                 end
486                 minetest.sound_play("piston", {pos=pos,pitch=math.random(85,100)/100})
487                 minetest.set_node(piston_location,{name="redstone:sticky_actuator",param2=facedir})
488                 minetest.swap_node(pos,{name="redstone:sticky_piston_on",param2=facedir})
489
490                 redstone.inject(pos,{
491                         name = "redstone:sticky_piston_on",
492                         activator = true,
493                 })
494                 
495                 redstone.update(pos)
496         end
497 end
498
499
500 --[[
501  ██████╗ ███████╗███████╗
502 ██╔═══██╗██╔════╝██╔════╝
503 ██║   ██║█████╗  █████╗  
504 ██║   ██║██╔══╝  ██╔══╝  
505 ╚██████╔╝██║     ██║     
506  ╚═════╝ ╚═╝     ╚═╝     
507 ]]
508
509
510 minetest.register_node("redstone:sticky_piston_off", {
511     description = "Sticky Piston",
512     tiles = {"redstone_piston.png","redstone_piston.png^[transformR180","redstone_piston.png^[transformR270","redstone_piston.png^[transformR90","sticky_piston.png","stone.png"},
513     paramtype2 = "facedir",
514     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1,redstone_activation=1},
515     sounds = main.stoneSound(),
516     drop = "redstone:sticky_piston_off",
517     paramtype = "light",
518         sunlight_propagates = true,
519         on_construct = function(pos)
520                 redstone.inject(pos,{
521                         name = "redstone:sticky_piston_off",
522                         activator = true,
523                 })
524                 redstone.update(pos)
525         end,
526         on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
527                 local look = clicker:get_look_dir()
528                 look = vector.multiply(look,-1)
529                 local dir = minetest.dir_to_facedir(look, true)
530                 minetest.swap_node(pos,{name="redstone:sticky_piston_off",param2=dir})
531         end,
532     --reverse the direction to face the player
533     after_place_node = function(pos, placer, itemstack, pointed_thing)
534                 local look = placer:get_look_dir()
535                 look = vector.multiply(look,-1)
536                 local dir = minetest.dir_to_facedir(look, true)
537                 minetest.swap_node(pos,{name="redstone:sticky_piston_off",param2=dir})
538         end,
539         after_destruct = function(pos, oldnode)
540                 redstone.inject(pos,nil)
541     end,
542 })
543
544
545 redstone.register_activator({
546         name = "redstone:sticky_piston_off",
547         activate = function(pos)
548                 minetest.after(0,function()
549                         sticky_actuator_arm_function(pos)
550                 end)
551         end
552 })
553
554 minetest.register_lbm({
555         name = "redstone:sticky_piston_off",
556         nodenames = {"redstone:sticky_piston_off"},
557         run_at_every_load = true,
558         action = function(pos)
559                 redstone.inject(pos,{
560                         name = "redstone:sticky_piston_off",
561                         activator = true,
562                 })
563                 --redstone needs to warm up
564                 minetest.after(0,function()
565                         redstone.update(pos)
566                 end)
567         end,
568 })
569
570
571 --[[
572  ██████╗ ███╗   ██╗
573 ██╔═══██╗████╗  ██║
574 ██║   ██║██╔██╗ ██║
575 ██║   ██║██║╚██╗██║
576 ╚██████╔╝██║ ╚████║
577  ╚═════╝ ╚═╝  ╚═══╝
578 ]]
579
580 local function sticky_piston_pull_nodes(pos,dir)
581         local move_index = {}
582         local index_pos = vector.add(pos,dir)
583         
584         local node = minetest.get_node(index_pos)
585         local param2 = node.param2
586         local def = minetest.registered_nodes[node.name]
587         local name = node.name
588         local pull = ((excluded_mods[def.mod_origin] ~= true) and (excluded_nodes[name] ~= true))
589         --if it can be pulled pull it
590         if pull and name ~= "air" then
591                 minetest.remove_node(index_pos)
592                 minetest.set_node(pos,{name=name,param2=param2})
593                 minetest.check_for_falling(index_pos)
594         end
595 end
596
597
598
599
600 minetest.register_node("redstone:sticky_piston_on", {
601     description = "Sticky Piston",
602     tiles = {"redstone_piston.png","redstone_piston.png^[transformR180","redstone_piston.png^[transformR270","redstone_piston.png^[transformR90","stone.png","stone.png"},
603     drawtype = "nodebox",
604     paramtype = "light",
605     paramtype2 = "facedir",
606     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1,redstone_activation=1},
607     sounds = main.stoneSound(),
608     drop = "redstone:sticky_piston_off",
609     node_box = {
610                 type = "fixed",
611                 fixed = {
612                                 --left front bottom right back top
613                                 {-0.5, -0.5,  -0.5, 0.5,  0.5, 3/16},
614                         },
615                 },
616     after_destruct = function(pos, oldnode)
617                 local facedir = oldnode.param2
618                 local dir = minetest.facedir_to_dir(facedir)
619                 local piston_location = vector.add(pos,dir)
620                 minetest.remove_node(piston_location)
621                 redstone.inject(pos,nil)
622     end,
623 })
624
625 minetest.register_lbm({
626         name = "redstone:sticky_piston_on",
627         nodenames = {"redstone:sticky_piston_on"},
628         run_at_every_load = true,
629         action = function(pos)
630                 redstone.inject(pos,{
631                         name = "redstone:sticky_piston_on",
632                         activator = true,
633                 })
634                 --redstone needs to warm up
635                 minetest.after(0,function()
636                         redstone.update(pos)
637                 end)
638         end,
639 })
640
641 redstone.register_activator({
642         name = "redstone:sticky_piston_on",
643         deactivate = function(pos)
644                 --this is where the piston deactivates
645                 local facedir = minetest.get_node(pos).param2
646                 local dir = minetest.facedir_to_dir(facedir)
647                 local piston_location = vector.add(pos,dir)
648                 
649                 minetest.remove_node(piston_location)
650
651                 sticky_piston_pull_nodes(piston_location,dir)
652                 minetest.swap_node(pos,{name="redstone:sticky_piston_off",param2=facedir})
653
654                 minetest.sound_play("piston", {pos=pos,pitch=math.random(85,100)/100})
655                 redstone.inject(pos,{
656                         name = "redstone:sticky_piston_off",
657                         activator = true,
658                 })
659         end
660 })
661
662
663 --[[
664  █████╗ ██████╗ ███╗   ███╗
665 ██╔══██╗██╔══██╗████╗ ████║
666 ███████║██████╔╝██╔████╔██║
667 ██╔══██║██╔══██╗██║╚██╔╝██║
668 ██║  ██║██║  ██║██║ ╚═╝ ██║
669 ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝     ╚═╝
670 ]]
671
672
673
674 minetest.register_node("redstone:sticky_actuator", {
675     description = "Piston Actuator",
676     tiles = {"wood.png","wood.png","wood.png","wood.png","sticky_piston.png","wood.png"},
677     drawtype = "nodebox",
678     paramtype = "light",
679     paramtype2 = "facedir",
680     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1},
681     sounds = main.stoneSound(),
682     drop = "redstone:piston_off",
683     node_box = {
684                 type = "fixed",
685                 fixed = {
686                                 --left front bottom right back top
687                                 {-0.5, -0.5,  0.2, 0.5,  0.5, 0.5}, --mover
688                                 {-0.15, -0.15,  -0.9, 0.15,  0.15, 0.5}, --actuator
689                         },
690                 },
691         after_destruct = function(pos, oldnode)
692                 local facedir = oldnode.param2
693                 local dir = minetest.facedir_to_dir(facedir)
694                 dir = vector.multiply(dir,-1)
695                 local piston_location = vector.add(pos,dir)
696                 minetest.remove_node(piston_location)
697     end,
698 })
699