diff --git a/.test/source.lua b/.test/source.lua index 8f8c01a..eb0f735 100644 --- a/.test/source.lua +++ b/.test/source.lua @@ -47,7 +47,7 @@ minetest.register_node("techage:source", { }, paramtype2 = "facedir", - groups = {cracky=2, crumbly=2, choppy=2}, + groups = {cracky=2, crumbly=2, choppy=2, not_in_creative_inventory=1}, is_ground_content = false, on_rightclick = on_rightclick, on_timer = node_timer, diff --git a/basic_machines/distributor.lua b/basic_machines/distributor.lua index 33a1148..e018719 100644 --- a/basic_machines/distributor.lua +++ b/basic_machines/distributor.lua @@ -371,7 +371,7 @@ local tiles = {} -- '{power}' will be replaced by the power PNG tiles.pas = { -- up, down, right, left, back, front - "techage_filling_ta#.png^techage_appl_distri.png^techage_frame_ta#_top.png", + "techage_filling_ta#.png^techage_appl_distri.png^techage_frame_ta#_top.png^techage_appl_color_top.png", "techage_filling_ta#.png^techage_frame_ta#.png", "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_distri_yellow.png", "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_distri_green.png", @@ -390,7 +390,7 @@ tiles.act = { length = 1.0, }, }, - "techage_filling_ta#.png^techage_frame_ta#.png", + "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_color_top.png", "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_distri_yellow.png", "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_distri_green.png", "techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_distri_red.png", diff --git a/basic_machines/pusher.lua b/basic_machines/pusher.lua index 0fc81ff..f4f9391 100644 --- a/basic_machines/pusher.lua +++ b/basic_machines/pusher.lua @@ -108,6 +108,10 @@ tiles.act = { } local tubing = { + -- push item through the pusher in opposit direction + on_push_item = function(pos, in_dir, stack) + return in_dir == M(pos):get_int("pull_dir") and techage.push_items(pos, in_dir, stack) + end, is_pusher = true, -- is a pulling/pushing node on_recv_message = function(pos, src, topic, payload) diff --git a/basis/lib.lua b/basis/lib.lua index 7554565..db4cd8d 100644 --- a/basis/lib.lua +++ b/basis/lib.lua @@ -173,4 +173,21 @@ local function determine_ocean_ids() end end -determine_ocean_ids() \ No newline at end of file +determine_ocean_ids() + + +local function tooltip(name) + name = string.split(name, " ")[1] + local ndef = minetest.registered_nodes[name] or minetest.registered_items[name] or minetest.registered_craftitems[name] + if ndef and ndef.description then + return minetest.formspec_escape(ndef.description) + end + return "" +end + +function techage.item_image(x, y, itemname) + return "box["..x..","..y..";0.87,0.9;#808080]".. + "item_image["..x..","..y..";1,1;"..itemname.."]".. + "tooltip["..x..","..y..";1,1;"..tooltip(itemname)..";#0C3D32;#FFFFFF]" +end + diff --git a/basis/mark2.lua b/basis/mark2.lua index b691403..19cda66 100644 --- a/basis/mark2.lua +++ b/basis/mark2.lua @@ -24,7 +24,7 @@ function techage.unmark_position(name) end end -function techage.mark_position(name, pos, nametag, color) +function techage.mark_position(name, pos, nametag, color, time) local marker = minetest.add_entity(pos, "techage:position_cube") if marker ~= nil then marker:set_nametag_attributes({color = color, text = nametag}) @@ -34,7 +34,7 @@ function techage.mark_position(name, pos, nametag, color) end marker_region[name][#marker_region[name] + 1] = marker end - minetest.after(30, techage.unmark_position, name) + minetest.after(time or 30, techage.unmark_position, name) end minetest.register_entity(":techage:position_cube", { @@ -50,8 +50,8 @@ minetest.register_entity(":techage:position_cube", { }, --use_texture_alpha = true, physical = false, - visual_size = {x = 2, y = 2}, - collisionbox = {-1,-1,-1, 1,1,1}, + visual_size = {x = 1.2, y = 1.2}, + collisionbox = {-0.6,-0.6,-0.6, 0.6,0.6,0.6}, glow = 8, }, on_step = function(self, dtime) diff --git a/basis/networks.lua b/basis/networks.lua new file mode 100644 index 0000000..3804f65 --- /dev/null +++ b/basis/networks.lua @@ -0,0 +1,289 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + Networks - the connection of tubelib2 tube/pipe/cable lines to networks +]]-- + +local S2P = minetest.string_to_pos +local P2S = minetest.pos_to_string +local M = minetest.get_meta +local N = techage.get_node_lvm +local S = techage.S +local hex = function(val) return string.format("%x", val) end + +local Networks = {} -- cache for networks + +techage.networks = {} -- name space + +local MAX_NUM_NODES = 500 +local BEST_BEFORE = 5 * 60 -- 5 minutes +local Route = {} -- Used to determine the already passed nodes while walking +local NumNodes = 0 +local DirToSide = {"B", "R", "F", "L", "D", "U"} +local Sides = {B = true, R = true, F = true, L = true, D = true, U = true} +local SideToDir = {B=1, R=2, F=3, L=4, D=5, U=6} +local Flip = {[0]=0,3,4,1,2,6,5} -- 180 degree turn + +local function error(pos, msg) + minetest.log("error", msg.." at "..P2S(pos).." "..N(pos).name) +end + +local function count_nodes(ntype, nodes) + local num = 0 + for _,pos in ipairs(nodes or {}) do + num = num + 1 + end + return ntype.."="..num +end + +local function output(network, valid) + local tbl = {} + for ntype,table in pairs(network) do + if type(table) == "table" then + tbl[#tbl+1] = count_nodes(ntype, table) + end + end + print("Network ("..valid.."): "..table.concat(tbl, ", ")) +end + +-- return the node definition local networks table +local function net_def(pos, net_name) + local ndef = minetest.registered_nodes[techage.get_node_lvm(pos).name] + return ndef and ndef.networks and ndef.networks[net_name] or {} +end + +-- Calculate the node outdir based on node.param2 and nominal dir (according to side) +local function dir_to_outdir(dir, param2) + if dir < 5 then + return ((dir + param2 - 1) % 4) + 1 + end + return dir +end + +local function indir_to_dir(indir, param2) + if indir < 5 then + return ((indir - param2 + 5) % 4) + 1 + end + return Flip[indir] +end + +local function side_to_outdir(pos, side) + return dir_to_outdir(SideToDir[side], techage.get_node_lvm(pos).param2) +end + +-- Get tlib2 connection dirs as table +-- used e.g. for the connection walk +local function get_node_connections(pos, net_name) + local val = M(pos):get_int(net_name.."_conn") + local tbl = {} + if val % 0x40 >= 0x20 then tbl[#tbl+1] = 1 end + if val % 0x20 >= 0x10 then tbl[#tbl+1] = 2 end + if val % 0x10 >= 0x08 then tbl[#tbl+1] = 3 end + if val % 0x08 >= 0x04 then tbl[#tbl+1] = 4 end + if val % 0x04 >= 0x02 then tbl[#tbl+1] = 5 end + if val % 0x02 >= 0x01 then tbl[#tbl+1] = 6 end + return tbl +end + +local function pos_already_reached(pos) + local key = minetest.hash_node_position(pos) + if not Route[key] and NumNodes < MAX_NUM_NODES then + Route[key] = true + NumNodes = NumNodes + 1 + return false + end + return true +end + +-- check if the given pipe dir into the node is valid +local function valid_indir(pos, indir, param2, net_name) + local sides = net_def(pos, net_name).sides + if not sides then return false end + local side = DirToSide[indir_to_dir(indir, param2)] + if not sides[side] then return false end + return true +end + +-- do the walk through the tubelib2 network +local function connection_walk(pos, node, tlib2, clbk) + if clbk then clbk(pos, node) end + for _,outdir in pairs(get_node_connections(pos, tlib2.tube_type)) do + local pos2, indir2 = tlib2:get_connected_node_pos(pos, outdir) + local node = techage.get_node_lvm(pos2) + if pos2 and not pos_already_reached(pos2) and + valid_indir(pos2, indir2, node.param2, tlib2.tube_type) then + connection_walk(pos2, node, tlib2, clbk) + end + end +end + +-- determine all node sides with tube connections +local function node_connections(pos, tlib2) + local node = techage.get_node_lvm(pos) + local val = 0 + local sides = net_def(pos, tlib2.tube_type).sides + + if sides then + for dir = 1,6 do + val = val * 2 + local outdir = dir_to_outdir(dir, node.param2) + --if sides[DirToSide[outdir]] then -------------------------------------- TODO + local pos2 = tubelib2.get_pos(pos, dir) + local node2 = techage.get_node_lvm(pos2) + if tlib2.primary_node_names[node2.name] then + val = val + 1 + end + --end + end + M(pos):set_int(tlib2.tube_type.."_conn", val) + else + error(pos, "sides missing") + end +end + +-- determine network ID (largest hash number) +local function determine_netID(pos, tlib2) + Route = {} + NumNodes = 0 + pos_already_reached(pos) + local netID = minetest.hash_node_position(pos) + local tNetwork = {} + local node = techage.get_node_lvm(pos) + connection_walk(pos, node, tlib2, function(pos, node) + local new = minetest.hash_node_position(pos) + if netID <= new then + netID = new + end + end) + return netID +end + +-- store network ID on each node and build network tables +local function store_netID(pos, netID, tlib2) + Route = {} + NumNodes = 0 + pos_already_reached(pos) + local netw = {} + local node = techage.get_node_lvm(pos) + local net_name = tlib2.tube_type + connection_walk(pos, node, tlib2, function(pos, node) + local ntype = net_def(pos, net_name).ntype + if ntype then + if not netw[ntype] then netw[ntype] = {} end + netw[ntype][#netw[ntype] + 1] = pos + local mem = tubelib2.get_mem(pos) + mem[net_name] = mem[net_name] or {} + mem[net_name].netID = netID + end + end) + netw.best_before = minetest.get_gametime() + BEST_BEFORE + return netw +end + +local function collect_network_nodes(pos, netID, tlib2) + Route = {} + NumNodes = 0 + pos_already_reached(pos) + local netw = {} + local node = techage.get_node_lvm(pos) + local net_name = tlib2.tube_type + connection_walk(pos, node, tlib2, function(pos, node) + local ntype = net_def(pos, net_name).ntype + if ntype then + if not netw[ntype] then netw[ntype] = {} end + netw[ntype][#netw[ntype] + 1] = pos + end + end) + netw.best_before = minetest.get_gametime() + BEST_BEFORE + return netw +end + +-- keep data base small and valid +local function remove_outdated_networks() + local to_be_deleted = {} + local t = minetest.get_gametime() + for net_name,tbl in pairs(Networks) do + for netID,network in pairs(tbl) do + local valid = (network.best_before or 0) - t + output(network, valid) + if valid < 0 then + to_be_deleted[#to_be_deleted+1] = {net_name, netID} + end + end + end + for _,item in ipairs(to_be_deleted) do + local net_name, netID = unpack(item) + print("delete", net_name, netID) + Networks[net_name][netID] = nil + end + minetest.after(60, remove_outdated_networks) +end +minetest.after(60, remove_outdated_networks) + +-- +-- API Functions +-- +techage.networks.AllSides = Sides -- table for all 6 node sides + +-- techage.networks.side_to_outdir(pos, side) +techage.networks.side_to_outdir = side_to_outdir + +-- check if the given pipe dir into the node is valid +-- valid_indir(pos, indir, param2, net_name) +techage.networks.valid_indir = valid_indir + +-- Store tubelib2 connection dirs as node meta and +-- update network tables. +-- Function to be called from tubelib2_on_update2 +-- tlib2 is the tubelib2 instance +function techage.networks.update_network(pos, tlib2) + node_connections(pos, tlib2) + local netID = determine_netID(pos, tlib2) + if not Networks[tlib2.tube_type] then + Networks[tlib2.tube_type] = {} + end + Networks[tlib2.tube_type][netID] = store_netID(pos, netID, tlib2) +end + +function techage.networks.get_network(pos, tlib2) + local mem = tubelib2.get_mem(pos) + local netID = mem[tlib2.tube_type] and mem[tlib2.tube_type].netID + if netID then + if not Networks[tlib2.tube_type] then + Networks[tlib2.tube_type] = {} + end + if not Networks[tlib2.tube_type][netID] then + Networks[tlib2.tube_type][netID] = collect_network_nodes(pos, netID, tlib2) or {} + end + Networks[tlib2.tube_type][netID].best_before = minetest.get_gametime() + BEST_BEFORE + return Networks[tlib2.tube_type][netID] + end +end + +function techage.networks.get_network_table(pos, tlib2, ntype) + return techage.networks.get_network(pos, tlib2)[ntype] or {} +end + +function techage.networks.connection_walk(pos, tlib2, clbk) + Route = {} + NumNodes = 0 + pos_already_reached(pos) -- don't consider the start pos + local node = techage.get_node_lvm(pos) + connection_walk(pos, node, tlib2, clbk) + return NumNodes +end + +function techage.networks.connections(pos, tlib2) + for _,dir in ipairs(get_node_connections(pos, tlib2.tube_type)) do + print(({"North", "East", "South", "West", "Down", "Up"})[dir]) + end +end + + \ No newline at end of file diff --git a/basis/node_states.lua b/basis/node_states.lua index 1a67bd1..ec085b8 100644 --- a/basis/node_states.lua +++ b/basis/node_states.lua @@ -214,6 +214,7 @@ function NodeStates:stop(pos, mem) M(pos):set_string("infotext", self.infotext_name.." "..number..": stopped") end if self.formspec_func then + mem.ta_state_tooltip = "stopped" M(pos):set_string("formspec", self.formspec_func(self, pos, mem)) end if self.on_state_change then @@ -250,6 +251,7 @@ function NodeStates:start(pos, mem) M(pos):set_string("infotext", self.infotext_name.." "..number..": running") end if self.formspec_func then + mem.ta_state_tooltip = "running" M(pos):set_string("formspec", self.formspec_func(self, pos, mem)) end if minetest.get_node_timer(pos):is_started() then @@ -276,6 +278,7 @@ function NodeStates:standby(pos, mem) M(pos):set_string("infotext", self.infotext_name.." "..number..": standby") end if self.formspec_func then + mem.ta_state_tooltip = "standby" M(pos):set_string("formspec", self.formspec_func(self, pos, mem)) end if self.on_state_change then @@ -300,6 +303,7 @@ function NodeStates:blocked(pos, mem) M(pos):set_string("infotext", self.infotext_name.." "..number..": blocked") end if self.formspec_func then + mem.ta_state_tooltip = "blocked" M(pos):set_string("formspec", self.formspec_func(self, pos, mem)) end if self.on_state_change then @@ -311,7 +315,7 @@ function NodeStates:blocked(pos, mem) return false end -function NodeStates:nopower(pos, mem) +function NodeStates:nopower(pos, mem, err_string) local state = mem.techage_state or RUNNING if state ~= NOPOWER then mem.techage_state = NOPOWER @@ -323,6 +327,7 @@ function NodeStates:nopower(pos, mem) M(pos):set_string("infotext", self.infotext_name.." "..number..": no power") end if self.formspec_func then + mem.ta_state_tooltip = err_string or "no power" M(pos):set_string("formspec", self.formspec_func(self, pos, mem)) end if self.on_state_change then @@ -347,6 +352,7 @@ function NodeStates:fault(pos, mem, err_string) M(pos):set_string("infotext", self.infotext_name.." "..number..": "..err_string) end if self.formspec_func then + mem.ta_state_tooltip = err_string or "fault" M(pos):set_string("formspec", self.formspec_func(self, pos, mem)) end if self.on_state_change then @@ -418,6 +424,11 @@ function NodeStates:get_state_button_image(mem) return techage.state_button(state) end +function NodeStates:get_state_tooltip(mem) + local tp = mem.ta_state_tooltip or "" + return tp..";#0C3D32;#FFFFFF" +end + -- command interface function NodeStates:on_receive_message(pos, topic, payload) local mem = tubelib2.get_mem(pos) diff --git a/chemistry/reactor.lua b/chemistry/reactor.lua deleted file mode 100644 index 71bc990..0000000 --- a/chemistry/reactor.lua +++ /dev/null @@ -1,32 +0,0 @@ ---[[ - - TechAge - ======= - - Copyright (C) 2019 Joachim Stolberg - - GPL v3 - See LICENSE.txt for more information - - TA4 Reactor - -]]-- - -local S = techage.S - -minetest.register_node("techage:ta4_reactor", { - description = S("TA4 Reactor"), - tiles = {"techage_reactor_side.png"}, - drawtype = "mesh", - mesh = "techage_boiler_large.obj", - selection_box = { - type = "fixed", - fixed = {-13/32, -16/32, -13/32, 13/32, 16/32, 13/32}, - }, - - paramtype2 = "facedir", - on_rotate = screwdriver.disallow, - groups = {cracky=2}, - is_ground_content = false, - sounds = default.node_sound_stone_defaults(), -}) diff --git a/chemistry/ta4_doser.lua b/chemistry/ta4_doser.lua new file mode 100644 index 0000000..939a7fa --- /dev/null +++ b/chemistry/ta4_doser.lua @@ -0,0 +1,309 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + TA4 Doser + +]]-- + +local S = techage.S +local M = minetest.get_meta +local N = function(pos) return minetest.get_node(pos).name end +local Pipe = techage.BiogasPipe +local liquid = techage.liquid + +local Recipes = {} -- {ouput = {....},...} +local RecipeList = {} -- {,...} +local Liquids = {} -- {hash(pos) = {name = outdir},...} + +local STANDBY_TICKS = 0 +local COUNTDOWN_TICKS = 6 +local CYCLE_TIME = 2 +local POWER_NEED = 10 + +local range = techage.range + +-- Formspec +local function input_string(recipe) + local tbl = {} + for idx, item in ipairs(recipe.input) do + local x = ((idx-1) % 2) + 1 + local y = math.floor((idx-1) / 2) + tbl[idx] = techage.item_image(x, y, item.name.." "..item.num) + end + return table.concat(tbl, "") +end + +local function formspec(self, pos, mem) + mem.recipe_idx = range(mem.recipe_idx or 1, 1, #RecipeList) + local idx = mem.recipe_idx + local recipe = Recipes[RecipeList[idx]] + local output = recipe.output.name.." "..recipe.output.num + local waste = recipe.waste.name.." "..recipe.waste.num + return "size[8,7.2]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + input_string(recipe).. + "image[3,0.5;1,1;techage_form_arrow.png]".. + techage.item_image(4, 0, output).. + techage.item_image(4, 1, waste).. + "image_button[6.5,0.5;1,1;".. self:get_state_button_image(mem) ..";state_button;]".. + "tooltip[6.5,0.5;1,1;"..self:get_state_tooltip(mem).."]".. + "button[1,2.2;1,1;priv;<<]".. + "button[2,2.2;1,1;next;>>]".. + "label[3,2.5;"..S("Recipe")..": "..idx.."/"..#RecipeList.."]".. + + "list[current_player;main;0,3.5;8,4;]" .. + default.get_hotbar_bg(0, 3.5) +end + +local function get_liquids(pos) + local hash = minetest.hash_node_position(pos) + if Liquids[hash] then + return Liquids[hash] + end + -- determine the available input liquids + local tbl = {} + for outdir = 1,4 do + local name, num = liquid.peek(pos, outdir) + if name then + tbl[name] = outdir + end + end + Liquids[hash] = tbl + return Liquids[hash] +end + +local function del_liquids(pos) + local hash = minetest.hash_node_position(pos) + Liquids[hash] = nil +end + +local function reactor_cmnd(pos, cmnd, payload) + return techage.transfer( + pos, + 6, -- outdir + cmnd, -- topic + payload, -- payload + Pipe, -- network + {"techage:ta4_reactor_fillerpipe"}) +end + + +local function can_start(pos, mem, state) + -- check reactor + local res = reactor_cmnd(pos, "can_start") + if not res then + return S("reactor defect") + end + return true +end + +local function start_node(pos, mem, state) + reactor_cmnd(pos, "start", {cycle_time = CYCLE_TIME, pwr_needed = POWER_NEED}) + mem.running = true +end + +local function stop_node(pos, mem, state) + reactor_cmnd(pos, "stop", nil) + mem.running = false +end + +local State = techage.NodeStates:new({ + node_name_passive = "techage:ta4_doser", + node_name_active = "techage:ta4_doser_on", + cycle_time = CYCLE_TIME, + standby_ticks = STANDBY_TICKS, + formspec_func = formspec, + infotext_name = "TA4 Doser", + can_start = can_start, + start_node = start_node, + stop_node = stop_node, +}) + +local function reset_dosing(mem) + -- alle 4 ports checken und inputs vorladen +end + +local function dosing(pos, mem, elapsed) + -- trigger reactor (power) + if not reactor_cmnd(pos, "power", POWER_NEED) then + State:nopower(pos, mem, S("reactor has no power")) + return + end + -- available liquids + local liquids = get_liquids(pos) + local recipe = Recipes[RecipeList[mem.recipe_idx or 1]] + if not liquids or not recipe then return end + -- inputs + for _,item in pairs(recipe.input) do + if item.name ~= "" then + print("dosing", item.name, dump(liquids)) + local outdir = liquids[item.name] + if not outdir then + State:fault(pos, mem, S("input liquid missing")) + return + end + if liquid.take(pos, outdir, item.name, item.num) < item.num then + State:fault(pos, mem, S("input liquid gone out")) + return + end + end + end + -- output + if not reactor_cmnd(pos, "output", recipe.output.name) then + State:fault(pos, mem, S("output liquid blocked")) + return + end + if not reactor_cmnd(pos, "waste", recipe.waste.name) then + State:fault(pos, mem, S("output liquid blocked")) + return + end + State:keep_running(pos, mem, COUNTDOWN_TICKS) +end + +local function node_timer(pos, elapsed) + local mem = tubelib2.get_mem(pos) + dosing(pos, mem, elapsed) + return State:is_active(mem) +end + +local function on_rightclick(pos) + local mem = tubelib2.get_mem(pos) + M(pos):set_string("formspec", formspec(State, pos, mem)) +end + +local function on_receive_fields(pos, formname, fields, player) + if minetest.is_protected(pos, player:get_player_name()) then + return + end + local mem = tubelib2.get_mem(pos) + + mem.recipe_idx = mem.recipe_idx or 1 + if not mem.running then + if fields.next == ">>" then + mem.recipe_idx = range(mem.recipe_idx + 1, 1, #RecipeList) + M(pos):set_string("formspec", formspec(State, pos, mem)) + elseif fields.priv == "<<" then + mem.recipe_idx = range(mem.recipe_idx - 1, 1, #RecipeList) + M(pos):set_string("formspec", formspec(State, pos, mem)) + end + end + State:state_button_event(pos, mem, fields) +end + + +minetest.register_node("techage:ta4_doser", { + description = S("TA4 Doser"), + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta4_top.png^techage_appl_hole_biogas.png", + "techage_filling_ta4.png^techage_frame_ta4.png", + "techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_pump.png^techage_appl_hole_biogas.png", + }, + + on_receive_fields = on_receive_fields, + on_rightclick = on_rightclick, + on_timer = node_timer, + + paramtype2 = "facedir", + on_rotate = screwdriver.disallow, + groups = {cracky=2}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +minetest.register_node("techage:ta4_doser_on", { + description = S("TA4 Doser"), + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta4_top.png^techage_appl_hole_biogas.png", + "techage_filling_ta4.png^techage_frame_ta4.png", + { + image = "techage_filling8_ta4.png^techage_frame8_ta4.png^techage_appl_pump8.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 2.0, + }, + }, + }, + + on_receive_fields = on_receive_fields, + on_rightclick = on_rightclick, + on_timer = node_timer, + + paramtype2 = "facedir", + on_rotate = screwdriver.disallow, + groups = {cracky=2}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +-- for mechanical pipe connections +techage.power.register_node({"techage:ta4_doser", "techage:ta4_doser_on"}, { + conn_sides = {"F", "B", "R", "L", "U"}, + power_network = Pipe, + after_place_node = function(pos, placer) + local meta = M(pos) + local mem = tubelib2.init_mem(pos) + local number = techage.add_node(pos, "techage:ta4_doser") + meta:set_string("node_number", number) + meta:set_string("owner", placer:get_player_name()) + local node = minetest.get_node(pos) + local indir = techage.side_to_indir("R", node.param2) + meta:set_int("indir", indir) -- from liquid point of view + meta:set_string("formspec", formspec(State, pos, mem)) + meta:set_string("infotext", S("TA4 Tank").." "..number) + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + techage.remove_node(pos) + end, +}) + +-- Doser Recipe +-- { +-- output = " ", -- units = 1..n +-- waste = " ", +-- input = { -- up to 4 +-- " ", +-- " ", +-- }, +-- } +-- +function techage.add_doser_recipe(recipe) + local name, num + local item = {input = {}} + for idx = 1,4 do + local inp = recipe.input[idx] or "" + name, num = unpack(string.split(inp, " ")) + item.input[idx] = {name = name or "", num = tonumber(num) or 0} + end + if recipe.waste then + name, num = unpack(string.split(recipe.waste, " ")) + else + name, num = "", "0" + end + item.waste = {name = name or "", num = tonumber(num) or 0} + name, num = unpack(string.split(recipe.output, " ")) + item.output = {name = name or "", num = tonumber(num) or 0} + Recipes[name] = item + RecipeList[#RecipeList+1] = name +end + +techage.add_doser_recipe({ + output = "techage:ta4_epoxy 3", + input = { + "techage:oil_source 2", + "basic_materials:oil_extract 1", + } +}) \ No newline at end of file diff --git a/chemistry/ta4_pump.lua b/chemistry/ta4_pump.lua new file mode 100644 index 0000000..a772395 --- /dev/null +++ b/chemistry/ta4_pump.lua @@ -0,0 +1,92 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + TA4 Pump + +]]-- + +local S2P = minetest.string_to_pos +local P2S = minetest.pos_to_string +local M = minetest.get_meta +local S = techage.S +local Pipe = techage.LiquidPipe +local networks = techage.networks + +minetest.register_node("techage:ta4_pump", { + description = S("TA4 Pump"), + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta4_top.png^techage_appl_hole_biogas.png^techage_appl_color_top.png", + "techage_filling_ta4.png^techage_frame_ta4.png", + "techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_pump.png^techage_appl_hole_biogas.png", + }, + after_place_node = function(pos, placer) + M(pos):set_int("pipe_dir", networks.side_to_outdir(pos, "R")) + Pipe:after_place_node(pos) + minetest.get_node_timer(pos):start(5) + end, + on_timer = function(pos, elapsed) +-- networks.connection_walk(pos, Pipe, function(pos, node) +-- print("on_timer", P2S(pos), node.name) +-- end) + local mem = tubelib2.get_mem(pos) + local nw = networks.get_network(pos, Pipe) + if nw then + for _,pos in ipairs(nw.tank or {}) do + techage.mark_position("singleplayer", pos, "", "", 3) + end + end + return true + end, + tubelib2_on_update2 = function(pos, node, tlib2) + networks.update_network(pos, tlib2) + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Pipe:after_dig_node(pos) + end, + networks = { + pipe = { + sides = {R = 1}, -- Pipe connection side + ntype = "pump", + }, + }, + paramtype2 = "facedir", + on_rotate = screwdriver.disallow, + groups = {cracky=2}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +minetest.register_node("techage:ta4_pump_on", { + description = S("TA4 Pump"), + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta4_top.png^techage_appl_hole_biogas.png^techage_appl_color_top.png", + "techage_filling_ta4.png^techage_frame_ta4.png", + { + image = "techage_filling8_ta4.png^techage_frame8_ta4.png^techage_appl_pump8.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 2.0, + }, + }, + }, + + paramtype2 = "facedir", + on_rotate = screwdriver.disallow, + groups = {cracky=2}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + + Pipe:add_secondary_node_names({"techage:ta4_pump", "techage:ta4_pump_on"}) \ No newline at end of file diff --git a/chemistry/ta4_reactor.lua b/chemistry/ta4_reactor.lua new file mode 100644 index 0000000..2b1de0f --- /dev/null +++ b/chemistry/ta4_reactor.lua @@ -0,0 +1,170 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + TA4 Reactor + +]]-- + +local S = techage.S +local Pipe = techage.BiogasPipe +local Cable = techage.ElectricCable +local power = techage.power + +-- pos of the reactor stand +local function on_power(pos, mem) + mem.running = true +end + +local function on_nopower(pos, mem) + mem.running = false +end + +minetest.register_node("techage:ta4_reactor", { + description = S("TA4 Reactor"), + tiles = {"techage_reactor_side.png"}, + drawtype = "mesh", + mesh = "techage_boiler_huge.obj", + selection_box = { + type = "fixed", + fixed = {-1/2, -23/32, -1/2, 1/2, 32/32, 1/2}, + }, + collision_box = { + type = "fixed", + fixed = {-1/2, -23/32, -1/2, 1/2, 32/32, 1/2}, + }, + + paramtype2 = "facedir", + on_rotate = screwdriver.disallow, + groups = {cracky=2}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +minetest.register_node("techage:ta4_reactor_stand", { + description = S("TA4 Reactor"), + tiles = { + -- up, down, right, left, back, front + "techage_reactor_stand_top.png", + "techage_reactor_stand_bottom.png^[transformFY", + "techage_reactor_stand_side.png^[transformFX", + "techage_reactor_stand_side.png", + "techage_reactor_stand_back.png", + "techage_reactor_stand_front.png", + }, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + { -8/16, 2/16, -8/16, 8/16, 4/16, 8/16 }, + + { -8/16, -8/16, -8/16, -6/16, 8/16, -6/16 }, + { 6/16, -8/16, -8/16, 8/16, 8/16, -6/16 }, + { -8/16, -8/16, 6/16, -6/16, 8/16, 8/16 }, + { 6/16, -8/16, 6/16, 8/16, 8/16, 8/16 }, + + {-1/8, -1/8, -4/8, 1/8, 1/8, 4/8}, + {-1/8, 0/8, -1/8, 1/8, 4/8, 1/8}, + {-3/8, -1/8, -4/8, 3/8, 1/8, -3/8}, + {-3/8, -1/8, 3/8, 3/8, 1/8, 4/8}, + }, + }, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/2, 1/2, 1/2, 1/2}, + }, + paramtype2 = "facedir", + on_rotate = screwdriver.disallow, + groups = {cracky=2}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +-- for mechanical pipe connections +techage.power.register_node({"techage:ta4_reactor_stand"}, { + conn_sides = {"F"}, + power_network = Pipe, +}) + +-- for electrical connections +techage.power.register_node({"techage:ta4_reactor_stand"}, { + conn_sides = {"B"}, + power_network = Cable, +}) + +minetest.register_node("techage:ta4_reactor_fillerpipe", { + description = S("TA4 Reactor Filler Pipe"), + tiles = { + -- up, down, right, left, back, front + "techage_reactor_filler_top.png", + "techage_reactor_filler_top.png", + "techage_reactor_filler_side.png", + }, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-2/8, 13/32, -2/8, 2/8, 4/8, 2/8}, + {-1/8, 0/8, -1/8, 1/8, 4/8, 1/8}, + {-5/16, 0/8, -5/16, 5/16, 2/8, 5/16}, + }, + }, + selection_box = { + type = "fixed", + fixed = {-2/8, 0/8, -2/8, 2/8, 4/8, 2/8}, + }, + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "facedir", + on_rotate = screwdriver.disallow, + groups = {cracky=2}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +-- for mechanical pipe connections +techage.power.register_node({"techage:ta4_reactor_fillerpipe"}, { + conn_sides = {"U"}, + power_network = Pipe, + after_place_node = function(pos) + local pos1 = {x = pos.x, y = pos.y-1, z = pos.z} + print(minetest.get_node(pos1).name) + if minetest.get_node(pos1).name == "air" then + local node = minetest.get_node(pos) + minetest.remove_node(pos) + minetest.set_node(pos1, node) + end + end, +}) + +-- controlled by the doser +techage.register_node({"techage:ta4_reactor_fillerpipe"}, { + on_transfer = function(pos, in_dir, topic, payload) + -- pos of the reactor stand + local pos2 = {x = pos.x, y = pos.y-2, z = pos.z} + local mem = tubelib2.get_mem(pos2) + if topic == "power" then + power.consumer_alive(pos2, mem) + return mem.running + elseif topic == "can_start" then + local pos1 = {x = pos.x, y = pos.y-1, z = pos.z} + if minetest.get_node(pos1).name ~= "techage:ta4_reactor" then return false end + if minetest.get_node(pos2).name ~= "techage:ta4_reactor_stand" then return false end + return true + elseif topic == "start" and payload then + mem.running = true + power.consumer_start(pos2, mem, payload.cycle_time or 0, payload.pwr_needed or 0) + return true + elseif topic == "stop" then + mem.running = false + power.consumer_stop(pos2, mem) + return true + end + end, +}) diff --git a/init.lua b/init.lua index 40f6ced..44cdbc3 100644 --- a/init.lua +++ b/init.lua @@ -48,6 +48,7 @@ else dofile(MP.."/basis/mark.lua") dofile(MP.."/basis/mark2.lua") dofile(MP.."/basis/assemble.lua") + dofile(MP.."/basis/networks.lua") -- Main doc dofile(MP.."/doc/manual_DE.lua") @@ -59,7 +60,7 @@ else -- Nodes1 dofile(MP.."/nodes/baborium.lua") dofile(MP.."/nodes/usmium.lua") - --dofile(MP.."/nodes/bauxit.lua") + dofile(MP.."/nodes/bauxit.lua") -- Power networks dofile(MP.."/power/schedule.lua") @@ -75,8 +76,6 @@ else dofile(MP.."/power/junctionbox.lua") dofile(MP.."/power/powerswitch.lua") dofile(MP.."/power/protection.lua") - dofile(MP.."/power/ta4_pipe.lua") - dofile(MP.."/power/ta4_junction.lua") dofile(MP.."/power/ta4_cable.lua") -- Iron Age @@ -118,6 +117,13 @@ else dofile(MP.."/basic_machines/funnel.lua") dofile(MP.."/basic_machines/liquidsampler.lua") + -- Liquids + dofile(MP.."/liquids/liquid.lua") + dofile(MP.."/liquids/barrel.lua") + dofile(MP.."/liquids/oil.lua") + dofile(MP.."/liquids/liquid_pipe.lua") + dofile(MP.."/liquids/tank.lua") + -- Coal power station dofile(MP.."/coal_power_station/firebox.lua") dofile(MP.."/coal_power_station/boiler_base.lua") @@ -182,9 +188,9 @@ else -- Test dofile(MP.."/recipe_checker.lua") - dofile(MP.."/.test/sink.lua") + --dofile(MP.."/.test/sink.lua") dofile(MP.."/.test/source.lua") - dofile(MP.."/.test/akku.lua") + --dofile(MP.."/.test/akku.lua") --dofile(MP.."/.test/switch.lua") -- Solar @@ -206,7 +212,9 @@ else dofile(MP.."/energy_storage/nodes.lua") -- Chemistry - --dofile(MP.."/chemistry/reactor.lua") + dofile(MP.."/chemistry/ta4_reactor.lua") + dofile(MP.."/chemistry/ta4_pump.lua") + dofile(MP.."/chemistry/ta4_doser.lua") -- Hydrogen dofile(MP.."/hydrogen/hydrogen.lua") diff --git a/iron_age/recipes.lua b/iron_age/recipes.lua index 92ec4cf..2087e93 100644 --- a/iron_age/recipes.lua +++ b/iron_age/recipes.lua @@ -87,7 +87,7 @@ if techage.modified_recipes_enabled then }) minetest.register_craft({ - output = 'bucket:bucket_empty 1', + output = 'bucket:bucket_empty 2', recipe = { {'techage:iron_ingot', '', 'techage:iron_ingot'}, {'', 'techage:iron_ingot', ''}, diff --git a/liquids/barrel.lua b/liquids/barrel.lua new file mode 100644 index 0000000..cd8222d --- /dev/null +++ b/liquids/barrel.lua @@ -0,0 +1,38 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + Helper functions for liquid transportation (peer, put, take) + +]]-- + +local S = techage.S + +minetest.register_craftitem("techage:ta3_barrel_empty", { + description = S("TA Barrel"), + inventory_image = "techage_barrel_inv.png", +}) + +minetest.register_craft({ + output = 'techage:ta3_barrel_empty 6', + recipe = { + {'techage:iron_ingot', 'techage:iron_ingot', 'techage:iron_ingot'}, + {'techage:iron_ingot', '', 'techage:iron_ingot'}, + {'techage:iron_ingot', 'techage:iron_ingot', 'techage:iron_ingot'}, + } +}) + +minetest.register_craftitem("techage:liquid", { + description = S("TA Liquid"), + inventory_image = "techage_liquid_inv.png", + groups = {not_in_creative_inventory=1}, + +}) + +techage.register_liquid("techage:ta3_barrel_empty", "techage:ta3_barrel_empty", 10, "techage:liquid") \ No newline at end of file diff --git a/liquids/liquid.lua b/liquids/liquid.lua new file mode 100644 index 0000000..52578e0 --- /dev/null +++ b/liquids/liquid.lua @@ -0,0 +1,161 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + Helper functions for liquid transportation (peer, put, take) + +]]-- + +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.BiogasPipe + +techage.liquid = {} + +local LiquidDefs = {} + +local function get_dest_node(pos, outdir) + local pos2, indir = Pipe:get_connected_node_pos(pos, outdir) + local node = techage.get_node_lvm(pos2) + local liquid = (minetest.registered_nodes[node.name] or {}).liquid + if liquid then + return pos2, indir, liquid + end +end + +local function peek(stack, liquid) + liquid.amount = liquid.amount or 0 + return liquid.amount + stack:get_count() * 10 +end + +local function put(stack, liquid, amount) + liquid.amount = liquid.amount or 0 + if liquid.amount + amount > 1 then + local num = math.floor((liquid.amount + amount) / 10) + if stack:get_free_space() >= num then + stack:set_count(stack:get_count() + num) + liquid.amount = liquid.amount + amount - num + return 0 + else + local res = liquid.amount + amount - 1 + liquid.amount = 1 + return res + end + else + liquid.amount = liquid.amount + amount + return 0 + end +end + +local function take(stack, liquid, amount) + local res + liquid.amount = liquid.amount or 0 + if liquid.amount >= amount then + liquid.amount = liquid.amount - amount + res = amount + elseif amount > 10 then + local num = math.floor((liquid.amount + amount) / 10) + if stack:get_count() >= num then + stack:set_count(stack:get_count() - num) + liquid.amount = num + liquid.amount - amount + res = amount + end + elseif stack:get_count() > 0 then + stack:set_count(stack:get_count() - 1) + liquid.amount = 1 + liquid.amount - amount + res = amount + elseif liquid.amount > 0 then + res = liquid.amount + liquid.amount = 0 + else + res = 0 + end + return res +end + +-- +-- Client remote functions +-- + +-- Determine and return liquid 'name' and 'amount' from the +-- remote inventory. +function techage.liquid.peek(pos, outdir) + local pos2, indir, liquid = get_dest_node(pos, outdir) + print("peek", indir, liquid) + if liquid and liquid.peek then + return liquid.peek(pos2, indir) + end +end + +-- Add given amount of liquid to the remote inventory. +-- return leftover amount +function techage.liquid.put(pos, outdir, name, amount) + local pos2, indir, liquid = get_dest_node(pos, outdir) + if liquid and liquid.put then + return liquid.put(pos2, indir, name, amount) + end + return amount +end + +-- Take given amount of liquid for the remote inventory. +-- return taken amount +function techage.liquid.take(pos, outdir, name, amount) + local pos2, indir, liquid = get_dest_node(pos, outdir) + if liquid and liquid.take then + return liquid.take(pos2, indir, name, amount) + end + return 0 +end + +-- +-- Server local functions +-- + +function techage.liquid.srv_peek(pos, listname) + local mem = tubelib2.get_mem(pos) + if mem.liquid and mem.liquid.name then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(listname, 1) + return mem.liquid.name, peek(stack, mem.liquid) + end +end + +function techage.liquid.srv_put(pos, listname, name, amount) + local mem = tubelib2.get_mem(pos) + if mem.liquid and not mem.liquid.name or mem.liquid.name == name then + mem.liquid.name = name + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(listname, 1) + return put(stack, mem.liquid, amount) + end +end + +function techage.liquid.srv_take(pos, listname, name, amount) + local mem = tubelib2.get_mem(pos) + if mem.liquid and mem.liquid.name == name then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(listname, 1) + return take(stack, mem.liquid, amount) + end +end + + + +function techage.register_liquid(name, container, size, inv_item) + LiquidDefs[name] = {container = container, size = size, inv_item = inv_item} +end + +function techage.liquid.get_liquid_def(name) + return LiquidDefs[name] +end + \ No newline at end of file diff --git a/liquids/liquid_pipe.lua b/liquids/liquid_pipe.lua new file mode 100644 index 0000000..4241d33 --- /dev/null +++ b/liquids/liquid_pipe.lua @@ -0,0 +1,195 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + TA3/TA4 Liquid Pipes + +]]-- + +-- for lazy programmers +local S2P = minetest.string_to_pos +local P2S = minetest.pos_to_string +local M = minetest.get_meta +local S = techage.S + +local MAX_PIPE_LENGHT = 100 +local networks = techage.networks + +local Pipe = tubelib2.Tube:new({ + dirs_to_check = {1,2,3,4,5,6}, + max_tube_length = MAX_PIPE_LENGHT, + show_infotext = false, + force_to_use_tubes = true, + tube_type = "pipe", + primary_node_names = {"techage:ta3_pipeS", "techage:ta3_pipeA"}, + secondary_node_names = {}, + after_place_tube = function(pos, param2, tube_type, num_tubes) + minetest.swap_node(pos, {name = "techage:ta3_pipe"..tube_type, param2 = param2}) + end, +}) + +minetest.register_node("techage:ta3_pipeS", { + description = S("TA Pipe"), + tiles = { + "techage_gaspipe.png^[transformR90", + "techage_gaspipe.png^[transformR90", + "techage_gaspipe.png", + "techage_gaspipe.png", + "techage_gaspipe_hole2.png", + "techage_gaspipe_hole2.png", + }, + + after_place_node = function(pos, placer, itemstack, pointed_thing) + if not Pipe:after_place_tube(pos, placer, pointed_thing) then + minetest.remove_node(pos) + return true + end + return false + end, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Pipe:after_dig_tube(pos, oldnode) + end, + + paramtype2 = "facedir", -- important! + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-1/8, -1/8, -4/8, 1/8, 1/8, 4/8}, + }, + }, + on_rotate = screwdriver.disallow, -- important! + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + groups = {crumbly = 2, cracky = 2, snappy = 2}, + sounds = default.node_sound_metal_defaults(), +}) + +minetest.register_node("techage:ta3_pipeA", { + description = S("TA Pipe"), + tiles = { + "techage_gaspipe_knee2.png", + "techage_gaspipe_hole2.png^[transformR180", + "techage_gaspipe_knee.png^[transformR270", + "techage_gaspipe_knee.png", + "techage_gaspipe_knee2.png", + "techage_gaspipe_hole2.png", + }, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Pipe:after_dig_tube(pos, oldnode) + end, + + paramtype2 = "facedir", -- important! + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-1/8, -4/8, -1/8, 1/8, 1/8, 1/8}, + {-2/8, -0.5, -2/8, 2/8, -13/32, 2/8}, + {-1/8, -1/8, -4/8, 1/8, 1/8, -1/8}, + {-2/8, -2/8, -0.5, 2/8, 2/8, -13/32}, + }, + }, + on_rotate = screwdriver.disallow, -- important! + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + groups = {crumbly = 2, cracky = 2, snappy = 2, not_in_creative_inventory=1}, + sounds = default.node_sound_metal_defaults(), + drop = "techage:ta3_pipeS", +}) + +local size1 = 1/8 +local size2 = 2/8 +local size3 = 13/32 +local Boxes = { + { + {-size1, -size1, size1, size1, size1, 0.5 }, -- z+ + {-size2, -size2, size3, size2, size2, 0.5 }, -- z+ + }, + { + {-size1, -size1, -size1, 0.5, size1, size1}, -- x+ + { size3, -size2, -size2, 0.5, size2, size2}, -- x+ + }, + { + {-size1, -size1, -0.5, size1, size1, size1}, -- z- + {-size2, -size2, -0.5, size2, size2, -size3}, -- z- + }, + { + {-0.5, -size1, -size1, size1, size1, size1}, -- x- + {-0.5, -size2, -size2, -size3, size2, size2}, -- x- + }, + { + {-size1, -0.5, -size1, size1, size1, size1}, -- y- + {-size2, -0.5, -size2, size2, -size3, size2}, -- y- + }, + { + {-size1, -size1, -size1, size1, 0.5, size1}, -- y+ + {-size2, size3, -size2, size2, 0.5, size2}, -- y+ + } +} + +techage.register_junction("techage:ta3_junctionpipe", 1/8, Boxes, nil, { + description = S("TA Junction Pipe"), + tiles = {"techage_gaspipe_junction.png"}, + groups = {crumbly = 2, cracky = 2, snappy = 2, techage_trowel = 1}, + sounds = default.node_sound_metal_defaults(), + + after_place_node = function(pos, placer, itemstack, pointed_thing) + Pipe:after_place_node(pos) + end, + tubelib2_on_update2 = function(pos, node, tlib2) + print("tubelib2_on_update2 pipe") + local name = "techage:ta3_junctionpipe"..techage.junction_type(pos, Pipe) + minetest.swap_node(pos, {name = name, param2 = 0}) + networks.update_network(pos, Pipe) + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Pipe:after_dig_node(pos) + end, + networks = { + pipe = { + sides = networks.AllSides, -- connection sides for pipes + ntype = "junc", + }, + }, +}, 25) + +-- register by hand, as there is no power support +for idx = 0,63 do + Pipe:add_secondary_node_names({"techage:ta3_junctionpipe"..idx}) +end + +minetest.register_craft({ + output = "techage:ta3_junctionpipe25 2", + recipe = { + {"", "techage:ta3_pipeS", ""}, + {"techage:ta3_pipeS", "", "techage:ta3_pipeS"}, + {"", "techage:ta3_pipeS", ""}, + }, +}) + +minetest.register_craft({ + output = "techage:ta3_pipeS 6", + recipe = { + {'', '', "default:steel_ingot"}, + {'dye:yellow', 'techage:meridium_ingot', ''}, + {"default:steel_ingot", '', ''}, + }, +}) + +minetest.register_alias("techage:ta4_pipeA", "techage:ta3_pipeA") +minetest.register_alias("techage:ta4_pipeS", "techage:ta3_pipeS") + +techage.BiogasPipe = Pipe +techage.LiquidPipe = Pipe + diff --git a/liquids/oil.lua b/liquids/oil.lua new file mode 100644 index 0000000..c5f37fb --- /dev/null +++ b/liquids/oil.lua @@ -0,0 +1,136 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + TA3 Oil + +]]-- + +-- for lazy programmers +local M = minetest.get_meta +local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end +local S = techage.S + +minetest.register_node("techage:oil_source", { + description = S("Oil Source"), + drawtype = "liquid", + paramtype = "light", + + inventory_image = "techage_oil_inv.png", + tiles = { + { + name = "techage_oil_animated.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 10 + } + }, + { + name = "techage_oil_animated.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0 + } + } + }, + + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + drowning = 1, + liquidtype = "source", + liquid_alternative_flowing = "techage:oil_flowing", + liquid_alternative_source = "techage:oil_source", + liquid_viscosity = 20, + liquid_range = 10, + liquid_renewable = false, + post_effect_color = {a = 200, r = 1, g = 1, b = 1}, + groups = {liquid = 5}, +}) + +minetest.register_node("techage:oil_flowing", { + description = S("Flowing Oil"), + drawtype = "flowingliquid", + tiles = {"techage_oil.png"}, + special_tiles = { + { + name = "techage_oil_animated.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 10, + }, + }, + { + name = "techage_oil_animated.png", + backface_culling = true, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 10, + }, + }, + }, + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drop = "", + drowning = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "techage:oil_flowing", + liquid_alternative_source = "techage:oil_source", + liquid_viscosity = 20, + liquid_range = 10, + post_effect_color = {a = 200, r = 1, g = 1, b = 1}, + groups = {liquid = 5, not_in_creative_inventory = 1}, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "techage:oil_source", + burntime = 40, +}) + +bucket.register_liquid( + "techage:oil_source", + "techage:oil_flowing", + "techage:bucket_oil", + "techage_bucket_oil.png", + "Oil Bucket") + + +minetest.register_craftitem("techage:ta3_barrel_oil", { + description = S("TA3 Oil Barrel"), + inventory_image = "techage_barrel_oil_inv.png", + stack_max = 1, +}) + +minetest.register_craftitem("techage:oil", { + description = S("TA Oil"), + inventory_image = "techage_oil_inv.png", + groups = {not_in_creative_inventory=1}, + +}) + +techage.register_liquid("techage:ta3_barrel_oil", "techage:ta3_barrel_empty", 10, "techage:oil") + diff --git a/liquids/tank.lua b/liquids/tank.lua new file mode 100644 index 0000000..2816cbe --- /dev/null +++ b/liquids/tank.lua @@ -0,0 +1,314 @@ +--[[ + + TechAge + ======= + + Copyright (C) 2019 Joachim Stolberg + + GPL v3 + See LICENSE.txt for more information + + TA3/TA4 Tank + +]]-- + +local S2P = minetest.string_to_pos +local P2S = minetest.pos_to_string +local M = minetest.get_meta +local S = techage.S +local Pipe = techage.LiquidPipe +local liquid = techage.liquid +local networks = techage.networks + +local function formspec_tank(x, y, liquid) + local itemname = "techage:liquid" + if liquid.amount and liquid.amount > 0 and liquid.name then + itemname = liquid.name.." "..liquid.amount + end + return "container["..x..","..y.."]".. + "background[0,0;3,2.05;techage_form_grey.png]".. + "image[0,0;1,1;techage_form_input_arrow.png]".. + techage.item_image(1, 0, itemname).. + "image[2,0;1,1;techage_form_output_arrow.png]".. + "image[1,1;1,1;techage_form_arrow.png]".. + "list[context;src;0,1;1,1;]".. + "list[context;dst;2,1;1,1;]".. + --"listring[]".. + "container_end[]" +end + +local function formspec(liquid) + return "size[8,6]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + formspec_tank(2.5, 0, liquid).. + "list[current_player;main;0,2.3;8,4;]" +end + +local function liquid_item(mem, stack) + if mem.liquid and stack:get_count() == 1 then + if not mem.liquid.name or mem.liquid.name == stack:get_name() then + local def = techage.liquid.get_liquid_def(stack:get_name()) + if def then + return def.size, def.container, def.inv_item + end + end + end +end + +local function move_item(mem, inv, stack) + local amount, giving_back, inv_item = liquid_item(mem, stack) + if amount and inv:room_for_item("dst", ItemStack(giving_back)) then + mem.liquid.name = inv_item + mem.liquid.amount = (mem.liquid.amount or 0) + amount + inv:remove_item("src", stack) + inv:add_item("dst", ItemStack(giving_back)) + M(pos):set_string("formspec", formspec(mem.liquid)) + return true + end + return false +end + +local function move_item2(pos, itemname, amount, giving_back, formspec) + local mem = tubelib2.get_mem(pos) + local inv = M(pos):get_inventory() + if inv:room_for_item("dst", ItemStack(giving_back)) then + mem.liquid.name = itemname + mem.liquid.amount = (mem.liquid.amount or 0) + amount + inv:remove_item("src", ItemStack(itemname)) + inv:add_item("dst", ItemStack(giving_back)) + M(pos):set_string("formspec", formspec(mem.liquid)) + end +end + +local function add_barrel(pos, stack, formspec) + local mem = tubelib2.get_mem(pos) + local inv = minetest.get_meta(pos):get_inventory() + if inv:room_for_item("src", stack) then + --minetest.after(0.5, move_item, pos, stack:get_name(), amount, giving_back, formspec) + return stack:get_count() + end + return 0 +end + +local function empty_barrel(pos, inv, stack) + local mem = tubelib2.get_mem(pos) + if inv:room_for_item("src", stack) then + return move_item(mem, inv, stack) + end + return false +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 + return add_barrel(pos, stack, formspec) +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 on_rightclick(pos) + local mem = tubelib2.get_mem(pos) + M(pos):set_string("formspec", formspec(mem.liquid)) + techage.networks.connections(pos, Pipe) + print(mem.pipe.netID) +end + +local function can_dig(pos, player) + if minetest.is_protected(pos, player:get_player_name()) then + return false + end + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("main") +end + + +minetest.register_node("techage:ta3_tank", { + description = S("TA3 Tank"), + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta3.png^techage_frame_ta3_top.png", + "techage_filling_ta3.png^techage_frame_ta3.png", + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_hole_biogas.png", + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_hole_tube.png", + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_tank.png", + "techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_tank.png", + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size('src', 1) + inv:set_size('dst', 1) + end, + after_place_node = function(pos, placer) + local meta = M(pos) + local mem = tubelib2.init_mem(pos) + mem.liquid = {} + local number = techage.add_node(pos, "techage:ta3_tank") + meta:set_string("node_number", number) + meta:set_string("owner", placer:get_player_name()) + local node = minetest.get_node(pos) + local indir = techage.side_to_indir("R", node.param2) + meta:set_int("indir", indir) -- from liquid point of view + meta:set_string("formspec", formspec(mem.liquid)) + meta:set_string("infotext", S("TA3 Tank").." "..number) + Pipe:after_place_node(pos) + end, + tubelib2_on_update2 = function(pos, node, tlib2) + networks.update_network(pos, tlib2) + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Pipe:after_dig_node(pos) + techage.remove_node(pos) + end, + liquid = { + peek = function(pos, indir) + print("ta3_tank.peek", indir, M(pos):get_int("indir")) + if indir == M(pos):get_int("indir") then + return liquid.srv_peek(pos, "main") + end + end, + put = function(pos, indir, name, amount) + if indir == M(pos):get_int("indir") then + return liquid.srv_put(pos, "main", name, amount) + end + end, + take = function(pos, indir, name, amount) + if indir == M(pos):get_int("indir") then + return liquid.srv_take(pos, "main", name, amount) + end + end, + + }, + networks = { + pipe = { + sides = {R = 1}, -- Pipe connection side + ntype = "tank", + }, + }, + on_rightclick = on_rightclick, + can_dig = can_dig, + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_take = allow_metadata_inventory_take, + paramtype2 = "facedir", + on_rotate = screwdriver.disallow, + groups = {cracky=2}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), +}) + +Pipe:add_secondary_node_names({"techage:ta3_tank"}) + +--minetest.register_node("techage:ta4_tank", { +-- description = S("TA4 Tank"), +-- tiles = { +-- -- up, down, right, left, back, front +-- "techage_filling_ta4.png^techage_frame_ta4_top.png", +-- "techage_filling_ta4.png^techage_frame_ta4.png", +-- "techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_hole_biogas.png", +-- "techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_hole_tube.png", +-- "techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_tank.png", +-- "techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_tank.png", +-- }, + +-- on_construct = function(pos) +-- local meta = minetest.get_meta(pos) +-- local inv = meta:get_inventory() +-- inv:set_size('src', 1) +-- inv:set_size('dst', 1) +-- end, + +-- liquid = { +-- peek = function(pos, indir) +-- if indir == M(pos):get_int("indir") then +-- return liquid.srv_peek(pos, "main") +-- end +-- end, +-- put = function(pos, indir, name, amount) +-- if indir == M(pos):get_int("indir") then +-- return liquid.srv_put(pos, "main", name, amount) +-- end +-- end, +-- take = function(pos, indir, name, amount) +-- if indir == M(pos):get_int("indir") then +-- return liquid.srv_take(pos, "main", name, amount) +-- end +-- end, + +-- }, +-- on_rightclick = on_rightclick, +-- can_dig = can_dig, +-- allow_metadata_inventory_put = allow_metadata_inventory_put, +-- allow_metadata_inventory_take = allow_metadata_inventory_take, +-- paramtype2 = "facedir", +-- on_rotate = screwdriver.disallow, +-- groups = {cracky=2}, +-- is_ground_content = false, +-- sounds = default.node_sound_metal_defaults(), +--}) + +---- for mechanical pipe connections +--techage.power.register_node({"techage:ta4_tank"}, { +-- conn_sides = {"R"}, +-- power_network = Pipe, +-- after_place_node = function(pos, placer) +-- local meta = M(pos) +-- local mem = tubelib2.init_mem(pos) +-- mem.liquid = mem.liquid or {} +-- local number = techage.add_node(pos, "techage:ta4_tank") +-- meta:set_string("node_number", number) +-- meta:set_string("owner", placer:get_player_name()) +-- local node = minetest.get_node(pos) +-- local indir = techage.side_to_indir("R", node.param2) +-- meta:set_int("indir", indir) -- from liquid point of view +-- meta:set_string("formspec", formspec(mem.liquid)) +-- meta:set_string("infotext", S("TA4 Tank").." "..number) +-- end, +-- after_dig_node = function(pos, oldnode, oldmetadata, digger) +-- techage.remove_node(pos) +-- end, +--}) + +local function valid_indir(meta, indir) + return tubelib2.Turn180Deg[meta:get_int("indir")] == indir +end + +techage.register_node({"techage:ta3_tank", "techage:ta4_tank"}, { + on_pull_item = function(pos, in_dir, num) + local meta = M(pos) + if valid_indir(meta, in_dir) then + local inv = meta:get_inventory() + return techage.get_items(inv, "dst", num) + end + end, + on_push_item = function(pos, in_dir, stack) + local meta = M(pos) + if valid_indir(meta, in_dir) then + local inv = meta:get_inventory() + return empty_barrel(pos, inv, stack) + end + end, + on_unpull_item = function(pos, in_dir, stack) + local meta = M(pos) + if valid_indir(meta, in_dir) then + local inv = meta:get_inventory() + return techage.put_items(inv, "dst", stack) + end + end, + on_recv_message = function(pos, src, topic, payload) + if topic == "state" then + local meta = M(pos) + local inv = meta:get_inventory() + return techage.get_inv_state(inv, "main") + else + return "unsupported" + end + end, +}) diff --git a/manuals/api.md b/manuals/api.md index f269db6..aa871bd 100644 --- a/manuals/api.md +++ b/manuals/api.md @@ -5,26 +5,27 @@ ## History - v1.0 - 03.10.2019 - Erster Entwurf +- v1.1 - 26.10.2019 - `networks.lua` hinzugefügt ## Hierarchiediagramm ``` - +-------------------------------------------------------------+ - | consumer | - | (tubing/commands/states/formspec/power/connections/node) | - +-------------------------------------------------------------+ - | | | - V V V - +-----------------+ +-----------------+ +-------------------+ - | command | | node_states | | power | - |(tubing/commands)| |(states/formspec)| |(power,connections)| - +-----------------+ +-----------------+ +-------------------+ - | | | - V V V - +-------------------------------------------------------------+ - | Tube/tubelib2 | - | (tubes, mem, get_node_pos) | - +-------------------------------------------------------------+ + +-------------------------------------------------------------+ +-------------------+ + | consumer | | Nodes | + | (tubing/commands/states/formspec/power/connections/node) | | (Pipe/Tube/Cable) | + +-------------------------------------------------------------+ +-------------------+ + | | | | + V V V V + +-----------------+ +-----------------+ +-------------------+ +-------------------+ + | command | | node_states | | power | | networks | + |(tubing/commands)| |(states/formspec)| |(power,connections)| | (connections) | + +-----------------+ +-----------------+ +-------------------+ +-------------------+ + | | | | + V V V V + +-----------------------------------------------------------------------------------+ + | Tube/tubelib2 | + | (tubes, mem, get_node_pos) | + +-----------------------------------------------------------------------------------+ ``` ## Klasse `Tube` (Mod tubelib2) @@ -72,7 +73,7 @@ Um mit `tubelib2` arbeiten zu können, muss zuvor eine Tube Instanz angelegt wer local Tube = tubelib2.Tube:new(...) ``` -wird eine Instanz von tubes/pipes/cables angelegt. Hier die Parameter: +Hier die Parameter: ```lua dirs_to_check = attr.dirs_to_check or {1,2,3,4,5,6}, @@ -128,13 +129,22 @@ Damit der Block über Änderungen an Tubes oder Peer-Blöcken informiert wird, g ##### 1. Knoten-spezifische callback Funktion `tubelib2_on_update` -``` +```lua tubelib2_on_update(node, pos, out_dir, peer_pos, peer_in_dir) ``` Die Funktion muss Teil von `minetest.register_node()` sein. -##### 2. Zentrale callback Funktion `register_on_tube_update` +##### 2. Knoten-spezifische callback Funktion `tubelib2_on_update2` + +```lua +tubelib2_on_update2(node, pos, self) +``` + +Dies ist eine neue Funktion von tubelib2 v1.6 +Durch den Paramater `self` können nun unterschiedliche Instanzen den tubelib2 unterschieden werden, was für die verschiedenen Kabel/Röhren von techage notwendig wurde. + +##### 3. Zentrale callback Funktion `register_on_tube_update` ```lua Tube:register_on_tube_update(function(node, pos, out_dir, peer_pos, peer_in_dir) @@ -142,7 +152,7 @@ Tube:register_on_tube_update(function(node, pos, out_dir, peer_pos, peer_in_dir) end) ``` -Wird 1) aufgerufen, wird 2) **nicht** mehr gerufen! +Wird 1) oder 2) aufgerufen, wird 3) **nicht** mehr gerufen! ### API Funktionen @@ -163,16 +173,16 @@ Techage definiert `sides` , die wie folgt definiert sind `{B=1, R=2, F=3, L=4, D ``` sides: dirs: U - | B - | / 6 + | B + | / 6 (N) +--|-----+ | 1 / o /| | / +--------+ | |/ -L <----| |o----> R 4 <-------+-------> 2 +L <----| |o----> R (W) 4 <-------+-------> 2 (O) | o | | /| | / | + / | | / |/ 3 | - +-/------+ 5 + +-/------+ (S) 5 / | F | D @@ -274,7 +284,7 @@ techage.get_node_number(pos) --> number techage.get_new_number(pos, name) --> should ne be needed (repair function) ``` -## Wrapper `power` +## Wrapper `power` (veraltet) Im Gegensatz zu `tubelib2` und `command` verwaltet `power` ganze Netzwerke und nicht nur Einzelverbindungen zwischen zwei Knoten. Dazu muss `power` in jedem Knoten eine Connection-Liste anlegen, die alle angeschlossenen Tubes beinhaltet. @@ -333,7 +343,7 @@ Und es erfolgt eine Registrierung bei Tube: ### Alternative API -Sollen die Knoten-eigenen `after_...` Funktionen nicht überschrieben, so bietet sich folgende, alternative API an: +Sollen die Knoten-eigenen `after_...` Funktionen nicht überschrieben werden, so bietet sich folgende, alternative API an: ```lua techage.power.enrich_node(names, pwr_def) @@ -410,6 +420,8 @@ State = techage.NodeStates:new({ **Wird `NodeStates` verwendet, muss der Knoten die definierten Zustände unterstützen und sollte die formspec mit dem Button und die callbacks `can_start`, `start_node` und `stop_node` implementieren.** +Ein Beispiel dafür ist der Boiler aus `./steam_engine/boiler.lua` + ### Methods ```lua @@ -486,6 +498,97 @@ Ein einfaches Beispiele dafür wäre: `pusher.lua` **Es darf in `after_place_node` kein `tubelib2.init_mem(pos)` aufgerufen werden, sonst werden die Definitionen wieder zerstört!!!** +## Modul `networks` + +Tubelib2 verwaltet nur 1:1 Beziehungen, keine Netzwerke. Dazu wurde `power` entwickelt. Allerdings lässt `power` nicht mehrere unterschiedliche Netzwerke pro Knoten zu, da die Daten nicht unterschiedenen werden können. + +Deshalb wurde das Modul `networks.lua` entwickelt. Dies wird primär für Liquids benötigt, soll aber später `power` ablösen. + +`liquid_pipe.lua` ist die erste Implementierung von `networks`. + +### Anwendung + +Um `networks` nutzen zu können muss tubelib2_on_update2 implementiert werden: + +```lua + tubelib2_on_update2 = function(pos, node, tlib2) + networks.update_network(pos, tlib2) + end, +``` + +Zusätzlich muss eine Table pro Netzwerk angelegt werden: + +```lua +networks = { + pipe = { -- network name/type + sides = {R = 1}, -- connection sides for pipes + ntype = "junc", -- node type + }, +}, +``` + +Durch die Abstufung in bspw. `pipe` sind parallel auch andere Netze möglich wie: + +- `power` für Strom +- `solar` für die roten Solarkabel +- `steam` usw. + +Im Speicher wird lediglich die Netzwerk ID gespeichert: + +```lua +mem.pipe.netID = val +mem.solar.netID = val +mem.power.netID = val +``` + +Damit wird der Speicherbedarf pro Knoten drastisch reduziert. Allein schon deshalb macht die Umstellung von `power` auf `networks` Sinn. + +### Implementierung + +Die netID ist wie bei `power` die größte hash-Nummer aller Knoten-Positionen. Diese Nummer muss in jedem Knoten gespeichert werden. + +Im Gegensatz zu `power` werden die `connections` zu anderen Knoten nicht mehr unter `mem`, sondern nur als eine Zahl in Node `meta` gespeichert. Dabei wird pro Richtungen (dir) nur ein Bit abgespeichert. Die Verbindung zum nächsten Knoten muss über `tlib2:get_connected_node_pos(pos, outdir)` bestimmt werden. Da tubelib2 diese Verbindungen auch schon im Cache speichert, sollte dies völlig ausreichend sein. Besonders dann, wenn für den Betrieb die `networks` Tabellen genutzt werden. + +Bei jeder Änderung an Netzwerk wird folgendes aufgerufen: + +```lua +function techage.networks.update_network(pos, tlib2) + node_connections(pos, tlib2) + local netID = determine_netID(pos, tlib2) + Networks[netID] = store_netID(pos, netID, tlib2) +end +``` + +Dabei werden: + +- die Verbindingsinformationen im Knoten aktualisiert +- die netID bestimmt und in allen Knoten gespeichert +- die Netzwerk Tabellen generiert (pro Knotentyp `ntype` eine Tabelle) + +Um bspw. alle Consumer durchzuklappern, kann dann einfach die Tabelle über + +``` +networks.get_network(pos, Pipe).con +``` + +abgerufen werden. + +### API + +`networks` setzt auch auf `sides`, wie `command` oder `power` und nutzt dafür aber seine eigenen Funktionen. Bei `power` fliegt das dann irgendwann raus, bei `command` evtl. auch?? + +```lua +techage.networks.side_to_outdir(pos, side) -- beim after_place_node +techage.networks.valid_indir(pos, indir, param2, net_name) -- bei bspw. on_push_item +techage.networks.update_network(pos, tlib2) -- from tubelib2_on_update2 +techage.networks.get_network(pos, tlib2) +techage.networks.get_network_table(pos, tlib2, ntype) -- comfort function +techage.networks.connection_walk(pos, tlib2, clbk) -- classic way +``` + + + + ## Anhang ### Unschönheiten diff --git a/manuals/manual_ta2_DE.md b/manuals/manual_ta2_DE.md index e7cf74d..96bf32d 100644 --- a/manuals/manual_ta2_DE.md +++ b/manuals/manual_ta2_DE.md @@ -86,6 +86,7 @@ Die Transportkapazität einer Röhre ist unbegrenzt und nur durch die Schieber b ### TA2 Schieber / Pusher Ein Schieber ist in der Lage, Items aus Kisten oder Maschinen zu ziehen und in andere Kisten oder Maschinen zu schieben. Oder anders gesagt: Zwischen zwei Blöcken mit Inventar muss ein und genau ein Schieber sein. Mehrere Schieber in Reihe sind nicht möglich. +In die Gegenrichtung ist ein Schieber für Items aber durchlässig, so dass eine Kiste über eine Röhre gefüllt und ebenso gelehrt werden kann. Ein Schieber geht in den Zustand "standby", wenn der keine Items zum Schieben hat. Ist der Ausgang blockiert oder das Inventory des Empfängers voll, so geht der Schieber in den Zustand "blocked". Aus beiden Zuständen kommt der Schieber nach einigen Sekunden selbsttätig wieder raus, sofern sich die Situation geändert hat. diff --git a/models/techage_boiler_huge.obj b/models/techage_boiler_huge.obj new file mode 100644 index 0000000..0103304 --- /dev/null +++ b/models/techage_boiler_huge.obj @@ -0,0 +1,124 @@ +# Blender v2.78 (sub 0) OBJ File: 'oven.blend' +# www.blender.org +o Cylinder +v 0.000000 -0.750000 -0.600000 +v 0.000000 1.0 -0.600000 +v 0.229610 -0.750000 -0.554328 +v 0.229610 1.0 -0.554328 +v 0.424264 -0.750000 -0.424264 +v 0.424264 1.0 -0.424264 +v 0.554328 -0.750000 -0.229610 +v 0.554328 1.0 -0.229610 +v 0.600000 -0.750000 0.000000 +v 0.600000 1.0 0.000000 +v 0.554328 -0.750000 0.229610 +v 0.554328 1.0 0.229610 +v 0.424264 -0.750000 0.424264 +v 0.424264 1.0 0.424264 +v 0.229610 -0.750000 0.554328 +v 0.229610 1.0 0.554328 +v 0.000000 -0.750000 0.600000 +v 0.000000 1.0 0.600000 +v -0.229610 -0.750000 0.554328 +v -0.229610 1.0 0.554328 +v -0.424264 -0.750000 0.424264 +v -0.424264 1.0 0.424264 +v -0.554328 -0.750000 0.229610 +v -0.554328 1.0 0.229610 +v -0.600000 -0.750000 -0.000000 +v -0.600000 1.0 -0.000000 +v -0.554328 -0.750000 -0.229610 +v -0.554328 1.0 -0.229610 +v -0.424264 -0.750000 -0.424264 +v -0.424264 1.0 -0.424264 +v -0.229610 -0.750000 -0.554328 +v -0.229610 1.0 -0.554328 +vt 0.5486 0.5000 +vt 0.5486 1.0000 +vt 0.4725 1.0000 +vt 0.4725 0.5000 +vt 0.4142 1.0000 +vt 0.4142 0.5000 +vt 1.0000 0.5000 +vt 1.0000 1.0000 +vt 0.9239 1.0000 +vt 0.9239 0.5000 +vt 0.8415 1.0000 +vt 0.8415 0.5000 +vt 0.7654 1.0000 +vt 0.7654 0.5000 +vt 0.4142 0.5000 +vt 0.4142 0.0000 +vt 0.4725 0.0000 +vt 0.4725 0.5000 +vt 0.5486 0.0000 +vt 0.5486 0.5000 +vt 0.6310 0.0000 +vt 0.6310 0.5000 +vt 0.7071 0.0000 +vt 0.7071 0.5000 +vt 0.7654 0.0000 +vt 0.7654 0.5000 +vt 0.8415 0.0000 +vt 0.8415 0.5000 +vt 0.9239 0.0000 +vt 0.9239 0.5000 +vt 1.0000 0.0000 +vt 1.0000 0.5000 +vt 0.7654 0.5000 +vt 0.7654 1.0000 +vt 0.7071 1.0000 +vt 0.7071 0.5000 +vt 0.3244 0.4749 +vt 0.3827 0.5370 +vt 0.4142 0.6181 +vt 0.4142 0.7059 +vt 0.3827 0.7870 +vt 0.3244 0.8491 +vt 0.2483 0.8827 +vt 0.1659 0.8827 +vt 0.0898 0.8491 +vt 0.0315 0.7870 +vt 0.0000 0.7059 +vt 0.0000 0.6181 +vt 0.0315 0.5370 +vt 0.0898 0.4749 +vt 0.1659 0.4414 +vt 0.2483 0.4414 +vt 0.6310 1.0000 +vt 0.6310 0.5000 +vt 0.0000 0.2646 +vt 0.0000 0.1768 +vt 0.0315 0.0957 +vt 0.0898 0.0336 +vt 0.1659 0.0000 +vt 0.2483 0.0000 +vt 0.3244 0.0336 +vt 0.3827 0.0957 +vt 0.4142 0.1768 +vt 0.4142 0.2646 +vt 0.3827 0.3457 +vt 0.3244 0.4078 +vt 0.2483 0.4414 +vt 0.1659 0.4414 +vt 0.0898 0.4078 +vt 0.0315 0.3457 +s off +f 1/1 2/2 4/3 3/4 +f 3/4 4/3 6/5 5/6 +f 5/7 6/8 8/9 7/10 +f 7/10 8/9 10/11 9/12 +f 9/12 10/11 12/13 11/14 +f 11/15 12/16 14/17 13/18 +f 13/18 14/17 16/19 15/20 +f 15/20 16/19 18/21 17/22 +f 17/22 18/21 20/23 19/24 +f 19/24 20/23 22/25 21/26 +f 21/26 22/25 24/27 23/28 +f 23/28 24/27 26/29 25/30 +f 25/30 26/29 28/31 27/32 +f 27/33 28/34 30/35 29/36 +f 4/37 2/38 32/39 30/40 28/41 26/42 24/43 22/44 20/45 18/46 16/47 14/48 12/49 10/50 8/51 6/52 +f 29/36 30/35 32/53 31/54 +f 31/54 32/53 2/2 1/1 +f 1/55 3/56 5/57 7/58 9/59 11/60 13/61 15/62 17/63 19/64 21/65 23/66 25/67 27/68 29/69 31/70 diff --git a/oil/explore.lua b/oil/explore.lua index c7d7c08..adfd855 100644 --- a/oil/explore.lua +++ b/oil/explore.lua @@ -241,101 +241,6 @@ minetest.register_node("techage:oilexplorer_on", { sounds = default.node_sound_wood_defaults(), }) -minetest.register_node("techage:oil_source", { - description = S("Oil Source"), - drawtype = "liquid", - paramtype = "light", - - inventory_image = "techage_oil_inv.png", - tiles = { - { - name = "techage_oil_animated.png", - backface_culling = false, - animation = { - type = "vertical_frames", - aspect_w = 16, - aspect_h = 16, - length = 10 - } - }, - { - name = "techage_oil_animated.png", - backface_culling = false, - animation = { - type = "vertical_frames", - aspect_w = 16, - aspect_h = 16, - length = 2.0 - } - } - }, - - walkable = false, - pointable = false, - diggable = false, - buildable_to = true, - drowning = 1, - liquidtype = "source", - liquid_alternative_flowing = "techage:oil_flowing", - liquid_alternative_source = "techage:oil_source", - liquid_viscosity = 20, - liquid_range = 10, - liquid_renewable = false, - post_effect_color = {a = 200, r = 1, g = 1, b = 1}, - groups = {liquid = 5}, -}) - - - -minetest.register_node("techage:oil_flowing", { - description = S("Flowing Oil"), - drawtype = "flowingliquid", - tiles = {"techage_oil.png"}, - special_tiles = { - { - name = "techage_oil_animated.png", - backface_culling = false, - animation = { - type = "vertical_frames", - aspect_w = 16, - aspect_h = 16, - length = 10, - }, - }, - { - name = "techage_oil_animated.png", - backface_culling = true, - animation = { - type = "vertical_frames", - aspect_w = 16, - aspect_h = 16, - length = 10, - }, - }, - }, - paramtype = "light", - paramtype2 = "flowingliquid", - walkable = false, - pointable = false, - diggable = false, - buildable_to = true, - is_ground_content = false, - drop = "", - drowning = 1, - liquidtype = "flowing", - liquid_alternative_flowing = "techage:oil_flowing", - liquid_alternative_source = "techage:oil_source", - liquid_viscosity = 20, - liquid_range = 10, - post_effect_color = {a = 200, r = 1, g = 1, b = 1}, - groups = {liquid = 5, not_in_creative_inventory = 1}, -}) - -minetest.register_craft({ - type = "fuel", - recipe = "techage:oil_source", - burntime = 40, -}) minetest.register_craft({ output = "techage:oilexplorer", @@ -346,12 +251,6 @@ minetest.register_craft({ }, }) -bucket.register_liquid( - "techage:oil_source", - "techage:oil_flowing", - "techage:bucket_oil", - "techage_bucket_oil.png", - "Oil Bucket") techage.explore = {} diff --git a/power/junction.lua b/power/junction.lua index 125c25d..4d99371 100644 --- a/power/junction.lua +++ b/power/junction.lua @@ -48,7 +48,7 @@ end -- 'size' is the size of the junction cube without any connection, e.g. 1/8 -- 'boxes' is a table with 6 table elements for the 6 possible connection arms --- 'network' is the tubelib2 instance +-- 'network' is the power (tubelib2) instance or nil -- 'node' is the node definition with tiles, callback functions, and so on -- 'index' number for the inventory node (default 0) function techage.register_junction(name, size, boxes, network, node, index) @@ -70,10 +70,12 @@ function techage.register_junction(name, size, boxes, network, node, index) ndef.drop = name..(index or "0") minetest.register_node(name..idx, ndef) -- Register in addition for power distribution - techage.power.register_node({name..idx}, { - power_network = network, - after_tube_update = ndef.after_tube_update, - }) + if network then + techage.power.register_node({name..idx}, { + power_network = network, + after_tube_update = ndef.after_tube_update, + }) + end end end diff --git a/power/ta4_pipe.lua b/power/ta4_pipe.lua deleted file mode 100644 index 109a80c..0000000 --- a/power/ta4_pipe.lua +++ /dev/null @@ -1,126 +0,0 @@ ---[[ - - TechAge - ======= - - Copyright (C) 2019 Joachim Stolberg - - GPL v3 - See LICENSE.txt for more information - - TA4 Biogas/Stream/oil pipes - -]]-- - --- for lazy programmers -local S2P = minetest.string_to_pos -local P2S = minetest.pos_to_string -local M = minetest.get_meta -local S = techage.S - -local Pipe = tubelib2.Tube:new({ - dirs_to_check = {1,2,3,4,5,6}, - max_tube_length = 100, - show_infotext = false, - force_to_use_tubes = true, - tube_type = "ta4_pipe", - primary_node_names = {"techage:ta4_pipeS", "techage:ta4_pipeA"}, - secondary_node_names = {}, - after_place_tube = function(pos, param2, tube_type, num_tubes) - minetest.swap_node(pos, {name = "techage:ta4_pipe"..tube_type, param2 = param2}) - end, -}) - -Pipe:register_on_tube_update(function(node, pos, out_dir, peer_pos, peer_in_dir) - local ndef = minetest.registered_nodes[node.name] - if ndef and ndef.after_tube_update then - minetest.registered_nodes[node.name].after_tube_update(node, pos, out_dir, peer_pos, peer_in_dir) - end -end) - -techage.BiogasPipe = Pipe - -minetest.register_node("techage:ta4_pipeS", { - description = S("TA4 Pipe"), - tiles = { - "techage_gaspipe.png^[transformR90", - "techage_gaspipe.png^[transformR90", - "techage_gaspipe.png", - "techage_gaspipe.png", - "techage_gaspipe_hole2.png", - "techage_gaspipe_hole2.png", - }, - - after_place_node = function(pos, placer, itemstack, pointed_thing) - if not Pipe:after_place_tube(pos, placer, pointed_thing) then - minetest.remove_node(pos) - return true - end - return false - end, - - after_dig_node = function(pos, oldnode, oldmetadata, digger) - Pipe:after_dig_tube(pos, oldnode) - end, - - paramtype2 = "facedir", -- important! - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = { - {-1/8, -1/8, -4/8, 1/8, 1/8, 4/8}, - }, - }, - on_rotate = screwdriver.disallow, -- important! - paramtype = "light", - sunlight_propagates = true, - is_ground_content = false, - groups = {crumbly = 2, cracky = 2, snappy = 2}, - sounds = default.node_sound_metal_defaults(), -}) - -minetest.register_node("techage:ta4_pipeA", { - description = S("TA4 Pipe"), - tiles = { - "techage_gaspipe_knee2.png", - "techage_gaspipe_hole2.png^[transformR180", - "techage_gaspipe_knee.png^[transformR270", - "techage_gaspipe_knee.png", - "techage_gaspipe_knee2.png", - "techage_gaspipe_hole2.png", - }, - - after_dig_node = function(pos, oldnode, oldmetadata, digger) - Pipe:after_dig_tube(pos, oldnode) - end, - - paramtype2 = "facedir", -- important! - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = { - {-1/8, -4/8, -1/8, 1/8, 1/8, 1/8}, - {-2/8, -0.5, -2/8, 2/8, -13/32, 2/8}, - {-1/8, -1/8, -4/8, 1/8, 1/8, -1/8}, - {-2/8, -2/8, -0.5, 2/8, 2/8, -13/32}, - }, - }, - on_rotate = screwdriver.disallow, -- important! - paramtype = "light", - sunlight_propagates = true, - is_ground_content = false, - groups = {crumbly = 2, cracky = 2, snappy = 2, not_in_creative_inventory=1}, - sounds = default.node_sound_metal_defaults(), - drop = "techage:ta4_pipeS", -}) - - -minetest.register_craft({ - output = "techage:ta4_pipeS 6", - recipe = { - {'', '', "default:steel_ingot"}, - {'dye:yellow', 'techage:meridium_ingot', ''}, - {"default:steel_ingot", '', ''}, - }, -}) - diff --git a/textures/techage_appl_color_top.png b/textures/techage_appl_color_top.png new file mode 100644 index 0000000..37aeb2a Binary files /dev/null and b/textures/techage_appl_color_top.png differ diff --git a/textures/techage_appl_pump.png b/textures/techage_appl_pump.png new file mode 100644 index 0000000..c58f998 Binary files /dev/null and b/textures/techage_appl_pump.png differ diff --git a/textures/techage_appl_pump8.png b/textures/techage_appl_pump8.png new file mode 100644 index 0000000..e5ce81a Binary files /dev/null and b/textures/techage_appl_pump8.png differ diff --git a/textures/techage_appl_tank.png b/textures/techage_appl_tank.png new file mode 100644 index 0000000..17f9888 Binary files /dev/null and b/textures/techage_appl_tank.png differ diff --git a/textures/techage_barrel_inv.png b/textures/techage_barrel_inv.png new file mode 100644 index 0000000..d05ba2c Binary files /dev/null and b/textures/techage_barrel_inv.png differ diff --git a/textures/techage_barrel_oil_inv.png b/textures/techage_barrel_oil_inv.png new file mode 100644 index 0000000..23da888 Binary files /dev/null and b/textures/techage_barrel_oil_inv.png differ diff --git a/textures/techage_filling8_ta4.png b/textures/techage_filling8_ta4.png new file mode 100644 index 0000000..e43a955 Binary files /dev/null and b/textures/techage_filling8_ta4.png differ diff --git a/textures/techage_form_arrow_fg.png b/textures/techage_form_arrow_fg.png index f803d82..b8ffd16 100644 Binary files a/textures/techage_form_arrow_fg.png and b/textures/techage_form_arrow_fg.png differ diff --git a/textures/techage_form_grey.png b/textures/techage_form_grey.png new file mode 100644 index 0000000..cddf960 Binary files /dev/null and b/textures/techage_form_grey.png differ diff --git a/textures/techage_form_input_arrow.png b/textures/techage_form_input_arrow.png new file mode 100644 index 0000000..8de6aac Binary files /dev/null and b/textures/techage_form_input_arrow.png differ diff --git a/textures/techage_form_level_charge.png.png b/textures/techage_form_level_charge.png.png deleted file mode 100644 index 6c3526a..0000000 Binary files a/textures/techage_form_level_charge.png.png and /dev/null differ diff --git a/textures/techage_form_level_red_fg.png b/textures/techage_form_level_red_fg.png new file mode 100644 index 0000000..2e02102 Binary files /dev/null and b/textures/techage_form_level_red_fg.png differ diff --git a/textures/techage_form_output_arrow.png b/textures/techage_form_output_arrow.png new file mode 100644 index 0000000..285e416 Binary files /dev/null and b/textures/techage_form_output_arrow.png differ diff --git a/textures/techage_form_tank.png b/textures/techage_form_tank.png new file mode 100644 index 0000000..308c5b1 Binary files /dev/null and b/textures/techage_form_tank.png differ diff --git a/textures/techage_frame8_ta4.png b/textures/techage_frame8_ta4.png new file mode 100644 index 0000000..89ef0ed Binary files /dev/null and b/textures/techage_frame8_ta4.png differ diff --git a/textures/techage_liquid_inv.png b/textures/techage_liquid_inv.png new file mode 100644 index 0000000..141fdc7 Binary files /dev/null and b/textures/techage_liquid_inv.png differ diff --git a/textures/techage_reactor_filler_side.png b/textures/techage_reactor_filler_side.png new file mode 100644 index 0000000..ea813a9 Binary files /dev/null and b/textures/techage_reactor_filler_side.png differ diff --git a/textures/techage_reactor_filler_top.png b/textures/techage_reactor_filler_top.png new file mode 100644 index 0000000..a105fbb Binary files /dev/null and b/textures/techage_reactor_filler_top.png differ diff --git a/textures/techage_reactor_stand_back.png b/textures/techage_reactor_stand_back.png new file mode 100644 index 0000000..38669c6 Binary files /dev/null and b/textures/techage_reactor_stand_back.png differ diff --git a/textures/techage_reactor_stand_bottom.png b/textures/techage_reactor_stand_bottom.png new file mode 100644 index 0000000..17e238e Binary files /dev/null and b/textures/techage_reactor_stand_bottom.png differ diff --git a/textures/techage_reactor_stand_front.png b/textures/techage_reactor_stand_front.png new file mode 100644 index 0000000..b377981 Binary files /dev/null and b/textures/techage_reactor_stand_front.png differ diff --git a/textures/techage_reactor_stand_side.png b/textures/techage_reactor_stand_side.png new file mode 100644 index 0000000..91c521f Binary files /dev/null and b/textures/techage_reactor_stand_side.png differ diff --git a/textures/techage_reactor_stand_top.png b/textures/techage_reactor_stand_top.png new file mode 100644 index 0000000..b27456f Binary files /dev/null and b/textures/techage_reactor_stand_top.png differ