123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637 |
- -- pipelines are like pipes except much larger and more performant
- -- pipelines are also only point-to-point; there are no joints
- -- pipelines need pumps to force the fluid through, even downhill
- local networks = {}
- local net_members = {}
- local storage = {}
- local netname = 1
- --local mod_storage = minetest.get_mod_storage()
- local mod_storage = bitumen.mod_storage -- minetest.get_mod_storage()
- networks = minetest.deserialize(mod_storage:get_string("pl_networks")) or {}
- net_members = minetest.deserialize(mod_storage:get_string("pl_net_members")) or {}
- storage = minetest.deserialize(mod_storage:get_string("pl_storage")) or {}
- netname = mod_storage:get_int("pl_netname") or 1
- local function save_data()
- --print("saving")
-
- mod_storage:set_string("pl_networks", minetest.serialize(networks))
- mod_storage:set_string("pl_net_members", minetest.serialize(net_members))
- mod_storage:set_string("pl_storage", minetest.serialize(storage))
- mod_storage:set_int("pl_netname", netname)
- end
- -- centralized network creation for consistency
- local function new_network(pos)
- local hash = minetest.hash_node_position(pos)
- print("new pipeline network: hash: ".. hash .." name: " ..netname);
-
- networks[hash] = {
- hash = hash,
- pos = {x=pos.x, y=pos.y, z=pos.z},
- fluid = 'air',
- name = netname,
- count = 1,
- inputs = {
- [hash] = 1,
- },
- outputs = {},
- buffer = 0,
- in_pressure = -32000,
-
- storage = {
- --[[
- [entry_hash] = < storage_center_hash >
- ]]
- }
- }
-
- net_members[hash] = hash
-
- netname = netname + 1
-
- return networks[hash], hash
- end
- local function pnet_for(pos)
- local hash = minetest.hash_node_position(pos)
- local ph = net_members[hash]
- if ph == nil then
- return nil, hash
- end
-
- return networks[ph], hash
- end
- -- merge a list of networks, if the are multiple nets in the list
- local function try_merge(merge_list)
- 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
- networks[n.hash] = nil -- delete old networks
- end
- end
-
- return biggest
- end
-
- return merge_list[1]
- end
- -- check specific nearby nodes for existing networks
- local function check_merge(pos, npos1, npos2)
- 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(npos1)
- check_net(npos2)
-
- return found_net, merge_list
- end
- bitumen.pipelines = {}
- -- used by external machines to find the network for a node
- bitumen.pipelines.get_net = function(pos)
- local hash = minetest.hash_node_position(pos)
- local phash = net_members[hash]
- if phash == nil then
- return nil, nil, hash
- end
-
- return networks[phash], phash, hash
- end
- bitumen.pipes.after_change = function(pos, opos1, opos2, npos1, npos2)
- local o1net, o1phash, o1hash = bitumen.pipelines.get_net(opos1)
- local o2net, o2phash, o2hash = bitumen.pipelines.get_net(opos2)
- local n1net, n1phash, n1hash = bitumen.pipelines.get_net(npos1)
- local n2net, n2phash, n2hash = bitumen.pipelines.get_net(npos2)
-
- local check_o1 = true
- local check_o2 = true
- local check_n1 = true
- local check_n2 = true
-
- -- check if one of the nodes is still in the network. this will often be the case
- if vector.equals(opos1, npos1) then
- print("old pos 1 is new pos 1")
- check_o1 = false
- check_n1 = false
- elseif vector.equals(opos1, npos2) then
- print("old pos 1 is new pos 1")
- check_o1 = false
- check_n2 = false
- end
- if vector.equals(opos2, npos1) then
- print("old pos 1 is new pos 1")
- check_o2 = false
- check_n1 = false
- elseif vector.equals(opos2, npos2) then
- print("old pos 1 is new pos 1")
- check_o2 = false
- check_n2 = false
- end
-
- -- remove o1 from the network
- if check_o1 then
-
-
- end
-
-
- -- merge with n1's network
- if check_o1 then
-
-
- end
-
-
-
-
-
-
-
-
- local hash = minetest.hash_node_position(pos)
- local phash = net_members[hash]
- if phash == nil then
- print("wtf: pipe has no network in after_destruct")
- return
- end
- local pnet = networks[phash]
- if pnet == nil then
- print("wtf: no network in after_destruct for pipe")
- return
- end
-
- -- remove this node from the network
- net_members[hash] = nil
- pnet.count = pnet.count - 1
-
- -- neighboring nodes
- local check_pos = {
- {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+1, z=pos.z},
- {x=pos.x, y=pos.y-1, z=pos.z},
- {x=pos.x, y=pos.y, z=pos.z+1},
- {x=pos.x, y=pos.y, z=pos.z-1},
- }
-
- local stack = {}
- local found = 0
- -- check neighbors for network membership
- for _,p in ipairs(check_pos) do
- local h = minetest.hash_node_position(p)
-
- local lphash = net_members[h]
- if lphash ~= nil then
- local lpnet = networks[lphash]
-
- -- only process pipes/fixtures on the same network as the destroyed pipe
- if lpnet and lpnet.name == pnet.name then
- stack[h] = vector.new(p)
- found = found + 1
- --print("check stack: "..p.x..","..p.y..","..p.z)
- else
- print("no lpnet")
- end
- else
- print("no lphash "..p.x..","..p.y..","..p.z)
- end
- end
-
- -- don't need to split the network if this was just on the end
- if found > 1 then
- --print("check to split the network")
- for h,p in pairs(stack) do
- print(dump(p))
- print(dump(h))
- -- BUG: spouts and intakes can be counted as pipes when walking the network
-
- -- just rename the net
- local new_pnet = rebase_network(p)
- -- print("split off pnet ".. new_pnet.name .. " at " .. minetest.pos_to_string(p))
- -- all fluid is lost in the network atm
- -- some networks might get orphaned, for example, the first
- -- net to be rebased in a loop
- end
-
-
- end
-
- save_data()
- end
- minetest.register_node("bitumen:pipeline", {
- description = "Petroleum pipeline segment",
- drawtype = "nodebox",
- node_box = {
- type = "fixed",
- fixed = {
- {-.3, -.35, -.5, .3, .35, .5},
- {-.35, -.3, -.5, .35, .3, .5},
- -- {-.4, -.4, -.4, .4, .4, .4},
- -- {-.4, -.4, -.4, .4, .4, .4},
- },
- },
- paramtype = "light",
- is_ground_content = false,
- paramtype2 = "facedir",
- is_ground_content = false,
- tiles = { "default_gold_block.png" },
- walkable = true,
- groups = { cracky = 3, petroleum_pipeline = 1, },
- on_place = minetest.rotate_node,
-
- on_construct = function(pos)
- print("\npipeline placed at "..pos.x..","..pos.y..","..pos.z)
-
-
- local node = minetest.get_node(pos)
-
- local back_dir = minetest.facedir_to_dir(node.param2)
- local backpos = vector.add(pos, back_dir)
- local frontpos = vector.subtract(pos, back_dir)
-
- -- minetest.set_node(backpos, {name="default:dirt"})
-
- -- local found_net, merge_list = check_merge(pos)
-
- --if found_net == 0 then
- -- local net = new_network(pos)
- --end
-
- -- try_merge(merge_list)
-
- --save_data()
- end,
-
- --after_destruct = bitumen.pipes.after_destruct,
- })
- minetest.register_node("bitumen:pipeline_elbow", {
- description = "Petroleum pipeline elbow",
- drawtype = "nodebox",
- node_box = {
- type = "fixed",
- fixed = {
- {-.3, -.35, -.5, .3, .35, .3},
- {-.35, -.3, -.5, .35, .3, .3},
-
- {-.3, -.3, -.35, .3, .5, .35},
- {-.35, -.3, -.3, .35, .5, .3},
- -- {-.4, -.4, -.4, .4, .4, .4},
- -- {-.4, -.4, -.4, .4, .4, .4},
- },
- },
- paramtype = "light",
- is_ground_content = false,
- paramtype2 = "facedir",
- is_ground_content = false,
- tiles = { "default_gold_block.png" },
- walkable = true,
- groups = { cracky = 3, petroleum_pipeline = 1, },
- on_place = minetest.rotate_node,
-
- on_rotate = function(pos, node, player, mode, new_param2)
-
-
-
- local oldback_dir = minetest.facedir_to_dir(node.param2)
- local oldfrontpos = vector.subtract(pos, oldback_dir)
-
- local oldtop_dir = ({[0]={x=0, y=1, z=0},
- {x=0, y=0, z=1},
- {x=0, y=0, z=-1},
- {x=1, y=0, z=0},
- {x=-1, y=0, z=0},
- {x=0, y=-1, z=0}})[math.floor(node.param2/4)]
-
- local oldtoppos = vector.add(pos, oldtop_dir)
-
- minetest.set_node(oldfrontpos, {name="default:glass"})
- minetest.set_node(oldtoppos, {name="default:glass"})
-
-
-
- local back_dir = minetest.facedir_to_dir(new_param2)
- local frontpos = vector.subtract(pos, back_dir)
-
- local top_dir = ({[0]={x=0, y=1, z=0},
- {x=0, y=0, z=1},
- {x=0, y=0, z=-1},
- {x=1, y=0, z=0},
- {x=-1, y=0, z=0},
- {x=0, y=-1, z=0}})[math.floor(new_param2/4)]
-
- local toppos = vector.add(pos, top_dir)
-
- minetest.set_node(frontpos, {name="default:dirt"})
- minetest.set_node(toppos, {name="default:cobble"})
- end,
-
- on_construct = function(pos)
- print("\npipeline elbow placed at "..pos.x..","..pos.y..","..pos.z)
-
-
- local node = minetest.get_node(pos)
-
-
- local back_dir = minetest.facedir_to_dir(node.param2)
- local frontpos = vector.subtract(pos, back_dir)
-
- local top_dir = ({[0]={x=0, y=1, z=0},
- {x=0, y=0, z=1},
- {x=0, y=0, z=-1},
- {x=1, y=0, z=0},
- {x=-1, y=0, z=0},
- {x=0, y=-1, z=0}})[math.floor(node.param2/4)]
-
- local toppos = vector.add(pos, top_dir)
-
- minetest.set_node(frontpos, {name="default:dirt"})
- minetest.set_node(toppos, {name="default:cobble"})
-
- -- local found_net, merge_list = check_merge(pos)
-
- --if found_net == 0 then
- -- local net = new_network(pos)
- --end
-
- -- try_merge(merge_list)
-
- --save_data()
- end,
-
- --after_destruct = bitumen.pipelines.after_destruct,
- })
- local storage_tank_builder_formspec =
- "size[10,8;]" ..
- default.gui_bg ..
- default.gui_bg_img ..
- default.gui_slots ..
- "list[context;main;0,0.3;4,3;]" ..
- "button[5,1;1,4;build;Build]" ..
- "list[current_player;main;0,3.85;8,1;]" ..
- "list[current_player;main;0,5.08;8,3;8]" ..
- "listring[context;main]" ..
- "listring[current_player;main]" ..
- default.get_hotbar_bg(0, 3.85)
- minetest.register_node("bitumen:storage_tank_constructor", {
- description = "Storage Tank Constructor",
- drawtype = "normal",
- paramtype2 = "facedir",
- on_rotate = screwdriver.rotate_simple,
- groups = {cracky=1},
- tiles = {
- "default_copper_block.png","default_tin_block.png",
- },
-
- on_construct = function(pos)
- local meta = minetest.get_meta(pos)
- local inv = meta:get_inventory()
- inv:set_size("main", 12)
-
- meta:set_string("formspec", storage_tank_builder_formspec);
- end,
-
- on_receive_fields = function(pos, form, fields, player)
-
- local meta = minetest.get_meta(pos)
-
- if fields.build then
- -- tanks can only be built on thick foundations
- local ret = bitumen.check_foundation(
- {x = pos.x - 15, y = pos.y - 3, z = pos.z - 15},
- {x = pos.x + 15, y = pos.y - 1, z = pos.z + 15},
- {
- ["default:steelblock"] = 1,
- ["bitumen:concrete"] = 1,
- }
- )
-
- if ret == false then
- minetest.chat_send_player(player:get_player_name(), "Foundation is incomplete: 30x3x30")
- return
- else
- minetest.chat_send_player(player:get_player_name(), "Foundation is complete.")
- end
-
- -- tanks need room
- local ret = bitumen.check_foundation(
- {x = pos.x - 16, y = pos.y , z = pos.z - 16},
- {x = pos.x + 16, y = pos.y + 12, z = pos.z + 16},
- {
- ["air"] = 1,
- ["bitumen:storage_tank_constructor"] = 1,
- }
- )
-
- if ret == false then
- minetest.chat_send_player(player:get_player_name(), "Area is not clear: 32x12x32")
- return
- else
- minetest.chat_send_player(player:get_player_name(), "Area is clear.")
- end
-
- local inv = meta:get_inventory();
-
- -- should be ~1500 sheets
- if (inv:contains_item("main", "bitumen:galv_steel_sheet 99") and
- inv:contains_item("main", "default:coal_lump 20")) then
-
- inv:remove_item("main", "bitumen:galv_steel_sheet 99")
- inv:remove_item("main", "default:coal_lump 20")
- else
- minetest.chat_send_player(player:get_player_name(), "Not enough materials: 99x Galvanized Steel Sheet, 20x Coal Lump")
- return
- end
-
- -- ready to go
- minetest.chat_send_player(player:get_player_name(), "Clear area, construction starting...")
-
- for i = 9,1,-1 do
- minetest.after(10-i, (function(n)
- return function()
- minetest.chat_send_player(
- player:get_player_name(),
- "Storage Tank construction in "..n.."..."
- )
- end
- end)(i))
- end
-
- minetest.after(10, function()
- minetest.set_node(pos, {name="bitumen:storage_tank"})
- end)
-
- end
- end,
- })
- bitumen.register_blueprint({
- name = "bitumen:storage_tank",
- })
- minetest.register_node("bitumen:storage_tank", {
- paramtype = "light",
- drawtype = "mesh",
- mesh = "storage_tank.obj",
- description = "Storage Tank",
- tiles = {
- "default_sand.png",
- },
- inventory_image = "default_sand.png",
- selection_box = {
- type = "fixed",
- fixed = {
- { -.5, -.5, -.5, .5, 1.5, .5 },
- -- { -8.2, -.5, -.2, -7.8, 10, .2 },
- -- { -.2, -.5, -8.2, .2, 10, -7.8 },
- -- { 8.2, -.5, -.2, 7.8, 10, .2 },
- -- { -.2, -.5, 8.2, .2, 10, 7.8 },
- },
- },
- collision_box = {
- type = "fixed",
- fixed = {
- { -.5, -.5, -.5, .5, 1.5, .5 },
- }
- },
- paramtype2 = "facedir",
- groups = {choppy=1, petroleum_fixture=1, bitumen_magic_proof=1 },
- sounds = default.node_sound_wood_defaults(),
-
- on_construct = function(pos)
- local meta = minetest.get_meta(pos)
- if placer then
- local owner = placer:get_player_name()
- meta:set_string("owner", owner)
- end
- -- meta:set_float("fluid_level", 0)
- -- meta:set_float("capacity", math.floor(3.14159 * .75 * 9 * 9 * 9 * 64))
- -- meta:set_string("infotext", "0%")
-
- bitumen.magic.set_collision_nodes(pos, bitumen.magic.gencylinder({0, 0, 0}, 14.99, 9))
-
- -- bitumen.pipes.on_construct(pos)
- end,
-
- on_destruct = bitumen.magic.on_destruct,
-
- can_dig = function(pos, player)
- -- local meta = minetest.get_meta(pos);
- -- local owner = meta:get_string("owner")
- -- local fluid_level = meta:get_float("fluid_level") or 0
- -- return player:get_player_name() ~= owner and fluid_level <= 0.01
- return true
- end,
- })
|