summaryrefslogtreecommitdiff
path: root/flowing_logic.lua
blob: e633983ceb0b46308a3328e6e911cba63f6e255b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
-- This file provides the actual flow and pathfinding logic that makes water
-- move through the pipes.
--
-- Contributed by mauvebic, 2013-01-03, with tweaks by Vanessa Ezekowitz
--

local check4liquids = function(pos)
	local coords = {
		{x=pos.x,y=pos.y-1,z=pos.z},
		{x=pos.x,y=pos.y+1,z=pos.z},
		{x=pos.x-1,y=pos.y,z=pos.z},
		{x=pos.x+1,y=pos.y,z=pos.z},
		{x=pos.x,y=pos.y,z=pos.z-1},
		{x=pos.x,y=pos.y,z=pos.z+1},	}
	for i =1,6 do
		local name = minetest.env:get_node(coords[i]).name
		if string.find(name,'water') then 
			minetest.env:remove_node(coords[i])
			return true
		end
	end
	return false
end

local check4inflows = function(pos,node)
	local coords = {
		{x=pos.x,y=pos.y-1,z=pos.z},
		{x=pos.x,y=pos.y+1,z=pos.z},
		{x=pos.x-1,y=pos.y,z=pos.z},
		{x=pos.x+1,y=pos.y,z=pos.z},
		{x=pos.x,y=pos.y,z=pos.z-1},
		{x=pos.x,y=pos.y,z=pos.z+1},	}
	local newnode = false
	local source = false
	for i =1,6 do
		if newnode then break end
		local name = minetest.env:get_node(coords[i]).name
		if (name == 'pipeworks:pump_on' and check4liquids(coords[i])) or string.find(name,'_loaded') then
			if string.find(name,'_loaded') then
				local source = minetest.env:get_meta(coords[i]):get_string('source')
				if source == minetest.pos_to_string(pos) then break end
			end
			newnode = string.gsub(node.name,'empty','loaded')
			source = {x=coords[i].x,y=coords[i].y,z=coords[i].z}
			if newnode ~= nil then dbg(newnode) end
		end
	end
	if newnode then 
		dbg(newnode..' to replace '..node.name) 
		minetest.env:add_node(pos,{name=newnode, param2 = node.param2}) 
		minetest.env:get_meta(pos):set_string('source',minetest.pos_to_string(source))
	end
end

local checksources = function(pos,node)
	local sourcepos = minetest.string_to_pos(minetest.env:get_meta(pos):get_string('source'))
	if not sourcepos then return end
	local source = minetest.env:get_node(sourcepos).name
	local newnode = false
	if not ((source == 'pipeworks:pump_on' and check4liquids(sourcepos)) or string.find(source,'_loaded') or source == 'ignore' ) then
		newnode = string.gsub(node.name,'loaded','empty')
	end

	if newnode then dbg(newnode..' to replace '..node.name) end
	if newnode then 
		minetest.env:add_node(pos,{name=newnode, param2 = node.param2}) 
		minetest.env:get_meta(pos):set_string('source','')
	end
end

local update_outlet = function(pos)
	local top = minetest.env:get_node({x=pos.x,y=pos.y+1,z=pos.z}).name
	if string.find(top,'_loaded') then
		local name = minetest.env:get_node({x=pos.x,y=pos.y-1,z=pos.z}).name
		if name == 'air' or name == "default:water_source" or name == "default:water_flowing" then 
			minetest.env:add_node({x=pos.x,y=pos.y-1,z=pos.z},{name='default:water_source'}) 
		end
	elseif minetest.env:get_node({x=pos.x,y=pos.y-1,z=pos.z}).name == 'default:water_source' then
		minetest.env:remove_node({x=pos.x,y=pos.y-1,z=pos.z})
	end
end

local spigot_check = function(pos,node)
	local fdir=node.param2
	local check = {{x=pos.x,y=pos.y,z=pos.z+1},{x=pos.x+1,y=pos.y,z=pos.z},{x=pos.x,y=pos.y,z=pos.z-1},{x=pos.x-1,y=pos.y,z=pos.z}	}
	dbg(fdir..' checking '..minetest.pos_to_string(check[fdir+1])..' for spigot at '..minetest.pos_to_string(pos))
	local top = minetest.env:get_node(check[fdir+1]).name
	dbg('found '..top)
	local name = minetest.env:get_node({x=pos.x,y=pos.y-1,z=pos.z}).name
	if string.find(top,'_loaded') and (name == 'air' or name == "default:water_source" or name == "default:water_flowing") then 
		minetest.env:add_node({x=pos.x,y=pos.y-1,z=pos.z},{name='default:water_source'})
		minetest.env:add_node(pos,{name='pipeworks:spigot_pouring', param2 = fdir})
	else
		if minetest.env:get_node(pos).name == 'pipeworks:spigot_pouring' then
			minetest.env:add_node({x=pos.x,y=pos.y,z=pos.z},{name='pipeworks:spigot', param2 = fdir})
			if name == 'air' or name == "default:water_source" or name == "default:water_flowing" then
				minetest.env:remove_node({x=pos.x,y=pos.y-1,z=pos.z})
			end
		end
	end
end

table.insert(pipes_empty_nodenames,"pipeworks:valve_on_empty")
table.insert(pipes_empty_nodenames,"pipeworks:valve_off_empty")
table.insert(pipes_empty_nodenames,"pipeworks:valve_on_loaded")
table.insert(pipes_empty_nodenames,"pipeworks:entry_panel_empty")

table.insert(pipes_full_nodenames,"pipeworks:valve_on_empty")
table.insert(pipes_full_nodenames,"pipeworks:valve_off_empty")
table.insert(pipes_full_nodenames,"pipeworks:valve_on_loaded")
table.insert(pipes_full_nodenames,"pipeworks:entry_panel_loaded")

minetest.register_abm({
	nodenames = pipes_empty_nodenames,
	interval = 1,
	chance = 1,
	action = function(pos, node, active_object_count, active_object_count_wider) check4inflows(pos,node) end
})

minetest.register_abm({
	nodenames = pipes_full_nodenames,
	interval = 1,
	chance = 1,
	action = function(pos, node, active_object_count, active_object_count_wider) checksources(pos,node) end
})

minetest.register_abm({
	nodenames = {'pipeworks:outlet','pipeworks:spigot','pipeworks:spigot_pouring'},
	interval = 1,
	chance = 1,
	action = function(pos, node, active_object_count, active_object_count_wider) 
		if node.name == 'pipeworks:outlet' then update_outlet(pos)
		elseif node.name == 'pipeworks:spigot' or node.name == 'pipeworks:spigot_pouring' then spigot_check(pos,node) end
	end
})