]> git.lizzy.rs Git - Crafter.git/blob - mods/redstone/piston.lua
Stop player from dropping when they teleport through portals
[Crafter.git] / mods / redstone / piston.lua
1 --exclude certain mods and nodes from being pushed and pulled to stop glitches
2 local excluded_mods = {utility=true,craftingtable=true,buildtest=true,sign=true,bed=true}
3 local excluded_nodes = {["redstone:piston_on"]=true,["redstone:sticky_piston_on"]=true,["redstone:actuator"]=true,["redstone:sticky_actuator"]=true}
4
5 --this is how the piston pushes nodes
6 local function piston_push_nodes(pos,dir)
7         local move_index = {}
8         local space = false
9         for i = 1,30 do
10                 local index_pos = vector.multiply(dir,i)
11                 local index_pos = vector.add(index_pos,pos)
12                 local node = minetest.get_node(index_pos)
13                 local param2 = node.param2
14                 local def = minetest.registered_nodes[node.name]
15                 local name = node.name
16                 local push = ((excluded_mods[def.mod_origin] ~= true) and (excluded_nodes[name] ~= true))
17                 if push and name ~= "air" then
18                         local index = {}
19                         index.pos = index_pos
20                         index.name = name
21                         index.param2 = param2
22                         table.insert(move_index,index)
23                 elseif name == "air" then
24                         space = true
25                         break
26                 else
27                         space = false
28                         break
29                 end             
30         end
31         --check if room to move and objects in log
32         if space == true and next(move_index) then
33                 for i = 1,table.getn(move_index) do
34                         move_index[i].pos = vector.add(move_index[i].pos,dir)
35                         minetest.set_node(move_index[i].pos,{name=move_index[i].name,param2=move_index[i].param2})
36                 end
37         end
38         return(space)
39 end
40
41 --this is the logic of the piston
42 local function piston_push(pos)
43         --this is where the piston activates
44         local facedir = minetest.get_node(pos).param2
45         local dir = minetest.facedir_to_dir(facedir)
46         local piston_location = vector.add(pos,dir)
47         local worked = piston_push_nodes(pos,dir)
48         local node = minetest.get_node(vector.add(pos,dir)).name
49         if worked == true then
50                 --push player
51                 if node == "air" then
52                         for _,object in ipairs(minetest.get_objects_inside_radius(piston_location, 2)) do
53                                 if object:is_player() and object:get_hp() > 0 then
54                                         local pos2 = object:get_pos()
55                                         local compare = vector.subtract(pos2,piston_location)
56                                         local real_y = compare.y
57                                         compare = vector.abs(compare)
58                                         --piston pointing up
59                                         if dir.y == 1 then
60                                                 if compare.y <= 0.5 and compare.x < 0.8 and compare.z < 0.8 then
61                                                         object:move_to(vector.add(dir,pos2))
62                                                         object:add_player_velocity(vector.multiply(dir,20))
63                                                 end
64                                         --piston sideways
65                                         elseif dir.x ~=0 or dir.z ~= 0 then
66                                                 if real_y <= 0.5 and real_y >= -1.6 and compare.x < 0.8 and compare.z < 0.8 then
67                                                         object:move_to(vector.add(dir,pos2))
68                                                         object:add_player_velocity(vector.multiply(dir,20))
69                                                 
70                                                 end
71                                         end
72                                 end
73                         end
74                 end
75                 minetest.sound_play("piston", {pos=pos,pitch=math.random(85,100)/100})
76                 minetest.set_node(piston_location,{name="redstone:actuator",param2=facedir})
77                 minetest.set_node(pos,{name="redstone:piston_on",param2=facedir})
78         end
79 end
80
81
82 minetest.register_node("redstone:piston_off", {
83     description = "Piston",
84     tiles = {"redstone_piston.png","redstone_piston.png^[transformR180","redstone_piston.png^[transformR270","redstone_piston.png^[transformR90","wood.png","stone.png"},
85     paramtype2 = "facedir",
86     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1,redstone_activation=1},
87     sounds = main.stoneSound(),
88     drop = "redstone:piston_off",
89     paramtype = "light",
90     sunlight_propagates = true,
91     redstone_activation = function(pos)
92                 if minetest.get_node(pos).name == "redstone:piston_off" then
93                         piston_push(pos)
94                 end
95     end,
96     --reverse the direction to face the player
97     after_place_node = function(pos, placer, itemstack, pointed_thing)
98                 local look = placer:get_look_dir()
99                 look = vector.multiply(look,-1)
100                 dir = minetest.dir_to_facedir(look, true)
101                 minetest.set_node(pos,{name="redstone:piston_off",param2=dir})
102                 redstone.collect_info(pos)
103     end,
104 })
105 minetest.register_node("redstone:piston_on", {
106     description = "Piston",
107     tiles = {"redstone_piston.png","redstone_piston.png^[transformR180","redstone_piston.png^[transformR270","redstone_piston.png^[transformR90","stone.png","stone.png"},
108     drawtype = "nodebox",
109     paramtype = "light",
110     paramtype2 = "facedir",
111     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1,redstone_activation=1},
112     sounds = main.stoneSound(),
113     drop = "redstone:piston_off",
114     node_box = {
115                 type = "fixed",
116                 fixed = {
117                                 --left front bottom right back top
118                                 {-0.5, -0.5,  -0.5, 0.5,  0.5, 3/16},
119                         },
120                 },
121     redstone_deactivation = function(pos)
122                 --this is where the piston deactivates
123                 local facedir = minetest.get_node(pos).param2
124                 local dir = minetest.facedir_to_dir(facedir)
125                 local piston_location = vector.add(pos,dir)
126                 minetest.remove_node(piston_location)
127                 minetest.set_node(pos,{name="redstone:piston_off",param2=facedir})
128                 piston_location.y = piston_location.y + 1
129                 minetest.punch_node(piston_location)
130                 minetest.sound_play("piston", {pos=pos,pitch=math.random(85,100)/100})
131     end,
132     after_dig_node = function(pos, oldnode, oldmetadata, digger)
133                 local facedir = oldnode.param2
134                 local dir = minetest.facedir_to_dir(facedir)
135                 local piston_location = vector.add(pos,dir)
136                 minetest.remove_node(piston_location)
137     end,
138 })
139
140 minetest.register_node("redstone:actuator", {
141     description = "Piston Actuator",
142     tiles = {"wood.png"},
143     drawtype = "nodebox",
144     paramtype = "light",
145     paramtype2 = "facedir",
146     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1},
147     sounds = main.stoneSound(),
148     drop = "redstone:piston_off",
149     node_box = {
150                 type = "fixed",
151                 fixed = {
152                                 --left front bottom right back top
153                                 {-0.5, -0.5,  0.2, 0.5,  0.5, 0.5}, --mover
154                                 {-0.15, -0.15,  -0.9, 0.15,  0.15, 0.5}, --actuator
155                         },
156                 },
157         after_dig_node = function(pos, oldnode, oldmetadata, digger)
158                 local facedir = oldnode.param2
159                 local dir = minetest.facedir_to_dir(facedir)
160                 dir = vector.multiply(dir,-1)
161                 local piston_location = vector.add(pos,dir)
162                 minetest.remove_node(piston_location)
163     end,
164 })
165
166 -------------------------------------------------------------------------------------------------------------------------------------------------------
167 --this is how the piston pushes nodes
168 local function sticky_piston_push_nodes(pos,dir)
169         local move_index = {}
170         local space = false
171         for i = 1,30 do
172                 local index_pos = vector.multiply(dir,i)
173                 local index_pos = vector.add(index_pos,pos)
174                 local node = minetest.get_node(index_pos)
175                 local param2 = node.param2
176                 local def = minetest.registered_nodes[node.name]
177                 local name = node.name
178                 local push = ((excluded_mods[def.mod_origin] ~= true) and (excluded_nodes[name] ~= true))
179                 if push and name ~= "air" then
180                         local index = {}
181                         index.pos = index_pos
182                         index.name = name
183                         index.param2 = param2
184                         table.insert(move_index,index)
185                 elseif name == "air" then
186                         space = true
187                         break
188                 else
189                         space = false
190                         break
191                 end             
192         end
193         --check if room to move and objects in log
194         if space == true and next(move_index) then
195                 for i = 1,table.getn(move_index) do
196                         move_index[i].pos = vector.add(move_index[i].pos,dir)
197                         minetest.set_node(move_index[i].pos,{name=move_index[i].name,param2=move_index[i].param2})
198                 end
199         end
200         return(space)
201 end
202
203 --this is the logic of the piston
204 local function sticky_piston_push(pos)
205         --this is where the piston activates
206         local facedir = minetest.get_node(pos).param2
207         local dir = minetest.facedir_to_dir(facedir)
208         local piston_location = vector.add(pos,dir)
209         local worked = sticky_piston_push_nodes(pos,dir)
210         local node = minetest.get_node(vector.add(pos,dir)).name
211         if worked == true then
212                 --push player
213                 if node == "air" then
214                         for _,object in ipairs(minetest.get_objects_inside_radius(piston_location, 2)) do
215                                 if object:is_player() and object:get_hp() > 0 then
216                                         local pos2 = object:get_pos()
217                                         local compare = vector.subtract(pos2,piston_location)
218                                         local real_y = compare.y
219                                         compare = vector.abs(compare)
220                                         --piston pointing up
221                                         if dir.y == 1 then
222                                                 if compare.y <= 0.5 and compare.x < 0.8 and compare.z < 0.8 then
223                                                         object:move_to(vector.add(dir,pos2))
224                                                         --object:add_player_velocity(vector.multiply(dir,20))
225                                                 end
226                                         --piston sideways
227                                         elseif dir.x ~=0 or dir.z ~= 0 then
228                                                 if real_y <= 0.5 and real_y >= -1.6 and compare.x < 0.8 and compare.z < 0.8 then
229                                                         object:move_to(vector.add(dir,pos2))
230                                                         --object:add_player_velocity(vector.multiply(dir,20))
231                                                 
232                                                 end
233                                         end
234                                 end
235                         end
236                 end
237                 minetest.sound_play("piston", {pos=pos,pitch=math.random(85,100)/100})
238                 minetest.set_node(piston_location,{name="redstone:sticky_actuator",param2=facedir})
239                 minetest.set_node(pos,{name="redstone:sticky_piston_on",param2=facedir})
240         end
241 end
242
243
244
245 --this is how sticky pistons pull nodes
246 local function sticky_piston_pull_nodes(pos,dir)
247         
248         local move_index = {}
249         local index_pos = vector.add(pos,dir)
250         
251         local node = minetest.get_node(index_pos)
252         local param2 = node.param2
253         local def = minetest.registered_nodes[node.name]
254         local name = node.name
255         local pull = ((excluded_mods[def.mod_origin] ~= true) and (excluded_nodes[name] ~= true))
256         --if it can be pulled pull it
257         if pull and name ~= "air" then
258                 minetest.remove_node(index_pos)
259                 minetest.set_node(pos,{name=name,param2=param2})
260         end
261 end
262
263 ------------------------------[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
264
265 --this is the logic of the sticky piston on return
266 local function sticky_piston_pull(pos,dir)
267         --this is where the piston activates
268         --local facedir = minetest.get_node(pos).param2
269         --local dir = minetest.facedir_to_dir(facedir)
270         --local piston_location = vector.add(pos,dir)
271         
272         local in_front_pos = vector.add(pos,dir)
273         
274         local node = minetest.get_node(in_front_pos).name
275         --pull nodes
276         sticky_piston_pull_nodes(pos,dir)
277         
278         --pull player
279         if node == "air" then
280                 for _,object in ipairs(minetest.get_objects_inside_radius(in_front_pos, 2)) do
281                         if object:is_player() and object:get_hp() > 0 then
282                                 local pos2 = object:get_pos()
283                                 local compare = vector.subtract(pos2,in_front_pos)
284                                 local real_y = compare.y
285                                 compare = vector.abs(compare)
286                                 --piston pointing up
287                                 if dir.y == 1 then
288                                         if compare.y <= 0.5 and compare.x < 0.8 and compare.z < 0.8 then
289                                                 dir = vector.multiply(dir,-1)
290                                                 object:move_to(vector.add(dir,pos2))
291                                                 --object:add_player_velocity(vector.multiply(dir,20))
292                                         end
293                                 --piston sideways
294                                 elseif dir.x ~=0 or dir.z ~= 0 then
295                                         if real_y <= 0.5 and real_y >= -1.6 and compare.x < 0.8 and compare.z < 0.8 then
296                                                 dir = vector.multiply(dir,-1)
297                                                 object:move_to(vector.add(dir,pos2))
298                                                 --object:add_player_velocity(vector.multiply(dir,20))
299                                         
300                                         end
301                                 end
302                         end
303                 end
304         end
305         minetest.sound_play("piston", {pos=pos,pitch=math.random(85,100)/100})
306         --minetest.set_node(piston_location,{name="redstone:sticky_actuator",param2=facedir})
307         --minetest.set_node(pos,{name="redstone:sticky_piston_on",param2=facedir})
308 end
309
310 ------------------------------[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
311
312 minetest.register_node("redstone:sticky_piston_off", {
313     description = "Sticky Piston",
314     tiles = {"redstone_piston.png","redstone_piston.png^[transformR180","redstone_piston.png^[transformR270","redstone_piston.png^[transformR90","sticky_piston.png","stone.png"},
315     paramtype2 = "facedir",
316     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1,redstone_activation=1},
317     sounds = main.stoneSound(),
318     drop = "redstone:sticky_piston_off",
319     paramtype = "light",
320     sunlight_propagates = true,
321     redstone_activation = function(pos)
322                 if minetest.get_node(pos).name == "redstone:sticky_piston_off" then
323                         sticky_piston_push(pos)
324                 end
325     end,
326     --reverse the direction to face the player
327     after_place_node = function(pos, placer, itemstack, pointed_thing)
328                 local look = placer:get_look_dir()
329                 look = vector.multiply(look,-1)
330                 dir = minetest.dir_to_facedir(look, true)
331                 minetest.set_node(pos,{name="redstone:sticky_piston_off",param2=dir})
332                 redstone.collect_info(pos)
333     end,
334 })
335
336
337 --------------------------
338
339
340 minetest.register_node("redstone:sticky_piston_on", {
341     description = "Sticky Piston",
342     tiles = {"redstone_piston.png","redstone_piston.png^[transformR180","redstone_piston.png^[transformR270","redstone_piston.png^[transformR90","stone.png","stone.png"},
343     drawtype = "nodebox",
344     paramtype = "light",
345     paramtype2 = "facedir",
346     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1,redstone_activation=1},
347     sounds = main.stoneSound(),
348     drop = "redstone:sticky_piston_off",
349     node_box = {
350                 type = "fixed",
351                 fixed = {
352                                 --left front bottom right back top
353                                 {-0.5, -0.5,  -0.5, 0.5,  0.5, 3/16},
354                         },
355                 },
356     redstone_deactivation = function(pos)
357                 --this is where the piston deactivates
358                 local facedir = minetest.get_node(pos).param2
359                 local dir = minetest.facedir_to_dir(facedir)
360                 local piston_location = vector.add(pos,dir)
361                 minetest.remove_node(piston_location)
362                 minetest.set_node(pos,{name="redstone:sticky_piston_off",param2=facedir})
363                 
364                 sticky_piston_pull(piston_location,dir)
365                 
366                 piston_location.y = piston_location.y + 1
367                 minetest.punch_node(piston_location)
368                 --minetest.sound_play("piston", {pos=pos,pitch=math.random(85,100)/100})
369     end,
370     after_dig_node = function(pos, oldnode, oldmetadata, digger)
371                 local facedir = oldnode.param2
372                 local dir = minetest.facedir_to_dir(facedir)
373                 local piston_location = vector.add(pos,dir)
374                 minetest.remove_node(piston_location)
375     end,
376 })
377
378 minetest.register_node("redstone:sticky_actuator", {
379     description = "Redstone Piston",
380     tiles = {"wood.png","wood.png","wood.png","wood.png","sticky_piston.png","wood.png"},
381     drawtype = "nodebox",
382     paramtype = "light",
383     paramtype2 = "facedir",
384     groups = {stone = 1, hard = 1, pickaxe = 1, hand = 4,pathable = 1},
385     sounds = main.stoneSound(),
386     drop = "redstone:sticky_piston_off",
387     node_box = {
388                 type = "fixed",
389                 fixed = {
390                                 --left front bottom right back top
391                                 {-0.5, -0.5,  0.2, 0.5,  0.5, 0.5}, --mover
392                                 {-0.15, -0.15,  -0.9, 0.15,  0.15, 0.5}, --actuator
393                         },
394                 },
395         after_dig_node = function(pos, oldnode, oldmetadata, digger)
396                 local facedir = oldnode.param2
397                 local dir = minetest.facedir_to_dir(facedir)
398                 dir = vector.multiply(dir,-1)
399                 local piston_location = vector.add(pos,dir)
400                 minetest.remove_node(piston_location)
401     end,
402 })