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