networks, liquids, reactor, barrels, tanks, and pumps introduced, still untested

master
Joachim Stolberg 2019-10-27 11:14:37 +01:00
parent 7b180200bc
commit 68c8a74da8
47 changed files with 2021 additions and 306 deletions

View File

@ -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,

View File

@ -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",

View File

@ -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)

View File

@ -173,4 +173,21 @@ local function determine_ocean_ids()
end
end
determine_ocean_ids()
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

View File

@ -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)

289
basis/networks.lua Normal file
View File

@ -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

View File

@ -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)

View File

@ -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(),
})

309
chemistry/ta4_doser.lua Normal file
View File

@ -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 = {} -- {<output name>,...}
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 = "<item-name> <units>", -- units = 1..n
-- waste = "<item-name> <units>",
-- input = { -- up to 4
-- "<item-name> <units>",
-- "<item-name> <units>",
-- },
-- }
--
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",
}
})

92
chemistry/ta4_pump.lua Normal file
View File

@ -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"})

170
chemistry/ta4_reactor.lua Normal file
View File

@ -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,
})

View File

@ -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")

View File

@ -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', ''},

38
liquids/barrel.lua Normal file
View File

@ -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")

161
liquids/liquid.lua Normal file
View File

@ -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

195
liquids/liquid_pipe.lua Normal file
View File

@ -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

136
liquids/oil.lua Normal file
View File

@ -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")

314
liquids/tank.lua Normal file
View File

@ -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,
})

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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 = {}

View File

@ -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

View File

@ -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", '', ''},
},
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 B

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 934 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 734 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 742 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 645 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 823 B