summaryrefslogtreecommitdiff
path: root/technic/technic/machines/register
diff options
context:
space:
mode:
Diffstat (limited to 'technic/technic/machines/register')
-rw-r--r--technic/technic/machines/register/alloy_furnace.lua10
-rw-r--r--technic/technic/machines/register/alloy_recipes.lua35
-rw-r--r--technic/technic/machines/register/battery_box.lua291
-rw-r--r--technic/technic/machines/register/cables.lua177
-rw-r--r--technic/technic/machines/register/centrifuge.lua8
-rw-r--r--technic/technic/machines/register/centrifuge_recipes.lua38
-rw-r--r--technic/technic/machines/register/common.lua214
-rw-r--r--technic/technic/machines/register/compressor.lua9
-rw-r--r--technic/technic/machines/register/compressor_recipes.lua34
-rw-r--r--technic/technic/machines/register/electric_furnace.lua9
-rw-r--r--technic/technic/machines/register/extractor.lua9
-rw-r--r--technic/technic/machines/register/extractor_recipes.lua59
-rw-r--r--technic/technic/machines/register/generator.lua173
-rw-r--r--technic/technic/machines/register/grinder.lua9
-rw-r--r--technic/technic/machines/register/grinder_recipes.lua161
-rw-r--r--technic/technic/machines/register/grindings.lua62
-rw-r--r--technic/technic/machines/register/init.lua33
-rw-r--r--technic/technic/machines/register/machine_base.lua197
-rw-r--r--technic/technic/machines/register/recipes.lua107
-rw-r--r--technic/technic/machines/register/solar_array.lua65
20 files changed, 1700 insertions, 0 deletions
diff --git a/technic/technic/machines/register/alloy_furnace.lua b/technic/technic/machines/register/alloy_furnace.lua
new file mode 100644
index 0000000..879e528
--- /dev/null
+++ b/technic/technic/machines/register/alloy_furnace.lua
@@ -0,0 +1,10 @@
+
+local S = technic.getter
+
+function technic.register_alloy_furnace(data)
+ data.typename = "alloy"
+ data.machine_name = "alloy_furnace"
+ data.machine_desc = S("%s Alloy Furnace")
+ technic.register_base_machine(data)
+end
+
diff --git a/technic/technic/machines/register/alloy_recipes.lua b/technic/technic/machines/register/alloy_recipes.lua
new file mode 100644
index 0000000..bd09bd6
--- /dev/null
+++ b/technic/technic/machines/register/alloy_recipes.lua
@@ -0,0 +1,35 @@
+
+local S = technic.getter
+
+technic.register_recipe_type("alloy", {
+ description = S("Alloying"),
+ input_size = 2,
+})
+
+function technic.register_alloy_recipe(data)
+ data.time = data.time or 6
+ technic.register_recipe("alloy", data)
+end
+
+local recipes = {
+ {"technic:copper_dust 3", "technic:tin_dust", "technic:bronze_dust 4"},
+ {"default:copper_ingot 3", "moreores:tin_ingot", "default:bronze_ingot 4"},
+ {"technic:wrought_iron_dust", "technic:coal_dust", "technic:carbon_steel_dust", 3},
+ {"technic:wrought_iron_ingot", "technic:coal_dust", "technic:carbon_steel_ingot", 3},
+ {"technic:carbon_steel_dust", "technic:coal_dust", "technic:cast_iron_dust", 3},
+ {"technic:carbon_steel_ingot", "technic:coal_dust", "technic:cast_iron_ingot", 3},
+ {"technic:carbon_steel_dust 3", "technic:chromium_dust", "technic:stainless_steel_dust 4"},
+ {"technic:carbon_steel_ingot 3", "technic:chromium_ingot", "technic:stainless_steel_ingot 4"},
+ {"technic:copper_dust 2", "technic:zinc_dust", "technic:brass_dust 3"},
+ {"default:copper_ingot 2", "technic:zinc_ingot", "technic:brass_ingot 3"},
+ {"default:sand 2", "technic:coal_dust 2", "technic:silicon_wafer"},
+ {"technic:silicon_wafer", "technic:gold_dust", "technic:doped_silicon_wafer"},
+ -- from https://en.wikipedia.org/wiki/Carbon_black
+ -- The highest volume use of carbon black is as a reinforcing filler in rubber products, especially tires.
+ -- "[Compounding a] pure gum vulcanizate … with 50% of its weight of carbon black improves its tensile strength and wear resistance …"
+ {"technic:raw_latex 4", "technic:coal_dust 2", "technic:rubber 6", 2},
+}
+
+for _, data in pairs(recipes) do
+ technic.register_alloy_recipe({input = {data[1], data[2]}, output = data[3], time = data[4]})
+end
diff --git a/technic/technic/machines/register/battery_box.lua b/technic/technic/machines/register/battery_box.lua
new file mode 100644
index 0000000..82edca0
--- /dev/null
+++ b/technic/technic/machines/register/battery_box.lua
@@ -0,0 +1,291 @@
+
+local S = technic.getter
+
+technic.register_power_tool("technic:battery", 10000)
+technic.register_power_tool("technic:red_energy_crystal", 50000)
+technic.register_power_tool("technic:green_energy_crystal", 150000)
+technic.register_power_tool("technic:blue_energy_crystal", 450000)
+
+minetest.register_craft({
+ output = 'technic:battery',
+ recipe = {
+ {'group:wood', 'default:copper_ingot', 'group:wood'},
+ {'group:wood', 'moreores:tin_ingot', 'group:wood'},
+ {'group:wood', 'default:copper_ingot', 'group:wood'},
+ }
+})
+
+minetest.register_tool("technic:battery", {
+ description = S("RE Battery"),
+ inventory_image = "technic_battery.png",
+ wear_represents = "technic_RE_charge",
+ on_refill = technic.refill_RE_charge,
+ tool_capabilities = {
+ charge = 0,
+ max_drop_level = 0,
+ groupcaps = {
+ fleshy = {times={}, uses=10000, maxlevel=0}
+ }
+ }
+})
+
+local tube = {
+ insert_object = function(pos, node, stack, direction)
+ if direction.y == 0 then
+ return stack
+ end
+ local meta = minetest.get_meta(pos)
+ local inv = meta:get_inventory()
+ if direction.y > 0 then
+ return inv:add_item("src", stack)
+ else
+ return inv:add_item("dst", stack)
+ end
+ end,
+ can_insert = function(pos, node, stack, direction)
+ if direction.y == 0 then
+ return false
+ end
+ local meta = minetest.get_meta(pos)
+ local inv = meta:get_inventory()
+ if direction.y > 0 then
+ return inv:room_for_item("src", stack)
+ else
+ return inv:room_for_item("dst", stack)
+ end
+ end,
+ connect_sides = {left=1, right=1, back=1, top=1, bottom=1},
+}
+
+function technic.register_battery_box(data)
+ local tier = data.tier
+ local ltier = string.lower(tier)
+
+ local formspec =
+ "invsize[8,9;]"..
+ "image[1,1;1,2;technic_power_meter_bg.png]"..
+ "list[current_name;src;3,1;1,1;]"..
+ "image[4,1;1,1;technic_battery_reload.png]"..
+ "list[current_name;dst;5,1;1,1;]"..
+ "label[0,0;"..S("%s Battery Box"):format(tier).."]"..
+ "label[3,0;"..S("Charge").."]"..
+ "label[5,0;"..S("Discharge").."]"..
+ "label[1,3;"..S("Power level").."]"..
+ "list[current_player;main;0,5;8,4;]"..
+ "listring[current_name;dst]"..
+ "listring[current_player;main]"..
+ "listring[current_name;src]"..
+ "listring[current_player;main]"
+
+ if data.upgrade then
+ formspec = formspec..
+ "list[current_name;upgrade1;3.5,3;1,1;]"..
+ "list[current_name;upgrade2;4.5,3;1,1;]"..
+ "label[3.5,4;"..S("Upgrade Slots").."]"..
+ "listring[current_name;upgrade1]"..
+ "listring[current_player;main]"..
+ "listring[current_name;upgrade2]"..
+ "listring[current_player;main]"
+ end
+
+ local run = function(pos, node)
+ local meta = minetest.get_meta(pos)
+ local eu_input = meta:get_int(tier.."_EU_input")
+ local current_charge = meta:get_int("internal_EU_charge")
+
+ local EU_upgrade, tube_upgrade = 0, 0
+ if data.upgrade then
+ EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
+ end
+ local max_charge = data.max_charge * (1 + EU_upgrade / 10)
+
+ -- Charge/discharge the battery with the input EUs
+ if eu_input >= 0 then
+ current_charge = math.min(current_charge + eu_input, max_charge)
+ else
+ current_charge = math.max(current_charge + eu_input, 0)
+ end
+
+ -- Charging/discharging tools here
+ local tool_full, tool_empty
+ current_charge, tool_full = technic.charge_tools(meta,
+ current_charge, data.charge_step)
+ current_charge, tool_empty = technic.discharge_tools(meta,
+ current_charge, data.discharge_step,
+ max_charge)
+
+ if data.tube then
+ local inv = meta:get_inventory()
+ technic.handle_machine_pipeworks(pos, tube_upgrade,
+ function(pos, x_velocity, z_velocity)
+ if tool_full and not inv:is_empty("src") then
+ technic.send_items(pos, x_velocity, z_velocity, "src")
+ elseif tool_empty and not inv:is_empty("dst") then
+ technic.send_items(pos, x_velocity, z_velocity, "dst")
+ end
+ end)
+ end
+
+ -- We allow batteries to charge on less than the demand
+ meta:set_int(tier.."_EU_demand",
+ math.min(data.charge_rate, max_charge - current_charge))
+ meta:set_int(tier.."_EU_supply",
+ math.min(data.discharge_rate, current_charge))
+ meta:set_int("internal_EU_charge", current_charge)
+
+ -- Select node textures
+ local charge_count = math.ceil((current_charge / max_charge) * 8)
+ charge_count = math.min(charge_count, 8)
+ charge_count = math.max(charge_count, 0)
+ local last_count = meta:get_float("last_side_shown")
+ if charge_count ~= last_count then
+ technic.swap_node(pos,"technic:"..ltier.."_battery_box"..charge_count)
+ meta:set_float("last_side_shown", charge_count)
+ end
+
+ local charge_percent = math.floor(current_charge / max_charge * 100)
+ meta:set_string("formspec",
+ formspec..
+ "image[1,1;1,2;technic_power_meter_bg.png"
+ .."^[lowpart:"..charge_percent
+ ..":technic_power_meter_fg.png]")
+
+ local infotext = S("@1 Battery Box: @2/@3", tier,
+ technic.prettynum(current_charge), technic.prettynum(max_charge))
+ if eu_input == 0 then
+ infotext = S("%s Idle"):format(infotext)
+ end
+ meta:set_string("infotext", infotext)
+ end
+
+ for i = 0, 8 do
+ local groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_machine=1}
+ if i ~= 0 then
+ groups.not_in_creative_inventory = 1
+ end
+
+ if data.tube then
+ groups.tubedevice = 1
+ groups.tubedevice_receiver = 1
+ end
+
+ minetest.register_node("technic:"..ltier.."_battery_box"..i, {
+ description = S("%s Battery Box"):format(tier),
+ tiles = {"technic_"..ltier.."_battery_box_top.png",
+ "technic_"..ltier.."_battery_box_bottom.png",
+ "technic_"..ltier.."_battery_box_side.png^technic_power_meter"..i..".png",
+ "technic_"..ltier.."_battery_box_side.png^technic_power_meter"..i..".png",
+ "technic_"..ltier.."_battery_box_side.png^technic_power_meter"..i..".png",
+ "technic_"..ltier.."_battery_box_side.png^technic_power_meter"..i..".png"},
+ groups = groups,
+ tube = data.tube and tube or nil,
+ paramtype2 = "facedir",
+ sounds = default.node_sound_wood_defaults(),
+ drop = "technic:"..ltier.."_battery_box0",
+ on_construct = function(pos)
+ local meta = minetest.get_meta(pos)
+ local inv = meta:get_inventory()
+ local node = minetest.get_node(pos)
+
+ meta:set_string("infotext", S("%s Battery Box"):format(tier))
+ meta:set_string("formspec", formspec)
+ meta:set_int(tier.."_EU_demand", 0)
+ meta:set_int(tier.."_EU_supply", 0)
+ meta:set_int(tier.."_EU_input", 0)
+ meta:set_float("internal_EU_charge", 0)
+ inv:set_size("src", 1)
+ inv:set_size("dst", 1)
+ inv:set_size("upgrade1", 1)
+ inv:set_size("upgrade2", 1)
+ end,
+ can_dig = technic.machine_can_dig,
+ allow_metadata_inventory_put = technic.machine_inventory_put,
+ allow_metadata_inventory_take = technic.machine_inventory_take,
+ allow_metadata_inventory_move = technic.machine_inventory_move,
+ technic_run = run,
+ after_place_node = data.tube and pipeworks.after_place,
+ after_dig_node = technic.machine_after_dig_node
+ })
+ end
+
+ -- Register as a battery type
+ -- Battery type machines function as power reservoirs and can both receive and give back power
+ for i = 0, 8 do
+ technic.register_machine(tier, "technic:"..ltier.."_battery_box"..i, technic.battery)
+ end
+
+end -- End registration
+
+
+function technic.charge_tools(meta, batt_charge, charge_step)
+ local inv = meta:get_inventory()
+ if inv:is_empty("src") then
+ return batt_charge, false
+ end
+ local src_stack = inv:get_stack("src", 1)
+
+ local tool_name = src_stack:get_name()
+ if not technic.power_tools[tool_name] then
+ return batt_charge, false
+ end
+ -- Set meta data for the tool if it didn't do it itself
+ local src_meta = minetest.deserialize(src_stack:get_metadata()) or {}
+ if not src_meta.charge then
+ src_meta.charge = 0
+ end
+ -- Do the charging
+ local item_max_charge = technic.power_tools[tool_name]
+ local tool_charge = src_meta.charge
+ if tool_charge >= item_max_charge then
+ return batt_charge, true
+ elseif batt_charge <= 0 then
+ return batt_charge, false
+ end
+ charge_step = math.min(charge_step, batt_charge)
+ charge_step = math.min(charge_step, item_max_charge - tool_charge)
+ tool_charge = tool_charge + charge_step
+ batt_charge = batt_charge - charge_step
+ technic.set_RE_wear(src_stack, tool_charge, item_max_charge)
+ src_meta.charge = tool_charge
+ src_stack:set_metadata(minetest.serialize(src_meta))
+ inv:set_stack("src", 1, src_stack)
+ return batt_charge, (tool_charge == item_max_charge)
+end
+
+
+function technic.discharge_tools(meta, batt_charge, charge_step, max_charge)
+ local inv = meta:get_inventory()
+ if inv:is_empty("dst") then
+ return batt_charge, false
+ end
+ srcstack = inv:get_stack("dst", 1)
+ local toolname = srcstack:get_name()
+ if technic.power_tools[toolname] == nil then
+ return batt_charge, false
+ end
+ -- Set meta data for the tool if it didn't do it itself :-(
+ local src_meta = minetest.deserialize(srcstack:get_metadata())
+ src_meta = src_meta or {}
+ if not src_meta.charge then
+ src_meta.charge = 0
+ end
+
+ -- Do the discharging
+ local item_max_charge = technic.power_tools[toolname]
+ local tool_charge = src_meta.charge
+ if tool_charge <= 0 then
+ return batt_charge, true
+ elseif batt_charge >= max_charge then
+ return batt_charge, false
+ end
+ charge_step = math.min(charge_step, max_charge - batt_charge)
+ charge_step = math.min(charge_step, tool_charge)
+ tool_charge = tool_charge - charge_step
+ batt_charge = batt_charge + charge_step
+ technic.set_RE_wear(srcstack, tool_charge, item_max_charge)
+ src_meta.charge = tool_charge
+ srcstack:set_metadata(minetest.serialize(src_meta))
+ inv:set_stack("dst", 1, srcstack)
+ return batt_charge, (tool_charge == 0)
+end
+
diff --git a/technic/technic/machines/register/cables.lua b/technic/technic/machines/register/cables.lua
new file mode 100644
index 0000000..a1e7bc8
--- /dev/null
+++ b/technic/technic/machines/register/cables.lua
@@ -0,0 +1,177 @@
+
+local S = technic.getter
+
+local cable_itstr_to_tier = {}
+
+function technic.register_cable(tier, size)
+ local ltier = string.lower(tier)
+
+ for x1 = 0, 1 do
+ for x2 = 0, 1 do
+ for y1 = 0, 1 do
+ for y2 = 0, 1 do
+ for z1 = 0, 1 do
+ for z2 = 0, 1 do
+ local id = technic.get_cable_id({x1, x2, y1, y2, z1, z2})
+
+ cable_itstr_to_tier["technic:"..ltier.."_cable"..id] = tier
+
+ local groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2}
+ if id ~= 0 then
+ groups.not_in_creative_inventory = 1
+ end
+
+ minetest.register_node("technic:"..ltier.."_cable"..id, {
+ description = S("%s Cable"):format(tier),
+ tiles = {"technic_"..ltier.."_cable.png"},
+ inventory_image = "technic_"..ltier.."_cable_wield.png",
+ wield_image = "technic_"..ltier.."_cable_wield.png",
+ groups = groups,
+ sounds = default.node_sound_wood_defaults(),
+ drop = "technic:"..ltier.."_cable0",
+ paramtype = "light",
+ sunlight_propagates = true,
+ drawtype = "nodebox",
+ node_box = {
+ type = "fixed",
+ fixed = technic.gen_cable_nodebox(x1, y1, z1, x2, y2, z2, size)
+ },
+ on_construct = function()
+ technic.networks = {}
+ end,
+ on_destruct = function()
+ technic.networks = {}
+ end,
+ after_place_node = function(pos)
+ local node = minetest.get_node(pos)
+ technic.update_cables(pos, technic.get_cable_tier(node.name))
+ end,
+ after_dig_node = function(pos, oldnode)
+ local tier = technic.get_cable_tier(oldnode.name)
+ technic.update_cables(pos, tier, true)
+ end
+ })
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+minetest.register_on_placenode(function(pos, node)
+ for tier, machine_list in pairs(technic.machines) do
+ if machine_list[node.name] ~= nil then
+ technic.update_cables(pos, tier, true)
+ technic.networks = {}
+ end
+ end
+end)
+
+
+minetest.register_on_dignode(function(pos, node)
+ for tier, machine_list in pairs(technic.machines) do
+ if machine_list[node.name] ~= nil then
+ technic.update_cables(pos, tier, true)
+ technic.networks = {}
+ end
+ end
+end)
+
+function technic.get_cable_id(links)
+ return (links[6] * 1) + (links[5] * 2)
+ + (links[4] * 4) + (links[3] * 8)
+ + (links[2] * 16) + (links[1] * 32)
+end
+
+function technic.update_cables(pos, tier, no_set, secondrun)
+ local link_positions = {
+ {x=pos.x+1, y=pos.y, z=pos.z},
+ {x=pos.x-1, y=pos.y, z=pos.z},
+ {x=pos.x, y=pos.y+1, z=pos.z},
+ {x=pos.x, y=pos.y-1, z=pos.z},
+ {x=pos.x, y=pos.y, z=pos.z+1},
+ {x=pos.x, y=pos.y, z=pos.z-1}}
+
+ local links = {0, 0, 0, 0, 0, 0}
+
+ for i, link_pos in pairs(link_positions) do
+ local connect_type = technic.cables_should_connect(pos, link_pos, tier)
+ if connect_type then
+ links[i] = 1
+ -- Have cables next to us update theirselves,
+ -- but only once. (We don't want to update the entire
+ -- network or start an infinite loop of updates)
+ if not secondrun and connect_type == "cable" then
+ technic.update_cables(link_pos, tier, false, true)
+ end
+ end
+ end
+ -- We don't want to set ourselves if we have been removed or we are
+ -- updating a machine
+ if not no_set then
+ minetest.set_node(pos, {name="technic:"..string.lower(tier)
+ .."_cable"..technic.get_cable_id(links)})
+
+ end
+end
+
+
+function technic.is_tier_cable(name, tier)
+ return cable_itstr_to_tier[name] and cable_itstr_to_tier[name] == tier
+end
+
+
+function technic.get_cable_tier(name)
+ return cable_itstr_to_tier[name]
+end
+
+
+function technic.cables_should_connect(pos1, pos2, tier)
+ local name = minetest.get_node(pos2).name
+
+ if name == "technic:switching_station" then
+ return pos2.y == pos1.y + 1 and "machine" or false
+ elseif name == "technic:supply_converter" then
+ return math.abs(pos2.y - pos1.y) == 1 and "machine" or false
+ elseif technic.is_tier_cable(name, tier) then
+ return "cable"
+ elseif technic.machines[tier][name] then
+ return "machine"
+ end
+ return false
+end
+
+
+function technic.gen_cable_nodebox(x1, y1, z1, x2, y2, z2, size)
+ -- Nodeboxes
+ local box_center = {-size, -size, -size, size, size, size}
+ local box_y1 = {-size, -size, -size, size, 0.5, size} -- y+
+ local box_x1 = {-size, -size, -size, 0.5, size, size} -- x+
+ local box_z1 = {-size, -size, size, size, size, 0.5} -- z+
+ local box_z2 = {-size, -size, -0.5, size, size, size} -- z-
+ local box_y2 = {-size, -0.5, -size, size, size, size} -- y-
+ local box_x2 = {-0.5, -size, -size, size, size, size} -- x-
+
+ local box = {box_center}
+ if x1 == 1 then
+ table.insert(box, box_x1)
+ end
+ if y1 == 1 then
+ table.insert(box, box_y1)
+ end
+ if z1 == 1 then
+ table.insert(box, box_z1)
+ end
+ if x2 == 1 then
+ table.insert(box, box_x2)
+ end
+ if y2 == 1 then
+ table.insert(box, box_y2)
+ end
+ if z2 == 1 then
+ table.insert(box, box_z2)
+ end
+ return box
+end
+
diff --git a/technic/technic/machines/register/centrifuge.lua b/technic/technic/machines/register/centrifuge.lua
new file mode 100644
index 0000000..dd05977
--- /dev/null
+++ b/technic/technic/machines/register/centrifuge.lua
@@ -0,0 +1,8 @@
+local S = technic.getter
+
+function technic.register_centrifuge(data)
+ data.typename = "separating"
+ data.machine_name = "centrifuge"
+ data.machine_desc = S("%s Centrifuge")
+ technic.register_base_machine(data)
+end
diff --git a/technic/technic/machines/register/centrifuge_recipes.lua b/technic/technic/machines/register/centrifuge_recipes.lua
new file mode 100644
index 0000000..05642f5
--- /dev/null
+++ b/technic/technic/machines/register/centrifuge_recipes.lua
@@ -0,0 +1,38 @@
+local S = technic.getter
+
+technic.register_recipe_type("separating", {
+ description = S("Separating"),
+ output_size = 2,
+})
+
+function technic.register_separating_recipe(data)
+ data.time = data.time or 10
+ technic.register_recipe("separating", data)
+end
+
+local recipes = {
+ { "technic:bronze_dust 4", "technic:copper_dust 3", "technic:tin_dust" },
+ { "technic:stainless_steel_dust 4", "technic:wrought_iron_dust 3", "technic:chromium_dust" },
+ { "technic:brass_dust 3", "technic:copper_dust 2", "technic:zinc_dust" },
+}
+
+local function uranium_dust(p)
+ return "technic:uranium"..(p == 7 and "" or p).."_dust"
+end
+for p = 1, 34 do
+ table.insert(recipes, { uranium_dust(p).." 2", uranium_dust(p-1), uranium_dust(p+1) })
+end
+
+if minetest.get_modpath("bushes_classic") then
+ for _, berry in ipairs({ "blackberry", "blueberry", "gooseberry", "raspberry", "strawberry" }) do
+ table.insert(recipes, { "bushes:"..berry.."_bush", "default:stick 20", "bushes:"..berry.." 4" })
+ end
+end
+
+if minetest.get_modpath("farming") then
+ table.insert(recipes, { "farming:wheat 4", "farming:seed_wheat 3", "default:dry_shrub 1" })
+end
+
+for _, data in pairs(recipes) do
+ technic.register_separating_recipe({ input = { data[1] }, output = { data[2], data[3] } })
+end
diff --git a/technic/technic/machines/register/common.lua b/technic/technic/machines/register/common.lua
new file mode 100644
index 0000000..ce0eee6
--- /dev/null
+++ b/technic/technic/machines/register/common.lua
@@ -0,0 +1,214 @@
+
+local S = technic.getter
+
+-- handles the machine upgrades every tick
+function technic.handle_machine_upgrades(meta)
+ -- Get the names of the upgrades
+ local inv = meta:get_inventory()
+
+ local srcstack = inv:get_stack("upgrade1", 1)
+ local upg_item1 = srcstack and srcstack:get_name()
+
+ srcstack = inv:get_stack("upgrade2", 1)
+ local upg_item2 = srcstack and srcstack:get_name()
+
+ -- Save some power by installing battery upgrades.
+ -- Tube loading speed can be upgraded using control logic units.
+ local EU_upgrade = 0
+ local tube_upgrade = 0
+
+ if upg_item1 == "technic:control_logic_unit" then
+ tube_upgrade = tube_upgrade + 1
+ elseif upg_item1 == "technic:battery" then
+ EU_upgrade = EU_upgrade + 1
+ end
+
+ if upg_item2 == "technic:control_logic_unit" then
+ tube_upgrade = tube_upgrade + 1
+ elseif upg_item2 == "technic:battery" then
+ EU_upgrade = EU_upgrade + 1
+ end
+
+ return EU_upgrade, tube_upgrade
+end
+
+-- handles the machine upgrades when set or removed
+local function on_machine_upgrade(meta, stack)
+ local stack_name = stack:get_name()
+ if stack_name == "default:chest" then
+ meta:set_int("public", 1)
+ return 1
+ elseif stack_name ~= "technic:control_logic_unit"
+ and stack_name ~= "technic:battery" then
+ return 0
+ end
+ return 1
+end
+
+-- something is about to be removed
+local function on_machine_downgrade(meta, stack, list)
+ if stack:get_name() == "default:chest" then
+ local inv = meta:get_inventory()
+ local upg1, upg2 = inv:get_stack("upgrade1", 1), inv:get_stack("upgrade2", 1)
+
+ -- only set 0 if theres not a nother chest in the other list too
+ if (not upg1 or not upg2 or upg1:get_name() ~= upg2:get_name()) then
+ meta:set_int("public", 0)
+ end
+ end
+ return 1
+end
+
+
+function technic.send_items(pos, x_velocity, z_velocity, output_name)
+ -- Send items on their way in the pipe system.
+ if output_name == nil then
+ output_name = "dst"
+ end
+
+ local meta = minetest.get_meta(pos)
+ local inv = meta:get_inventory()
+ local i = 0
+ for _, stack in ipairs(inv:get_list(output_name)) do
+ i = i + 1
+ if stack then
+ local item0 = stack:to_table()
+ if item0 then
+ item0["count"] = "1"
+ technic.tube_inject_item(pos, pos, vector.new(x_velocity, 0, z_velocity), item0)
+ stack:take_item(1)
+ inv:set_stack(output_name, i, stack)
+ return
+ end
+ end
+ end
+end
+
+
+function technic.smelt_item(meta, result, speed)
+ local inv = meta:get_inventory()
+ meta:set_int("cook_time", meta:get_int("cook_time") + 1)
+ if meta:get_int("cook_time") < result.time / speed then
+ return
+ end
+ local result
+ local afterfuel
+ result, afterfuel = minetest.get_craft_result({method = "cooking", width = 1, items = inv:get_list("src")})
+
+ if result and result.item then
+ meta:set_int("cook_time", 0)
+ -- check if there's room for output in "dst" list
+ if inv:room_for_item("dst", result.item) then
+ inv:set_stack("src", 1, afterfuel.items[1])
+ inv:add_item("dst", result.item)
+ end
+ end
+end
+
+function technic.handle_machine_pipeworks(pos, tube_upgrade, send_function)
+ if send_function == nil then
+ send_function = technic.send_items
+ end
+
+ local node = minetest.get_node(pos)
+ local meta = minetest.get_meta(pos)
+ local inv = meta:get_inventory()
+ local pos1 = vector.new(pos)
+ local x_velocity = 0
+ local z_velocity = 0
+
+ -- Output is on the left side of the furnace
+ if node.param2 == 3 then pos1.z = pos1.z - 1 z_velocity = -1 end
+ if node.param2 == 2 then pos1.x = pos1.x - 1 x_velocity = -1 end
+ if node.param2 == 1 then pos1.z = pos1.z + 1 z_velocity = 1 end
+ if node.param2 == 0 then pos1.x = pos1.x + 1 x_velocity = 1 end
+
+ local output_tube_connected = false
+ local node1 = minetest.get_node(pos1)
+ if minetest.get_item_group(node1.name, "tubedevice") > 0 then
+ output_tube_connected = true
+ end
+ local tube_time = meta:get_int("tube_time") + tube_upgrade
+ if tube_time >= 2 then
+ tube_time = 0
+ if output_tube_connected then
+ send_function(pos, x_velocity, z_velocity)
+ end
+ end
+ meta:set_int("tube_time", tube_time)
+end
+
+function technic.machine_can_dig(pos, player)
+ local meta = minetest.get_meta(pos)
+ local inv = meta:get_inventory()
+ if not inv:is_empty("src") or not inv:is_empty("dst") then
+ if player then
+ minetest.chat_send_player(player:get_player_name(),
+ S("Machine cannot be removed because it is not empty"))
+ end
+ return false
+ end
+
+ return true
+end
+
+function technic.machine_after_dig_node(pos, oldnode, oldmetadata, player)
+ if oldmetadata.inventory then
+ if oldmetadata.inventory.upgrade1 and oldmetadata.inventory.upgrade1[1] then
+ local stack = ItemStack(oldmetadata.inventory.upgrade1[1])
+ if not stack:is_empty() then
+ minetest.item_drop(stack, "", pos)
+ end
+ end
+ if oldmetadata.inventory.upgrade2 and oldmetadata.inventory.upgrade2[1] then
+ local stack = ItemStack(oldmetadata.inventory.upgrade2[1])
+ if not stack:is_empty() then
+ minetest.item_drop(stack, "", pos)
+ end
+ end
+ end
+
+ if minetest.registered_nodes[oldnode.name].tube then
+ pipeworks.after_dig(pos, oldnode, oldmetadata, player)
+ end
+end
+
+local function inv_change(pos, player, count, from_list, to_list, stack)
+ local playername = player:get_player_name()
+ local meta = minetest.get_meta(pos);
+ local public = (meta:get_int("public") == 1)
+ local to_upgrade = to_list == "upgrade1" or to_list == "upgrade2"
+ local from_upgrade = from_list == "upgrade1" or from_list == "upgrade2"
+
+ if (not public or to_upgrade or from_upgrade) and minetest.is_protected(pos, playername) then
+ minetest.chat_send_player(playername, S("Inventory move disallowed due to protection"))
+ return 0
+ end
+ if to_upgrade then
+ -- only place a single item into it, if it's empty
+ local empty = meta:get_inventory():is_empty(to_list)
+ if empty then
+ return on_machine_upgrade(meta, stack)
+ end
+ return 0
+ elseif from_upgrade then
+ -- only called on take (not move)
+ on_machine_downgrade(meta, stack, from_list)
+ end
+ return count
+end
+
+function technic.machine_inventory_put(pos, listname, index, stack, player)
+ return inv_change(pos, player, stack:get_count(), nil, listname, stack)
+end
+
+function technic.machine_inventory_take(pos, listname, index, stack, player)
+ return inv_change(pos, player, stack:get_count(), listname, nil, stack)
+end
+
+function technic.machine_inventory_move(pos, from_list, from_index,
+ to_list, to_index, count, player)
+ local stack = minetest.get_meta(pos):get_inventory():get_stack(from_list, from_index)
+ return inv_change(pos, player, count, from_list, to_list, stack)
+end
+
diff --git a/technic/technic/machines/register/compressor.lua b/technic/technic/machines/register/compressor.lua
new file mode 100644
index 0000000..49830d7
--- /dev/null
+++ b/technic/technic/machines/register/compressor.lua
@@ -0,0 +1,9 @@
+
+local S = technic.getter
+
+function technic.register_compressor(data)
+ data.typename = "compressing"
+ data.machine_name = "compressor"
+ data.machine_desc = S("%s Compressor")
+ technic.register_base_machine(data)
+end
diff --git a/technic/technic/machines/register/compressor_recipes.lua b/technic/technic/machines/register/compressor_recipes.lua
new file mode 100644
index 0000000..872be04
--- /dev/null
+++ b/technic/technic/machines/register/compressor_recipes.lua
@@ -0,0 +1,34 @@
+
+local S = technic.getter
+
+technic.register_recipe_type("compressing", { description = S("Compressing") })
+
+function technic.register_compressor_recipe(data)
+ data.time = data.time or 4
+ technic.register_recipe("compressing", data)
+end
+
+local recipes = {
+ {"default:snowblock", "default:ice"},
+ {"default:sand 2", "default:sandstone"},
+ {"default:desert_sand", "default:desert_stone"},
+ {"technic:mixed_metal_ingot", "technic:composite_plate"},
+ {"default:copper_ingot 5", "technic:copper_plate"},
+ {"technic:coal_dust 4", "technic:graphite"},
+ {"technic:carbon_cloth", "technic:carbon_plate"},
+ {"technic:uranium35_ingot 5", "technic:uranium_fuel"},
+}
+
+-- defuse the default sandstone recipe, since we have the compressor to take over in a more realistic manner
+minetest.register_craft({
+ output = "default:sand 0",
+ recipe = {
+ {'group:sand', 'group:sand'},
+ {'group:sand', 'group:sand'}
+ },
+})
+
+for _, data in pairs(recipes) do
+ technic.register_compressor_recipe({input = {data[1]}, output = data[2]})
+end
+
diff --git a/technic/technic/machines/register/electric_furnace.lua b/technic/technic/machines/register/electric_furnace.lua
new file mode 100644
index 0000000..44de16c
--- /dev/null
+++ b/technic/technic/machines/register/electric_furnace.lua
@@ -0,0 +1,9 @@
+
+local S = technic.getter
+
+function technic.register_electric_furnace(data)
+ data.typename = "cooking"
+ data.machine_name = "electric_furnace"
+ data.machine_desc = S("%s Furnace")
+ technic.register_base_machine(data)
+end
diff --git a/technic/technic/machines/register/extractor.lua b/technic/technic/machines/register/extractor.lua
new file mode 100644
index 0000000..eeef9ff
--- /dev/null
+++ b/technic/technic/machines/register/extractor.lua
@@ -0,0 +1,9 @@
+
+local S = technic.getter
+
+function technic.register_extractor(data)
+ data.typename = "extracting"
+ data.machine_name = "extractor"
+ data.machine_desc = S("%s Extractor")
+ technic.register_base_machine(data)
+end
diff --git a/technic/technic/machines/register/extractor_recipes.lua b/technic/technic/machines/register/extractor_recipes.lua
new file mode 100644
index 0000000..1de0ba0
--- /dev/null
+++ b/technic/technic/machines/register/extractor_recipes.lua
@@ -0,0 +1,59 @@
+
+local S = technic.getter
+
+technic.register_recipe_type("extracting", { description = S("Extracting") })
+
+function technic.register_extractor_recipe(data)
+ data.time = data.time or 4
+ technic.register_recipe("extracting", data)
+end
+
+if minetest.get_modpath("dye") then
+ -- check if we are using dye or unifieddyes
+ local unifieddyes = minetest.get_modpath("unifieddyes")
+
+ -- register recipes with the same crafting ratios as `dye` provides
+ local dye_recipes = {
+ {"technic:coal_dust", "dye:black 2"},
+ {"default:grass_1", "dye:green 1"},
+ {"default:dry_shrub", "dye:brown 1"},
+ {"default:junglegrass", "dye:green 2"},
+ {"default:cactus", "dye:green 4"},
+ {"flowers:geranium", "dye:blue 4"},
+ {"flowers:dandelion_white", "dye:white 4"},
+ {"flowers:dandelion_yellow", "dye:yellow 4"},
+ {"flowers:tulip", "dye:orange 4"},
+ {"flowers:rose", "dye:red 4"},
+ {"flowers:viola", "dye:violet 4"},
+ {"bushes:blackberry", unifieddyes and "unifieddyes:magenta_s50 4" or "dye:violet 4"},
+ {"bushes:blueberry", unifieddyes and "unifieddyes:magenta_s50 4" or "dye:magenta 4"},
+ }
+
+ for _, data in ipairs(dye_recipes) do
+ technic.register_extractor_recipe({input = {data[1]}, output = data[2]})
+ end
+
+ -- overwrite the existing crafting recipes
+ local dyes = {"white", "red", "yellow", "blue", "violet", "orange"}
+ for _, color in ipairs(dyes) do
+ minetest.register_craft({
+ type = "shapeless",
+ output = "dye:"..color.." 1",
+ recipe = {"group:flower,color_"..color},
+ })
+
+ end
+ minetest.register_craft({
+ type = "shapeless",
+ output = "dye:black 1",
+ recipe = {"group:coal"},
+ })
+
+ if unifieddyes then
+ minetest.register_craft({
+ type = "shapeless",
+ output = "dye:green 1",
+ recipe = {"default:cactus"},
+ })
+ end
+end
diff --git a/technic/technic/machines/register/generator.lua b/technic/technic/machines/register/generator.lua
new file mode 100644
index 0000000..31c1cef
--- /dev/null
+++ b/technic/technic/machines/register/generator.lua
@@ -0,0 +1,173 @@
+local S = technic.getter
+
+local tube = {
+ insert_object = function(pos, node, stack, direction)
+ local meta = minetest.get_meta(pos)
+ local inv = meta:get_inventory()
+ return inv:add_item("src", stack)
+ end,
+ can_insert = function(pos, node, stack, direction)
+ local meta = minetest.get_meta(pos)
+ local inv = meta:get_inventory()
+ return inv:room_for_item("src", stack)
+ end,
+ connect_sides = {left=1, right=1, back=1, top=1, bottom=1},
+}
+
+function technic.register_generator(data)
+ local tier = data.tier
+ local ltier = string.lower(tier)
+
+ local groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_machine=1}
+ local active_groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_machine=1, not_in_creative_inventory=1}
+ if data.tube then
+ groups.tubedevice = 1
+ groups.tubedevice_receiver = 1
+ active_groups.tubedevice = 1
+ active_groups.tubedevice_receiver = 1
+ end
+
+ local generator_formspec =
+ "invsize[8,9;]"..
+ "label[0,0;"..S("Fuel-Fired %s Generator"):format(tier).."]"..
+ "list[current_name;src;3,1;1,1;]"..
+ "image[4,1;1,1;default_furnace_fire_bg.png]"..
+ "list[current_player;main;0,5;8,4;]"..
+ "listring[]"
+
+ local desc = S("Fuel-Fired %s Generator"):format(tier)
+
+ local run = function(pos, node)
+ local meta = minetest.get_meta(pos)
+ local burn_time = meta:get_int("burn_time")
+ local burn_totaltime = meta:get_int("burn_totaltime")
+ -- If more to burn and the energy produced was used: produce some more
+ if burn_time > 0 then
+ meta:set_int(tier.."_EU_supply", data.supply)
+ burn_time = burn_time - 1
+ meta:set_int("burn_time", burn_time)
+ end
+ -- Burn another piece of fuel
+ if burn_time == 0 then
+ local inv = meta:get_inventory()
+ if not inv:is_empty("src") then
+ local fuellist = inv:get_list("src")
+ local fuel
+ local afterfuel
+ fuel, afterfuel = minetest.get_craft_result(
+ {method = "fuel", width = 1,
+ items = fuellist})
+ if not fuel or fuel.time == 0 then
+ meta:set_string("infotext", S("%s Out Of Fuel"):format(desc))
+ technic.swap_node(pos, "technic:"..ltier.."_generator")
+ meta:set_int(tier.."_EU_supply", 0)
+ return
+ end
+ meta:set_int("burn_time", fuel.time)
+ meta:set_int("burn_totaltime", fuel.time)
+ inv:set_stack("src", 1, afterfuel.items[1])
+ technic.swap_node(pos, "technic:"..ltier.."_generator_active")
+ meta:set_int(tier.."_EU_supply", data.supply)
+ else
+ technic.swap_node(pos, "technic:"..ltier.."_generator")
+ meta:set_int(tier.."_EU_supply", 0)
+ end
+ end
+ if burn_totaltime == 0 then burn_totaltime = 1 end
+ local percent = math.floor((burn_time / burn_totaltime) * 100)
+ meta:set_string("infotext", desc.." ("..percent.."%)")
+ meta:set_string("formspec",
+ "size[8, 9]"..
+ "label[0, 0;"..minetest.formspec_escape(desc).."]"..
+ "list[current_name;src;3, 1;1, 1;]"..
+ "image[4, 1;1, 1;default_furnace_fire_bg.png^[lowpart:"..
+ (percent)..":default_furnace_fire_fg.png]"..
+ "list[current_player;main;0, 5;8, 4;]"..
+ "listring[]")
+ end
+
+ minetest.register_node("technic:"..ltier.."_generator", {
+ description = desc,
+ tiles = {"technic_"..ltier.."_generator_top.png", "technic_machine_bottom.png",
+ "technic_"..ltier.."_generator_side.png", "technic_"..ltier.."_generator_side.png",
+ "technic_"..ltier.."_generator_side.png", "technic_"..ltier.."_generator_front.png"},
+ paramtype2 = "facedir",
+ groups = groups,
+ legacy_facedir_simple = true,
+ sounds = default.node_sound_wood_defaults(),
+ tube = data.tube and tube or nil,
+ on_construct = function(pos)
+ local meta = minetest.get_meta(pos)
+ meta:set_string("infotext", desc)
+ meta:set_int(data.tier.."_EU_supply", 0)
+ meta:set_int("burn_time", 0)
+ meta:set_int("tube_time", 0)
+ meta:set_string("formspec", generator_formspec)
+ local inv = meta:get_inventory()
+ inv:set_size("src", 1)
+ end,
+ can_dig = technic.machine_can_dig,
+ allow_metadata_inventory_put = technic.machine_inventory_put,
+ allow_metadata_inventory_take = technic.machine_inventory_take,
+ allow_metadata_inventory_move = technic.machine_inventory_move,
+ technic_run = run,
+ after_place_node = data.tube and pipeworks.after_place,
+ after_dig_node = technic.machine_after_dig_node
+ })
+
+ minetest.register_node("technic:"..ltier.."_generator_active", {
+ description = desc,
+ tiles = {"technic_"..ltier.."_generator_top.png", "technic_machine_bottom.png",
+ "technic_"..ltier.."_generator_side.png", "technic_"..ltier.."_generator_side.png",
+ "technic_"..ltier.."_generator_side.png", "technic_"..ltier.."_generator_front_active.png"},
+ paramtype2 = "facedir",
+ groups = active_groups,
+ legacy_facedir_simple = true,
+ sounds = default.node_sound_wood_defaults(),
+ tube = data.tube and tube or nil,
+ drop = "technic:"..ltier.."_generator",
+ can_dig = technic.machine_can_dig,
+ allow_metadata_inventory_put = technic.machine_inventory_put,
+ allow_metadata_inventory_take = technic.machine_inventory_take,
+ allow_metadata_inventory_move = technic.machine_inventory_move,
+ technic_run = run,
+ technic_on_disable = function(pos, node)
+ local timer = minetest.get_node_timer(pos)
+ timer:start(1)
+ end,
+ on_timer = function(pos, node)
+ local meta = minetest.get_meta(pos)
+
+ -- Connected back?
+ if meta:get_int(tier.."_EU_timeout") > 0 then return false end
+
+ local burn_time = meta:get_int("burn_time") or 0
+
+ if burn_time <= 0 then
+ meta:set_int(tier.."_EU_supply", 0)
+ meta:set_int("burn_time", 0)
+ technic.swap_node(pos, "technic:"..ltier.."_generator")
+ return false
+ end
+
+ local burn_totaltime = meta:get_int("burn_totaltime") or 0
+ if burn_totaltime == 0 then burn_totaltime = 1 end
+ burn_time = burn_time - 1
+ meta:set_int("burn_time", burn_time)
+ local percent = math.floor(burn_time / burn_totaltime * 100)
+ meta:set_string("formspec",
+ "size[8, 9]"..
+ "label[0, 0;"..minetest.formspec_escape(desc).."]"..
+ "list[current_name;src;3, 1;1, 1;]"..
+ "image[4, 1;1, 1;default_furnace_fire_bg.png^[lowpart:"..
+ (percent)..":default_furnace_fire_fg.png]"..
+ "list[current_player;main;0, 5;8, 4;]"..
+ "listring[]")
+ return true
+ end,
+ })
+
+ technic.register_machine(tier, "technic:"..ltier.."_generator", technic.producer)
+ technic.register_machine(tier, "technic:"..ltier.."_generator_active", technic.producer)
+end
+
diff --git a/technic/technic/machines/register/grinder.lua b/technic/technic/machines/register/grinder.lua
new file mode 100644
index 0000000..19ea094
--- /dev/null
+++ b/technic/technic/machines/register/grinder.lua
@@ -0,0 +1,9 @@
+
+local S = technic.getter
+
+function technic.register_grinder(data)
+ data.typename = "grinding"
+ data.machine_name = "grinder"
+ data.machine_desc = S("%s Grinder")
+ technic.register_base_machine(data)
+end
diff --git a/technic/technic/machines/register/grinder_recipes.lua b/technic/technic/machines/register/grinder_recipes.lua
new file mode 100644
index 0000000..87c6ade
--- /dev/null
+++ b/technic/technic/machines/register/grinder_recipes.lua
@@ -0,0 +1,161 @@
+
+local S = technic.getter
+
+technic.register_recipe_type("grinding", { description = S("Grinding") })
+
+function technic.register_grinder_recipe(data)
+ data.time = data.time or 3
+ technic.register_recipe("grinding", data)
+end
+
+local recipes = {
+ -- Dusts
+ {"default:coal_lump", "technic:coal_dust 2"},
+ {"default:copper_lump", "technic:copper_dust 2"},
+ {"default:desert_stone", "default:desert_sand"},
+ {"default:gold_lump", "technic:gold_dust 2"},
+ {"default:iron_lump", "technic:wrought_iron_dust 2"},
+ {"technic:chromium_lump", "technic:chromium_dust 2"},
+ {"technic:uranium_lump", "technic:uranium_dust 2"},
+ {"technic:zinc_lump", "technic:zinc_dust 2"},
+ {"technic:lead_lump", "technic:lead_dust 2"},
+ {"technic:sulfur_lump", "technic:sulfur_dust 2"},
+
+ -- Other
+ {"default:cobble", "default:gravel"},
+ {"default:gravel", "default:dirt"},
+ {"default:stone", "default:sand"},
+ {"default:sandstone", "default:sand 2"}, -- reverse recipe can be found in the compressor
+}
+
+-- defuse the sandstone -> 4 sand recipe to avoid infinite sand bugs (also consult the inverse compressor recipe)
+minetest.register_craft({
+ output = "default:sandstone 0",
+ recipe = {
+ {'default:sandstone'}
+ },
+})
+
+if minetest.get_modpath("farming") then
+ table.insert(recipes, {"farming:seed_wheat", "farming:flour 1"})
+end
+
+if minetest.get_modpath("moreores") then
+ table.insert(recipes, {"moreores:mithril_lump", "technic:mithril_dust 2"})
+ table.insert(recipes, {"moreores:silver_lump", "technic:silver_dust 2"})
+ table.insert(recipes, {"moreores:tin_lump", "technic:tin_dust 2"})
+end
+
+if minetest.get_modpath("gloopores") or minetest.get_modpath("glooptest") then
+ table.insert(recipes, {"gloopores:alatro_lump", "technic:alatro_dust 2"})
+ table.insert(recipes, {"gloopores:kalite_lump", "technic:kalite_dust 2"})
+ table.insert(recipes, {"gloopores:arol_lump", "technic:arol_dust 2"})
+ table.insert(recipes, {"gloopores:talinite_lump", "technic:talinite_dust 2"})
+ table.insert(recipes, {"gloopores:akalin_lump", "technic:akalin_dust 2"})
+end
+
+if minetest.get_modpath("homedecor") then
+ table.insert(recipes, {"home_decor:brass_ingot", "technic:brass_dust 1"})
+end
+
+for _, data in pairs(recipes) do
+ technic.register_grinder_recipe({input = {data[1]}, output = data[2]})
+end
+
+-- defuse common grinder unfriendly recipes
+if minetest.get_modpath("fake_fire") then -- from homedecor_modpack
+ minetest.register_craft({ output='default:cobble 0', recipe={{'default:cobble'}}})
+ minetest.register_craft({ output='default:gravel 0', recipe={{'default:gravel'}}})
+end
+
+-- dusts
+local function register_dust(name, ingot)
+ local lname = string.lower(name)
+ lname = string.gsub(lname, ' ', '_')
+ minetest.register_craftitem("technic:"..lname.."_dust", {
+ description = S("%s Dust"):format(S(name)),
+ inventory_image = "technic_"..lname.."_dust.png",
+ })
+ if ingot then
+ minetest.register_craft({
+ type = "cooking",
+ recipe = "technic:"..lname.."_dust",
+ output = ingot,
+ })
+ technic.register_grinder_recipe({ input = {ingot}, output = "technic:"..lname.."_dust 1" })
+ end
+end
+
+-- Sorted alphibeticaly
+register_dust("Brass", "technic:brass_ingot")
+register_dust("Bronze", "default:bronze_ingot")
+register_dust("Carbon Steel", "technic:carbon_steel_ingot")
+register_dust("Cast Iron", "technic:cast_iron_ingot")
+register_dust("Chromium", "technic:chromium_ingot")
+register_dust("Coal", nil)
+register_dust("Copper", "default:copper_ingot")
+register_dust("Lead", "technic:lead_ingot")
+register_dust("Gold", "default:gold_ingot")
+register_dust("Mithril", "moreores:mithril_ingot")
+register_dust("Silver", "moreores:silver_ingot")
+register_dust("Stainless Steel", "technic:stainless_steel_ingot")
+register_dust("Sulfur", nil)
+register_dust("Tin", "moreores:tin_ingot")
+register_dust("Wrought Iron", "technic:wrought_iron_ingot")
+register_dust("Zinc", "technic:zinc_ingot")
+if minetest.get_modpath("gloopores") or minetest.get_modpath("glooptest") then
+ register_dust("Akalin", "glooptest:akalin_ingot")
+ register_dust("Alatro", "glooptest:alatro_ingot")
+ register_dust("Arol", "glooptest:arol_ingot")
+ register_dust("Kalite", nil)
+ register_dust("Talinite", "glooptest:talinite_ingot")
+end
+
+for p = 0, 35 do
+ local nici = (p ~= 0 and p ~= 7 and p ~= 35) and 1 or nil
+ local psuffix = p == 7 and "" or p
+ local ingot = "technic:uranium"..psuffix.."_ingot"
+ local dust = "technic:uranium"..psuffix.."_dust"
+ minetest.register_craftitem(dust, {
+ description = S("%s Dust"):format(string.format(S("%.1f%%-Fissile Uranium"), p/10)),
+ inventory_image = "technic_uranium_dust.png",
+ on_place_on_ground = minetest.craftitem_place_item,
+ groups = {uranium_dust=1, not_in_creative_inventory=nici},
+ })
+ minetest.register_craft({
+ type = "cooking",
+ recipe = dust,
+ output = ingot,
+ })
+ technic.register_grinder_recipe({ input = {ingot}, output = dust })
+end
+
+local function uranium_dust(p)
+ return "technic:uranium"..(p == 7 and "" or p).."_dust"
+end
+for pa = 0, 34 do
+ for pb = pa+1, 35 do
+ local pc = (pa+pb)/2
+ if pc == math.floor(pc) then
+ minetest.register_craft({
+ type = "shapeless",
+ recipe = { uranium_dust(pa), uranium_dust(pb) },
+ output = uranium_dust(pc).." 2",
+ })
+ end
+ end
+end
+
+minetest.register_craft({
+ type = "fuel",
+ recipe = "technic:coal_dust",
+ burntime = 50,
+})
+
+if minetest.get_modpath("gloopores") or minetest.get_modpath("glooptest") then
+ minetest.register_craft({
+ type = "fuel",
+ recipe = "technic:kalite_dust",
+ burntime = 37.5,
+ })
+end
diff --git a/technic/technic/machines/register/grindings.lua b/technic/technic/machines/register/grindings.lua
new file mode 100644
index 0000000..9231166
--- /dev/null
+++ b/technic/technic/machines/register/grindings.lua
@@ -0,0 +1,62 @@
+local S = technic.getter
+local moretrees = minetest.get_modpath("moretrees")
+local mesecons_materials = minetest.get_modpath("mesecons_materials")
+local dye = minetest.get_modpath("dye")
+
+-- sawdust, the finest wood/tree grinding
+local sawdust = "technic:sawdust"
+minetest.register_craftitem(sawdust, {
+ description = S("Sawdust"),
+ inventory_image = "technic_sawdust.png",
+})
+minetest.register_craft({ type = "fuel", recipe = sawdust, burntime = 6 })
+technic.register_compressor_recipe({ input = {sawdust .. " 4"}, output = "default:wood" })
+
+-- tree/wood grindings
+local function register_tree_grinding(name, tree, wood, extract, grinding_color)
+ local lname = string.lower(name)
+ lname = string.gsub(lname, ' ', '_')
+ local grindings_name = "technic:"..lname.."_grindings"
+ local inventory_image = "technic_"..lname.."_grindings.png"
+ if grinding_color then
+ inventory_image = inventory_image .. "^[colorize:" .. grinding_color
+ end
+ minetest.register_craftitem(grindings_name, {
+ description = S("%s Grinding"):format(S(name)),
+ inventory_image = inventory_image,
+ })
+ minetest.register_craft({
+ type = "fuel",
+ recipe = grindings_name,
+ burntime = 8,
+ })
+ technic.register_grinder_recipe({ input = { tree }, output = grindings_name .. " 4" })
+ technic.register_grinder_recipe({ input = { grindings_name }, output = sawdust .. " 4" })
+ if wood then
+ technic.register_grinder_recipe({ input = { wood }, output = grindings_name })
+ end
+ if extract then
+ technic.register_extractor_recipe({ input = { grindings_name .. " 4" }, output = extract})
+ technic.register_separating_recipe({
+ input = { grindings_name .. " 4" },
+ output = { sawdust .. " 4", extract }
+ })
+ end
+end
+
+local rubber_tree_planks = moretrees and "moretrees:rubber_tree_planks"
+local default_extract = dye and "dye:brown 2"
+
+local grinding_recipes = {
+ {"Common Tree", "group:tree", "group:wood", default_extract },
+ {"Rubber Tree", "moretrees:rubber_tree_trunk", rubber_tree_planks, "technic:raw_latex"}
+}
+
+for _, data in pairs(grinding_recipes) do
+ register_tree_grinding(unpack(data))
+end
+
+if moretrees and dye then
+ -- https://en.wikipedia.org/wiki/Catechu ancient brown dye from the wood of acacia trees
+ register_tree_grinding("Acacia", "moretrees:acacia_trunk", "moretrees:acacia_planks", "dye:brown 8")
+end
diff --git a/technic/technic/machines/register/init.lua b/technic/technic/machines/register/init.lua
new file mode 100644
index 0000000..1667d75
--- /dev/null
+++ b/technic/technic/machines/register/init.lua
@@ -0,0 +1,33 @@
+local path = technic.modpath.."/machines/register"
+
+dofile(path.."/common.lua")
+
+-- Wiring stuff
+dofile(path.."/cables.lua")
+dofile(path.."/battery_box.lua")
+
+-- Generators
+dofile(path.."/solar_array.lua")
+dofile(path.."/generator.lua")
+
+-- API for machines
+dofile(path.."/recipes.lua")
+dofile(path.."/machine_base.lua")
+
+-- Recipes
+dofile(path.."/alloy_recipes.lua")
+dofile(path.."/grinder_recipes.lua")
+dofile(path.."/extractor_recipes.lua")
+dofile(path.."/compressor_recipes.lua")
+dofile(path.."/centrifuge_recipes.lua")
+
+-- Multi-Machine Recipes
+dofile(path.."/grindings.lua")
+
+-- Machines
+dofile(path.."/alloy_furnace.lua")
+dofile(path.."/electric_furnace.lua")
+dofile(path.."/grinder.lua")
+dofile(path.."/extractor.lua")
+dofile(path.."/compressor.lua")
+dofile(path.."/centrifuge.lua")
diff --git a/technic/technic/machines/register/machine_base.lua b/technic/technic/machines/register/machine_base.lua
new file mode 100644
index 0000000..0c46261
--- /dev/null
+++ b/technic/technic/machines/register/machine_base.lua
@@ -0,0 +1,197 @@
+
+local S = technic.getter
+
+local tube = {
+ insert_object = function(pos, node, stack, direction)
+ local meta = minetest.get_meta(pos)
+ local inv = meta:get_inventory()
+ return inv:add_item("src", stack)
+ end,
+ can_insert = function(pos, node, stack, direction)
+ local meta = minetest.get_meta(pos)
+ local inv = meta:get_inventory()
+ return inv:room_for_item("src", stack)
+ end,
+ connect_sides = {left = 1, right = 1, back = 1, top = 1, bottom = 1},
+}
+
+local function round(v)
+ return math.floor(v + 0.5)
+end
+
+function technic.register_base_machine(data)
+ local typename = data.typename
+ local input_size = technic.recipes[typename].input_size
+ local machine_name = data.machine_name
+ local machine_desc = data.machine_desc
+ local tier = data.tier
+ local ltier = string.lower(tier)
+
+ local groups = {cracky = 2, technic_machine = 1}
+ local active_groups = {cracky = 2, technic_machine = 1, not_in_creative_inventory = 1}
+ if data.tube then
+ groups.tubedevice = 1
+ groups.tubedevice_receiver = 1
+ active_groups.tubedevice = 1
+ active_groups.tubedevice_receiver = 1
+ end
+
+
+ local formspec =
+ "invsize[8,9;]"..
+ "list[current_name;src;"..(4-input_size)..",1;"..input_size..",1;]"..
+ "list[current_name;dst;5,1;2,2;]"..
+ "list[current_player;main;0,5;8,4;]"..
+ "label[0,0;"..machine_desc:format(tier).."]"..
+ "listring[current_name;dst]"..
+ "listring[current_player;main]"..
+ "listring[current_name;src]"..
+ "listring[current_player;main]"
+ if data.upgrade then
+ formspec = formspec..
+ "list[current_name;upgrade1;1,3;1,1;]"..
+ "list[current_name;upgrade2;2,3;1,1;]"..
+ "label[1,4;"..S("Upgrade Slots").."]"..
+ "listring[current_name;upgrade1]"..
+ "listring[current_player;main]"..
+ "listring[current_name;upgrade2]"..
+ "listring[current_player;main]"
+ end
+
+ local run = function(pos, node)
+ local meta = minetest.get_meta(pos)
+ local inv = meta:get_inventory()
+ local eu_input = meta:get_int(tier.."_EU_input")
+
+ local machine_desc_tier = machine_desc:format(tier)
+ local machine_node = "technic:"..ltier.."_"..machine_name
+ local machine_demand = data.demand
+
+ -- Setup meta data if it does not exist.
+ if not eu_input then
+ meta:set_int(tier.."_EU_demand", machine_demand[1])
+ meta:set_int(tier.."_EU_input", 0)
+ return
+ end
+
+ local EU_upgrade, tube_upgrade = 0, 0
+ if data.upgrade then
+ EU_upgrade, tube_upgrade = technic.handle_machine_upgrades(meta)
+ end
+ if data.tube then
+ technic.handle_machine_pipeworks(pos, tube_upgrade)
+ end
+
+ local powered = eu_input >= machine_demand[EU_upgrade+1]
+ if powered then
+ meta:set_int("src_time", meta:get_int("src_time") + round(data.speed*10))
+ end
+ while true do
+ local result = technic.get_recipe(typename, inv:get_list("src"))
+ if not result then
+ technic.swap_node(pos, machine_node)
+ meta:set_string("infotext", S("%s Idle"):format(machine_desc_tier))
+ meta:set_int(tier.."_EU_demand", 0)
+ meta:set_int("src_time", 0)
+ return
+ end
+ meta:set_int(tier.."_EU_demand", machine_demand[EU_upgrade+1])
+ technic.swap_node(pos, machine_node.."_active")
+ meta:set_string("infotext", S("%s Active"):format(machine_desc_tier))
+ if meta:get_int("src_time") < round(result.time*10) then
+ if not powered then
+ technic.swap_node(pos, machine_node)
+ meta:set_string("infotext", S("%s Unpowered"):format(machine_desc_tier))
+ end
+ return
+ end
+ local output = result.output
+ if type(output) ~= "table" then output = { output } end
+ local output_stacks = {}
+ for _, o in ipairs(output) do
+ table.insert(output_stacks, ItemStack(o))
+ end
+ local room_for_output = true
+ inv:set_size("dst_tmp", inv:get_size("dst"))
+ inv:set_list("dst_tmp", inv:get_list("dst"))
+ for _, o in ipairs(output_stacks) do
+ if not inv:room_for_item("dst_tmp", o) then
+ room_for_output = false
+ break
+ end
+ inv:add_item("dst_tmp", o)
+ end
+ if not room_for_output then
+ technic.swap_node(pos, machine_node)
+ meta:set_string("infotext", S("%s Idle"):format(machine_desc_tier))
+ meta:set_int(tier.."_EU_demand", 0)
+ meta:set_int("src_time", round(result.time*10))
+ return
+ end
+ meta:set_int("src_time", meta:get_int("src_time") - round(result.time*10))
+ inv:set_list("src", result.new_input)
+ inv:set_list("dst", inv:get_list("dst_tmp"))
+ end
+ end
+
+ minetest.register_node("technic:"..ltier.."_"..machine_name, {
+ description = machine_desc:format(tier),
+ tiles = {"technic_"..ltier.."_"..machine_name.."_top.png",
+ "technic_"..ltier.."_"..machine_name.."_bottom.png",
+ "technic_"..ltier.."_"..machine_name.."_side.png",
+ "technic_"..ltier.."_"..machine_name.."_side.png",
+ "technic_"..ltier.."_"..machine_name.."_side.png",
+ "technic_"..ltier.."_"..machine_name.."_front.png"},
+ paramtype2 = "facedir",
+ groups = groups,
+ tube = data.tube and tube or nil,
+ legacy_facedir_simple = true,
+ sounds = default.node_sound_wood_defaults(),
+ on_construct = function(pos)
+ local node = minetest.get_node(pos)
+ local meta = minetest.get_meta(pos)
+ meta:set_string("infotext", machine_desc:format(tier))
+ meta:set_int("tube_time", 0)
+ meta:set_string("formspec", formspec)
+ local inv = meta:get_inventory()
+ inv:set_size("src", input_size)
+ inv:set_size("dst", 4)
+ inv:set_size("upgrade1", 1)
+ inv:set_size("upgrade2", 1)
+ end,
+ can_dig = technic.machine_can_dig,
+ allow_metadata_inventory_put = technic.machine_inventory_put,
+ allow_metadata_inventory_take = technic.machine_inventory_take,
+ allow_metadata_inventory_move = technic.machine_inventory_move,
+ technic_run = run,
+ after_place_node = data.tube and pipeworks.after_place,
+ after_dig_node = technic.machine_after_dig_node
+ })
+
+ minetest.register_node("technic:"..ltier.."_"..machine_name.."_active",{
+ description = machine_desc:format(tier),
+ tiles = {"technic_"..ltier.."_"..machine_name.."_top.png",
+ "technic_"..ltier.."_"..machine_name.."_bottom.png",
+ "technic_"..ltier.."_"..machine_name.."_side.png",
+ "technic_"..ltier.."_"..machine_name.."_side.png",
+ "technic_"..ltier.."_"..machine_name.."_side.png",
+ "technic_"..ltier.."_"..machine_name.."_front_active.png"},
+ paramtype2 = "facedir",
+ drop = "technic:"..ltier.."_"..machine_name,
+ groups = active_groups,
+ legacy_facedir_simple = true,
+ sounds = default.node_sound_wood_defaults(),
+ tube = data.tube and tube or nil,
+ can_dig = technic.machine_can_dig,
+ allow_metadata_inventory_put = technic.machine_inventory_put,
+ allow_metadata_inventory_take = technic.machine_inventory_take,
+ allow_metadata_inventory_move = technic.machine_inventory_move,
+ technic_run = run,
+ technic_disabled_machine_name = "technic:"..ltier.."_"..machine_name,
+ })
+
+ technic.register_machine(tier, "technic:"..ltier.."_"..machine_name, technic.receiver)
+ technic.register_machine(tier, "technic:"..ltier.."_"..machine_name.."_active", technic.receiver)
+
+end -- End registration
+
diff --git a/technic/technic/machines/register/recipes.lua b/technic/technic/machines/register/recipes.lua
new file mode 100644
index 0000000..d30fd4f
--- /dev/null
+++ b/technic/technic/machines/register/recipes.lua
@@ -0,0 +1,107 @@
+local have_ui = minetest.get_modpath("unified_inventory")
+
+technic.recipes = { cooking = { input_size = 1, output_size = 1 } }
+function technic.register_recipe_type(typename, origdata)
+ local data = {}
+ for k, v in pairs(origdata) do data[k] = v end
+ data.input_size = data.input_size or 1
+ data.output_size = data.output_size or 1
+ if have_ui and unified_inventory.register_craft_type and data.output_size == 1 then
+ unified_inventory.register_craft_type(typename, {
+ description = data.description,
+ width = data.input_size,
+ height = 1,
+ })
+ end
+ data.recipes = {}
+ technic.recipes[typename] = data
+end
+
+local function get_recipe_index(items)
+ if not items or type(items) ~= "table" then return false end
+ local l = {}
+ for i, stack in ipairs(items) do
+ l[i] = ItemStack(stack):get_name()
+ end
+ table.sort(l)
+ return table.concat(l, "/")
+end
+
+local function register_recipe(typename, data)
+ -- Handle aliases
+ for i, stack in ipairs(data.input) do
+ data.input[i] = ItemStack(stack):to_string()
+ end
+ if type(data.output) == "table" then
+ for i, v in ipairs(data.output) do
+ data.output[i] = ItemStack(data.output[i]):to_string()
+ end
+ else
+ data.output = ItemStack(data.output):to_string()
+ end
+
+ local recipe = {time = data.time, input = {}, output = data.output}
+ local index = get_recipe_index(data.input)
+ if not index then
+ print("[Technic] ignored registration of garbage recipe!")
+ return
+ end
+ for _, stack in ipairs(data.input) do
+ recipe.input[ItemStack(stack):get_name()] = ItemStack(stack):get_count()
+ end
+
+ technic.recipes[typename].recipes[index] = recipe
+ if unified_inventory and technic.recipes[typename].output_size == 1 then
+ unified_inventory.register_craft({
+ type = typename,
+ output = data.output,
+ items = data.input,
+ width = 0,
+ })
+ end
+end
+
+function technic.register_recipe(typename, data)
+ minetest.after(0.01, register_recipe, typename, data) -- Handle aliases
+end
+
+function technic.get_recipe(typename, items)
+ if typename == "cooking" then -- Already builtin in Minetest, so use that
+ local result, new_input = minetest.get_craft_result({
+ method = "cooking",
+ width = 1,
+ items = items})
+ -- Compatibility layer
+ if not result or result.time == 0 then
+ return nil
+ else
+ return {time = result.time,
+ new_input = new_input.items,
+ output = result.item}
+ end
+ end
+ local index = get_recipe_index(items)
+ if not index then
+ print("[Technic] ignored registration of garbage recipe!")
+ return
+ end
+ local recipe = technic.recipes[typename].recipes[index]
+ if recipe then
+ local new_input = {}
+ for i, stack in ipairs(items) do
+ if stack:get_count() < recipe.input[stack:get_name()] then
+ return nil
+ else
+ new_input[i] = ItemStack(stack)
+ new_input[i]:take_item(recipe.input[stack:get_name()])
+ end
+ end
+ return {time = recipe.time,
+ new_input = new_input,
+ output = recipe.output}
+ else
+ return nil
+ end
+end
+
+
diff --git a/technic/technic/machines/register/solar_array.lua b/technic/technic/machines/register/solar_array.lua
new file mode 100644
index 0000000..39f50d2
--- /dev/null
+++ b/technic/technic/machines/register/solar_array.lua
@@ -0,0 +1,65 @@
+
+local S = technic.getter
+
+function technic.register_solar_array(data)
+ local tier = data.tier
+ local ltier = string.lower(tier)
+
+ local run = function(pos, node)
+ -- The action here is to make the solar array produce power
+ -- Power is dependent on the light level and the height above ground
+ -- There are many ways to cheat by using other light sources like lamps.
+ -- As there is no way to determine if light is sunlight that is just a shame.
+ -- To take care of some of it solar panels do not work outside daylight hours or if
+ -- built below 0m
+ local pos1 = {}
+ local machine_name = S("Arrayed Solar %s Generator"):format(tier)
+ pos1.y = pos.y + 1
+ pos1.x = pos.x
+ pos1.z = pos.z
+
+ technic.get_or_load_node(pos1)
+ local light = minetest.get_node_light(pos1, nil)
+ local time_of_day = minetest.get_timeofday()
+ local meta = minetest.get_meta(pos)
+ light = light or 0
+
+ -- turn on array only during day time and if sufficient light
+ -- I know this is counter intuitive when cheating by using other light sources.
+ if light >= 12 and time_of_day >= 0.24 and time_of_day <= 0.76 and pos.y > 0 then
+ local charge_to_give = math.floor((light + pos.y) * data.power)
+ charge_to_give = math.max(charge_to_give, 0)
+ charge_to_give = math.min(charge_to_give, data.power * 50)
+ meta:set_string("infotext", S("@1 Active (@2 EU)", machine_name, technic.prettynum(charge_to_give)))
+ meta:set_int(tier.."_EU_supply", charge_to_give)
+ else
+ meta:set_string("infotext", S("%s Idle"):format(machine_name))
+ meta:set_int(tier.."_EU_supply", 0)
+ end
+ end
+
+ minetest.register_node("technic:solar_array_"..ltier, {
+ tiles = {"technic_"..ltier.."_solar_array_top.png", "technic_"..ltier.."_solar_array_bottom.png",
+ "technic_"..ltier.."_solar_array_side.png", "technic_"..ltier.."_solar_array_side.png",
+ "technic_"..ltier.."_solar_array_side.png", "technic_"..ltier.."_solar_array_side.png"},
+ groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_machine=1},
+ sounds = default.node_sound_wood_defaults(),
+ description = S("Arrayed Solar %s Generator"):format(tier),
+ active = false,
+ drawtype = "nodebox",
+ paramtype = "light",
+ node_box = {
+ type = "fixed",
+ fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
+ },
+ on_construct = function(pos)
+ local meta = minetest.get_meta(pos)
+ local name = minetest.get_node(pos).name
+ meta:set_int(tier.."_EU_supply", 0)
+ end,
+ technic_run = run,
+ })
+
+ technic.register_machine(tier, "technic:solar_array_"..ltier, technic.producer)
+end
+