kpoppel
2013-07-02 053fa59739f4b772174bf0a090969b3395ab3f98
commit | author | age
478407 1 function get_face(pos,ppos,pvect)
R 2     ppos={x=ppos.x-pos.x,y=ppos.y-pos.y+1.5,z=ppos.z-pos.z}
3     if pvect.x>0 then
4         local t=(-0.5-ppos.x)/pvect.x
5         local y_int=ppos.y+t*pvect.y
6         local z_int=ppos.z+t*pvect.z
7         if y_int>-0.4 and y_int<0.4 and z_int>-0.4 and z_int<0.4 then return 1 end 
8     elseif pvect.x<0 then
9         local t=(0.5-ppos.x)/pvect.x
10         local y_int=ppos.y+t*pvect.y
11         local z_int=ppos.z+t*pvect.z
12         if y_int>-0.4 and y_int<0.4 and z_int>-0.4 and z_int<0.4 then return 2 end 
13     end
14     if pvect.y>0 then
15         local t=(-0.5-ppos.y)/pvect.y
16         local x_int=ppos.x+t*pvect.x
17         local z_int=ppos.z+t*pvect.z
18         if x_int>-0.4 and x_int<0.4 and z_int>-0.4 and z_int<0.4 then return 3 end 
19     elseif pvect.y<0 then
20         local t=(0.5-ppos.y)/pvect.y
21         local x_int=ppos.x+t*pvect.x
22         local z_int=ppos.z+t*pvect.z
23         if x_int>-0.4 and x_int<0.4 and z_int>-0.4 and z_int<0.4 then return 4 end 
24     end
25     if pvect.z>0 then
26         local t=(-0.5-ppos.z)/pvect.z
27         local x_int=ppos.x+t*pvect.x
28         local y_int=ppos.y+t*pvect.y
29         if x_int>-0.4 and x_int<0.4 and y_int>-0.4 and y_int<0.4 then return 5 end 
30     elseif pvect.z<0 then
31         local t=(0.5-ppos.z)/pvect.z
32         local x_int=ppos.x+t*pvect.x
33         local y_int=ppos.y+t*pvect.y
34         if x_int>-0.4 and x_int<0.4 and y_int>-0.4 and y_int<0.4 then return 6 end 
35     end
36 end
37
38
39 for xm=0,1 do
40 for xp=0,1 do
41 for ym=0,1 do
42 for yp=0,1 do
43 for zm=0,1 do
44 for zp=0,1 do
45
46 local a=8/16
47 local b=7/16
48 local nodeboxes= {
49     { -a, -a, -a, -b,  a, -b },
50     { -a, -a,  b, -b,  a,  a },
51     {  b, -a,  b,  a,  a,  a },
52     {  b, -a, -a,  a,  a, -b },
53
54     { -b,  b, -a,  b,  a, -b },
55     { -b, -a, -a,  b, -b, -b },
56     
57     { -b,  b,  b,  b,  a,  a },
58     { -b, -a,  b,  b, -b,  a },
59
60     {  b,  b, -b,  a,  a,  b },
61     {  b, -a, -b,  a, -b,  b },
62
63     { -a,  b, -b, -b,  a,  b },
64     { -a, -a, -b, -b, -b,  b },
65     }
66     
67     if yp==0 then
68         table.insert(nodeboxes, {-b,b,-b, b,a,b})
69     end
70     if ym==0 then
71         table.insert(nodeboxes, {-b,-a,-b, b,-b,b})
72     end
73     if xp==0 then
74         table.insert(nodeboxes, {b,b,b,a,-b,-b})
75     end
76     if xm==0 then
77         table.insert(nodeboxes, {-a,-b,-b,-b,b,b})
78     end
79     if zp==0 then
80         table.insert(nodeboxes, {-b,-b,b, b,b,a})
81     end
82     if zm==0 then
83         table.insert(nodeboxes, {-b,-b,-a, b,b,-b})
84     end
85     
86     local nameext=tostring(xm)..tostring(xp)..tostring(ym)..tostring(yp)..tostring(zm)..tostring(zp)
87     local groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}
88     if nameext~="111111" then groups.not_in_creative_inventory=1 end
89     
90
91     minetest.register_node("technic:frame_"..nameext,{
92         description = "Frame",
93         tiles = {"technic_frame.png"},
94         groups=groups,
95         drawtype = "nodebox",
96         node_box = {
97             type = "fixed",
98         fixed=nodeboxes,
99         },
3a5215 100         selection_box = {
N 101             type="fixed",
102             fixed={-0.5,-0.5,-0.5,0.5,0.5,0.5}
103         },
478407 104         paramtype = "light",
R 105         frame=1,
106         drop="technic:frame_111111",
107         frame_connect_all=function(pos)
108             local nodename=minetest.env:get_node(pos).name
109             l2={}
110             l1={{x=-1,y=0,z=0},{x=1,y=0,z=0},{x=0,y=-1,z=0},{x=0,y=1,z=0},{x=0,y=0,z=-1},{x=0,y=0,z=1}}
111             for i,dir in ipairs(l1) do
112                 if string.sub(nodename,-7+i,-7+i)=="1" then
113                     l2[#(l2)+1]=dir
114                 end
115             end
116             return l2
117         end,
118         on_punch=function(pos,node,puncher)
119             local ppos=puncher:getpos()
120             local pvect=puncher:get_look_dir()
121             local pface=get_face(pos,ppos,pvect)
122             if pface==nil then return end
123             local nodename=node.name
124             local newstate=tostring(1-tonumber(string.sub(nodename,-7+pface,-7+pface)))
125             if pface<=5 then
126                 nodename=string.sub(nodename,1,-7+pface-1)..newstate..string.sub(nodename,-7+pface+1)
127             else
128                 nodename=string.sub(nodename,1,-2)..newstate
129             end
130             node.name=nodename
131             minetest.env:set_node(pos,node)
132         end
133     })
134
135 end
136 end
137 end
138 end
139 end
140 end
141
142
143 function frame_motor1_on(pos,node)
144     local npos={x=pos.x,y=pos.y+1,z=pos.z}
145     local nnode=minetest.env:get_node(npos)
146     if node.param2==0 then
147         dir={x=1,y=0,z=0}
148     elseif node.param2==1 then
149         dir={x=0,y=0,z=-1}
150     elseif node.param2==2 then
151         dir={x=-1,y=0,z=0}
152     else
153         dir={x=0,y=0,z=1}
154     end
155     if minetest.registered_nodes[nnode.name].frame==1 then
156         local connected_nodes=get_connected_nodes(npos)
157         move_nodes_vect(connected_nodes,dir)
158     end
159 end
160
161 function frame_motor2_on(pos,node)
162     local npos={x=pos.x,y=pos.y-1,z=pos.z}
163     local nnode=minetest.env:get_node(npos)
164     if node.param2==0 then
165         dir={x=1,y=0,z=0}
166     elseif node.param2==1 then
167         dir={x=0,y=0,z=-1}
168     elseif node.param2==2 then
169         dir={x=-1,y=0,z=0}
170     else
171         dir={x=0,y=0,z=1}
172     end
173     if minetest.registered_nodes[nnode.name].frame==1 then
174         local connected_nodes=get_connected_nodes(npos)
175         move_nodes_vect(connected_nodes,dir)
176     end
177 end
178
179 function frame_motor3_on(pos,node)
180     local npos={x=pos.x,y=pos.y,z=pos.z}
181     if node.param2==0 then
182         dir={x=1,y=0,z=0}
183         npos.z=npos.z-1
184     elseif node.param2==1 then
185         dir={x=0,y=0,z=-1}
186         npos.x=npos.x-1
187     elseif node.param2==2 then
188         dir={x=-1,y=0,z=0}
189         npos.z=npos.z+1
190     else
191         dir={x=0,y=0,z=1}
192         npos.x=npos.x+1
193     end
194     local nnode=minetest.env:get_node(npos)
195     if minetest.registered_nodes[nnode.name].frame==1 then
196         local connected_nodes=get_connected_nodes(npos)
197         move_nodes_vect(connected_nodes,dir)
198     end
199 end
200
201 function frame_motor4_on(pos,node)
202     local npos={x=pos.x,y=pos.y,z=pos.z}
203     if node.param2==0 then
204         dir={x=-1,y=0,z=0}
205         npos.z=npos.z-1
206     elseif node.param2==1 then
207         dir={x=0,y=0,z=1}
208         npos.x=npos.x-1
209     elseif node.param2==2 then
210         dir={x=1,y=0,z=0}
211         npos.z=npos.z+1
212     else
213         dir={x=0,y=0,z=-1}
214         npos.x=npos.x+1
215     end
216     local nnode=minetest.env:get_node(npos)
217     if minetest.registered_nodes[nnode.name].frame==1 then
218         local connected_nodes=get_connected_nodes(npos)
219         move_nodes_vect(connected_nodes,dir)
220     end
221 end
222
223 function frame_motor5_on(pos,node)
224     local npos={x=pos.x,y=pos.y,z=pos.z}
225     if node.param2==0 then
226         npos.z=npos.z-1
227     elseif node.param2==1 then
228         npos.x=npos.x-1
229     elseif node.param2==2 then
230         npos.z=npos.z+1
231     else
232         npos.x=npos.x+1
233     end
234     dir={x=0,y=1,z=0}
235     local nnode=minetest.env:get_node(npos)
236     if minetest.registered_nodes[nnode.name].frame==1 then
237         local connected_nodes=get_connected_nodes(npos)
238         move_nodes_vect(connected_nodes,dir)
239     end
240 end
241
242 function frame_motor6_on(pos,node)
243     local npos={x=pos.x,y=pos.y,z=pos.z}
244     if node.param2==0 then
245         npos.z=npos.z-1
246     elseif node.param2==1 then
247         npos.x=npos.x-1
248     elseif node.param2==2 then
249         npos.z=npos.z+1
250     else
251         npos.x=npos.x+1
252     end
253     dir={x=0,y=-1,z=0}
254     local nnode=minetest.env:get_node(npos)
255     if minetest.registered_nodes[nnode.name].frame==1 then
256         local connected_nodes=get_connected_nodes(npos)
257         move_nodes_vect(connected_nodes,dir)
258     end
259 end
260
261
262 minetest.register_node("technic:frame_motor1",{
263     description = "Frame motor 1",
264     tiles = {"pipeworks_filter_top.png", "technic_lv_cable.png", "technic_lv_cable.png",
265         "technic_lv_cable.png", "technic_lv_cable.png", "technic_lv_cable.png"},
266     groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,mesecon=2},
267     paramtype2 = "facedir",
268     mesecons={effector={action_on=frame_motor1_on}},
269     frames_can_connect=function(pos,dir)
270         return dir.y~=-1
271     end
272 })
273
274 minetest.register_node("technic:frame_motor2",{
275     description = "Frame motor 2",
276     tiles = {"technic_lv_cable.png", "pipeworks_filter_top.png", "technic_lv_cable.png",
277         "technic_lv_cable.png", "technic_lv_cable.png", "technic_lv_cable.png"},
278     groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,mesecon=2},
279     paramtype2 = "facedir",
280     mesecons={effector={action_on=frame_motor2_on}},
281     frames_can_connect=function(pos,dir)
282         return dir.y~=1
283     end
284 })
285
286 minetest.register_node("technic:frame_motor3",{
287     description = "Frame motor 3",
288     tiles = {"technic_lv_cable.png", "technic_lv_cable.png", "technic_lv_cable.png",
289         "technic_lv_cable.png", "technic_lv_cable.png", "pipeworks_filter_top.png"},
290     groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,mesecon=2},
291     paramtype2 = "facedir",
292     mesecons={effector={action_on=frame_motor3_on}},
293     frames_can_connect=function(pos,dir)
294         local node=minetest.env:get_node(pos)
295         if node.param2==0 then return dir.z~=1
296         elseif node.param2==1 then return dir.x~=1
297         elseif node.param2==2 then return dir.z~=-1
298         else return dir.x~=-1 end
299     end
300 })
301
302 minetest.register_node("technic:frame_motor4",{
303     description = "Frame motor 4",
304     tiles = {"technic_lv_cable.png", "technic_lv_cable.png", "technic_lv_cable.png",
4b0d4b 305         "technic_lv_cable.png", "technic_lv_cable.png", "pipeworks_filter_top.png^[transformR180"},
478407 306     groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,mesecon=2},
R 307     paramtype2 = "facedir",
308     mesecons={effector={action_on=frame_motor4_on}},
309     frames_can_connect=function(pos,dir)
310         local node=minetest.env:get_node(pos)
311         if node.param2==0 then return dir.z~=1
312         elseif node.param2==1 then return dir.x~=1
313         elseif node.param2==2 then return dir.z~=-1
314         else return dir.x~=-1 end
315     end
316 })
317
318 minetest.register_node("technic:frame_motor5",{
319     description = "Frame motor 5",
320     tiles = {"technic_lv_cable.png", "technic_lv_cable.png", "technic_lv_cable.png",
4b0d4b 321         "technic_lv_cable.png", "technic_lv_cable.png", "pipeworks_filter_top.png^[transformR90"},
478407 322     groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,mesecon=2},
R 323     paramtype2 = "facedir",
324     mesecons={effector={action_on=frame_motor5_on}},
325     frames_can_connect=function(pos,dir)
326         local node=minetest.env:get_node(pos)
327         if node.param2==0 then return dir.z~=1
328         elseif node.param2==1 then return dir.x~=1
329         elseif node.param2==2 then return dir.z~=-1
330         else return dir.x~=-1 end
331     end
332 })
333
334 minetest.register_node("technic:frame_motor6",{
335     description = "Frame motor 6",
336     tiles = {"technic_lv_cable.png", "technic_lv_cable.png", "technic_lv_cable.png",
4b0d4b 337         "technic_lv_cable.png", "technic_lv_cable.png", "pipeworks_filter_top.png^[transformR270"},
478407 338     groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,mesecon=2},
R 339     paramtype2 = "facedir",
340     mesecons={effector={action_on=frame_motor6_on}},
341     frames_can_connect=function(pos,dir)
342         local node=minetest.env:get_node(pos)
343         if node.param2==0 then return dir.z~=1
344         elseif node.param2==1 then return dir.x~=1
345         elseif node.param2==2 then return dir.z~=-1
346         else return dir.x~=-1 end
347     end
348 })
349
4a5877 350 function add_table(table,toadd)
R 351     local i=1
352     while true do
353         o=table[i]
354         if o==toadd then return end
355         if o==nil then break end
356         i=i+1
357     end
358     table[i]=toadd
359 end
478407 360
R 361 function move_nodes_vect(poslist,vect)
4a5877 362         for _,pos in ipairs(poslist) do
478407 363         local npos=addVect(pos,vect)
R 364         if minetest.env:get_node(npos).name~="air" and not(pos_in_list(poslist,npos)) then return end
365     end
366     nodelist={}
367     for _,pos in ipairs(poslist) do
368         local node=minetest.env:get_node(pos)
369         local meta=minetest.env:get_meta(pos):to_table()
370         nodelist[#(nodelist)+1]={pos=pos,node=node,meta=meta}
371     end
4a5877 372     objects={}
R 373     for _,pos in ipairs(poslist) do
374         for _,object in ipairs(minetest.env:get_objects_inside_radius(pos, 1)) do
375             add_table(objects,object)
376         end
377     end
378     for _,obj in ipairs(objects) do
379         obj:setpos(addVect(obj:getpos(),vect))
985401 380         le=obj:get_luaentity()
K 381         if le and le.name == "pipeworks:tubed_item" then
4a5877 382             le.start_pos=addVect(le.start_pos,vect)
R 383         end
384     end
478407 385     for _,n in ipairs(nodelist) do
R 386         local npos=addVect(n.pos,vect)
387         minetest.env:set_node(npos,n.node)
388         local meta=minetest.env:get_meta(npos)
389         meta:from_table(n.meta)
08acac 390         for __,pos in ipairs(poslist) do
K 391             if npos.x==pos.x and npos.y==pos.y and npos.z==pos.z then
392                 table.remove(poslist, __)
393                 break
394             end
395         end
396     end
397     for __,pos in ipairs(poslist) do
398         minetest.env:remove_node(pos)
478407 399     end
R 400 end
401
402 function get_connected_nodes(pos)
403     c={pos}
404     local nodename=minetest.env:get_node(pos).name
405     connected(pos,c,minetest.registered_nodes[nodename].frame_connect_all(pos))
406     return c
407 end
408
409 function addVect(pos,vect)
410     return {x=pos.x+vect.x,y=pos.y+vect.y,z=pos.z+vect.z}
411 end
412
413 function pos_in_list(l,pos)
414     for _,p in ipairs(l) do
415         if p.x==pos.x and p.y==pos.y and p.z==pos.z then return true end
416     end
417     return false
418 end
419
420 function connected(pos,c,adj)
421     for _,vect in ipairs(adj) do
422         local pos1=addVect(pos,vect)
423         local nodename=minetest.env:get_node(pos1).name
424         if not(pos_in_list(c,pos1)) and nodename~="air" and
425         (minetest.registered_nodes[nodename].frames_can_connect==nil or
426         minetest.registered_nodes[nodename].frames_can_connect(pos1,vect)) then
427             c[#(c)+1]=pos1
428             if minetest.registered_nodes[nodename].frame==1 then
429                 local adj=minetest.registered_nodes[nodename].frame_connect_all(pos1)
430                 connected(pos1,c,adj)
431             end
432         end
433     end
434 end
435