From dc3d80a49a8628790fff46ad354bae1d267445ea Mon Sep 17 00:00:00 2001 From: Izzy Date: Sun, 6 May 2018 20:15:29 -0600 Subject: [PATCH] first commit --- depends.txt | 1 + init.lua | 450 +++++++++++++++++++++++++++++++++++++++++++++++++ pipes.lua | 472 ++++++++++++++++++++++++++++++++++++++++++++++++++++ sluice.lua | 140 ++++++++++++++++ wells.lua | 194 +++++++++++++++++++++ 5 files changed, 1257 insertions(+) create mode 100644 depends.txt create mode 100644 init.lua create mode 100644 pipes.lua create mode 100644 sluice.lua create mode 100644 wells.lua diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..4ad96d5 --- /dev/null +++ b/depends.txt @@ -0,0 +1 @@ +default diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..7ac91a2 --- /dev/null +++ b/init.lua @@ -0,0 +1,450 @@ + + +local modpath = minetest.get_modpath("springs") +dofile(modpath.."/pipes.lua") +dofile(modpath.."/sluice.lua") +dofile(modpath.."/wells.lua") + +--[[ +TODO: + +water filters +pipe inlet/outlet pressure checks +broken outlet sharing +non-connected pipes and splitters +fix wells +convert springs to cracked rock +pumps +fix spout and intake nodeboxes + +crafts + +]] + + + +minetest.register_node("springs:spring", { + description = "Spring", + drawtype = "nodebox", + paramtype = "light", + tiles = { + { + name = "default_river_water_source_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + }, + }, + special_tiles = { + { + name = "default_river_water_source_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + backface_culling = false, + }, + }, + leveled = 64, + alpha = 160, + drop = "", + drowning = 1, + walkable = false, -- because viscosity doesn't work for regular nodes, and the liquid hack can't be leveled + climbable = true, -- because viscosity doesn't work for regular nodes, and the liquid hack can't be leveled + pointable = false, + diggable = false, + buildable_to = true, + + post_effect_color = {a = 103, r = 30, g = 76, b = 120}, + groups = { puts_out_fire = 1, liquid = 3, cools_lava = 1}, + sounds = default.node_sound_water_defaults(), + node_box = { + type = "leveled", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, -- NodeBox1 + } + } +}) + + +minetest.register_node("springs:water", { + description = "node ", + drawtype = "nodebox", + paramtype = "light", + tiles = { + { + name = "default_river_water_source_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + }, + }, + special_tiles = { + { + name = "default_river_water_source_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + backface_culling = false, + }, + }, + leveled = 64, + alpha = 160, + drop = "", + drowning = 1, + walkable = false, -- because viscosity doesn't work for regular nodes, and the liquid hack can't be leveled + climbable = true, -- because viscosity doesn't work for regular nodes, and the liquid hack can't be leveled + pointable = false, + diggable = false, + buildable_to = true, + +-- liquid_viscosity = 14, +-- liquidtype = "source", +-- liquid_alternative_flowing = "springs:water", +-- liquid_alternative_source = "springs:water", +-- liquid_renewable = false, +-- liquid_range = 0, +-- groups = {crumbly=3,soil=1,falling_node=1}, + post_effect_color = {a = 103, r = 30, g = 76, b = 90}, + groups = { puts_out_fire = 1, liquid = 3, cools_lava = 1, fresh_water=1}, + sounds = default.node_sound_water_defaults(), + node_box = { + type = "leveled", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, -- NodeBox1 + } + } +}) + +-- spring +minetest.register_abm({ + nodenames = {"springs:spring"}, + neighbors = {"group:fresh_water", "air"}, + interval = 2, + chance = 1, + action = function(pos) +-- local mylevel = minetest.get_node_level(pos) + + -- print("spring at: "..pos.x..","..pos.y..","..pos.z) + local air_nodes = minetest.find_nodes_in_area( + {x=pos.x - 1, y=pos.y - 1, z=pos.z - 1}, + {x=pos.x + 1, y=pos.y, z=pos.z + 1}, + {"group:fresh_water", "air"} + ) + + if nil == air_nodes or #air_nodes == 0 then + return + end + + local tpos = air_nodes[math.random(#air_nodes)] + + -- calculate flow rate based on absolute location + local prate = minetest.hash_node_position(pos) % 48 + local amount = math.random(1, 16) + prate + + local t = minetest.get_node(tpos) + if t.name == "air" then + minetest.set_node(tpos, {name = "springs:water"}) + minetest.set_node_level(tpos, amount) + else -- it's group:fresh_water + local tlevel = minetest.get_node_level(tpos) + minetest.set_node_level(tpos, math.min(64, tlevel + amount)) + end + + end +}) + +-- evaporation +minetest.register_abm({ + nodenames = {"group:fresh_water"}, + neighbors = {"group:fresh_water", "air"}, + interval = 5, + chance = 10, + action = function(pos) + local mylevel = minetest.get_node_level(pos) + if math.random(16 - minetest.get_node_light(pos)) == 1 then + if mylevel > 1 then + minetest.set_node_level(pos, mylevel - 1) + else + minetest.set_node(pos, {name = "air"}) + end + end + end +}) + + +local soak = { + ["default:cobble"] = 10, + ["default:desert_cobble"] = 10, + ["default:mossycobble"] = 9, + ["default:dirt"] = 2, + ["default:dirt_with_grass"] = 2, + ["default:dirt_with_grass_footsteps"] = 2, + ["default:dirt_with_dry_grass"] = 2, + ["default:dirt_with_coniferous_litter"] = 2, + ["default:dirt_with_rainforest_litter"] = 1, + ["default:gravel"] = 8, + ["default:coral_orange"] = 6, + ["default:coral_brown"] = 6, + ["default:coral_skeleton"] = 6, + ["default:sand"] = 6, + ["default:sand_with_kelp"] = 6, + ["default:desert_sand"] = 7, + ["default:silver_sand"] = 7, + ["default:snow"] = 4, + ["default:snowblock"] = 4, + ["default:leaves"] = 60, + ["default:bush_leaves"] = 60, + ["default:jungleleaves"] = 60, + ["default:pine_needles"] = 60, + ["default:acacia_leaves"] = 60, + ["default:acacia_bush_leaves"] = 60, + ["default:aspen_leaves"] = 60, + + -- dilution + ["default:water_source"] = 65, + ["default:water_flowing"] = 65, + ["default:river_water_source"] = 65, + ["default:river_water_flowing"] = 65, + + -- boiling -- TODO: steam effect + ["default:lava_source"] = 65, + ["default:lava_flowing"] = 65, + + -- no ladder hacks + ["default:ladder_wood"] = 65, + ["default:ladder_steel"] = 65, + ["default:sign_wall_wood"] = 65, + ["default:sign_wall_steel"] = 65, + + ["default:fence_wood"] = 65, + ["default:fence_acacia_wood"] = 65, + ["default:fence_junglewood"] = 65, + ["default:fence_pine_wood"] = 65, + ["default:fence_aspen_wood"] = 65, + + ["default:torch"] = 65, + ["carts:rail"] = 65, + ["carts:brakerail"] = 65, + ["carts:powerrail"] = 65, + + +} + +local soak_names = {} +for n,_ in pairs(soak) do + table.insert(soak_names, n) +end + + + +-- soaking sideways +minetest.register_abm({ + nodenames = {"group:fresh_water"}, + neighbors = soak_names, + interval = 4, + chance = 10, + action = function(pos) + -- print("\nsoak ") + local soak_nodes = minetest.find_nodes_in_area( + {x=pos.x - 1, y=pos.y, z=pos.z - 1}, + {x=pos.x + 1, y=pos.y, z=pos.z + 1}, + soak_names + ) + + local mylevel = minetest.get_node_level(pos) + local total_loss = 0 + for _,spos in ipairs(soak_nodes) do + local sn = minetest.get_node(spos) + total_loss = total_loss + soak[sn.name] + + if 1 == math.random(120 / mylevel) then + minetest.set_node(spos, {name = "air"}) + end + + end + + if total_loss == 0 then + return + end + + --print("loss: ".. total_loss) + + + local remain = mylevel - (total_loss * (mylevel / 64)) + if remain > 0 then + minetest.set_node_level(pos, remain) + else + minetest.set_node(pos, {name="air"}) + end + end +}) + +-- flowing +minetest.register_abm({ + nodenames = {"group:fresh_water"}, + neighbors = {"group:fresh_water", "air"}, + interval = 1, + chance = 1, + action = function(pos) + local mylevel = minetest.get_node_level(pos) +-- print("\n mylevel ".. mylevel) + + local below = {x=pos.x, y=pos.y - 1, z=pos.z} + local nbelow = minetest.get_node(below).name + if nbelow == "air" then + minetest.set_node(below, {name="springs:water"}) + minetest.set_node_level(below, mylevel) + minetest.set_node(pos, {name="air"}) + return + elseif nbelow == "springs:water" then + local blevel = minetest.get_node_level(below) + if blevel < 64 then + local sum = mylevel + blevel + minetest.set_node_level(below, math.min(64, sum)) + + if sum > 64 then + mylevel = sum - 64 + minetest.set_node_level(pos, mylevel) + -- keep flowing the liquid. this speeds up cascades + else + minetest.set_node(pos, {name="air"}) + return + end + end + else -- check soaking + local rate = soak[nbelow] + if rate ~= nil then + local remains = mylevel - rate + if remains > 0 then + minetest.set_node_level(pos, remains) + else + minetest.set_node(pos, {name="air"}) + end + + if 1 == math.random(120 / mylevel) then + minetest.set_node(below, {name = "air"}) + end + + mylevel = remains + --return -- keep the fluid mechanics + end + end + + local air_nodes = minetest.find_nodes_in_area( + {x=pos.x - 1, y=pos.y - 1, z=pos.z - 1}, + {x=pos.x + 1, y=pos.y, z=pos.z + 1}, + "air" + ) + + + + +-- print("x: "..pos.x.." y: "..pos.y.." z: "..pos.z) +-- print("air list len ".. #air_nodes) + local off = math.random(#air_nodes) + + for i = 1,#air_nodes do + --local theirlevel = minetest.get_node_level(fp) + local fp = air_nodes[((i + off) % #air_nodes) + 1] + if mylevel >= 2 then + local half = math.ceil(mylevel / 2) + + minetest.set_node_level(pos, mylevel - half) + minetest.set_node(fp, {name= "springs:water"}) + minetest.set_node_level(fp, half) +-- minetest.check_for_falling(fp) + return + end + end + + local flow_nodes = minetest.find_nodes_in_area( + {x=pos.x - 1, y=pos.y , z=pos.z - 1}, + {x=pos.x + 1, y=pos.y, z=pos.z + 1}, + "group:fresh_water" + ) + +-- print("x: "..pos.x.." y: "..pos.y.." z: "..pos.z) +-- print("list len ".. #flow_nodes) + local off = math.random(#flow_nodes) + + for i = 1,#flow_nodes do + local fp = flow_nodes[((i + off) % #flow_nodes) + 1] + local theirlevel = minetest.get_node_level(fp) +-- print("theirlevel "..theirlevel) + if mylevel - theirlevel >= 2 then + local diff = (mylevel - theirlevel) + local half = math.ceil(diff / 2) + + minetest.set_node_level(pos, mylevel - half) + minetest.set_node_level(fp, theirlevel + (diff - half)) + return + end + end + +-- local n = minetest.get_node(fp); +-- -- check above to make sure it can get here +-- local na = minetest.get_node({x=fp.x, y=fp.y+1, z=fp.z}) +-- +-- -- print("name: " .. na.name .. " l: " ..g) +-- if na.name == "default:river_water_flowing" or na.name == "default:river_water_flowing" then +-- minetest.set_node(fp, {name=node.name}) +-- minetest.set_node(pos, {name=n.name}) +-- return +-- end +-- end + + end +}) + + + +-- surface water +minetest.register_ore({ + ore_type = "scatter", + ore = "springs:spring", + wherein = {"default:dirt_with_grass", "default:dirt_with_coniferous_litter", "default:dirt_with_rainforest_litter"}, + clust_scarcity = 64 * 64 * 64, + clust_num_ores = 1, + clust_size = 1, + y_min = -20, + y_max = 200, +}) + +minetest.register_ore({ + ore_type = "scatter", + ore = "springs:spring", + wherein = "default:dirt", + clust_scarcity = 48 * 48 * 48, + clust_num_ores = 1, + clust_size = 1, + y_min = -20, + y_max = 200, +}) + + +-- ground water +minetest.register_ore({ + ore_type = "scatter", + ore = "springs:spring", + wherein = "default:stone", + clust_scarcity = 16 * 16 * 16, + clust_num_ores = 2, + clust_size = 2, + y_min = -50, + y_max = -20, +}) + +-- TODO: desert stone, sandstone + diff --git a/pipes.lua b/pipes.lua new file mode 100644 index 0000000..e007dcd --- /dev/null +++ b/pipes.lua @@ -0,0 +1,472 @@ + + + +local networks = {} +local net_members = {} +local netname = 1 + +local mod_storage = minetest.get_mod_storage() + + + +networks = minetest.deserialize(mod_storage:get_string("networks")) or {} +net_members = minetest.deserialize(mod_storage:get_string("net_members")) or {} +netname = minetest.deserialize(mod_storage:get_int("netname")) or 1 + + +local function save_data() + --print("saving") + + mod_storage:set_string("networks", minetest.serialize(networks)) + mod_storage:set_string("net_members", minetest.serialize(net_members)) + mod_storage:set_int("netname", minetest.serialize(netname)) +end + + +minetest.register_node("springs:intake", { + description = "Intake", + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = {{-.1, -.1, -.1, .1, .1, .1}}, + -- connect_bottom = + connect_front = {{-.1, -.1, -.5, .1, .1, .1}}, + connect_left = {{-.5, -.1, -.1, -.1, .1, .1}}, + connect_back = {{-.1, -.1, .1, .1, .1, .5}}, + connect_right = {{ .1, -.1, -.1, .5, .1, .1}}, + connect_bottom = {{ -.1, -.5, -.1, .1, .1, .1}}, + }, + connects_to = { "group:water_pipe", "group:water_fixture" }, + paramtype = "light", + is_ground_content = false, + tiles = { "default_tin_block.png" }, + walkable = true, + groups = { cracky = 3, water_fixture = 1, }, + on_construct = function(pos) + print("\nintake placed at "..pos.x..","..pos.y..","..pos.z) + local hash = minetest.hash_node_position(pos) + + local merge_list = {} + local current_net = nil + local found_net = 0 + + + local check_net = function(npos) + local nhash = minetest.hash_node_position(npos) + local nphash = net_members[nhash] + if nphash ~= nil then + local pnet = networks[nphash] + + if nil == current_net then + print("joining existing network: ".. pnet.name) + net_members[hash] = nphash + current_net = nphash + pnet.count = pnet.count + 1 + pnet.inputs[hash] = 1 + table.insert(merge_list, pnet) + elseif current_net == nphash then + print("alternate connection to existing network") + else + print("found seconday network: "..pnet.name) + table.insert(merge_list, pnet) + end + + found_net = 1 + end + end + + + + + check_net({x=pos.x, y=pos.y - 1, z=pos.z}) + check_net({x=pos.x, y=pos.y + 1, z=pos.z}) + check_net({x=pos.x + 1, y=pos.y, z=pos.z}) + check_net({x=pos.x - 1, y=pos.y, z=pos.z}) + check_net({x=pos.x, y=pos.y, z=pos.z + 1}) + check_net({x=pos.x, y=pos.y, z=pos.z - 1}) + + + if found_net == 0 then + + print("new network: hash: ".. hash .." name: " ..netname); + networks[hash] = { + hash = hash, + pos = {x=pos.x, y=pos.y, z=pos.z}, + name = netname, + count = 1, + inputs = { + [hash] = 1, + }, + outputs = {}, + buffer = 0, + } + + net_members[hash] = hash + + netname = netname + 1 + end + + + + + if #merge_list > 1 then + print("\n merging "..#merge_list.." networks") + + local biggest = {count = 0} + local mlookup = {} + + for _,n in ipairs(merge_list) do + mlookup[n.hash] = 1 + if n.count > biggest.count then + biggest = n + end + end + + mlookup[biggest.hash] = 0 + + for k,v in pairs(net_members) do + if mlookup[v] == 1 then + net_members[k] = biggest.hash + end + end + + + for _,n in ipairs(merge_list) do + if n.hash ~= biggest.hash then + biggest.count = biggest.count + n.count + n.count = 0 + end + end + + end + + + save_data() + + end + +}) + +minetest.register_abm({ + nodenames = {"springs:intake"}, + neighbors = {"group:fresh_water"}, + interval = 1, + chance = 1, + action = function(pos) + local hash = minetest.hash_node_position(pos) + + pos.y = pos.y + 1 + local unode = minetest.get_node(pos) + if unode.name ~= "springs:water" then + return + end + + local ulevel = minetest.get_node_level(pos) + if ulevel < 1 then + print("!!!!!!!!!!!! intake level less than one?") + return + end + + local rate = math.max(1, math.ceil(ulevel / 2)) + + local phash = net_members[hash] + local pnet = networks[phash] + local cap = 64 + local take = math.max(0, cap - pnet.buffer) + pnet.buffer = pnet.buffer + take + if ulevel - rate > 0 then + minetest.set_node_level(pos, ulevel - take) + else + minetest.set_node(pos, {name = "air"}) + end + end +}) + + + +minetest.register_node("springs:spout", { + description = "Spout", + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = {{-.1, -.1, -.1, .1, .1, .1}}, + -- connect_bottom = + connect_front = {{-.1, -.1, -.5, .1, .1, .1}}, + connect_left = {{-.5, -.1, -.1, -.1, .1, .1}}, + connect_back = {{-.1, -.1, .1, .1, .1, .5}}, + connect_right = {{ .1, -.1, -.1, .5, .1, .1}}, + connect_top = {{ -.1, -.1, -.1, .1, .5, .1}}, + }, + connects_to = { "group:water_pipe", "group:water_fixture" }, + paramtype = "light", + is_ground_content = false, + tiles = { "default_copper_block.png" }, + walkable = true, + groups = { cracky = 3, water_fixture = 1, }, + on_construct = function(pos) + print("\nspout placed at "..pos.x..","..pos.y..","..pos.z) + local hash = minetest.hash_node_position(pos) + + local merge_list = {} + local current_net = nil + local found_net = 0 + + + local check_net = function(npos) + local nhash = minetest.hash_node_position(npos) + local nphash = net_members[nhash] + if nphash ~= nil then + local pnet = networks[nphash] + + if nil == current_net then + print("joining existing network: ".. pnet.name) + net_members[hash] = nphash + current_net = nphash + pnet.count = pnet.count + 1 + pnet.outputs[hash] = 1 + table.insert(merge_list, pnet) + elseif current_net == nphash then + print("alternate connection to existing network") + else + print("found seconday network: "..pnet.name) + table.insert(merge_list, pnet) + end + + found_net = 1 + end + end + + + + + check_net({x=pos.x, y=pos.y - 1, z=pos.z}) + check_net({x=pos.x, y=pos.y + 1, z=pos.z}) + check_net({x=pos.x + 1, y=pos.y, z=pos.z}) + check_net({x=pos.x - 1, y=pos.y, z=pos.z}) + check_net({x=pos.x, y=pos.y, z=pos.z + 1}) + check_net({x=pos.x, y=pos.y, z=pos.z - 1}) + + + if found_net == 0 then + + print("new network: hash: ".. hash .." name: " ..netname); + networks[hash] = { + hash = hash, + pos = {x=pos.x, y=pos.y, z=pos.z}, + name = netname, + count = 1, + outputs = { + [hash] = 1, + }, + inputs = {}, + buffer = 0, + } + + net_members[hash] = hash + + netname = netname + 1 + end + + + + + if #merge_list > 1 then + print("\n merging "..#merge_list.." networks") + + local biggest = {count = 0} + local mlookup = {} + + for _,n in ipairs(merge_list) do + mlookup[n.hash] = 1 + if n.count > biggest.count then + biggest = n + end + end + + mlookup[biggest.hash] = 0 + + for k,v in pairs(net_members) do + if mlookup[v] == 1 then + net_members[k] = biggest.hash + end + end + + + for _,n in ipairs(merge_list) do + if n.hash ~= biggest.hash then + biggest.count = biggest.count + n.count + n.count = 0 + end + end + + end + + + save_data() + + end + +}) + + +minetest.register_abm({ + nodenames = {"springs:spout"}, +-- neighbors = {"group:fresh_water"}, + interval = 1, + chance = 1, + action = function(pos) + local hash = minetest.hash_node_position(pos) + local phash = net_members[hash] + local pnet = networks[phash] + + if pnet.buffer <= 0 then + return -- no water in the pipe + end + + pos.y = pos.y - 1 + + local bnode = minetest.get_node(pos) + local avail = 10 -- pnet.buffer / #pnet.outputs + if bnode.name == "springs:water" then + local blevel = minetest.get_node_level(pos) + local cap = 64 - blevel + local out = math.min(cap, math.min(avail, cap)) + --print("cap: ".. cap .." avail: ".. avail .. " out: "..out) + pnet.buffer = pnet.buffer - out + minetest.set_node_level(pos, blevel + out) + elseif bnode.name == "air" then + local out = math.min(64, math.max(0, avail)) + pnet.buffer = pnet.buffer - out + minetest.set_node(pos, {name = "springs:water"}) + minetest.set_node_level(pos, out) + end + + + end +}) + + +minetest.register_node("springs:pipe", { + description = "water pipe", + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = {{-.1, -.1, -.1, .1, .1, .1}}, + -- connect_bottom = + connect_front = {{-.1, -.1, -.5, .1, .1, .1}}, + connect_left = {{-.5, -.1, -.1, -.1, .1, .1}}, + connect_back = {{-.1, -.1, .1, .1, .1, .5}}, + connect_right = {{ .1, -.1, -.1, .5, .1, .1}}, + connect_top = {{ -.1, -.1, -.1, .1, .5, .1}}, + connect_bottom = {{ -.1, -.5, -.1, .1, .1, .1}}, + }, + connects_to = { "group:water_pipe", "group:water_fixture" }, + paramtype = "light", + is_ground_content = false, + tiles = { "default_steel_block.png" }, + walkable = true, + groups = { cracky = 3, water_pipe = 1, }, + + on_construct = function(pos) + print("\npipe placed at "..pos.x..","..pos.y..","..pos.z) + local hash = minetest.hash_node_position(pos) + + local merge_list = {} + local current_net = nil + local found_net = 0 + + + local check_net = function(npos) + local nhash = minetest.hash_node_position(npos) + local nphash = net_members[nhash] + if nphash ~= nil then + local pnet = networks[nphash] + + if nil == current_net then + print("joining existing network: ".. pnet.name) + net_members[hash] = nphash + current_net = nphash + pnet.count = pnet.count + 1 + table.insert(merge_list, pnet) + elseif current_net == nphash then + print("alternate connection to existing network") + else + print("found seconday network: "..pnet.name) + table.insert(merge_list, pnet) + end + + found_net = 1 + end + end + + + + + + + check_net({x=pos.x, y=pos.y - 1, z=pos.z}) + check_net({x=pos.x, y=pos.y + 1, z=pos.z}) + check_net({x=pos.x + 1, y=pos.y, z=pos.z}) + check_net({x=pos.x - 1, y=pos.y, z=pos.z}) + check_net({x=pos.x, y=pos.y, z=pos.z + 1}) + check_net({x=pos.x, y=pos.y, z=pos.z - 1}) + + + if found_net == 0 then + + print("new network: hash: ".. hash .." name: " ..netname); + networks[hash] = { + hash = hash, + pos = {x=pos.x, y=pos.y, z=pos.z}, + name = netname, + count = 1, + outputs = {}, + inputs = {}, + buffer = 0, + } + + net_members[hash] = hash + + netname = netname + 1 + end + + + + + if #merge_list > 1 then + print("\n merging "..#merge_list.." networks") + + local biggest = {count = 0} + local mlookup = {} + + for _,n in ipairs(merge_list) do + mlookup[n.hash] = 1 + if n.count > biggest.count then + biggest = n + end + end + + mlookup[biggest.hash] = 0 + + for k,v in pairs(net_members) do + if mlookup[v] == 1 then + net_members[k] = biggest.hash + end + end + + + for _,n in ipairs(merge_list) do + if n.hash ~= biggest.hash then + biggest.count = biggest.count + n.count + n.count = 0 + end + end + + end + + + save_data() + + end + +}) diff --git a/sluice.lua b/sluice.lua new file mode 100644 index 0000000..a936cad --- /dev/null +++ b/sluice.lua @@ -0,0 +1,140 @@ + + + + + +for i=0,8 do + + local nici = 1 + if i == 0 then + nici = 0 + end + + minetest.register_node("springs:sluice_gate_"..i, { + description = "Sluice Gate", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + -- top bar + {-.3, .3, -.15, .3, .5, .15}, + + -- sides + {-.5, -.5, -.4, -.3, .5, .4}, + {.3, -.5, -.4, .5, .5, .4}, + + -- rod + {-.01, .5, -.01, .01, 1.0, .01 }, + -- handle + {-.02, 1.0 - .01, -.02, .02, 1.01, .02 }, + {-.06, 1.0 - .01, -.01, .06, 1.0, .01 }, + {-.01, 1.0 - .01, -.06, .01, 1.0, .06 }, + + -- gate + {-.3, -.5 + (.08 * i), -.02, .3, .3, .02}, + + }, + }, + connects_to = { "group:water_pipe", "group:water_fixture" }, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + tiles = { "default_copper_block.png" }, + walkable = true, + groups = { cracky = 3, sluice_gate = i, not_in_creative_inventory = nici }, + drop = "springs:sluice_gate_0", + on_place = minetest.rotate_node, + on_punch = function(pos) + local node = minetest.get_node(pos) + local n = math.min(8, i + 1) + minetest.set_node(pos, {name = "springs:sluice_gate_"..n, param2 = node.param2}) + end, + on_rightclick = function(pos) + local node = minetest.get_node(pos) + local n = math.max(0, i - 1) + minetest.set_node(pos, {name = "springs:sluice_gate_"..n, param2 = node.param2}) + + end, + + + }) + +end + +minetest.register_abm({ + nodenames = {"group:sluice_gate"}, + neighbors = {"group:fresh_water"}, + interval = 1, + chance = 1, + action = function(pos) + local node = minetest.get_node(pos) + + local rate = minetest.get_item_group(node.name, "sluice_gate") * 4 + if rate == 0 then + return + end + + local back_dir = minetest.facedir_to_dir(node.param2) + local backpos = vector.add(pos, back_dir) + local backnode = minetest.get_node(backpos) + -- print("back node: "..backnode.name) + local backlevel = minetest.get_node_level(backpos) + + local front_dir = vector.multiply(back_dir, -1) + local frontpos = vector.add(pos, front_dir) + local frontnode = minetest.get_node(frontpos) + local frontlevel = minetest.get_node_level(frontpos) + + if frontnode.name ~= "air" and frontnode.name ~= "springs:water" then + -- print("not front") + return + end + if backnode.name ~= "air" and backnode.name ~= "springs:water" then + -- print("not back: ".. backnode.name) + return + end + + -- print("back level: "..backlevel) + -- print("front level: "..frontlevel) + + if math.abs(backlevel - frontlevel) < 2 then + return + end + + if frontlevel > backlevel then + local tmppos = backpos + local tmpnode = backnode + local tmplevel = backlevel + backnode = frontnode + backpos = frontpos + backlevel = frontlevel + frontnode = tmpnode + frontpos = tmppos + frontlevel = tmplevel + end + + -- from back to front + + local max_cap = 64 - frontlevel + local max_avail = backlevel + local diff = backlevel - frontlevel + local half = math.floor(diff / 2) + local trans = math.min(rate, math.min(half, math.min(max_avail, max_cap))) + -- print("trans: " .. trans) + -- print("front pos: "..frontpos.x ..","..frontpos.y.. ","..frontpos.z) + minetest.set_node_level(backpos, backlevel - trans) + if frontnode.name == "air" then + minetest.set_node(frontpos, {name= "springs:water"}) + minetest.set_node_level(frontpos, trans) + else + -- print("setting front level: ".. (frontlevel + trans)) + minetest.set_node_level(frontpos, frontlevel + trans) + end + + + + end +}) + + + diff --git a/wells.lua b/wells.lua new file mode 100644 index 0000000..048617e --- /dev/null +++ b/wells.lua @@ -0,0 +1,194 @@ + + + + + + + + + +minetest.register_node("springs:well_pipe", { + description = "Well Pipe Section", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + -- pump bar + {-.05, .5, -.05, .05, .65, .05 }, + + -- casing + {-.2, -.5, -.2, .2, .5, .2 }, + {-.10, -.5, -.25, .10, .5, .25 }, + {-.25, -.5, -.10, .25, .5, .10 }, + + }, + }, + paramtype = "light", + is_ground_content = false, + tiles = { "default_steel_block.png" }, + walkable = true, + groups = { cracky = 3 }, + +}) + + + + +local function check_well_pipe(pos) + + + + + + +end + + + +minetest.register_node("springs:well_head", { + description = "Well Head", + drawtype = "connected", + node_box = { + type = "fixed", + fixed = { + -- housing + {-.3, -.3, -.3, .3, .3, .3 }, + + -- casing + {-.2, -.5, -.2, .2, 0, .2 }, + {-.10, -.5, -.25, .10, 0, .25 }, + {-.25, -.5, -.10, .25, 0, .10 }, + + }, + connect_front = {{-.1, -.1, -.5, .1, .1, .1}}, + connect_left = {{-.5, -.1, -.1, -.1, .1, .1}}, + connect_back = {{-.1, -.1, .1, .1, .1, .5}}, + connect_right = {{ .1, -.1, -.1, .5, .1, .1}}, + }, + connects_to = { "group:water_pipe" }, + paramtype = "light", + is_ground_content = false, + tiles = { "default_steel_block.png" }, + walkable = true, + groups = { cracky = 3, water_fixture = 1 }, + + on_punch = function(pos) + ----local node = minetest.get_node(pos) + --local n = math.min(8, i + 1) + --minetest.set_node(pos, {name = "springs:sluice_gate_"..n, param2 = node.param2}) + end, + on_construct = function(pos) + print("\nwell head placed at "..pos.x..","..pos.y..","..pos.z) + local hash = minetest.hash_node_position(pos) + + local merge_list = {} + local current_net = nil + local found_net = 0 + + + local check_net = function(npos) + local nhash = minetest.hash_node_position(npos) + local nphash = net_members[nhash] + if nphash ~= nil then + local pnet = networks[nphash] + + if nil == current_net then + print("joining existing network: ".. pnet.name) + net_members[hash] = nphash + current_net = nphash + pnet.count = pnet.count + 1 + pnet.inputs[hash] = 1 + table.insert(merge_list, pnet) + elseif current_net == nphash then + print("alternate connection to existing network") + else + print("found seconday network: "..pnet.name) + table.insert(merge_list, pnet) + end + + found_net = 1 + end + end + + + + + check_net({x=pos.x, y=pos.y - 1, z=pos.z}) + check_net({x=pos.x, y=pos.y + 1, z=pos.z}) + check_net({x=pos.x, y=pos.y, z=pos.z + 1}) + check_net({x=pos.x, y=pos.y, z=pos.z - 1}) + + + if found_net == 0 then + + print("new network: hash: ".. hash .." name: " ..netname); + networks[hash] = { + hash = hash, + pos = {x=pos.x, y=pos.y, z=pos.z}, + name = netname, + count = 1, + inputs = { + [hash] = 1, + }, + outputs = {}, + buffer = 0, + } + + net_members[hash] = hash + + netname = netname + 1 + end + + + + + if #merge_list > 1 then + print("\n merging "..#merge_list.." networks") + + local biggest = {count = 0} + local mlookup = {} + + for _,n in ipairs(merge_list) do + mlookup[n.hash] = 1 + if n.count > biggest.count then + biggest = n + end + end + + mlookup[biggest.hash] = 0 + + for k,v in pairs(net_members) do + if mlookup[v] == 1 then + net_members[k] = biggest.hash + end + end + + + for _,n in ipairs(merge_list) do + if n.hash ~= biggest.hash then + biggest.count = biggest.count + n.count + n.count = 0 + end + end + + end + + + save_data() + + end +}) + + + + + + + + + + + + + +