Declare observers not opaque
[MineClone/MineClone2.git] / mods / CORE / flowlib / init.lua
blobe4e22a20eac16c4015da966a93b1192696f08b82
1 flowlib = {}
3 --sum of direction vectors must match an array index
4 local function to_unit_vector(dir_vector)
5 --(sum,root)
6 -- (0,1), (1,1+0=1), (2,1+1=2), (3,1+2^2=5), (4,2^2+2^2=8)
7 local inv_roots = {[0] = 1, [1] = 1, [2] = 0.70710678118655, [4] = 0.5
8 , [5] = 0.44721359549996, [8] = 0.35355339059327}
9 local sum = dir_vector.x*dir_vector.x + dir_vector.z*dir_vector.z
10 return {x=dir_vector.x*inv_roots[sum],y=dir_vector.y
11 ,z=dir_vector.z*inv_roots[sum]}
12 end
14 local is_touching = function(realpos,nodepos,radius)
15 local boarder = 0.5 - radius
16 return (math.abs(realpos - nodepos) > (boarder))
17 end
19 flowlib.is_touching = is_touching
21 local is_water = function(pos)
22 return (minetest.get_item_group(minetest.get_node(
23 {x=pos.x,y=pos.y,z=pos.z}).name
24 , "water") ~= 0)
25 end
27 flowlib.is_water = is_water
29 local node_is_water = function(node)
30 return (minetest.get_item_group(node.name, "water") ~= 0)
31 end
33 flowlib.node_is_water = node_is_water
35 local is_lava = function(pos)
36 return (minetest.get_item_group(minetest.get_node(
37 {x=pos.x,y=pos.y,z=pos.z}).name
38 , "lava") ~= 0)
39 end
41 flowlib.is_lava = is_lava
43 local node_is_lava = function(node)
44 return (minetest.get_item_group(node.name, "lava") ~= 0)
45 end
47 flowlib.node_is_lava = node_is_lava
50 local is_liquid = function(pos)
51 return (minetest.get_item_group(minetest.get_node(
52 {x=pos.x,y=pos.y,z=pos.z}).name
53 , "liquid") ~= 0)
54 end
56 flowlib.is_liquid = is_liquid
58 local node_is_liquid = function(node)
59 return (minetest.get_item_group(node.name, "liquid") ~= 0)
60 end
62 flowlib.node_is_liquid = node_is_liquid
64 --This code is more efficient
65 local function quick_flow_logic(node,pos_testing,direction)
66 local name = node.name
67 if not minetest.registered_nodes[name] then
68 return 0
69 end
70 if minetest.registered_nodes[name].liquidtype == "source" then
71 local node_testing = minetest.get_node(pos_testing)
72 local param2_testing = node_testing.param2
73 if not minetest.registered_nodes[node_testing.name] then
74 return 0
75 end
76 if minetest.registered_nodes[node_testing.name].liquidtype
77 ~= "flowing" then
78 return 0
79 else
80 return direction
81 end
82 elseif minetest.registered_nodes[name].liquidtype == "flowing" then
83 local node_testing = minetest.get_node(pos_testing)
84 local param2_testing = node_testing.param2
85 if not minetest.registered_nodes[node_testing.name] then
86 return 0
87 end
88 if minetest.registered_nodes[node_testing.name].liquidtype
89 == "source" then
90 return -direction
91 elseif minetest.registered_nodes[node_testing.name].liquidtype
92 == "flowing" then
93 if param2_testing < node.param2 then
94 if (node.param2 - param2_testing) > 6 then
95 return -direction
96 else
97 return direction
98 end
99 elseif param2_testing > node.param2 then
100 if (param2_testing - node.param2) > 6 then
101 return direction
102 else
103 return -direction
108 return 0
111 local quick_flow = function(pos,node)
112 local x = 0
113 local z = 0
115 if not node_is_liquid(node) then
116 return {x=0,y=0,z=0}
119 x = x + quick_flow_logic(node,{x=pos.x-1,y=pos.y,z=pos.z},-1)
120 x = x + quick_flow_logic(node,{x=pos.x+1,y=pos.y,z=pos.z}, 1)
121 z = z + quick_flow_logic(node,{x=pos.x,y=pos.y,z=pos.z-1},-1)
122 z = z + quick_flow_logic(node,{x=pos.x,y=pos.y,z=pos.z+1}, 1)
124 return to_unit_vector({x=x,y=0,z=z})
127 flowlib.quick_flow = quick_flow
130 --if not in water but touching, move centre to touching block
131 --x has higher precedence than z
132 --if pos changes with x, it affects z
133 local move_centre = function(pos,realpos,node,radius)
134 if is_touching(realpos.x,pos.x,radius) then
135 if is_liquid({x=pos.x-1,y=pos.y,z=pos.z}) then
136 node = minetest.get_node({x=pos.x-1,y=pos.y,z=pos.z})
137 pos = {x=pos.x-1,y=pos.y,z=pos.z}
138 elseif is_liquid({x=pos.x+1,y=pos.y,z=pos.z}) then
139 node = minetest.get_node({x=pos.x+1,y=pos.y,z=pos.z})
140 pos = {x=pos.x+1,y=pos.y,z=pos.z}
143 if is_touching(realpos.z,pos.z,radius) then
144 if is_liquid({x=pos.x,y=pos.y,z=pos.z-1}) then
145 node = minetest.get_node({x=pos.x,y=pos.y,z=pos.z-1})
146 pos = {x=pos.x,y=pos.y,z=pos.z-1}
147 elseif is_liquid({x=pos.x,y=pos.y,z=pos.z+1}) then
148 node = minetest.get_node({x=pos.x,y=pos.y,z=pos.z+1})
149 pos = {x=pos.x,y=pos.y,z=pos.z+1}
152 return pos,node
155 flowlib.move_centre = move_centre