mods that hopefully work for a TechAge-based pack

This commit is contained in:
2026-09-09 06:27:51 -06:00
parent 4e6b08d194
commit c27db2a537
6234 changed files with 375578 additions and 0 deletions
@@ -0,0 +1,200 @@
--[[
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
TA3 Booster
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
local PWR_NEEDED = 3
local CYCLE_TIME = 2
local Cable = techage.ElectricCable
local power = networks.power
local function infotext(pos, state)
M(pos):set_string("infotext", S("TA3 Booster")..": "..state)
end
local function swap_node(pos, name)
local node = techage.get_node_lvm(pos)
if node.name == name then
return
end
node.name = name
minetest.swap_node(pos, node)
end
local function play_sound(pos)
local mem = techage.get_mem(pos)
if not mem.handle or mem.handle == -1 then
mem.handle = minetest.sound_play("techage_booster", {
pos = pos,
gain = 1,
max_hear_distance = 7,
loop = true})
if mem.handle == -1 then
minetest.after(1, play_sound, pos)
end
end
end
local function stop_sound(pos)
local mem = techage.get_mem(pos)
if mem.handle then
minetest.sound_stop(mem.handle)
mem.handle = nil
end
end
local function after_place_node(pos)
local nvm = techage.get_nvm(pos)
Cable:after_place_node(pos)
local node = minetest.get_node(pos)
local indir = techage.side_to_indir("R", node.param2)
M(pos):set_int("indir", indir)
infotext(pos, "stopped")
end
local function after_dig_node(pos, oldnode)
Cable:after_dig_node(pos)
techage.del_mem(pos)
end
minetest.register_node("techage:ta3_booster", {
description = S("TA3 Booster"),
tiles = {
-- up, down, right, left, back, front
"techage_filling_ta3.png^techage_appl_arrow.png^techage_frame_ta3.png",
"techage_filling_ta3.png^techage_frame_ta3.png",
"techage_filling_ta3.png^techage_appl_hole_pipe.png^techage_frame_ta3.png",
"techage_filling_ta3.png^techage_appl_hole_electric.png^techage_frame_ta3.png",
"techage_filling_ta3.png^techage_appl_compressor.png^techage_frame_ta3.png",
"techage_filling_ta3.png^techage_appl_compressor.png^[transformFX^techage_frame_ta3.png",
},
on_timer = function(pos, elapsed)
local consumed = power.consume_power(pos, Cable, nil, PWR_NEEDED)
if consumed == PWR_NEEDED then
swap_node(pos, "techage:ta3_booster_on")
infotext(pos, "running")
play_sound(pos)
end
return true
end,
after_place_node = after_place_node,
after_dig_node = after_dig_node,
paramtype2 = "facedir",
groups = {cracky=2, crumbly=2, choppy=2},
on_rotate = screwdriver.disallow,
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
})
minetest.register_node("techage:ta3_booster_on", {
description = S("TA3 Booster"),
tiles = {
-- up, down, right, left, back, front
"techage_filling_ta3.png^techage_appl_arrow.png^techage_frame_ta3.png",
"techage_filling_ta3.png^techage_frame_ta3.png",
"techage_filling_ta3.png^techage_appl_hole_pipe.png^techage_frame_ta3.png",
"techage_filling_ta3.png^techage_appl_hole_electric.png^techage_frame_ta3.png",
{
name = "techage_filling4_ta3.png^techage_appl_compressor4.png^techage_frame4_ta3.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 32,
aspect_h = 32,
length = 0.2,
},
},
{
name = "techage_filling4_ta3.png^techage_appl_compressor4.png^[transformFX]^techage_frame4_ta3.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 32,
aspect_h = 32,
length = 0.2,
},
},
},
on_timer = function(pos, elapsed)
local consumed = power.consume_power(pos, Cable, nil, PWR_NEEDED)
if consumed < PWR_NEEDED then
swap_node(pos, "techage:ta3_booster")
infotext(pos, "no power")
stop_sound(pos)
end
return true
end,
after_place_node = after_place_node,
after_dig_node = after_dig_node,
paramtype2 = "facedir",
groups = {not_in_creative_inventory = 1},
diggable = false,
on_rotate = screwdriver.disallow,
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
})
power.register_nodes({"techage:ta3_booster", "techage:ta3_booster_on"}, Cable, "con", {"B", "F", "L", "D", "U"})
-- for intra machine communication
techage.register_node({"techage:ta3_booster", "techage:ta3_booster_on"}, {
on_transfer = function(pos, in_dir, topic, payload)
if M(pos):get_int("indir") == in_dir then
local nvm = techage.get_nvm(pos)
if topic == "power" then
return techage.get_node_lvm(pos).name == "techage:ta3_booster_on" or
power.power_available(pos, Cable)
elseif topic == "running" then
return techage.get_node_lvm(pos).name == "techage:ta3_booster_on"
elseif topic == "start" and not nvm.running then
if power.power_available(pos, Cable) then
nvm.running = true
minetest.get_node_timer(pos):start(CYCLE_TIME)
swap_node(pos, "techage:ta3_booster_on")
infotext(pos, "running")
play_sound(pos)
else
infotext(pos, "no power")
end
elseif topic == "stop" then
nvm.running = false
swap_node(pos, "techage:ta3_booster")
minetest.get_node_timer(pos):stop()
infotext(pos, "stopped")
stop_sound(pos)
end
end
end,
on_node_load = function(pos, node)
if node.name == "techage:ta3_booster_on" then
play_sound(pos)
end
end,
})
minetest.register_craft({
output = "techage:ta3_booster",
recipe = {
{"basic_materials:steel_bar", "default:wood", "basic_materials:steel_bar"},
{"", "basic_materials:gear_steel", ""},
{"basic_materials:steel_bar", "default:wood", "basic_materials:steel_bar"},
},
})
@@ -0,0 +1,228 @@
--[[
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Cooking routines for furnace
]]--
-- for lazy programmers
local P = minetest.string_to_pos
local M = minetest.get_meta
local S = techage.S
local range = techage.in_range
local Recipes = {} -- registered recipes {output = {recipe, ...},}
local Ingredients = {} -- {{input = output},
local KeyList = {} -- index to Recipes key translation
techage.furnace = {}
local function all_ingredients_available(output, ingr)
if Recipes[output] then
for idx,recipe in ipairs(Recipes[output]) do
local not_in_list = false
for _,item in ipairs(recipe.input) do
if not techage.in_list(ingr, item) then
not_in_list = true
end
end
if not_in_list == false then
return idx -- list number of the recipe
end
end
end
end
-- Return a list with all outputs of the given list of ingredients
local function get_recipes(ingr)
if #ingr > 0 then
local tbl = {}
for _,item in ipairs(ingr) do
if Ingredients[item] then
for _,output in ipairs(Ingredients[item]) do
if all_ingredients_available(output, ingr) then
techage.add_to_set(tbl, output)
end
end
end
end
return tbl
else
return KeyList
end
end
function techage.furnace.get_ingredients(pos)
local inv = M(pos):get_inventory()
local tbl = {}
for _,stack in ipairs(inv:get_list('src')) do
if stack:get_name() ~= "" then
tbl[#tbl+1] = stack:get_name()
end
end
return tbl
end
local function remove_item_from_list(list, item)
for _,stack in ipairs(list) do
if stack:get_name() == item then
stack:set_count(stack:get_count() - 1)
return true
end
end
return false
end
-- move recipe src items to output inventory
local function process(inv, recipe, output)
-- check dst inv
local stack = ItemStack(output)
stack:set_count(recipe.number)
if not inv:room_for_item("dst", stack) then
return techage.BLOCKED
end
-- handle waste
if recipe.waste then
if not inv:room_for_item("dst", ItemStack(recipe.waste)) then
return techage.BLOCKED
end
end
-- remove items
local list = inv:get_list("src")
for _,item in ipairs(recipe.input) do
if not remove_item_from_list(list, item) then
return techage.STANDBY
end
end
-- store changes on scr
inv:set_list("src", list)
-- add output to dst
inv:add_item("dst", stack)
-- add waste to dst
if recipe.waste then
local leftover = inv:add_item("dst", ItemStack(recipe.waste))
if leftover:get_count() > 0 then
inv:add_item("src", leftover)
return techage.BLOCKED
end
end
return techage.RUNNING
end
function techage.furnace.check_if_worth_to_wakeup(pos, nvm)
local inv = M(pos):get_inventory()
if not nvm.output or not nvm.num_recipe then
return false
end
local recipe = Recipes[nvm.output] and Recipes[nvm.output][nvm.num_recipe]
if not recipe then
return false
end
-- check dst inv
local stack = ItemStack(nvm.output)
stack:set_count(recipe.number)
if not inv:room_for_item("dst", stack) then
return false
end
-- check src inv
local list = inv:get_list("src")
for _,item in ipairs(recipe.input) do
if not remove_item_from_list(list, item) then
return false
end
end
return true
end
function techage.furnace.smelting(pos, nvm, elapsed)
local inv = M(pos):get_inventory()
local state = techage.RUNNING
if inv and not inv:is_empty("src") then
if not nvm.output or not nvm.num_recipe then
return techage.FAULT, "recipe error"
end
local recipe = Recipes[nvm.output] and Recipes[nvm.output][nvm.num_recipe]
if not recipe then
return techage.FAULT, "recipe error"
end
elapsed = elapsed + (nvm.leftover or 0)
while elapsed >= recipe.time do
state = process(inv, recipe, nvm.output)
if state ~= techage.RUNNING then
return state
end
elapsed = elapsed - recipe.time
end
nvm.leftover = elapsed
if recipe.time >= 10 then
nvm.item_percent = math.min(math.floor((nvm.leftover * 100.0) / recipe.time), 100)
else
nvm.item_percent = 100
end
return state
end
return techage.STANDBY
end
function techage.furnace.get_output(nvm, ingr, idx)
local tbl = get_recipes(ingr)
idx = range(idx, 1, #tbl)
nvm.output = tbl[idx] or tbl[1]
nvm.num_recipe = all_ingredients_available(nvm.output, ingr)
return nvm.output
end
function techage.furnace.get_num_recipes(ingr)
return #get_recipes(ingr)
end
function techage.furnace.reset_cooking(nvm)
nvm.leftover = 0
nvm.item_percent = 0
end
techage.recipes.register_craft_type("ta3_melting", {
description = S("TA3 Melting"),
icon = "techage_concrete.png^techage_appl_furnace.png^techage_frame_ta3.png",
width = 2,
height = 2,
})
function techage.furnace.register_recipe(recipe)
local words = string.split(recipe.output, " ")
local output = words[1]
local number = tonumber(words[2] or 1)
table.insert(KeyList, output)
--print(recipe.output, dump(recipe.recipe))
if not Recipes[output] then
Recipes[output] = {}
end
table.insert(Recipes[output], {
input = recipe.recipe,
waste = recipe.waste,
number = number,
time = math.max((recipe.time or 3) * number, 2),
})
for _,item in ipairs(recipe.recipe) do
if Ingredients[item] then
techage.add_to_set(Ingredients[item], output)
else
Ingredients[item] = {output}
end
end
recipe.items = recipe.recipe
recipe.type = "ta3_melting"
techage.recipes.register_craft(recipe)
end
@@ -0,0 +1,226 @@
--[[
TechAge
=======
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
TA3 Industrial Furnace Firebox
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
local firebox = techage.firebox
local fuel = techage.fuel
local Pipe = techage.LiquidPipe
local liquid = networks.liquid
local CYCLE_TIME = 2
local EFFICIENCY = 2 -- burn cycles
local CATEGORY = 3
local function has_fuel(pos, nvm)
return (nvm.burn_cycles or 0) > 0 or (nvm.liquid and nvm.liquid.amount and nvm.liquid.amount > 0)
end
local function stop_firebox(pos, nvm)
nvm.running = false
firebox.swap_node(pos, "techage:furnace_firebox")
minetest.get_node_timer(pos):stop()
M(pos):set_string("formspec", fuel.formspec(nvm))
end
local function furnace_active(pos)
-- Check if furnace is not in standby mode
return techage.get_node_lvm({x=pos.x, y=pos.y+1, z=pos.z}).name == "techage:ta3_furnace_act"
end
local function node_timer(pos, elapsed)
local nvm = techage.get_nvm(pos)
nvm.liquid = nvm.liquid or {}
nvm.liquid.amount = nvm.liquid.amount or 0
if nvm.running and furnace_active(pos) then
nvm.burn_cycles = (nvm.burn_cycles or 0) - 1
if nvm.burn_cycles <= 0 then
if nvm.liquid.amount > 0 then
nvm.liquid.amount = nvm.liquid.amount - 1
nvm.burn_cycles = fuel.burntime(nvm.liquid.name) * EFFICIENCY / CYCLE_TIME
nvm.burn_cycles_total = nvm.burn_cycles
else
nvm.liquid.name = nil
stop_firebox(pos, nvm)
return false
end
end
else
stop_firebox(pos, nvm)
return false
end
if techage.is_activeformspec(pos) then
M(pos):set_string("formspec", fuel.formspec(nvm))
end
return true
end
local function start_firebox(pos, nvm)
if not nvm.running and furnace_active(pos) then
nvm.running = true
node_timer(pos, 0)
firebox.swap_node(pos, "techage:furnace_firebox_on")
minetest.get_node_timer(pos):start(CYCLE_TIME)
M(pos):set_string("formspec", fuel.formspec(nvm))
end
end
local function booster_cmnd(pos, cmnd)
return techage.transfer(
pos,
"L", -- outdir
cmnd, -- topic
nil, -- payload
nil, -- network
{"techage:ta3_booster", "techage:ta3_booster_on"})
end
minetest.register_node("techage:furnace_firebox", {
description = S("TA3 Furnace Oil Burner"),
tiles = {
-- up, down, right, left, back, front
"techage_concrete.png^techage_appl_open.png^techage_frame_ta3.png",
"techage_concrete.png^techage_frame_ta3.png",
"techage_concrete.png^techage_frame_ta3.png",
"techage_concrete.png^techage_appl_hole_pipe.png^techage_frame_ta3.png",
"techage_concrete.png^techage_frame_ta3.png",
"techage_concrete.png^techage_appl_firehole.png^techage_frame_ta3.png",
},
paramtype2 = "facedir",
on_rotate = screwdriver.disallow,
groups = {cracky=2},
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
on_timer = node_timer,
can_dig = fuel.can_dig,
on_punch = fuel.on_punch,
on_receive_fields = fuel.on_receive_fields,
on_rightclick = fuel.on_rightclick,
on_construct = function(pos)
local nvm = techage.get_nvm(pos)
techage.add_node(pos, "techage:furnace_firebox", true)
nvm.running = false
nvm.burn_cycles = 0
nvm.liquid = {}
nvm.liquid.amount = 0
local meta = M(pos)
meta:set_string("formspec", fuel.formspec(nvm))
local inv = meta:get_inventory()
inv:set_size('fuel', 1)
end,
})
minetest.register_node("techage:furnace_firebox_on", {
description = S("TA3 Furnace Oil Burner"),
tiles = {
-- up, down, right, left, back, front
"techage_concrete.png^techage_frame_ta3.png",
"techage_concrete.png^techage_frame_ta3.png",
"techage_concrete.png^techage_frame_ta3.png",
"techage_concrete.png^techage_frame_ta3.png",
"techage_concrete.png^techage_frame_ta3.png",
{
name = "techage_concrete4.png^techage_appl_firehole4.png^techage_frame4_ta3.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 32,
aspect_h = 32,
length = 0.4,
},
},
},
paramtype2 = "facedir",
light_source = 8,
on_rotate = screwdriver.disallow,
diggable = false,
groups = {not_in_creative_inventory = 1},
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
drop = "techage:furnace_firebox",
on_timer = node_timer,
can_dig = fuel.can_dig,
on_receive_fields = fuel.on_receive_fields,
on_punch = fuel.on_punch,
on_rightclick = fuel.on_rightclick,
})
minetest.register_craft({
output = "techage:furnace_firebox",
recipe = {
{'techage:basalt_stone', 'techage:basalt_stone', 'techage:basalt_stone'},
{'default:steel_ingot', '', 'default:steel_ingot'},
{'techage:basalt_stone', 'techage:basalt_stone', 'techage:basalt_stone'},
},
})
techage.register_node({"techage:furnace_firebox", "techage:furnace_firebox_on"}, {
on_recv_message = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == "state" then
return nvm.running and "running" or "stopped"
elseif topic == "fuel" then
return fuel.get_fuel_amount(nvm)
else
return "unsupported"
end
end,
on_beduino_request_data = function(pos, src, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == 128 then
return 0, techage.get_node_lvm(pos).name
elseif topic == 129 then -- State
return 0, {nvm.running and techage.RUNNING or techage.STOPPED}
elseif topic == 132 then -- Fuel Level
return 0, {fuel.get_fuel_amount(nvm)}
else
return 2, ""
end
end,
-- called from furnace_top
on_transfer = function(pos, in_dir, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == "fuel" then
return has_fuel(pos, nvm) and booster_cmnd(pos, "power")
elseif topic == "running" then
return nvm.running and booster_cmnd(pos, "running")
elseif topic == "start" then
start_firebox(pos, nvm)
booster_cmnd(pos, "start")
elseif topic == "stop" then
stop_firebox(pos, nvm)
booster_cmnd(pos, "stop")
end
end,
on_node_load = function(pos, node)
local inv = M(pos):get_inventory()
if not inv:is_empty("fuel") then
local nvm = techage.get_nvm(pos)
nvm.liquid = nvm.liquid or {}
local count = inv:get_stack("fuel", 1):get_count()
nvm.liquid.amount = (nvm.liquid.amount or 0) + count
nvm.liquid.name = "techage:gasoline"
inv:set_stack("fuel", 1, nil)
end
end,
})
liquid.register_nodes({"techage:furnace_firebox", "techage:furnace_firebox_on"},
Pipe, "tank", nil, fuel.get_liquid_table(fuel.BT_OIL, fuel.CAPACITY, start_firebox))
@@ -0,0 +1,339 @@
--[[
TechAge
=======
Copyright (C) 2019-2022 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
TA3 Industrial Furnace Top
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
-- Consumer Related Data
local CRD = function(pos) return (minetest.registered_nodes[techage.get_node_lvm(pos).name] or {}).consumer end
local STANDBY_TICKS = 6
local COUNTDOWN_TICKS = 6
local CYCLE_TIME = 2
local smelting = techage.furnace.smelting
local get_output = techage.furnace.get_output
local num_recipes = techage.furnace.get_num_recipes
local reset_cooking = techage.furnace.reset_cooking
local get_ingredients = techage.furnace.get_ingredients
local check_if_worth_to_wakeup = techage.furnace.check_if_worth_to_wakeup
local range = techage.in_range
local MP = minetest.get_modpath(minetest.get_current_modname())
local mConf = assert(loadfile(MP .. "/basis/conf_inv.lua"))("cfg")
local WRENCH_MENU3 = {
{
type = "items",
name = "config",
label = S("Pre-Assignment Input Inv."),
tooltip = S("Stack locations can be pre-assigned to specific items,\nto be filled only with those items."),
width = 2,
height = 2,
}
}
local function update_recipe_menu(pos, nvm)
local ingr = get_ingredients(pos)
nvm.rp_num = num_recipes(ingr)
nvm.rp_idx = range(nvm.rp_idx or 1, 0, nvm.rp_num)
nvm.rp_outp = get_output(nvm, ingr, nvm.rp_idx)
end
local function formspec(self, pos, nvm)
local idx = nvm.rp_idx or 1
local num = nvm.rp_num or 1
local outp = nvm.rp_outp or ""
return "size[8,7.2]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
techage.wrench_image(7.6, -0.2) ..
"list[context;src;0,0;2,2;]"..
mConf.preassigned_stacks(pos, 2, 2)..
"image[2,0.5;1,1;techage_form_arrow_bg.png^[lowpart:"..
(nvm.item_percent or 0)..":techage_form_arrow_fg.png^[transformR270]"..
"image_button[2,2;1,1;".. self:get_state_button_image(nvm) ..";state_button;]"..
"tooltip[2,2;1,1;"..self:get_state_tooltip(nvm).."]"..
"list[context;dst;3,0;2,2;]"..
"label[6,0;"..S("Outp")..": "..idx.."/"..num.."]"..
"item_image_button[6.5,0.5;1,1;"..outp..";b1;]"..
"button[6,1.5;1,1;priv;<<]"..
"button[7,1.5;1,1;next;>>]"..
"list[current_player;main;0,3.5;8,4;]" ..
"listring[current_player;main]"..
"listring[context;src]" ..
"listring[current_player;main]"..
"listring[context;dst]" ..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 3.5)
end
local function on_rightclick(pos, node, clicker)
local nvm = techage.get_nvm(pos)
M(pos):set_string("formspec", formspec(CRD(pos).State, pos, nvm))
end
local function firebox_cmnd(pos, cmnd)
return techage.transfer(
{x=pos.x, y=pos.y-1, z=pos.z},
nil, -- outdir
cmnd, -- topic
nil, -- payload
nil, -- network
{"techage:furnace_firebox", "techage:furnace_firebox_on",
"techage:furnace_heater", "techage:furnace_heater_on"})
end
local function firebox_has_fuel(nvm, pos)
if nvm.techage_state == techage.RUNNING then
return firebox_cmnd(pos, "running")
else
return firebox_cmnd(pos, "fuel")
end
end
local function cooking(pos, crd, nvm, elapsed)
if nvm.techage_state == techage.RUNNING or check_if_worth_to_wakeup(pos, nvm) then
if firebox_has_fuel(nvm, pos) then
local state, err = smelting(pos, nvm, elapsed)
if state == techage.RUNNING then
crd.State:keep_running(pos, nvm, COUNTDOWN_TICKS)
elseif state == techage.BLOCKED then
crd.State:blocked(pos, nvm)
elseif state == techage.FAULT then
crd.State:fault(pos, nvm, err)
elseif state == techage.STANDBY then
crd.State:idle(pos, nvm)
end
else
crd.State:standby(pos, nvm, S("no fuel or no power"))
end
end
end
local function keep_running(pos, elapsed)
local nvm = techage.get_nvm(pos)
local crd = CRD(pos)
cooking(pos, crd, nvm, elapsed)
nvm.toggle = not nvm.toggle
if nvm.toggle then -- progress bar/arrow
M(pos):set_string("formspec", formspec(crd.State, pos, nvm))
end
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
if listname == "src" then
local nvm = techage.get_nvm(pos)
return stack:get_count()
elseif listname == "dst" then
return 0
end
end
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
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_metadata_inventory(pos)
local nvm = techage.get_nvm(pos)
local crd = CRD(pos)
M(pos):set_string("formspec", formspec(crd.State, pos, nvm))
end
local function on_receive_fields(pos, formname, fields, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
local nvm = techage.get_nvm(pos)
nvm.rp_idx = nvm.rp_idx or 1
if fields.next == ">>" then
local ingr = get_ingredients(pos)
nvm.rp_idx = math.min(nvm.rp_idx + 1, num_recipes(ingr))
update_recipe_menu(pos, nvm)
M(pos):set_string("formspec", formspec(CRD(pos).State, pos, nvm))
reset_cooking(nvm)
elseif fields.priv == "<<" then
local ingr = get_ingredients(pos)
nvm.rp_idx = range(nvm.rp_idx - 1, 1, num_recipes(ingr))
update_recipe_menu(pos, nvm)
M(pos):set_string("formspec", formspec(CRD(pos).State, pos, nvm))
reset_cooking(nvm)
end
CRD(pos).State:state_button_event(pos, nvm, fields)
end
local function can_dig(pos, player)
if minetest.is_protected(pos, player:get_player_name()) then
return false
end
local inv = M(pos):get_inventory()
return inv:is_empty("dst") and inv:is_empty("src")
end
local function can_start(pos, nvm, state)
if not firebox_cmnd(pos, "fuel") then
return S("no fuel or no power")
end
return true
end
local function on_node_state_change(pos, old_state, new_state)
local pwr1 = techage.needs_power2(old_state)
local pwr2 = techage.needs_power2(new_state)
if pwr1 ~= pwr2 then
if pwr2 then
firebox_cmnd(pos, "start")
else
firebox_cmnd(pos, "stop")
end
end
local nvm = techage.get_nvm(pos)
reset_cooking(nvm)
end
local tiles = {}
-- '#' will be replaced by the stage number
tiles.pas = {
-- up, down, right, left, back, front
"techage_concrete.png^techage_frame_ta#_top.png",
"techage_concrete.png^techage_frame_ta#_top.png",
"techage_concrete.png^techage_frame_ta#.png^techage_appl_outp.png",
"techage_concrete.png^techage_frame_ta#.png^techage_appl_inp.png",
"techage_concrete.png^techage_frame_ta#.png",
"techage_concrete.png^techage_appl_furnace.png^techage_frame_ta#.png",
}
tiles.act = tiles.pas
local tubing = {
on_inv_request = function(pos, in_dir, access_type)
if access_type == "push" then
local meta = minetest.get_meta(pos)
if meta:get_int("push_dir") == in_dir or in_dir == 5 then
return meta:get_inventory(), "src"
end
end
end,
on_pull_item = function(pos, in_dir, num)
local meta = minetest.get_meta(pos)
if meta:get_int("pull_dir") == in_dir then
local inv = M(pos):get_inventory()
return techage.get_items(pos, inv, "dst", num)
end
end,
on_push_item = function(pos, in_dir, stack, idx)
local meta = minetest.get_meta(pos)
if meta:get_int("push_dir") == in_dir or in_dir == 5 then
local inv = M(pos):get_inventory()
local mem = techage.get_mem(pos)
mem.filter = mem.filter or mConf.item_filter(pos, 4)
mem.chest_configured = mem.chest_configured or not inv:is_empty("cfg")
if mem.chest_configured then
local name = stack:get_name()
local stacks = mem.filter[name] or mem.filter["unconfigured"]
return mConf.put_items(pos, inv, "src", stack, stacks, idx)
else
return techage.put_items(inv, "src", stack, idx)
end
end
end,
on_unpull_item = function(pos, in_dir, stack)
local meta = minetest.get_meta(pos)
if meta:get_int("pull_dir") == in_dir then
local inv = M(pos):get_inventory()
return techage.put_items(inv, "dst", stack)
end
end,
on_recv_message = function(pos, src, topic, payload)
if topic == "output" then
local nvm = techage.get_nvm(pos)
return string.split(nvm.output or "unknown", " ")[1]
else
return CRD(pos).State:on_receive_message(pos, topic, payload)
end
end,
on_beduino_receive_cmnd = function(pos, src, topic, payload)
return CRD(pos).State:on_beduino_receive_cmnd(pos, topic, payload)
end,
on_beduino_request_data = function(pos, src, topic, payload)
if topic == 141 then -- Furnace Output
local nvm = techage.get_nvm(pos)
return 0, string.split(nvm.output or "unknown", " ")[1]
else
return CRD(pos).State:on_beduino_request_data(pos, topic, payload)
end
end,
}
local _, node_name_ta3, _ =
techage.register_consumer("furnace", S("Furnace Top"), tiles, {
drawtype = "normal",
cycle_time = CYCLE_TIME,
standby_ticks = STANDBY_TICKS,
formspec = formspec,
tubing = tubing,
can_start = can_start,
on_state_change = on_node_state_change,
after_place_node = function(pos, placer)
local inv = M(pos):get_inventory()
inv:set_size("src", 2*2)
inv:set_size("dst", 2*2)
inv:set_size("cfg", 2*2)
end,
can_dig = can_dig,
node_timer = keep_running,
on_receive_fields = on_receive_fields,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_move = allow_metadata_inventory_move,
allow_metadata_inventory_take = allow_metadata_inventory_take,
on_metadata_inventory_put = on_metadata_inventory,
on_metadata_inventory_take = on_metadata_inventory,
on_metadata_inventory_move = on_metadata_inventory,
ta3_formspec = WRENCH_MENU3,
on_rightclick = on_rightclick,
groups = {choppy=2, cracky=2, crumbly=2},
sounds = default.node_sound_wood_defaults(),
num_items = {0,1,1,1},
},
{false, false, true, false}) -- TA3 only
minetest.register_craft({
output = node_name_ta3,
recipe = {
{"", "techage:usmium_nuggets", ""},
{"default:steel_ingot", "default:furnace", "default:steel_ingot"},
{"", "techage:vacuum_tube", ""},
},
})
@@ -0,0 +1,137 @@
--[[
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
TA4 Industrial Furnace Heater
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
local PWR_NEEDED = 14
local CYCLE_TIME = 2
local Cable = techage.ElectricCable
local power = networks.power
local function swap_node(pos, name)
local node = techage.get_node_lvm(pos)
if node.name == name then
return
end
node.name = name
minetest.swap_node(pos, node)
end
local function after_place_node(pos)
Cable:after_place_node(pos)
end
local function after_dig_node(pos, oldnode)
Cable:after_dig_node(pos)
techage.del_mem(pos)
end
minetest.register_node("techage:furnace_heater", {
description = S("TA4 Furnace Heater"),
tiles = {
-- up, down, right, left, back, front
"techage_concrete.png^techage_appl_open.png^techage_frame_ta3.png",
"techage_concrete.png^techage_frame_ta3.png",
"techage_concrete.png^techage_frame_ta3.png",
"techage_concrete.png^techage_frame_ta3.png^techage_appl_hole_electric.png",
"techage_concrete.png^techage_frame_ta3.png",
"techage_concrete.png^techage_appl_heater.png^techage_frame_ta3.png",
},
on_timer = function(pos, elapsed)
local consumed = power.consume_power(pos, Cable, nil, PWR_NEEDED)
if consumed == PWR_NEEDED then
swap_node(pos, "techage:furnace_heater_on")
end
return true
end,
after_place_node = after_place_node,
after_dig_node = after_dig_node,
paramtype2 = "facedir",
groups = {cracky=2, crumbly=2, choppy=2},
on_rotate = screwdriver.disallow,
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
})
minetest.register_node("techage:furnace_heater_on", {
description = S("TA4 Furnace Heater"),
tiles = {
-- up, down, right, left, back, front
"techage_concrete.png^techage_appl_open.png^techage_frame_ta3.png",
"techage_concrete.png^techage_frame_ta3.png",
"techage_concrete.png^techage_frame_ta3.png",
"techage_concrete.png^techage_frame_ta3.png^techage_appl_hole_electric.png",
"techage_concrete.png^techage_frame_ta3.png",
"techage_concrete.png^techage_appl_heater_on.png^techage_frame_ta3.png",
},
on_timer = function(pos, elapsed)
local consumed = power.consume_power(pos, Cable, nil, PWR_NEEDED)
if consumed < PWR_NEEDED then
swap_node(pos, "techage:furnace_heater")
end
return true
end,
after_place_node = after_place_node,
after_dig_node = after_dig_node,
light_source = 8,
paramtype2 = "facedir",
groups = {not_in_creative_inventory = 1},
diggable = false,
on_rotate = screwdriver.disallow,
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
})
power.register_nodes({"techage:furnace_heater", "techage:furnace_heater_on"}, Cable, "con", {"B", "F", "L", "D", "U"})
techage.register_node({"techage:furnace_heater", "techage:furnace_heater_on"}, {
-- called from furnace_top
on_transfer = function(pos, in_dir, topic, payload)
local nvm = techage.get_nvm(pos)
if topic == "fuel" then
return power.power_available(pos, Cable)
elseif topic == "running" then
return techage.get_node_lvm(pos).name == "techage:furnace_heater_on"
elseif topic == "start" and not nvm.running then
if power.power_available(pos, Cable) then
nvm.running = true
minetest.get_node_timer(pos):start(CYCLE_TIME)
return true
end
elseif topic == "stop" and nvm.running then
nvm.running = false
swap_node(pos, "techage:furnace_heater")
minetest.get_node_timer(pos):stop()
return true
end
end
})
minetest.register_craft({
output = "techage:furnace_heater",
recipe = {
{'techage:aluminum', 'default:steel_ingot', 'techage:aluminum'},
{'techage:basalt_stone', 'basic_materials:heating_element', 'techage:basalt_stone'},
{'techage:aluminum', 'techage:ta4_furnace_ceramic', 'techage:aluminum'},
},
})
@@ -0,0 +1,188 @@
--[[
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Cooking recipes for furnace
]]--
techage.furnace.register_recipe({
output = "techage:iron_ingot",
recipe = {"default:iron_lump"},
time = 2,
})
techage.furnace.register_recipe({
output = "default:obsidian",
recipe = {"default:cobble"},
time = 8,
})
if techage.modified_recipes_enabled then
techage.furnace.register_recipe({
output = "default:bronze_ingot 4",
recipe = {"default:copper_ingot", "default:copper_ingot", "default:copper_ingot", "default:tin_ingot"},
time = 2,
})
techage.furnace.register_recipe({
output = "default:steel_ingot 4",
recipe = {"default:coal_lump", "default:iron_lump", "default:iron_lump", "default:iron_lump"},
time = 4,
})
techage.furnace.register_recipe({
output = "default:steel_ingot 4",
recipe = {"default:coal_lump", "techage:iron_ingot", "techage:iron_ingot", "techage:iron_ingot"},
time = 4,
})
end
if minetest.global_exists("wielded_light") then
techage.furnace.register_recipe({
output = "techage:meridium_ingot",
recipe = {"default:steel_ingot", "default:mese_crystal_fragment"},
heat = 4,
time = 3,
})
end
local function node_group(group)
local tbl = {}
for key,_ in pairs(minetest.registered_items) do
if minetest.get_item_group(key, group) > 0 then
tbl[#tbl + 1] = key
end
end
return tbl
end
local function get_waste(input)
local output, decremented_input = minetest.get_craft_result(input)
if decremented_input and decremented_input.items[1] and decremented_input.items[1]:get_name() ~= "" then
return decremented_input.items[1]:get_name()
end
return nil
end
minetest.after(1, function()
for key,_ in pairs(minetest.registered_items) do
if key ~= "" then
local tbl = minetest.get_all_craft_recipes(key)
if tbl then
for _,recipe in ipairs(tbl) do
if recipe and recipe.method == "cooking" then
if recipe.items[1] and string.split(recipe.items[1], ":")[1] == "group" then
for _,item in ipairs(node_group(string.split(recipe.items[1], ":")[2])) do
techage.furnace.register_recipe({
output = recipe.output,
recipe = {item},
waste = get_waste(recipe),
time = math.floor((recipe.width + 1) / 2),
})
end
else
techage.furnace.register_recipe({
output = recipe.output,
recipe = recipe.items,
waste = get_waste(recipe),
time = math.floor((recipe.width + 1) / 2),
})
end
end
end
end
end
end
end)
techage.furnace.register_recipe({
output = "techage:basalt_glass2",
recipe = {
"techage:basalt_gravel",
"techage:basalt_gravel",
},
time = 4,
})
techage.furnace.register_recipe({
output = "techage:basalt_glass",
recipe = {
"techage:sieved_basalt_gravel",
"techage:sieved_basalt_gravel",
},
time = 4,
})
techage.furnace.register_recipe({
output = "techage:basalt_glass_thin2 2",
recipe = {
"techage:basalt_gravel",
},
time = 4,
})
techage.furnace.register_recipe({
output = "techage:basalt_glass_thin 2",
recipe = {
"techage:sieved_basalt_gravel",
},
time = 4,
})
techage.furnace.register_recipe({
output = "techage:basalt_glass_thin_xl2",
recipe = {
"techage:basalt_gravel",
},
time = 4,
})
techage.furnace.register_recipe({
output = "techage:basalt_glass_thin_xl",
recipe = {
"techage:sieved_basalt_gravel",
},
time = 4,
})
techage.furnace.register_recipe({
output = "basic_materials:concrete_block 4",
recipe = {
"basic_materials:wet_cement",
"default:sand",
"default:gravel",
"techage:steelmat",
},
time = 4,
})
if minetest.global_exists("moreores") then
if techage.modified_recipes_enabled then
-- delete cooking mithril lumps into mithril ingots
minetest.clear_craft({
type = "cooking",
recipe = "moreores:mithril_lump",
})
end
techage.furnace.register_recipe({
output = 'moreores:silver_ingot',
recipe = {'moreores:silver_lump'},
time = 2,
})
techage.furnace.register_recipe({
output = 'moreores:mithril_ingot',
recipe = {'moreores:mithril_lump'},
time = 5,
})
end