]> git.lizzy.rs Git - Crafter.git/blob - mods/redstone/piston.lua
Add additional check to lights on place
[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                                 print("trying")
89                                 move_index[i].pos = vector.add(move_index[i].pos,dir)
90                                 minetest.set_node(move_index[i].pos,{name="air"})
91
92                                 local obj = minetest.add_entity(vector.add(move_index[i].pos,dir), "__builtin:falling_node")
93                                 obj:get_luaentity():set_node({name=move_index[i].name})
94                                 obj:set_velocity(vector.multiply(dir,19))
95                         end
96                 else
97                         for i = 1,table.getn(move_index) do
98                                 move_index[i].pos = vector.add(move_index[i].pos,dir)
99                                 minetest.set_node(move_index[i].pos,move_index[i])
100                                 minetest.check_for_falling(move_index[i].pos)
101                         end
102                 end
103         end
104         return(space)
105 end
106
107 --this is the logic of the piston
108 local facedir
109 local dir
110 local piston_location
111 local worked
112 local function actuator_arm_function(pos)
113         --this is where the piston activates
114         facedir = minetest.get_node(pos).param2
115         dir = minetest.facedir_to_dir(facedir)
116         piston_location = vector.add(pos,dir)
117         worked = push_nodes(pos,dir)
118         local node = minetest.get_node(vector.add(pos,dir)).name
119         
120         if worked == true then
121                 --push player
122                 if node == "air" then
123                         for _,object in ipairs(minetest.get_objects_inside_radius(piston_location, 2)) do
124
125                                 if object:is_player() and object:get_hp() > 0 then
126                                         local pos2 = object:get_pos()
127                                         local compare = vector.subtract(pos2,piston_location)
128                                         local real_y = compare.y
129                                         compare = vector.abs(compare)
130                                         --piston pointing up
131                                         if dir.y == 1 then
132                                                 if compare.y <= 0.5 and compare.x < 0.8 and compare.z < 0.8 then
133                                                         object:move_to(vector.add(dir,pos2))
134                                                         object:add_player_velocity(vector.multiply(dir,20))
135                                                 end
136                                         --piston sideways
137                                         elseif dir.x ~=0 or dir.z ~= 0 then
138                                                 if real_y <= 0.5 and real_y >= -1.6 and compare.x < 0.8 and compare.z < 0.8 then
139                                                         object:move_to(vector.add(dir,pos2))
140                                                         object:add_player_velocity(vector.multiply(dir,19))
141                                                 end
142                                         end
143                                 elseif not object:is_player() and object:get_luaentity().name == "__builtin:falling_node" then
144                                         local pos2 = object:get_pos()
145                                         local compare = vector.subtract(pos2,piston_location)
146                                         local real_y = compare.y
147                                         compare = vector.abs(compare)
148                                         if compare.y <= 1.5 and compare.x <= 1.5 and compare.z <= 1.5 then
149                                                 object:move_to(vector.add(dir,pos2))
150                                                 object:add_velocity(vector.multiply(dir,20))
151                                         end
152                                 elseif not object:is_player() and object:get_luaentity().name == "__builtin:item" then
153                                         local pos2 = object:get_pos()
154                                         local compare = vector.subtract(pos2,piston_location)
155                                         local real_y = compare.y
156                                         compare = vector.abs(compare)
157                                         if compare.y <= 1 and compare.x <= 1 and compare.z <= 1 then
158                                                 object:move_to(vector.add(dir,pos2))
159                                                 object:add_velocity(vector.multiply(dir,20))
160                                                 object:get_luaentity().poll_timer = 0
161                                         end
162                                 end
163                         end
164                 end
165                 minetest.sound_play("piston", {pos=pos,pitch=math.random(85,100)/100})
166                 minetest.set_node(piston_location,{name="redstone:actuator",param2=facedir})
167                 minetest.swap_node(pos,{name="redstone:piston_on",param2=facedir})
168
169                 redstone.inject(pos,{
170                         name = "redstone:piston_on",
171                         activator = true,
172                 })
173                 minetest.after(0,function()
174                         redstone.update(pos)
175                 end)
176         end
177 end
178
179
180 --[[
181  ██████╗ ███████╗███████╗
182 ██╔═══██╗██╔════╝██╔════╝
183 ██║   ██║█████╗  █████╗  
184 ██║   ██║██╔══╝  ██╔══╝  
185 ╚██████╔╝██║     ██║     
186  ╚═════╝ ╚═╝     ╚═╝     
187 ]]
188
189
190 minetest.register_node("redstone:piston_off", {
191     description = "Piston",
192     tiles = {"redstone_piston.png","redstone_piston.png^[transformR180","redstone_piston.png^[transformR270","redstone_piston.png^[transformR90","wood.png","stone.png"},
193     paramtype2 = "facedir",
194     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1,redstone_activation=1},
195     sounds = main.stoneSound(),
196     drop = "redstone:piston_off",
197     paramtype = "light",
198         sunlight_propagates = true,
199     --reverse the direction to face the player
200     after_place_node = function(pos, placer, itemstack, pointed_thing)
201                 local look = placer:get_look_dir()
202                 look = vector.multiply(look,-1)
203                 local dir = minetest.dir_to_facedir(look, true)
204                 minetest.swap_node(pos,{name="redstone:piston_off",param2=dir})
205                 redstone.inject(pos,{
206                         name = "redstone:piston_off",
207                         activator = true,
208                 })
209                 redstone.update(pos)
210         end,
211         after_destruct = function(pos, oldnode)
212                 redstone.inject(pos,nil)
213     end,
214 })
215
216
217 redstone.register_activator({
218         name = "redstone:piston_off",
219         activate = function(pos)
220                 actuator_arm_function(pos)
221         end
222 })
223
224 minetest.register_lbm({
225         name = "redstone:piston_off",
226         nodenames = {"redstone:piston_off"},
227         run_at_every_load = true,
228         action = function(pos)
229                 redstone.inject(pos,{
230                         name = "redstone:piston_off",
231                         activator = true,
232                 })
233                 minetest.after(0,function()
234                         redstone.update(pos)
235                 end)
236         end,
237 })
238
239
240 --[[
241  ██████╗ ███╗   ██╗
242 ██╔═══██╗████╗  ██║
243 ██║   ██║██╔██╗ ██║
244 ██║   ██║██║╚██╗██║
245 ╚██████╔╝██║ ╚████║
246  ╚═════╝ ╚═╝  ╚═══╝
247 ]]
248
249 minetest.register_node("redstone:piston_on", {
250     description = "Piston",
251     tiles = {"redstone_piston.png","redstone_piston.png^[transformR180","redstone_piston.png^[transformR270","redstone_piston.png^[transformR90","stone.png","stone.png"},
252     drawtype = "nodebox",
253     paramtype = "light",
254     paramtype2 = "facedir",
255     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1,redstone_activation=1},
256     sounds = main.stoneSound(),
257     drop = "redstone:piston_off",
258     node_box = {
259                 type = "fixed",
260                 fixed = {
261                                 --left front bottom right back top
262                                 {-0.5, -0.5,  -0.5, 0.5,  0.5, 3/16},
263                         },
264                 },
265     after_destruct = function(pos, oldnode)
266                 local facedir = oldnode.param2
267                 local dir = minetest.facedir_to_dir(facedir)
268                 local piston_location = vector.add(pos,dir)
269                 minetest.remove_node(piston_location)
270                 redstone.inject(pos,nil)
271     end,
272 })
273
274 minetest.register_lbm({
275         name = "redstone:piston_on",
276         nodenames = {"redstone:piston_on"},
277         run_at_every_load = true,
278         action = function(pos)
279                 redstone.inject(pos,{
280                         name = "redstone:piston_on",
281                         activator = true,
282                 })
283                 minetest.after(0,function()
284                         redstone.update(pos)
285                 end)
286         end,
287 })
288
289 redstone.register_activator({
290         name = "redstone:piston_on",
291         deactivate = function(pos)
292                 --this is where the piston deactivates
293                 local facedir = minetest.get_node(pos).param2
294                 local dir = minetest.facedir_to_dir(facedir)
295                 local piston_location = vector.add(pos,dir)
296                 minetest.remove_node(piston_location)
297                 minetest.swap_node(pos,{name="redstone:piston_off",param2=facedir})
298                 piston_location.y = piston_location.y + 1
299                 minetest.sound_play("piston", {pos=pos,pitch=math.random(85,100)/100})
300                 redstone.inject(pos,{
301                         name = "redstone:piston_off",
302                         activator = true,
303                 })
304         end
305 })
306
307
308 --[[
309  █████╗ ██████╗ ███╗   ███╗
310 ██╔══██╗██╔══██╗████╗ ████║
311 ███████║██████╔╝██╔████╔██║
312 ██╔══██║██╔══██╗██║╚██╔╝██║
313 ██║  ██║██║  ██║██║ ╚═╝ ██║
314 ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝     ╚═╝
315 ]]
316
317
318
319 minetest.register_node("redstone:actuator", {
320     description = "Piston Actuator",
321     tiles = {"wood.png"},
322     drawtype = "nodebox",
323     paramtype = "light",
324     paramtype2 = "facedir",
325     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1},
326     sounds = main.stoneSound(),
327     drop = "redstone:piston_off",
328     node_box = {
329                 type = "fixed",
330                 fixed = {
331                                 --left front bottom right back top
332                                 {-0.5, -0.5,  0.2, 0.5,  0.5, 0.5}, --mover
333                                 {-0.15, -0.15,  -0.9, 0.15,  0.15, 0.5}, --actuator
334                         },
335                 },
336         after_destruct = function(pos, oldnode)
337                 local facedir = oldnode.param2
338                 local dir = minetest.facedir_to_dir(facedir)
339                 dir = vector.multiply(dir,-1)
340                 local piston_location = vector.add(pos,dir)
341                 minetest.remove_node(piston_location)
342     end,
343 })
344
345 --[[
346 -------------------------------------------------------------------------------------------------------------------------------------------------------
347 --this is how the piston pushes nodes
348 local function sticky_piston_push_nodes(pos,dir)
349         local move_index = {}
350         local space = false
351         for i = 1,30 do
352                 local index_pos = vector.multiply(dir,i)
353                 local index_pos = vector.add(index_pos,pos)
354                 local node = minetest.get_node(index_pos)
355                 local param2 = node.param2
356                 local def = minetest.registered_nodes[node.name]
357                 local name = node.name
358                 local push = ((excluded_mods[def.mod_origin] ~= true) and (excluded_nodes[name] ~= true))
359                 if push and name ~= "air" then
360                         local index = {}
361                         index.pos = index_pos
362                         index.name = name
363                         index.param2 = param2
364                         table.insert(move_index,index)
365                 elseif name == "air" then
366                         space = true
367                         break
368                 else
369                         space = false
370                         break
371                 end             
372         end
373         --check if room to move and objects in log
374         if space == true and next(move_index) then
375                 for i = 1,table.getn(move_index) do
376                         move_index[i].pos = vector.add(move_index[i].pos,dir)
377                         minetest.set_node(move_index[i].pos,{name=move_index[i].name,param2=move_index[i].param2})
378                 end
379         end
380         return(space)
381 end
382
383 --this is the logic of the piston
384 local function sticky_piston_push(pos)
385         --this is where the piston activates
386         local facedir = minetest.get_node(pos).param2
387         local dir = minetest.facedir_to_dir(facedir)
388         local piston_location = vector.add(pos,dir)
389         local worked = sticky_piston_push_nodes(pos,dir)
390         local node = minetest.get_node(vector.add(pos,dir)).name
391         if worked == true then
392                 --push player
393                 if node == "air" then
394                         for _,object in ipairs(minetest.get_objects_inside_radius(piston_location, 2)) do
395                                 if object:is_player() and object:get_hp() > 0 then
396                                         local pos2 = object:get_pos()
397                                         local compare = vector.subtract(pos2,piston_location)
398                                         local real_y = compare.y
399                                         compare = vector.abs(compare)
400                                         --piston pointing up
401                                         if dir.y == 1 then
402                                                 if compare.y <= 0.5 and compare.x < 0.8 and compare.z < 0.8 then
403                                                         object:move_to(vector.add(dir,pos2))
404                                                         --object:add_player_velocity(vector.multiply(dir,20))
405                                                 end
406                                         --piston sideways
407                                         elseif dir.x ~=0 or dir.z ~= 0 then
408                                                 if real_y <= 0.5 and real_y >= -1.6 and compare.x < 0.8 and compare.z < 0.8 then
409                                                         object:move_to(vector.add(dir,pos2))
410                                                         --object:add_player_velocity(vector.multiply(dir,20))
411                                                 
412                                                 end
413                                         end
414                                 end
415                         end
416                 end
417                 minetest.sound_play("piston", {pos=pos,pitch=math.random(85,100)/100})
418                 minetest.set_node(piston_location,{name="redstone:sticky_actuator",param2=facedir})
419                 minetest.set_node(pos,{name="redstone:sticky_piston_on",param2=facedir})
420         end
421 end
422
423
424
425 --this is how sticky pistons pull nodes
426 local function sticky_piston_pull_nodes(pos,dir)
427         
428         local move_index = {}
429         local index_pos = vector.add(pos,dir)
430         
431         local node = minetest.get_node(index_pos)
432         local param2 = node.param2
433         local def = minetest.registered_nodes[node.name]
434         local name = node.name
435         local pull = ((excluded_mods[def.mod_origin] ~= true) and (excluded_nodes[name] ~= true))
436         --if it can be pulled pull it
437         if pull and name ~= "air" then
438                 minetest.remove_node(index_pos)
439                 minetest.set_node(pos,{name=name,param2=param2})
440         end
441 end
442
443 ------------------------------[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
444
445 --this is the logic of the sticky piston on return
446 local function sticky_piston_pull(pos,dir)
447         --this is where the piston activates
448         --local facedir = minetest.get_node(pos).param2
449         --local dir = minetest.facedir_to_dir(facedir)
450         --local piston_location = vector.add(pos,dir)
451         
452         local in_front_pos = vector.add(pos,dir)
453         
454         local node = minetest.get_node(in_front_pos).name
455         --pull nodes
456         sticky_piston_pull_nodes(pos,dir)
457         
458         --pull player
459         if node == "air" then
460                 for _,object in ipairs(minetest.get_objects_inside_radius(in_front_pos, 2)) do
461                         if object:is_player() and object:get_hp() > 0 then
462                                 local pos2 = object:get_pos()
463                                 local compare = vector.subtract(pos2,in_front_pos)
464                                 local real_y = compare.y
465                                 compare = vector.abs(compare)
466                                 --piston pointing up
467                                 if dir.y == 1 then
468                                         if compare.y <= 0.5 and compare.x < 0.8 and compare.z < 0.8 then
469                                                 dir = vector.multiply(dir,-1)
470                                                 object:move_to(vector.add(dir,pos2))
471                                                 --object:add_player_velocity(vector.multiply(dir,20))
472                                         end
473                                 --piston sideways
474                                 elseif dir.x ~=0 or dir.z ~= 0 then
475                                         if real_y <= 0.5 and real_y >= -1.6 and compare.x < 0.8 and compare.z < 0.8 then
476                                                 dir = vector.multiply(dir,-1)
477                                                 object:move_to(vector.add(dir,pos2))
478                                                 --object:add_player_velocity(vector.multiply(dir,20))
479                                         
480                                         end
481                                 end
482                         end
483                 end
484         end
485         minetest.sound_play("piston", {pos=pos,pitch=math.random(85,100)/100})
486         --minetest.set_node(piston_location,{name="redstone:sticky_actuator",param2=facedir})
487         --minetest.set_node(pos,{name="redstone:sticky_piston_on",param2=facedir})
488 end
489
490 ------------------------------[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
491
492 minetest.register_node("redstone:sticky_piston_off", {
493     description = "Sticky Piston",
494     tiles = {"redstone_piston.png","redstone_piston.png^[transformR180","redstone_piston.png^[transformR270","redstone_piston.png^[transformR90","sticky_piston.png","stone.png"},
495     paramtype2 = "facedir",
496     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1,redstone_activation=1},
497     sounds = main.stoneSound(),
498     drop = "redstone:sticky_piston_off",
499     paramtype = "light",
500     sunlight_propagates = true,
501     redstone_activation = function(pos)
502                 if minetest.get_node(pos).name == "redstone:sticky_piston_off" then
503                         sticky_piston_push(pos)
504                 end
505     end,
506     --reverse the direction to face the player
507     after_place_node = function(pos, placer, itemstack, pointed_thing)
508                 local look = placer:get_look_dir()
509                 look = vector.multiply(look,-1)
510                 local dir = minetest.dir_to_facedir(look, true)
511                 minetest.set_node(pos,{name="redstone:sticky_piston_off",param2=dir})
512                 redstone.collect_info(pos)
513     end,
514 })
515
516
517 --------------------------
518
519
520 minetest.register_node("redstone:sticky_piston_on", {
521     description = "Sticky Piston",
522     tiles = {"redstone_piston.png","redstone_piston.png^[transformR180","redstone_piston.png^[transformR270","redstone_piston.png^[transformR90","stone.png","stone.png"},
523     drawtype = "nodebox",
524     paramtype = "light",
525     paramtype2 = "facedir",
526     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1,redstone_activation=1},
527     sounds = main.stoneSound(),
528     drop = "redstone:sticky_piston_off",
529     node_box = {
530                 type = "fixed",
531                 fixed = {
532                                 --left front bottom right back top
533                                 {-0.5, -0.5,  -0.5, 0.5,  0.5, 3/16},
534                         },
535                 },
536     redstone_deactivation = function(pos)
537                 --this is where the piston deactivates
538                 local facedir = minetest.get_node(pos).param2
539                 local dir = minetest.facedir_to_dir(facedir)
540                 local piston_location = vector.add(pos,dir)
541                 minetest.remove_node(piston_location)
542                 minetest.set_node(pos,{name="redstone:sticky_piston_off",param2=facedir})
543                 
544                 sticky_piston_pull(piston_location,dir)
545                 
546                 piston_location.y = piston_location.y + 1
547                 minetest.punch_node(piston_location)
548                 --minetest.sound_play("piston", {pos=pos,pitch=math.random(85,100)/100})
549     end,
550     after_dig_node = function(pos, oldnode, oldmetadata, digger)
551                 local facedir = oldnode.param2
552                 local dir = minetest.facedir_to_dir(facedir)
553                 local piston_location = vector.add(pos,dir)
554                 minetest.remove_node(piston_location)
555     end,
556 })
557
558 minetest.register_node("redstone:sticky_actuator", {
559     description = "Redstone Piston",
560     tiles = {"wood.png","wood.png","wood.png","wood.png","sticky_piston.png","wood.png"},
561     drawtype = "nodebox",
562     paramtype = "light",
563     paramtype2 = "facedir",
564     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1},
565     sounds = main.stoneSound(),
566     drop = "redstone:sticky_piston_off",
567     node_box = {
568                 type = "fixed",
569                 fixed = {
570                                 --left front bottom right back top
571                                 {-0.5, -0.5,  0.2, 0.5,  0.5, 0.5}, --mover
572                                 {-0.15, -0.15,  -0.9, 0.15,  0.15, 0.5}, --actuator
573                         },
574                 },
575         after_dig_node = function(pos, oldnode, oldmetadata, digger)
576                 local facedir = oldnode.param2
577                 local dir = minetest.facedir_to_dir(facedir)
578                 dir = vector.multiply(dir,-1)
579                 local piston_location = vector.add(pos,dir)
580                 minetest.remove_node(piston_location)
581     end,
582 })
583 ]]--
584