diff --git a/basis/fuel_lib.lua b/basis/fuel_lib.lua new file mode 100644 index 0000000..7b48fa4 --- /dev/null +++ b/basis/fuel_lib.lua @@ -0,0 +1,231 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2020 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + Oil fuel burning lib + +]]-- + +local S2P = minetest.string_to_pos +local P2S = minetest.pos_to_string +local M = minetest.get_meta +local S = techage.S +local LQD = function(pos) return (minetest.registered_nodes[techage.get_node_lvm(pos).name] or {}).liquid end +local Pipe = techage.LiquidPipe +local liquid = techage.liquid +local ValidOilFuels = techage.firebox.ValidOilFuels +local Burntime = techage.firebox.Burntime + +techage.fuel = {} + +local CAPACITY = 50 +local BLOCKING_TIME = 0.3 -- 300ms + +techage.fuel.CAPACITY = CAPACITY + +-- fuel burning categories (better than...) +techage.fuel.BT_BITUMEN = 4 +techage.fuel.BT_OIL = 3 +techage.fuel.BT_FUELOIL = 2 +techage.fuel.BT_NAPHTHA = 1 + + +function techage.fuel.fuel_container(x, y, nvm) + local itemname = "" + if nvm.liquid and nvm.liquid.name and nvm.liquid.amount and nvm.liquid.amount > 0 then + itemname = nvm.liquid.name.." "..nvm.liquid.amount + end + local fuel_percent = 0 + if nvm.running then + fuel_percent = ((nvm.burn_cycles or 1) * 100) / (nvm.burn_cycles_total or 1) + end + return "container["..x..","..y.."]".. + "box[0,0;1.05,2.1;#000000]".. + "image[0.1,0.1;1,1;default_furnace_fire_bg.png^[lowpart:".. + fuel_percent..":default_furnace_fire_fg.png]".. + techage.item_image(0.1, 1.1, itemname).. + "container_end[]" +end + +local function help(x, y) + local tooltip = S("To add fuel punch\nthis block\nwith a fuel container") + return "label["..x..","..y..";"..minetest.colorize("#000000", minetest.formspec_escape("[?]")).."]".. + "tooltip["..x..","..y..";0.5,0.5;"..tooltip..";#0C3D32;#FFFFFF]" +end + +function techage.fuel.formspec(nvm) + local title = S("Fuel Menu") + return "size[4,3]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "box[0,-0.1;3.8,0.5;#c6e8ff]".. + "label[1,-0.1;"..minetest.colorize("#000000", title).."]".. + help(3.4, -0.1).. + techage.fuel.fuel_container(1.5, 1, nvm) +end + +--local function fill_container(pos, inv, nvm) +-- nvm.liquid = nvm.liquid or {} +-- nvm.liquid.amount = nvm.liquid.amount or 0 +-- local empty_container = inv:get_stack("fuel", 1):get_name() +-- local full_container = liquid.get_full_container(empty_container, nvm.liquid.name) +-- if empty_container and full_container then +-- local ldef = liquid.get_liquid_def(full_container) +-- if ldef and nvm.liquid.amount - ldef.size >= 0 then +-- inv:remove_item("fuel", ItemStack(empty_container)) +-- inv:add_item("fuel", ItemStack(full_container)) +-- nvm.liquid.amount = nvm.liquid.amount - ldef.size +-- if nvm.liquid.amount == 0 then +-- nvm.liquid.name = nil +-- end +-- end +-- end +--end + +--local function empty_container(pos, inv, nvm) +-- nvm.liquid = nvm.liquid or {} +-- nvm.liquid.amount = nvm.liquid.amount or 0 +-- local stack = inv:get_stack("fuel", 1) +-- if stack:get_count() == 1 then +-- local ldef = liquid.get_liquid_def(stack:get_name()) +-- if ldef and ValidOilFuels[ldef.inv_item] then +-- if not nvm.liquid.name or ldef.inv_item == nvm.liquid.name then +-- if nvm.liquid.amount + ldef.size <= CAPACITY then +-- inv:remove_item("fuel", stack) +-- inv:add_item("fuel", ItemStack(ldef.container)) +-- nvm.liquid.amount = nvm.liquid.amount + ldef.size +-- nvm.liquid.name = ldef.inv_item +-- end +-- end +-- end +-- end +--end + +--local function move_item(pos, stack) +-- local nvm = techage.get_nvm(pos) +-- local inv = M(pos):get_inventory() +-- if liquid.is_container_empty(stack:get_name()) then +-- fill_container(pos, inv, nvm) +-- else +-- empty_container(pos, inv, nvm) +-- end +-- M(pos):set_string("formspec", techage.fuel.formspec(nvm)) +--end + +--function techage.fuel.move_item(pos, stack, formspec) +-- local nvm = techage.get_nvm(pos) +-- local inv = M(pos):get_inventory() +-- if liquid.is_container_empty(stack:get_name()) then +-- fill_container(pos, inv, nvm) +-- else +-- empty_container(pos, inv, nvm) +-- end +-- M(pos):set_string("formspec", formspec(pos, nvm)) +--end + +--function techage.fuel.allow_metadata_inventory_put(pos, listname, index, stack, player) +-- if minetest.is_protected(pos, player:get_player_name()) then +-- return 0 +-- end +-- if liquid.is_container_empty(stack:get_name()) then +-- return 1 +-- end +-- local category = LQD(pos).fuel_cat +-- local ldef = liquid.get_liquid_def(stack:get_name()) +-- if ldef and ValidOilFuels[ldef.inv_item] and ValidOilFuels[ldef.inv_item] <= category then +-- return 1 +-- end +-- return 0 +--end + +--function techage.fuel.allow_metadata_inventory_take(pos, listname, index, stack, player) +-- if minetest.is_protected(pos, player:get_player_name()) then +-- return 0 +-- end +-- return stack:get_count() +--end + +--function techage.fuel.on_metadata_inventory_put(pos, listname, index, stack, player) +-- minetest.after(0.5, move_item, pos, stack) +--end + +function techage.fuel.can_dig(pos, player) + if minetest.is_protected(pos, player:get_player_name()) then + return false + end + local nvm = techage.get_nvm(pos) + nvm.liquid = nvm.liquid or {} + nvm.liquid.amount = nvm.liquid.amount or 0 + local inv = M(pos):get_inventory() + return inv:is_empty("fuel") and nvm.liquid.amount == 0 +end + +function techage.fuel.on_rightclick(pos, node, clicker) + techage.set_activeformspec(pos, clicker) + local nvm = techage.get_nvm(pos) + M(pos):set_string("formspec", techage.fuel.formspec(nvm)) +end + +--function techage.fuel.on_receive_fields(pos, formname, fields, player) +-- if minetest.is_protected(pos, player:get_player_name()) then +-- return +-- end +-- local nvm = techage.get_nvm(pos) +-- nvm.countdown = 10 +-- M(pos):set_string("formspec", techage.fuel.formspec(nvm)) +--end + +--function techage.fuel.formspec_update(pos, nvm) +-- if nvm.countdown and nvm.countdown > 0 then +-- nvm.countdown = nvm.countdown - 1 +-- M(pos):set_string("formspec", techage.fuel.formspec(nvm)) +-- end +--end + +-- name is the fuel item name +function techage.fuel.burntime(name) + if ValidOilFuels[name] then + return Burntime[name] or 0.01 -- not zero ! + end + return 0.01 -- not zero ! +end + +function techage.fuel.valid_fuel(name, category) + return ValidOilFuels[name] and ValidOilFuels[name] <= category +end + +function techage.fuel.on_punch(pos, node, puncher, pointed_thing) + local nvm = techage.get_nvm(pos) + local mem = techage.get_mem(pos) + mem.blocking_time = mem.blocking_time or 0 + if mem.blocking_time > techage.SystemTime then + return + end + + local wielded_item = puncher:get_wielded_item():get_name() + local item_count = puncher:get_wielded_item():get_count() + local new_item = liquid.fill_on_punch(nvm, wielded_item, item_count, puncher) + if new_item then + puncher:set_wielded_item(new_item) + M(pos):set_string("formspec", techage.fuel.formspec(pos, nvm)) + mem.blocking_time = techage.SystemTime + BLOCKING_TIME + return + end + + local ldef = liquid.get_liquid_def(wielded_item) + if ldef and ValidOilFuels[ldef.inv_item] then + local new_item = liquid.empty_on_punch(pos, nvm, wielded_item) + if new_item then + puncher:set_wielded_item(new_item) + M(pos):set_string("formspec", techage.fuel.formspec(pos, nvm)) + mem.blocking_time = techage.SystemTime + BLOCKING_TIME + end + end +end diff --git a/basis/liquid_lib.lua b/basis/liquid_lib.lua new file mode 100644 index 0000000..4a360c7 --- /dev/null +++ b/basis/liquid_lib.lua @@ -0,0 +1,254 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2020 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + Liquid lib + +]]-- + +local M = minetest.get_meta +local S = techage.S +local P2S = minetest.pos_to_string +local LQD = function(pos) return (minetest.registered_nodes[techage.get_node_lvm(pos).name] or {}).liquid end + +local BLOCKING_TIME = 0.3 -- 300ms + +techage.liquid = {} +local LiquidDef = {} +local ContainerDef = {} + +local function help(x, y) + local tooltip = S("To add liquids punch\nthe tank\nwith a liquid container") + return "label["..x..","..y..";"..minetest.colorize("#000000", minetest.formspec_escape("[?]")).."]".. + "tooltip["..x..","..y..";0.5,0.5;"..tooltip..";#0C3D32;#FFFFFF]" +end + +function techage.liquid.formspec(pos, nvm) + local title = S("Liquid Tank") + local itemname = "techage:liquid" + if nvm.liquid and nvm.liquid.amount and nvm.liquid.amount > 0 and nvm.liquid.name then + itemname = nvm.liquid.name.." "..nvm.liquid.amount + end + return "size[4,2]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "box[0,-0.1;3.8,0.5;#c6e8ff]".. + "label[1,-0.1;"..minetest.colorize("#000000", title).."]".. + help(3.4, -0.1).. + techage.item_image(1.5, 1, itemname) +end + +--function techage.liquid.move_item(pos, stack, size, formspec) +-- local nvm = techage.get_nvm(pos) +-- local inv = M(pos):get_inventory() +-- if liquid.is_container_empty(stack:get_name()) then +-- fill_container(pos, inv) +-- else +-- empty_container(pos, inv, size) +-- end +-- M(pos):set_string("formspec", formspec(pos, nvm)) +--end + +function techage.liquid.is_empty(pos) + local nvm = techage.get_nvm(pos) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("src") and inv:is_empty("dst") and (not nvm.liquid or (nvm.liquid.amount or 0) == 0) +end + +techage.liquid.tubing = { +-- on_pull_item = function(pos, in_dir, num) +-- local inv = M(pos):get_inventory() +-- if not inv:is_empty("dst") then +-- local taken = techage.get_items(inv, "dst", num) +-- if not inv:is_empty("src") then +-- fill_container(pos, inv) +-- end +-- return taken +-- end +-- end, +-- on_push_item = function(pos, in_dir, stack) +-- local inv = M(pos):get_inventory() +-- if inv:room_for_item("src", stack) then +-- inv:add_item("src", stack) +-- if liquid.is_container_empty(stack:get_name()) then +-- fill_container(pos, inv) +-- else +-- empty_container(pos, inv) +-- end +-- return true +-- end +-- return false +-- end, +-- on_unpull_item = function(pos, in_dir, stack) +-- local meta = M(pos) +-- local inv = meta:get_inventory() +-- return techage.put_items(inv, "dst", stack) +-- end, + on_recv_message = function(pos, src, topic, payload) + if topic == "load" then + local nvm = techage.get_nvm(pos) + return techage.power.percent(LQD(pos).capa, (nvm.liquid and nvm.liquid.amount) or 0) + elseif topic == "size" then + return LQD(pos).capa + else + return "unsupported" + end + end, +} + +-- like: register_liquid("techage:ta3_barrel_oil", "techage:ta3_barrel_empty", 10, "techage:oil") +function techage.register_liquid(full_container, empty_container, container_size, inv_item) + LiquidDef[full_container] = {container = empty_container, size = container_size, inv_item = inv_item} + ContainerDef[empty_container] = ContainerDef[empty_container] or {} + ContainerDef[empty_container][inv_item] = full_container +end + +local function get_liquid_def(full_container) + return LiquidDef[full_container] +end + +local function get_container_def(container_name) + return ContainerDef[container_name] +end + +local function is_container_empty(container_name) + return ContainerDef[container_name] +end + +local function get_full_container(empty_container, inv_item) + return ContainerDef[empty_container] and ContainerDef[empty_container][inv_item] +end + +local function fill_container(pos, inv, empty_container) + local nvm = techage.get_nvm(pos) + nvm.liquid = nvm.liquid or {} + nvm.liquid.amount = nvm.liquid.amount or 0 + local full_container = get_full_container(empty_container, nvm.liquid.name) + if empty_container and full_container then + local ldef = get_liquid_def(full_container) + if ldef and nvm.liquid.amount - ldef.size >= 0 then + if inv:room_for_item("dst", {name = full_container}) then + inv:add_item("dst", {name = full_container}) + nvm.liquid.amount = nvm.liquid.amount - ldef.size + if nvm.liquid.amount == 0 then + nvm.liquid.name = nil + end + return true + end + end + end + -- undo + inv:add_item("src", {name = empty_container}) + return false +end + +local function empty_container(pos, inv, full_container) + local nvm = techage.get_nvm(pos) + nvm.liquid = nvm.liquid or {} + nvm.liquid.amount = nvm.liquid.amount or 0 + local tank_size = LQD(pos).capa or 0 + local ldef = get_liquid_def(full_container) + --print("ldef", dump(ldef), "tank_size", tank_size) + if ldef and (not nvm.liquid.name or ldef.inv_item == nvm.liquid.name) then + if nvm.liquid.amount + ldef.size <= tank_size then + if inv:room_for_item("dst", {name = ldef.container}) then + inv:add_item("dst", {name = ldef.container}) + nvm.liquid.amount = nvm.liquid.amount + ldef.size + nvm.liquid.name = ldef.inv_item + return true + end + end + end + -- undo + inv:add_item("src", {name = full_container}) + return false +end + +-- check if the given empty container can be replaced by a full +-- container and added to the players inventory +local function fill_on_punch(nvm, empty_container, item_count, puncher) + nvm.liquid = nvm.liquid or {} + nvm.liquid.amount = nvm.liquid.amount or 0 + local full_container = get_full_container(empty_container, nvm.liquid.name) + if empty_container and full_container then + local item = {name = full_container} + local ldef = get_liquid_def(full_container) + if ldef and nvm.liquid.amount - ldef.size >= 0 then + if item_count > 1 then -- can't be simply replaced? + -- check for extra free space + local inv = puncher:get_inventory() + if inv:room_for_item("main", {name = full_container}) then + -- add full container and return + -- the empty once - 1 + inv:add_item("main", {name = full_container}) + item = {name = empty_container, count = item_count - 1} + else + return -- no free space + end + end + nvm.liquid.amount = nvm.liquid.amount - ldef.size + if nvm.liquid.amount == 0 then + nvm.liquid.name = nil + end + return item -- to be added to the players inv. + end + end +end + +local function empty_on_punch(pos, nvm, full_container) + nvm.liquid = nvm.liquid or {} + nvm.liquid.amount = nvm.liquid.amount or 0 + local ldef = get_liquid_def(full_container) + if ldef then + local tank_size = LQD(pos).capa or 0 + if not nvm.liquid.name or ldef.inv_item == nvm.liquid.name then + if nvm.liquid.amount + ldef.size <= tank_size then + nvm.liquid.amount = nvm.liquid.amount + ldef.size + nvm.liquid.name = ldef.inv_item + return {name = ldef.container} + end + end + end +end + +function techage.liquid.on_punch(pos, node, puncher, pointed_thing) + local nvm = techage.get_nvm(pos) + local mem = techage.get_mem(pos) + mem.blocking_time = mem.blocking_time or 0 + if mem.blocking_time > techage.SystemTime then + return + end + + local wielded_item = puncher:get_wielded_item():get_name() + local item_count = puncher:get_wielded_item():get_count() + local new_item = fill_on_punch(nvm, wielded_item, item_count, puncher) + or empty_on_punch(pos, nvm, wielded_item) + if new_item then + puncher:set_wielded_item(new_item) + M(pos):set_string("formspec", techage.fuel.formspec(pos, nvm)) + mem.blocking_time = techage.SystemTime + BLOCKING_TIME + return + end +end + +function techage.register_liquid(full_container, empty_container, container_size, inv_item) + LiquidDef[full_container] = {container = empty_container, size = container_size, inv_item = inv_item} + ContainerDef[empty_container] = ContainerDef[empty_container] or {} + ContainerDef[empty_container][inv_item] = full_container +end + +techage.liquid.get_liquid_def = get_liquid_def +techage.liquid.get_container_def = get_container_def +techage.liquid.is_container_empty = is_container_empty +techage.liquid.get_full_container = get_full_container +techage.liquid.fill_container = fill_container +techage.liquid.empty_container = empty_container +techage.liquid.fill_on_punch = fill_on_punch +techage.liquid.empty_on_punch = empty_on_punch diff --git a/liquids/filler.lua b/liquids/filler.lua new file mode 100644 index 0000000..cde0e87 --- /dev/null +++ b/liquids/filler.lua @@ -0,0 +1,147 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2020 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + TA3 Liquid Filler + +]]-- + +-- for lazy programmers +local M = minetest.get_meta +local S = techage.S + +local liquid = techage.liquid +local CYCLE_TIME = 2 + +local function formspec(pos) + return "size[8,7]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "box[0,-0.1;7.8,0.5;#c6e8ff]".. + "label[3,-0.1;"..minetest.colorize( "#000000", S("Liquid Filler")).."]".. + "list[context;src;0,0.8;3,3;]".. + "image[3.5,1.8;1,1;techage_form_arrow_bg.png^[transformR270]".. + "list[context;dst;5,0.8;3,3;]".. + "list[current_player;main;0,4.2;8,3;]".. + "listring[current_player;main]".. + "listring[context;src]" .. + "listring[current_player;main]".. + "listring[context;dst]" .. + "listring[current_player;main]".. + default.get_hotbar_bg(0, 4.2) + +end + +local function allow_metadata_inventory_put(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + minetest.get_node_timer(pos):start(CYCLE_TIME) + return stack:get_count() +end + +local function allow_metadata_inventory_take(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + return stack:get_count() +end + +local function can_dig(pos, player) + if minetest.is_protected(pos, player:get_player_name()) then + return false + end + local inv = M(pos):get_inventory() + return inv:is_empty("src") and inv:is_empty("dst") +end + +local function on_rightclick(pos, node, clicker) + local inv = M(pos):get_inventory() + if not inv:is_empty("src") then + minetest.get_node_timer(pos):start(CYCLE_TIME) + end +end + +local function node_timer(pos, elapsed) + print("node_timer") + local inv = M(pos):get_inventory() + if not inv:is_empty("src") then + local taken = techage.get_items(inv, "src", 1) + if liquid.is_container_empty(taken:get_name()) then + return liquid.fill_container({x = pos.x, y = pos.y+1, z = pos.z}, inv, taken:get_name()) + else + return liquid.empty_container({x = pos.x, y = pos.y-1, z = pos.z}, inv, taken:get_name()) + end + end + return false +end + +minetest.register_node("techage:filler", { + description = S("TA Liquid Filler"), + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_hole_tube.png", + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_hole_tube.png", + "techage_filling_ta3.png^techage_frame_small_ta3.png^techage_appl_outp.png", + "techage_filling_ta3.png^techage_frame_small_ta3.png^techage_appl_inp.png", + "techage_filling_ta3.png^techage_appl_liquid_hopper.png^techage_frame_ta3.png", + "techage_filling_ta3.png^techage_appl_liquid_hopper.png^techage_frame_ta3.png", + }, + + paramtype2 = "facedir", -- important! + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + { -1/2, -3/8, -3/8, 1/2, 3/8, 3/8}, -- box + { -2/8, 3/8, -2/8, 2/8, 4/8, 2/8}, -- top + { -2/8, -4/8, -2/8, 2/8, -3/8, 2/8}, -- bottom + }, + }, + + on_construct = function(pos) + local inv = M(pos):get_inventory() + inv:set_size('src', 9) + inv:set_size('dst', 9) + end, + + after_place_node = function(pos, placer) + M(pos):set_string("formspec", formspec(pos)) + end, + + on_rightclick = on_rightclick, + on_timer = node_timer, + can_dig = can_dig, + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_take = allow_metadata_inventory_take, + + on_rotate = screwdriver.disallow, -- important! + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + groups = {cracky=2, crumbly=2, choppy=2}, + sounds = default.node_sound_defaults(), +}) + +techage.register_node({"techage:filler"}, { + on_pull_item = function(pos, in_dir, num) + local inv = M(pos):get_inventory() + return techage.get_items(inv, "dst", num) + end, + on_push_item = function(pos, in_dir, stack) + local inv = M(pos):get_inventory() + minetest.get_node_timer(pos):start(CYCLE_TIME) + return techage.put_items(inv, "src", stack) + end, + on_unpull_item = function(pos, in_dir, stack) + local inv = M(pos):get_inventory() + return techage.put_items(inv, "dst", stack) + end, +}) diff --git a/liquids/node_api.lua b/liquids/node_api.lua new file mode 100644 index 0000000..550297b --- /dev/null +++ b/liquids/node_api.lua @@ -0,0 +1,220 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019-2020 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + Liquid transportation API via Pipe(s) (peer, put, take) + +]]-- + +local P2S = minetest.pos_to_string +local M = minetest.get_meta +local N = function(pos) return minetest.get_node(pos).name end +local LQD = function(pos) return (minetest.registered_nodes[techage.get_node_lvm(pos).name] or {}).liquid end +local Pipe = techage.LiquidPipe +local S = techage.S + +local net_def = techage.networks.net_def +local networks = techage.networks + +local liquid = techage.liquid + +-- +-- Networks +-- + +-- determine network ID (largest hash number of all pumps) +local function determine_netID(pos, outdir) + local netID = 0 + networks.connection_walk(pos, outdir, Pipe, function(pos, indir, node) + local ntype = net_def(pos, "pipe2").ntype + if ntype and ntype == "pump" then + local new = minetest.hash_node_position(pos) * 8 + outdir + if netID <= new then + netID = new + end + end + end) + return netID +end + +-- store network ID on each pump like node +local function store_netID(pos, outdir, netID) + networks.connection_walk(pos, outdir, Pipe, function(pos, indir, node) + local ntype = net_def(pos, "pipe2").ntype + if ntype and ntype == "pump" then + local nvm = techage.get_nvm(pos) + local outdir = networks.Flip[indir] + nvm.pipe2 = nvm.pipe2 or {} + nvm.pipe2.netIDs = nvm.pipe2.netIDs or {} + nvm.pipe2.netIDs[outdir] = netID + end + end) +end + +-- delete network and ID on each pump like node +local function delete_netID(pos, outdir) + local netID = 0 + networks.connection_walk(pos, outdir, Pipe, function(pos, indir, node) + local ntype = net_def(pos, "pipe2").ntype + if ntype and ntype == "pump" then + local nvm = techage.get_nvm(pos) + local outdir = networks.Flip[indir] + if nvm.pipe2 and nvm.pipe2.netIDs and nvm.pipe2.netIDs[outdir] then + netID = nvm.pipe2.netIDs[outdir] + nvm.pipe2.netIDs[outdir] = nil + end + end + end) + networks.delete_network("pipe2", netID) +end + +local function get_netID(pos, outdir) + local nvm = techage.get_nvm(pos) + if not nvm.pipe2 or not nvm.pipe2.netIDs or not nvm.pipe2.netIDs[outdir] then + local netID = determine_netID(pos, outdir) + store_netID(pos, outdir, netID) + end + return nvm.pipe2 and nvm.pipe2.netIDs and nvm.pipe2.netIDs[outdir] +end + +local function get_network_table(pos, outdir, ntype) + local netID = get_netID(pos, outdir) + if netID then + local netw = networks.get_network("pipe2", netID) + if not netw then + netw = networks.collect_network_nodes(pos, outdir, Pipe) + networks.set_network("pipe2", netID, netw) + end + --print("netw", string.format("%012X", netID), dump(netw)) + return netw[ntype] or {} + end + return {} +end + + +-- +-- Client remote functions +-- + +-- Determine and return liquid 'name' from the +-- remote inventory. +function liquid.peek(pos, outdir) + for _,item in ipairs(get_network_table(pos, outdir, "tank")) do + local liquid = LQD(item.pos) + if liquid and liquid.peek then + return liquid.peek(item.pos, item.indir) + end + end +end + +-- Add given amount of liquid to the remote inventory. +-- return leftover amount +function liquid.put(pos, outdir, name, amount, player_name) + for _,item in ipairs(get_network_table(pos, outdir, "tank")) do + local liquid = LQD(item.pos) + if liquid and liquid.put and liquid.peek then + -- wrong items? + local peek = liquid.peek(item.pos, item.indir) + if peek and peek ~= name then return amount or 0 end + if player_name then + local num = techage.get_node_number(pos) or "000" + techage.mark_position(player_name, item.pos, "("..num..") put", "", 1) + end + amount = liquid.put(item.pos, item.indir, name, amount) + if not amount or amount == 0 then break end + end + end + return amount or 0 +end + +-- Take given amount of liquid for the remote inventory. +-- return taken amount and item name +function liquid.take(pos, outdir, name, amount, player_name) + local taken = 0 + local item_name = nil + for _,item in ipairs(get_network_table(pos, outdir, "tank")) do + local liquid = LQD(item.pos) + if liquid and liquid.take then + if player_name then + local num = techage.get_node_number(pos) + techage.mark_position(player_name, item.pos, "("..num..") take", "", 1) + end + local val, name = liquid.take(item.pos, item.indir, name, amount - taken) + if val and name then + taken = taken + val + item_name = name + if amount - taken == 0 then break end + end + end + end + return taken, item_name +end + +-- +-- Server local functions +-- + +function liquid.srv_peek(pos, indir) + local nvm = techage.get_nvm(pos) + nvm.liquid = nvm.liquid or {} + return nvm.liquid.name +end + +function liquid.srv_put(pos, indir, name, amount) + local nvm = techage.get_nvm(pos) + nvm.liquid = nvm.liquid or {} + amount = amount or 0 + if not nvm.liquid.name then + nvm.liquid.name = name + nvm.liquid.amount = amount + return 0 + elseif nvm.liquid.name == name then + nvm.liquid.amount = nvm.liquid.amount or 0 + local capa = LQD(pos).capa + if nvm.liquid.amount + amount <= capa then + nvm.liquid.amount = nvm.liquid.amount + amount + return 0 + else + local rest = nvm.liquid.amount + amount - capa + nvm.liquid.amount = capa + return rest + end + end + return amount +end + +function liquid.srv_take(pos, indir, name, amount) + local nvm = techage.get_nvm(pos) + nvm.liquid = nvm.liquid or {} + amount = amount or 0 + if not name or nvm.liquid.name == name then + name = nvm.liquid.name + nvm.liquid.amount = nvm.liquid.amount or 0 + if nvm.liquid.amount > amount then + nvm.liquid.amount = nvm.liquid.amount - amount + return amount, name + else + local rest = nvm.liquid.amount + local name = nvm.liquid.name + nvm.liquid.amount = 0 + nvm.liquid.name = nil + return rest, name + end + end + return 0 +end + + +-- To be called from each node via 'tubelib2_on_update2' +-- 'output' is optional and only needed for nodes with dedicated +-- pipe sides (e.g. pumps). +function liquid.update_network(pos, outdir) + networks.node_connections(pos, Pipe) + delete_netID(pos, outdir) +end diff --git a/textures/techage_appl_liquid_hopper.png b/textures/techage_appl_liquid_hopper.png new file mode 100644 index 0000000..0e2d39b Binary files /dev/null and b/textures/techage_appl_liquid_hopper.png differ diff --git a/textures/techage_frame_small_ta3.png b/textures/techage_frame_small_ta3.png new file mode 100644 index 0000000..4bdf081 Binary files /dev/null and b/textures/techage_frame_small_ta3.png differ