Make switching station run all machines it is connected to, including those in unloaded blocks.
| | |
| | | %s Unpowered = |
| | | %s Out Of Fuel = |
| | | %s Has Bad Cabling = |
| | | %s (Slave) = |
| | | %s Has No Network = |
| | | %s Finished = |
| | | Enable/Disable = |
| | |
| | | } |
| | | } |
| | | |
| | | local run = function(pos, node, active_object_count, active_object_count_wider) |
| | | local meta = minetest.get_meta(pos) |
| | | local eu_input = meta:get_int("HV_EU_input") |
| | | local eu_demand = meta:get_int("HV_EU_demand") |
| | | local enabled = meta:get_int("enabled") |
| | | local machine_name = S("%s Forcefield Emitter"):format("HV") |
| | | |
| | | local power_requirement = math.floor( |
| | | 4 * math.pi * math.pow(meta:get_int("range"), 2) |
| | | ) * forcefield_power_drain |
| | | |
| | | if meta:get_int("enabled") == 0 then |
| | | if node.name == "technic:forcefield_emitter_on" then |
| | | meta:set_int("HV_EU_demand", 0) |
| | | update_forcefield(pos, meta:get_int("range"), false) |
| | | technic.swap_node(pos, "technic:forcefield_emitter_off") |
| | | meta:set_string("infotext", S("%s Disabled"):format(machine_name)) |
| | | return |
| | | end |
| | | elseif eu_input < power_requirement then |
| | | meta:set_string("infotext", S("%s Unpowered"):format(machine_name)) |
| | | if node.name == "technic:forcefield_emitter_on" then |
| | | update_forcefield(pos, meta:get_int("range"), false) |
| | | technic.swap_node(pos, "technic:forcefield_emitter_off") |
| | | end |
| | | elseif eu_input >= power_requirement then |
| | | if node.name == "technic:forcefield_emitter_off" then |
| | | technic.swap_node(pos, "technic:forcefield_emitter_on") |
| | | meta:set_string("infotext", S("%s Active"):format(machine_name)) |
| | | end |
| | | update_forcefield(pos, meta:get_int("range"), true) |
| | | end |
| | | meta:set_int("HV_EU_demand", power_requirement) |
| | | end |
| | | |
| | | minetest.register_node("technic:forcefield_emitter_off", { |
| | | description = S("%s Forcefield Emitter"):format("HV"), |
| | | tiles = {"technic_forcefield_emitter_off.png"}, |
| | | groups = {cracky = 1}, |
| | | groups = {cracky = 1, technic_machine = 1}, |
| | | on_receive_fields = forcefield_receive_fields, |
| | | on_construct = function(pos) |
| | | local meta = minetest.get_meta(pos) |
| | |
| | | meta:set_string("infotext", S("%s Forcefield Emitter"):format("HV")) |
| | | set_forcefield_formspec(meta) |
| | | end, |
| | | mesecons = mesecons |
| | | mesecons = mesecons, |
| | | technic_run = run, |
| | | }) |
| | | |
| | | minetest.register_node("technic:forcefield_emitter_on", { |
| | | description = S("%s Forcefield Emitter"):format("HV"), |
| | | tiles = {"technic_forcefield_emitter_on.png"}, |
| | | groups = {cracky = 1, not_in_creative_inventory=1}, |
| | | groups = {cracky = 1, technic_machine = 1, not_in_creative_inventory=1}, |
| | | drop = "technic:forcefield_emitter_off", |
| | | on_receive_fields = forcefield_receive_fields, |
| | | on_construct = function(pos) |
| | |
| | | local meta = minetest.get_meta(pos) |
| | | update_forcefield(pos, meta:get_int("range"), false) |
| | | end, |
| | | mesecons = mesecons |
| | | mesecons = mesecons, |
| | | technic_run = run, |
| | | technic_disabled_machine_name = "technic:forcefield_emitter", |
| | | }) |
| | | |
| | | minetest.register_node("technic:forcefield", { |
| | |
| | | }, |
| | | }}, |
| | | }) |
| | | minetest.register_abm({ |
| | | nodenames = {"technic:forcefield_emitter_on", "technic:forcefield_emitter_off"}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | local meta = minetest.get_meta(pos) |
| | | local eu_input = meta:get_int("HV_EU_input") |
| | | local eu_demand = meta:get_int("HV_EU_demand") |
| | | local enabled = meta:get_int("enabled") |
| | | local machine_name = S("%s Forcefield Emitter"):format("HV") |
| | | -- Power off automatically if no longer connected to a switching station |
| | | technic.switching_station_timeout_count(pos, "HV") |
| | | |
| | | local power_requirement = math.floor( |
| | | 4 * math.pi * math.pow(meta:get_int("range"), 2) |
| | | ) * forcefield_power_drain |
| | | |
| | | if meta:get_int("enabled") == 0 then |
| | | if node.name == "technic:forcefield_emitter_on" then |
| | | meta:set_int("HV_EU_demand", 0) |
| | | update_forcefield(pos, meta:get_int("range"), false) |
| | | technic.swap_node(pos, "technic:forcefield_emitter_off") |
| | | meta:set_string("infotext", S("%s Disabled"):format(machine_name)) |
| | | return |
| | | end |
| | | elseif eu_input < power_requirement then |
| | | meta:set_string("infotext", S("%s Unpowered"):format(machine_name)) |
| | | if node.name == "technic:forcefield_emitter_on" then |
| | | update_forcefield(pos, meta:get_int("range"), false) |
| | | technic.swap_node(pos, "technic:forcefield_emitter_off") |
| | | end |
| | | elseif eu_input >= power_requirement then |
| | | if node.name == "technic:forcefield_emitter_off" then |
| | | technic.swap_node(pos, "technic:forcefield_emitter_on") |
| | | meta:set_string("infotext", S("%s Active"):format(machine_name)) |
| | | end |
| | | update_forcefield(pos, meta:get_int("range"), true) |
| | | end |
| | | meta:set_int("HV_EU_demand", power_requirement) |
| | | end |
| | | }) |
| | | |
| | | if minetest.get_modpath("mesecons_mvps") then |
| | | mesecon:register_mvps_stopper("technic:forcefield") |
| | | end |
| | | -- TODO: Register a stopper for frames |
| | | |
| | | technic.register_machine("HV", "technic:forcefield_emitter_on", technic.receiver) |
| | | technic.register_machine("HV", "technic:forcefield_emitter_off", technic.receiver) |
| | |
| | | { -0.303, -0.303, -0.397, 0.303, 0.303, 0.397 }, |
| | | } |
| | | |
| | | minetest.register_node("technic:hv_nuclear_reactor_core", { |
| | | description = S("Nuclear %s Generator Core"):format("HV"), |
| | | tiles = {"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png", |
| | | "technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png", |
| | | "technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png"}, |
| | | groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2}, |
| | | legacy_facedir_simple = true, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | drawtype="nodebox", |
| | | paramtype = "light", |
| | | stack_max = 1, |
| | | node_box = { |
| | | type = "fixed", |
| | | fixed = nodebox |
| | | }, |
| | | on_construct = function(pos) |
| | | local meta = minetest.get_meta(pos) |
| | | meta:set_string("infotext", S("Nuclear %s Generator Core"):format("HV")) |
| | | meta:set_int("HV_EU_supply", 0) |
| | | -- Signal to the switching station that this device burns some |
| | | -- sort of fuel and needs special handling |
| | | meta:set_int("HV_EU_from_fuel", 1) |
| | | meta:set_int("burn_time", 0) |
| | | meta:set_string("formspec", generator_formspec) |
| | | local inv = meta:get_inventory() |
| | | inv:set_size("src", 6) |
| | | 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, |
| | | }) |
| | | |
| | | minetest.register_node("technic:hv_nuclear_reactor_core_active", { |
| | | tiles = {"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png", |
| | | "technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png", |
| | | "technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png"}, |
| | | groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, not_in_creative_inventory=1}, |
| | | legacy_facedir_simple = true, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | drop="technic:hv_nuclear_reactor_core", |
| | | drawtype="nodebox", |
| | | light_source = 15, |
| | | paramtype = "light", |
| | | node_box = { |
| | | type = "fixed", |
| | | fixed = nodebox |
| | | }, |
| | | 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, |
| | | }) |
| | | |
| | | local check_reactor_structure = function(pos) |
| | | -- The reactor consists of a 9x9x9 cube structure |
| | | -- A cross section through the middle: |
| | |
| | | end |
| | | end |
| | | |
| | | minetest.register_abm({ |
| | | nodenames = {"technic:hv_nuclear_reactor_core", "technic:hv_nuclear_reactor_core_active"}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | local meta = minetest.get_meta(pos) |
| | | local machine_name = S("Nuclear %s Generator Core"):format("HV") |
| | | local burn_time = meta:get_int("burn_time") or 0 |
| | | local run = function(pos, node) |
| | | local meta = minetest.get_meta(pos) |
| | | local machine_name = S("Nuclear %s Generator Core"):format("HV") |
| | | local burn_time = meta:get_int("burn_time") or 0 |
| | | |
| | | if burn_time >= burn_ticks or burn_time == 0 then |
| | | local inv = meta:get_inventory() |
| | | if not inv:is_empty("src") then |
| | | local srclist = inv:get_list("src") |
| | | local correct_fuel_count = 0 |
| | | for _, srcstack in pairs(srclist) do |
| | | if srcstack then |
| | | if srcstack:get_name() == fuel_type then |
| | | correct_fuel_count = correct_fuel_count + 1 |
| | | end |
| | | if burn_time >= burn_ticks or burn_time == 0 then |
| | | local inv = meta:get_inventory() |
| | | if not inv:is_empty("src") then |
| | | local srclist = inv:get_list("src") |
| | | local correct_fuel_count = 0 |
| | | for _, srcstack in pairs(srclist) do |
| | | if srcstack then |
| | | if srcstack:get_name() == fuel_type then |
| | | correct_fuel_count = correct_fuel_count + 1 |
| | | end |
| | | end |
| | | -- Check that the reactor is complete as well |
| | | -- as the correct number of correct fuel |
| | | if correct_fuel_count == 6 and |
| | | check_reactor_structure(pos) then |
| | | meta:set_int("burn_time", 1) |
| | | technic.swap_node(pos, "technic:hv_nuclear_reactor_core_active") |
| | | meta:set_int("HV_EU_supply", power_supply) |
| | | for idx, srcstack in pairs(srclist) do |
| | | srcstack:take_item() |
| | | inv:set_stack("src", idx, srcstack) |
| | | end |
| | | return |
| | | end |
| | | -- Check that the reactor is complete as well |
| | | -- as the correct number of correct fuel |
| | | if correct_fuel_count == 6 and |
| | | check_reactor_structure(pos) then |
| | | meta:set_int("burn_time", 1) |
| | | technic.swap_node(pos, "technic:hv_nuclear_reactor_core_active") |
| | | meta:set_int("HV_EU_supply", power_supply) |
| | | for idx, srcstack in pairs(srclist) do |
| | | srcstack:take_item() |
| | | inv:set_stack("src", idx, srcstack) |
| | | end |
| | | return |
| | | end |
| | | meta:set_int("HV_EU_supply", 0) |
| | | meta:set_int("burn_time", 0) |
| | | meta:set_string("infotext", S("%s Idle"):format(machine_name)) |
| | | technic.swap_node(pos, "technic:hv_nuclear_reactor_core") |
| | | elseif burn_time > 0 then |
| | | damage_nearby_players(pos) |
| | | if not check_reactor_structure(pos) then |
| | | explode_reactor(pos) |
| | | end |
| | | burn_time = burn_time + 1 |
| | | meta:set_int("burn_time", burn_time) |
| | | local percent = math.floor(burn_time / burn_ticks * 100) |
| | | meta:set_string("infotext", machine_name.." ("..percent.."%)") |
| | | meta:set_int("HV_EU_supply", power_supply) |
| | | end |
| | | meta:set_int("HV_EU_supply", 0) |
| | | meta:set_int("burn_time", 0) |
| | | meta:set_string("infotext", S("%s Idle"):format(machine_name)) |
| | | technic.swap_node(pos, "technic:hv_nuclear_reactor_core") |
| | | elseif burn_time > 0 then |
| | | damage_nearby_players(pos) |
| | | if not check_reactor_structure(pos) then |
| | | explode_reactor(pos) |
| | | end |
| | | burn_time = burn_time + 1 |
| | | meta:set_int("burn_time", burn_time) |
| | | local percent = math.floor(burn_time / burn_ticks * 100) |
| | | meta:set_string("infotext", machine_name.." ("..percent.."%)") |
| | | meta:set_int("HV_EU_supply", power_supply) |
| | | end |
| | | end |
| | | |
| | | minetest.register_node("technic:hv_nuclear_reactor_core", { |
| | | description = S("Nuclear %s Generator Core"):format("HV"), |
| | | tiles = {"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png", |
| | | "technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png", |
| | | "technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png"}, |
| | | groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_machine=1}, |
| | | legacy_facedir_simple = true, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | drawtype="nodebox", |
| | | paramtype = "light", |
| | | stack_max = 1, |
| | | node_box = { |
| | | type = "fixed", |
| | | fixed = nodebox |
| | | }, |
| | | on_construct = function(pos) |
| | | local meta = minetest.get_meta(pos) |
| | | meta:set_string("infotext", S("Nuclear %s Generator Core"):format("HV")) |
| | | meta:set_int("HV_EU_supply", 0) |
| | | -- Signal to the switching station that this device burns some |
| | | -- sort of fuel and needs special handling |
| | | meta:set_int("HV_EU_from_fuel", 1) |
| | | meta:set_int("burn_time", 0) |
| | | meta:set_string("formspec", generator_formspec) |
| | | local inv = meta:get_inventory() |
| | | inv:set_size("src", 6) |
| | | 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, |
| | | }) |
| | | |
| | | minetest.register_node("technic:hv_nuclear_reactor_core_active", { |
| | | tiles = {"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png", |
| | | "technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png", |
| | | "technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png"}, |
| | | groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_machine=1, not_in_creative_inventory=1}, |
| | | legacy_facedir_simple = true, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | drop="technic:hv_nuclear_reactor_core", |
| | | drawtype="nodebox", |
| | | light_source = 15, |
| | | paramtype = "light", |
| | | node_box = { |
| | | type = "fixed", |
| | | fixed = nodebox |
| | | }, |
| | | 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:hv_nuclear_reactor_core", |
| | | }) |
| | | |
| | | technic.register_machine("HV", "technic:hv_nuclear_reactor_core", technic.producer) |
| | |
| | | end |
| | | end |
| | | |
| | | local run = function(pos, node) |
| | | local meta = minetest.get_meta(pos) |
| | | local size = meta:get_int("size") |
| | | local eu_input = meta:get_int("HV_EU_input") |
| | | local demand = 10000 |
| | | local center = get_quarry_center(pos, size) |
| | | local dig_y = meta:get_int("dig_y") |
| | | local machine_name = S("%s Quarry"):format("HV") |
| | | |
| | | if meta:get_int("enabled") == 0 then |
| | | meta:set_string("infotext", S("%s Disabled"):format(machine_name)) |
| | | meta:set_int("HV_EU_demand", 0) |
| | | return |
| | | end |
| | | |
| | | if eu_input < demand then |
| | | meta:set_string("infotext", S("%s Unpowered"):format(machine_name)) |
| | | elseif eu_input >= demand then |
| | | meta:set_string("infotext", S("%s Active"):format(machine_name)) |
| | | |
| | | local items = quarry_dig(pos, center, size) |
| | | send_items(items, pos, node) |
| | | |
| | | if dig_y < pos.y - quarry_max_depth then |
| | | meta:set_string("infotext", S("%s Finished"):format(machine_name)) |
| | | end |
| | | end |
| | | meta:set_int("HV_EU_demand", demand) |
| | | end |
| | | |
| | | minetest.register_node("technic:quarry", { |
| | | description = S("%s Quarry"):format("HV"), |
| | | tiles = {"technic_carbon_steel_block.png", "technic_carbon_steel_block.png", |
| | | "technic_carbon_steel_block.png", "technic_carbon_steel_block.png", |
| | | "technic_carbon_steel_block.png^default_tool_mesepick.png", "technic_carbon_steel_block.png"}, |
| | | paramtype2 = "facedir", |
| | | groups = {cracky=2, tubedevice=1}, |
| | | groups = {cracky=2, tubedevice=1, technic_machine = 1}, |
| | | tube = { |
| | | connect_sides = {top = 1}, |
| | | }, |
| | |
| | | end, |
| | | after_dig_node = pipeworks.scan_for_tube_objects, |
| | | on_receive_fields = quarry_receive_fields, |
| | | }) |
| | | |
| | | minetest.register_abm({ |
| | | nodenames = {"technic:quarry"}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | local meta = minetest.get_meta(pos) |
| | | local size = meta:get_int("size") |
| | | local eu_input = meta:get_int("HV_EU_input") |
| | | local demand = 10000 |
| | | local center = get_quarry_center(pos, size) |
| | | local dig_y = meta:get_int("dig_y") |
| | | local machine_name = S("%s Quarry"):format("HV") |
| | | |
| | | technic.switching_station_timeout_count(pos, "HV") |
| | | |
| | | if meta:get_int("enabled") == 0 then |
| | | meta:set_string("infotext", S("%s Disabled"):format(machine_name)) |
| | | meta:set_int("HV_EU_demand", 0) |
| | | return |
| | | end |
| | | |
| | | if eu_input < demand then |
| | | meta:set_string("infotext", S("%s Unpowered"):format(machine_name)) |
| | | elseif eu_input >= demand then |
| | | meta:set_string("infotext", S("%s Active"):format(machine_name)) |
| | | |
| | | local items = quarry_dig(pos, center, size) |
| | | send_items(items, pos, node) |
| | | |
| | | if dig_y < pos.y - quarry_max_depth then |
| | | meta:set_string("infotext", S("%s Finished"):format(machine_name)) |
| | | end |
| | | end |
| | | meta:set_int("HV_EU_demand", demand) |
| | | end |
| | | technic_run = run, |
| | | }) |
| | | |
| | | technic.register_machine("HV", "technic:quarry", technic.receiver) |
| | |
| | | return |
| | | end |
| | | |
| | | -- Action code performing the transformation |
| | | local run = function(pos, node) |
| | | local meta = minetest.get_meta(pos) |
| | | local inv = meta:get_inventory() |
| | | local eu_input = meta:get_int("LV_EU_input") |
| | | local machine_name = S("%s CNC Machine"):format("LV") |
| | | local machine_node = "technic:cnc" |
| | | local demand = 450 |
| | | |
| | | local result = meta:get_string("cnc_product") |
| | | if inv:is_empty("src") or |
| | | (not minetest.registered_nodes[result]) or |
| | | (not inv:room_for_item("dst", result)) then |
| | | technic.swap_node(pos, machine_node) |
| | | meta:set_string("infotext", S("%s Idle"):format(machine_name)) |
| | | meta:set_string("cnc_product", "") |
| | | meta:set_int("LV_EU_demand", 0) |
| | | return |
| | | end |
| | | |
| | | if eu_input < demand then |
| | | technic.swap_node(pos, machine_node) |
| | | meta:set_string("infotext", S("%s Unpowered"):format(machine_name)) |
| | | elseif eu_input >= demand then |
| | | technic.swap_node(pos, machine_node.."_active") |
| | | meta:set_string("infotext", S("%s Active"):format(machine_name)) |
| | | meta:set_int("src_time", meta:get_int("src_time") + 1) |
| | | if meta:get_int("src_time") >= 3 then -- 3 ticks per output |
| | | meta:set_int("src_time", 0) |
| | | srcstack = inv:get_stack("src", 1) |
| | | srcstack:take_item() |
| | | inv:set_stack("src", 1, srcstack) |
| | | inv:add_item("dst", result.." "..meta:get_int("cnc_multiplier")) |
| | | end |
| | | end |
| | | meta:set_int("LV_EU_demand", demand) |
| | | end |
| | | |
| | | -- The actual block inactive state |
| | | minetest.register_node("technic:cnc", { |
| | | description = S("%s CNC Machine"):format("LV"), |
| | |
| | | {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, |
| | | }, |
| | | }, |
| | | groups = {cracky=2}, |
| | | groups = {cracky=2, technic_machine=1}, |
| | | legacy_facedir_simple = true, |
| | | on_construct = function(pos) |
| | | local meta = minetest.get_meta(pos) |
| | |
| | | allow_metadata_inventory_take = technic.machine_inventory_take, |
| | | allow_metadata_inventory_move = technic.machine_inventory_move, |
| | | on_receive_fields = form_handler, |
| | | technic_run = run, |
| | | }) |
| | | |
| | | -- Active state block |
| | |
| | | "technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front_active.png"}, |
| | | paramtype2 = "facedir", |
| | | drop = "technic:cnc", |
| | | groups = {cracky=2, not_in_creative_inventory=1}, |
| | | groups = {cracky=2, technic_machine=1, not_in_creative_inventory=1}, |
| | | legacy_facedir_simple = true, |
| | | 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, |
| | | on_receive_fields = form_handler, |
| | | technic_run = run, |
| | | technic_disabled_machine_name = "technic:cnc", |
| | | }) |
| | | |
| | | -- Action code performing the transformation |
| | | minetest.register_abm({ |
| | | nodenames = {"technic:cnc","technic:cnc_active"}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | local meta = minetest.get_meta(pos) |
| | | local inv = meta:get_inventory() |
| | | local eu_input = meta:get_int("LV_EU_input") |
| | | local machine_name = S("%s CNC Machine"):format("LV") |
| | | local machine_node = "technic:cnc" |
| | | local demand = 450 |
| | | |
| | | -- Power off automatically if no longer connected to a switching station |
| | | technic.switching_station_timeout_count(pos, "LV") |
| | | |
| | | local result = meta:get_string("cnc_product") |
| | | if inv:is_empty("src") or |
| | | (not minetest.registered_nodes[result]) or |
| | | (not inv:room_for_item("dst", result)) then |
| | | technic.swap_node(pos, machine_node) |
| | | meta:set_string("infotext", S("%s Idle"):format(machine_name)) |
| | | meta:set_string("cnc_product", "") |
| | | meta:set_int("LV_EU_demand", 0) |
| | | return |
| | | end |
| | | |
| | | if eu_input < demand then |
| | | technic.swap_node(pos, machine_node) |
| | | meta:set_string("infotext", S("%s Unpowered"):format(machine_name)) |
| | | elseif eu_input >= demand then |
| | | technic.swap_node(pos, machine_node.."_active") |
| | | meta:set_string("infotext", S("%s Active"):format(machine_name)) |
| | | meta:set_int("src_time", meta:get_int("src_time") + 1) |
| | | if meta:get_int("src_time") >= 3 then -- 3 ticks per output |
| | | meta:set_int("src_time", 0) |
| | | srcstack = inv:get_stack("src", 1) |
| | | srcstack:take_item() |
| | | inv:set_stack("src", 1, srcstack) |
| | | inv:add_item("dst", result.." "..meta:get_int("cnc_multiplier")) |
| | | end |
| | | end |
| | | meta:set_int("LV_EU_demand", demand) |
| | | end |
| | | }) |
| | | |
| | | technic.register_machine("LV", "technic:cnc", technic.receiver) |
| | | technic.register_machine("LV", "technic:cnc_active", technic.receiver) |
| | |
| | | description = S("Geothermal %s Generator"):format("LV"), |
| | | }) |
| | | |
| | | local check_node_around = function(pos) |
| | | local node = minetest.get_node(pos) |
| | | if node.name == "default:water_source" or node.name == "default:water_flowing" then return 1 end |
| | | if node.name == "default:lava_source" or node.name == "default:lava_flowing" then return 2 end |
| | | return 0 |
| | | end |
| | | |
| | | local run = function(pos, node) |
| | | local meta = minetest.get_meta(pos) |
| | | local water_nodes = 0 |
| | | local lava_nodes = 0 |
| | | local production_level = 0 |
| | | local eu_supply = 0 |
| | | |
| | | -- Correct positioning is water on one side and lava on the other. |
| | | -- The two cannot be adjacent because the lava the turns into obsidian or rock. |
| | | -- To get to 100% production stack the water and lava one extra block down as well: |
| | | -- WGL (W=Water, L=Lava, G=the generator, |=an LV cable) |
| | | -- W|L |
| | | |
| | | local positions = { |
| | | {x=pos.x+1, y=pos.y, z=pos.z}, |
| | | {x=pos.x+1, y=pos.y-1, z=pos.z}, |
| | | {x=pos.x-1, y=pos.y, z=pos.z}, |
| | | {x=pos.x-1, y=pos.y-1, z=pos.z}, |
| | | {x=pos.x, y=pos.y, z=pos.z+1}, |
| | | {x=pos.x, y=pos.y-1, z=pos.z+1}, |
| | | {x=pos.x, y=pos.y, z=pos.z-1}, |
| | | {x=pos.x, y=pos.y-1, z=pos.z-1}, |
| | | } |
| | | for _, p in pairs(positions) do |
| | | local check = check_node_around(p) |
| | | if check == 1 then water_nodes = water_nodes + 1 end |
| | | if check == 2 then lava_nodes = lava_nodes + 1 end |
| | | end |
| | | |
| | | if water_nodes == 1 and lava_nodes == 1 then production_level = 25; eu_supply = 50 end |
| | | if water_nodes == 2 and lava_nodes == 1 then production_level = 50; eu_supply = 100 end |
| | | if water_nodes == 1 and lava_nodes == 2 then production_level = 75; eu_supply = 200 end |
| | | if water_nodes == 2 and lava_nodes == 2 then production_level = 100; eu_supply = 300 end |
| | | |
| | | if production_level > 0 then |
| | | meta:set_int("LV_EU_supply", eu_supply) |
| | | end |
| | | |
| | | meta:set_string("infotext", |
| | | S("Geothermal %s Generator"):format("LV").." ("..production_level.."%)") |
| | | |
| | | if production_level > 0 and minetest.get_node(pos).name == "technic:geothermal" then |
| | | technic.swap_node (pos, "technic:geothermal_active") |
| | | return |
| | | end |
| | | if production_level == 0 then |
| | | technic.swap_node(pos, "technic:geothermal") |
| | | meta:set_int("LV_EU_supply", 0) |
| | | end |
| | | end |
| | | |
| | | minetest.register_node("technic:geothermal", { |
| | | description = S("Geothermal %s Generator"):format("LV"), |
| | | tiles = {"technic_geothermal_top.png", "technic_machine_bottom.png", "technic_geothermal_side.png", |
| | | "technic_geothermal_side.png", "technic_geothermal_side.png", "technic_geothermal_side.png"}, |
| | | paramtype2 = "facedir", |
| | | groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2}, |
| | | groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_machine=1}, |
| | | legacy_facedir_simple = true, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | on_construct = function(pos) |
| | | local meta = minetest.get_meta(pos) |
| | | meta:set_string("infotext", S("Geothermal %s Generator"):format("LV")) |
| | | meta:set_int("LV_EU_supply", 0) |
| | | end, |
| | | end, |
| | | technic_run = run, |
| | | }) |
| | | |
| | | minetest.register_node("technic:geothermal_active", { |
| | |
| | | legacy_facedir_simple = true, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | drop = "technic:geothermal", |
| | | technic_run = run, |
| | | }) |
| | | |
| | | local check_node_around = function(pos) |
| | | local node = minetest.get_node(pos) |
| | | if node.name == "default:water_source" or node.name == "default:water_flowing" then return 1 end |
| | | if node.name == "default:lava_source" or node.name == "default:lava_flowing" then return 2 end |
| | | return 0 |
| | | end |
| | | |
| | | minetest.register_abm({ |
| | | nodenames = {"technic:geothermal","technic:geothermal_active"}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | local meta = minetest.get_meta(pos) |
| | | local water_nodes = 0 |
| | | local lava_nodes = 0 |
| | | local production_level = 0 |
| | | local eu_supply = 0 |
| | | |
| | | -- Correct positioning is water on one side and lava on the other. |
| | | -- The two cannot be adjacent because the lava the turns into obsidian or rock. |
| | | -- To get to 100% production stack the water and lava one extra block down as well: |
| | | -- WGL (W=Water, L=Lava, G=the generator, |=an LV cable) |
| | | -- W|L |
| | | |
| | | local positions = { |
| | | {x=pos.x+1, y=pos.y, z=pos.z}, |
| | | {x=pos.x+1, y=pos.y-1, z=pos.z}, |
| | | {x=pos.x-1, y=pos.y, z=pos.z}, |
| | | {x=pos.x-1, y=pos.y-1, z=pos.z}, |
| | | {x=pos.x, y=pos.y, z=pos.z+1}, |
| | | {x=pos.x, y=pos.y-1, z=pos.z+1}, |
| | | {x=pos.x, y=pos.y, z=pos.z-1}, |
| | | {x=pos.x, y=pos.y-1, z=pos.z-1}, |
| | | } |
| | | for _, p in pairs(positions) do |
| | | local check = check_node_around(p) |
| | | if check == 1 then water_nodes = water_nodes + 1 end |
| | | if check == 2 then lava_nodes = lava_nodes + 1 end |
| | | end |
| | | |
| | | if water_nodes == 1 and lava_nodes == 1 then production_level = 25; eu_supply = 50 end |
| | | if water_nodes == 2 and lava_nodes == 1 then production_level = 50; eu_supply = 100 end |
| | | if water_nodes == 1 and lava_nodes == 2 then production_level = 75; eu_supply = 200 end |
| | | if water_nodes == 2 and lava_nodes == 2 then production_level = 100; eu_supply = 300 end |
| | | |
| | | if production_level > 0 then |
| | | meta:set_int("LV_EU_supply", eu_supply) |
| | | end |
| | | |
| | | meta:set_string("infotext", |
| | | S("Geothermal %s Generator"):format("LV").." ("..production_level.."%)") |
| | | |
| | | if production_level > 0 and minetest.get_node(pos).name == "technic:geothermal" then |
| | | technic.swap_node (pos, "technic:geothermal_active") |
| | | return |
| | | end |
| | | if production_level == 0 then |
| | | technic.swap_node(pos, "technic:geothermal") |
| | | meta:set_int("LV_EU_supply", 0) |
| | | end |
| | | end |
| | | }) |
| | | |
| | | technic.register_machine("LV", "technic:geothermal", technic.producer) |
| | | technic.register_machine("LV", "technic:geothermal_active", technic.producer) |
| | |
| | | {pos = pos, gain = 1.0, loop = true, max_hear_distance = 72,}) |
| | | end |
| | | |
| | | local run = function(pos, node) |
| | | local meta = minetest.get_meta(pos) |
| | | local eu_input = meta:get_int("LV_EU_input") |
| | | local machine_name = S("%s Music Player"):format("LV") |
| | | local machine_node = "technic:music_player" |
| | | local demand = 150 |
| | | |
| | | local current_track = meta:get_int("current_track") |
| | | local pos_hash = minetest.hash_node_position(pos) |
| | | local music_handle = music_handles[pos_hash] |
| | | |
| | | -- Setup meta data if it does not exist. |
| | | if not eu_input then |
| | | meta:set_int("LV_EU_demand", demand) |
| | | meta:set_int("LV_EU_input", 0) |
| | | return |
| | | end |
| | | |
| | | if meta:get_int("active") == 0 then |
| | | meta:set_string("infotext", S("%s Idle"):format(machine_name)) |
| | | meta:set_int("LV_EU_demand", 0) |
| | | return |
| | | end |
| | | |
| | | if eu_input < demand then |
| | | meta:set_string("infotext", S("%s Unpowered"):format(machine_name)) |
| | | if music_handle then |
| | | minetest.sound_stop(music_handle) |
| | | music_handle = nil |
| | | end |
| | | elseif eu_input >= demand then |
| | | meta:set_string("infotext", S("%s Active"):format(machine_name)) |
| | | if not music_handle then |
| | | music_handle = play_track(pos, current_track) |
| | | end |
| | | end |
| | | music_handles[pos_hash] = music_handle |
| | | meta:set_int("LV_EU_demand", demand) |
| | | end |
| | | |
| | | minetest.register_node("technic:music_player", { |
| | | description = S("%s Music Player"):format("LV"), |
| | | tiles = {"technic_music_player_top.png", "technic_machine_bottom.png", "technic_music_player_side.png", |
| | | "technic_music_player_side.png", "technic_music_player_side.png", "technic_music_player_side.png"}, |
| | | groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, |
| | | groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_machine=1}, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | on_construct = function(pos) |
| | | local meta = minetest.get_meta(pos) |
| | |
| | | end |
| | | music_handles[pos_hash] = music_handle |
| | | end, |
| | | }) |
| | | |
| | | minetest.register_abm({ |
| | | nodenames = {"technic:music_player"}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | local meta = minetest.get_meta(pos) |
| | | local eu_input = meta:get_int("LV_EU_input") |
| | | local machine_name = S("%s Music Player"):format("LV") |
| | | local machine_node = "technic:music_player" |
| | | local demand = 150 |
| | | |
| | | local current_track = meta:get_int("current_track") |
| | | local pos_hash = minetest.hash_node_position(pos) |
| | | local music_handle = music_handles[pos_hash] |
| | | |
| | | -- Setup meta data if it does not exist. |
| | | if not eu_input then |
| | | meta:set_int("LV_EU_demand", demand) |
| | | meta:set_int("LV_EU_input", 0) |
| | | return |
| | | end |
| | | |
| | | -- Power off automatically if no longer connected to a switching station |
| | | technic.switching_station_timeout_count(pos, "LV") |
| | | |
| | | if meta:get_int("active") == 0 then |
| | | meta:set_string("infotext", S("%s Idle"):format(machine_name)) |
| | | meta:set_int("LV_EU_demand", 0) |
| | | return |
| | | end |
| | | |
| | | if eu_input < demand then |
| | | meta:set_string("infotext", S("%s Unpowered"):format(machine_name)) |
| | | if music_handle then |
| | | minetest.sound_stop(music_handle) |
| | | music_handle = nil |
| | | end |
| | | elseif eu_input >= demand then |
| | | meta:set_string("infotext", S("%s Active"):format(machine_name)) |
| | | if not music_handle then |
| | | music_handle = play_track(pos, current_track) |
| | | end |
| | | end |
| | | music_handles[pos_hash] = music_handle |
| | | meta:set_int("LV_EU_demand", demand) |
| | | end |
| | | technic_run = run, |
| | | }) |
| | | |
| | | technic.register_machine("LV", "technic:music_player", technic.receiver) |
| | |
| | | |
| | | local S = technic.getter |
| | | |
| | | local run = function(pos, node) |
| | | -- The action here is to make the solar panel prodice 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 = {x=pos.x, y=pos.y+1, z=pos.z} |
| | | local machine_name = S("Small Solar %s Generator"):format("LV") |
| | | |
| | | local light = minetest.get_node_light(pos1, nil) |
| | | local time_of_day = minetest.get_timeofday() |
| | | local meta = minetest.get_meta(pos) |
| | | if light == nil then light = 0 end |
| | | -- turn on panel only during day time and if sufficient light |
| | | -- I know this is counter intuitive when cheating by using other light sources underground. |
| | | if light >= 12 and time_of_day >= 0.24 and time_of_day <= 0.76 and pos.y > -10 then |
| | | local charge_to_give = math.floor((light + pos1.y) * 3) |
| | | charge_to_give = math.max(charge_to_give, 0) |
| | | charge_to_give = math.min(charge_to_give, 200) |
| | | meta:set_string("infotext", S("%s Active"):format(machine_name).." ("..charge_to_give.."EU)") |
| | | meta:set_int("LV_EU_supply", charge_to_give) |
| | | else |
| | | meta:set_string("infotext", S("%s Idle"):format(machine_name)) |
| | | meta:set_int("LV_EU_supply", 0) |
| | | end |
| | | end |
| | | |
| | | minetest.register_node("technic:solar_panel", { |
| | | tiles = {"technic_solar_panel_top.png", "technic_solar_panel_bottom.png", "technic_solar_panel_side.png", |
| | | "technic_solar_panel_side.png", "technic_solar_panel_side.png", "technic_solar_panel_side.png"}, |
| | | groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, |
| | | groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_machine=1}, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | description = S("Small Solar %s Generator"):format("LV"), |
| | | active = false, |
| | |
| | | meta:set_int("LV_EU_supply", 0) |
| | | meta:set_string("infotext", S("Small Solar %s Generator"):format("LV")) |
| | | end, |
| | | technic_run = run, |
| | | }) |
| | | |
| | | minetest.register_craft({ |
| | |
| | | |
| | | } |
| | | }) |
| | | |
| | | minetest.register_abm({ |
| | | nodenames = {"technic:solar_panel"}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | -- The action here is to make the solar panel prodice power |
| | | -- Power is dependent on the light level and the height above ground |
| | | -- 130m and above is optimal as it would be above cloud level. |
| | | -- Height gives 1/4 of the effect, light 3/4. Max. effect is 26EU. |
| | | -- 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 -10m |
| | | local pos1 = {x=pos.x, y=pos.y+1, z=pos.z} |
| | | local machine_name = S("Small Solar %s Generator"):format("LV") |
| | | |
| | | local light = minetest.get_node_light(pos1, nil) |
| | | local time_of_day = minetest.get_timeofday() |
| | | local meta = minetest.get_meta(pos) |
| | | if light == nil then light = 0 end |
| | | -- turn on panel only during day time and if sufficient light |
| | | -- I know this is counter intuitive when cheating by using other light sources underground. |
| | | if light >= 12 and time_of_day >= 0.24 and time_of_day <= 0.76 and pos.y > -10 then |
| | | local charge_to_give = math.floor((light + pos1.y) * 3) |
| | | charge_to_give = math.max(charge_to_give, 0) |
| | | charge_to_give = math.min(charge_to_give, 200) |
| | | meta:set_string("infotext", S("%s Active"):format(machine_name).." ("..charge_to_give.."EU)") |
| | | meta:set_int("LV_EU_supply", charge_to_give) |
| | | else |
| | | meta:set_string("infotext", S("%s Idle"):format(machine_name)) |
| | | meta:set_int("LV_EU_supply", 0) |
| | | end |
| | | end, |
| | | }) |
| | | |
| | | technic.register_machine("LV", "technic:solar_panel", technic.producer) |
| | | |
| | |
| | | } |
| | | }) |
| | | |
| | | minetest.register_node("technic:water_mill", { |
| | | description = S("Hydro %s Generator"):format("LV"), |
| | | tiles = {"technic_water_mill_top.png", "technic_machine_bottom.png", |
| | | "technic_water_mill_side.png", "technic_water_mill_side.png", |
| | | "technic_water_mill_side.png", "technic_water_mill_side.png"}, |
| | | paramtype2 = "facedir", |
| | | groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2}, |
| | | legacy_facedir_simple = true, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | on_construct = function(pos) |
| | | local meta = minetest.get_meta(pos) |
| | | meta:set_string("infotext", S("Hydro %s Generator"):format("LV")) |
| | | meta:set_int("LV_EU_supply", 0) |
| | | end, |
| | | }) |
| | | |
| | | minetest.register_node("technic:water_mill_active", { |
| | | description = S("Hydro %s Generator"):format("LV"), |
| | | tiles = {"technic_water_mill_top_active.png", "technic_machine_bottom.png", |
| | | "technic_water_mill_side.png", "technic_water_mill_side.png", |
| | | "technic_water_mill_side.png", "technic_water_mill_side.png"}, |
| | | paramtype2 = "facedir", |
| | | groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, not_in_creative_inventory=1}, |
| | | legacy_facedir_simple = true, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | drop = "technic:water_mill", |
| | | }) |
| | | |
| | | local function check_node_around_mill(pos) |
| | | local node = minetest.get_node(pos) |
| | | if node.name == "default:water_flowing" or |
| | |
| | | return false |
| | | end |
| | | |
| | | minetest.register_abm({ |
| | | nodenames = {"technic:water_mill", "technic:water_mill_active"}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | local meta = minetest.get_meta(pos) |
| | | local water_nodes = 0 |
| | | local lava_nodes = 0 |
| | | local production_level = 0 |
| | | local eu_supply = 0 |
| | | local run = function(pos, node) |
| | | local meta = minetest.get_meta(pos) |
| | | local water_nodes = 0 |
| | | local lava_nodes = 0 |
| | | local production_level = 0 |
| | | local eu_supply = 0 |
| | | |
| | | local 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, z=pos.z+1}, |
| | | {x=pos.x, y=pos.y, z=pos.z-1}, |
| | | } |
| | | local 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, z=pos.z+1}, |
| | | {x=pos.x, y=pos.y, z=pos.z-1}, |
| | | } |
| | | |
| | | for _, p in pairs(positions) do |
| | | local check = check_node_around_mill(p) |
| | | if check then |
| | | water_nodes = water_nodes + 1 |
| | | end |
| | | end |
| | | |
| | | production_level = 25 * water_nodes |
| | | eu_supply = 30 * water_nodes |
| | | |
| | | if production_level > 0 then |
| | | meta:set_int("LV_EU_supply", eu_supply) |
| | | end |
| | | |
| | | meta:set_string("infotext", |
| | | S("Hydro %s Generator"):format("LV").." ("..production_level.."%)") |
| | | |
| | | if production_level > 0 and |
| | | minetest.get_node(pos).name == "technic:water_mill" then |
| | | technic.swap_node (pos, "technic:water_mill_active") |
| | | meta:set_int("LV_EU_supply", 0) |
| | | return |
| | | end |
| | | if production_level == 0 then |
| | | technic.swap_node(pos, "technic:water_mill") |
| | | for _, p in pairs(positions) do |
| | | local check = check_node_around_mill(p) |
| | | if check then |
| | | water_nodes = water_nodes + 1 |
| | | end |
| | | end |
| | | }) |
| | | |
| | | production_level = 25 * water_nodes |
| | | eu_supply = 30 * water_nodes |
| | | |
| | | if production_level > 0 then |
| | | meta:set_int("LV_EU_supply", eu_supply) |
| | | end |
| | | |
| | | meta:set_string("infotext", |
| | | S("Hydro %s Generator"):format("LV").." ("..production_level.."%)") |
| | | |
| | | if production_level > 0 and |
| | | minetest.get_node(pos).name == "technic:water_mill" then |
| | | technic.swap_node (pos, "technic:water_mill_active") |
| | | meta:set_int("LV_EU_supply", 0) |
| | | return |
| | | end |
| | | if production_level == 0 then |
| | | technic.swap_node(pos, "technic:water_mill") |
| | | end |
| | | end |
| | | |
| | | minetest.register_node("technic:water_mill", { |
| | | description = S("Hydro %s Generator"):format("LV"), |
| | | tiles = {"technic_water_mill_top.png", "technic_machine_bottom.png", |
| | | "technic_water_mill_side.png", "technic_water_mill_side.png", |
| | | "technic_water_mill_side.png", "technic_water_mill_side.png"}, |
| | | paramtype2 = "facedir", |
| | | groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_machine=1}, |
| | | legacy_facedir_simple = true, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | on_construct = function(pos) |
| | | local meta = minetest.get_meta(pos) |
| | | meta:set_string("infotext", S("Hydro %s Generator"):format("LV")) |
| | | meta:set_int("LV_EU_supply", 0) |
| | | end, |
| | | technic_run, |
| | | }) |
| | | |
| | | minetest.register_node("technic:water_mill_active", { |
| | | description = S("Hydro %s Generator"):format("LV"), |
| | | tiles = {"technic_water_mill_top_active.png", "technic_machine_bottom.png", |
| | | "technic_water_mill_side.png", "technic_water_mill_side.png", |
| | | "technic_water_mill_side.png", "technic_water_mill_side.png"}, |
| | | paramtype2 = "facedir", |
| | | groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_machine=1, not_in_creative_inventory=1}, |
| | | legacy_facedir_simple = true, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | drop = "technic:water_mill", |
| | | technic_run, |
| | | technic_disabled_machine_name = "technic:water_mill", |
| | | }) |
| | | |
| | | technic.register_machine("LV", "technic:water_mill", technic.producer) |
| | | technic.register_machine("LV", "technic:water_mill_active", technic.producer) |
| | |
| | | "label[0,0;"..S("%s Tool Workshop"):format("MV").."]".. |
| | | "list[current_player;main;0,5;8,4;]" |
| | | |
| | | local run = function(pos, node) |
| | | local meta = minetest.get_meta(pos) |
| | | local inv = meta:get_inventory() |
| | | local eu_input = meta:get_int("MV_EU_input") |
| | | local machine_name = S("%s Tool Workshop"):format("MV") |
| | | local machine_node = "technic:tool_workshop" |
| | | local demand = 5000 |
| | | |
| | | -- Setup meta data if it does not exist. |
| | | if not eu_input then |
| | | meta:set_int("MV_EU_demand", demand) |
| | | meta:set_int("MV_EU_input", 0) |
| | | return |
| | | end |
| | | |
| | | local repairable = false |
| | | local srcstack = inv:get_stack("src", 1) |
| | | if not srcstack:is_empty() then |
| | | local itemdef = minetest.registered_items[srcstack:get_name()] |
| | | if itemdef and |
| | | (not itemdef.wear_represents or |
| | | itemdef.wear_represents == "mechanical_wear") and |
| | | srcstack:get_wear() ~= 0 then |
| | | repairable = true |
| | | end |
| | | end |
| | | if not repairable then |
| | | meta:set_string("infotext", S("%s Idle"):format(machine_name)) |
| | | meta:set_int("MV_EU_demand", 0) |
| | | return |
| | | end |
| | | |
| | | if eu_input < demand then |
| | | meta:set_string("infotext", S("%s Unpowered"):format(machine_name)) |
| | | elseif eu_input >= demand then |
| | | meta:set_string("infotext", S("%s Active"):format(machine_name)) |
| | | srcstack:add_wear(-1000) |
| | | inv:set_stack("src", 1, srcstack) |
| | | end |
| | | meta:set_int("MV_EU_demand", demand) |
| | | end |
| | | |
| | | minetest.register_node("technic:tool_workshop", { |
| | | description = S("%s Tool Workshop"):format("MV"), |
| | | tiles = {"technic_workshop_top.png", "technic_machine_bottom.png", "technic_workshop_side.png", |
| | | "technic_workshop_side.png", "technic_workshop_side.png", "technic_workshop_side.png"}, |
| | | groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, |
| | | groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_machine=1}, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | on_construct = function(pos) |
| | | local meta = minetest.get_meta(pos) |
| | |
| | | can_dig = technic.machine_can_dig, |
| | | allow_metadata_inventory_put = technic.machine_inventory_put, |
| | | allow_metadata_inventory_take = technic.machine_inventory_take, |
| | | technic_run = run, |
| | | }) |
| | | |
| | | minetest.register_abm({ |
| | | nodenames = {"technic:tool_workshop"}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | local meta = minetest.get_meta(pos) |
| | | local inv = meta:get_inventory() |
| | | local eu_input = meta:get_int("MV_EU_input") |
| | | local machine_name = S("%s Tool Workshop"):format("MV") |
| | | local machine_node = "technic:tool_workshop" |
| | | local demand = 5000 |
| | | |
| | | -- Setup meta data if it does not exist. |
| | | if not eu_input then |
| | | meta:set_int("MV_EU_demand", demand) |
| | | meta:set_int("MV_EU_input", 0) |
| | | return |
| | | end |
| | | |
| | | -- Power off automatically if no longer connected to a switching station |
| | | technic.switching_station_timeout_count(pos, "MV") |
| | | |
| | | local repairable = false |
| | | local srcstack = inv:get_stack("src", 1) |
| | | if not srcstack:is_empty() then |
| | | local itemdef = minetest.registered_items[srcstack:get_name()] |
| | | if itemdef and |
| | | (not itemdef.wear_represents or |
| | | itemdef.wear_represents == "mechanical_wear") and |
| | | srcstack:get_wear() ~= 0 then |
| | | repairable = true |
| | | end |
| | | end |
| | | if not repairable then |
| | | meta:set_string("infotext", S("%s Idle"):format(machine_name)) |
| | | meta:set_int("MV_EU_demand", 0) |
| | | return |
| | | end |
| | | |
| | | if eu_input < demand then |
| | | meta:set_string("infotext", S("%s Unpowered"):format(machine_name)) |
| | | elseif eu_input >= demand then |
| | | meta:set_string("infotext", S("%s Active"):format(machine_name)) |
| | | srcstack:add_wear(-1000) |
| | | inv:set_stack("src", 1, srcstack) |
| | | end |
| | | meta:set_int("MV_EU_demand", demand) |
| | | end |
| | | }) |
| | | |
| | | technic.register_machine("MV", "technic:tool_workshop", technic.receiver) |
| | | |
| | |
| | | paramtype = "light", |
| | | }) |
| | | |
| | | local function check_wind_mill(pos) |
| | | if pos.y < 30 then |
| | | return false |
| | | end |
| | | for i = 1, 20 do |
| | | local node = minetest.get_node({x=pos.x, y=pos.y-i, z=pos.z}) |
| | | if node.name ~= "technic:wind_mill_frame" then |
| | | return false |
| | | end |
| | | end |
| | | return true |
| | | end |
| | | |
| | | local run = function(pos, node) |
| | | local meta = minetest.get_meta(pos) |
| | | local machine_name = S("Wind %s Generator"):format("MV") |
| | | local power = math.min(pos.y * 100, 5000) |
| | | |
| | | if not check_wind_mill(pos) then |
| | | meta:set_int("MV_EU_supply", 0) |
| | | meta:set_string("infotext", S("%s Improperly Placed"):format(machine_name)) |
| | | return |
| | | else |
| | | meta:set_int("MV_EU_supply", power) |
| | | end |
| | | |
| | | meta:set_string("infotext", machine_name.." ("..power.."EU)") |
| | | end |
| | | |
| | | minetest.register_node("technic:wind_mill", { |
| | | description = S("Wind %s Generator"):format("MV"), |
| | | tiles = {"technic_carbon_steel_block.png"}, |
| | | paramtype2 = "facedir", |
| | | groups = {cracky=1}, |
| | | groups = {cracky=1, technic_machine=1}, |
| | | sounds = default.node_sound_stone_defaults(), |
| | | drawtype = "nodebox", |
| | | paramtype = "light", |
| | |
| | | local meta = minetest.get_meta(pos) |
| | | meta:set_string("infotext", S("Wind %s Generator"):format("MV")) |
| | | meta:set_int("MV_EU_supply", 0) |
| | | end, |
| | | }) |
| | | |
| | | local function check_wind_mill(pos) |
| | | if pos.y < 30 then |
| | | return false |
| | | end |
| | | for i = 1, 20 do |
| | | local node = minetest.get_node({x=pos.x, y=pos.y-i, z=pos.z}) |
| | | if node.name ~= "technic:wind_mill_frame" then |
| | | return false |
| | | end |
| | | end |
| | | return true |
| | | end |
| | | |
| | | minetest.register_abm({ |
| | | nodenames = {"technic:wind_mill"}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | local meta = minetest.get_meta(pos) |
| | | local machine_name = S("Wind %s Generator"):format("MV") |
| | | local power = math.min(pos.y * 100, 5000) |
| | | |
| | | if not check_wind_mill(pos) then |
| | | meta:set_int("MV_EU_supply", 0) |
| | | meta:set_string("infotext", S("%s Improperly Placed"):format(machine_name)) |
| | | return |
| | | else |
| | | meta:set_int("MV_EU_supply", power) |
| | | end |
| | | |
| | | meta:set_string("infotext", machine_name.." ("..power.."EU)") |
| | | end |
| | | end, |
| | | technic_run = run, |
| | | }) |
| | | |
| | | technic.register_machine("MV", "technic:wind_mill", technic.producer) |
| | |
| | | "label[3.5,4;"..S("Upgrade Slots").."]" |
| | | 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("%s Battery Box: %d/%d"):format(tier, |
| | | current_charge, 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} |
| | | 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 |
| | |
| | | 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, |
| | | }) |
| | | end |
| | | |
| | | |
| | | minetest.register_abm({ |
| | | nodenames = {"technic:"..ltier.."_battery_box0", "technic:"..ltier.."_battery_box1", |
| | | "technic:"..ltier.."_battery_box2", "technic:"..ltier.."_battery_box3", |
| | | "technic:"..ltier.."_battery_box4", "technic:"..ltier.."_battery_box5", |
| | | "technic:"..ltier.."_battery_box6", "technic:"..ltier.."_battery_box7", |
| | | "technic:"..ltier.."_battery_box8"}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | local meta = minetest.get_meta(pos) |
| | | local eu_input = meta:get_int(tier.."_EU_input") |
| | | local current_charge = meta:get_int("internal_EU_charge") |
| | | |
| | | -- Power off automatically if no longer connected to a switching station |
| | | technic.switching_station_timeout_count(pos, tier) |
| | | |
| | | 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("%s Battery Box: %d/%d"):format(tier, |
| | | current_charge, max_charge) |
| | | if eu_input == 0 then |
| | | infotext = S("%s Idle"):format(infotext) |
| | | end |
| | | meta:set_string("infotext", infotext) |
| | | end |
| | | }) |
| | | |
| | | -- Register as a battery type |
| | | -- Battery type machines function as power reservoirs and can both receive and give back power |
| | |
| | | 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 |
| | |
| | | end |
| | | end |
| | | end) |
| | | |
| | | |
| | | function technic.get_cable_id(links) |
| | | return (links[6] * 1) + (links[5] * 2) |
| | |
| | | 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_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 tier = data.tier |
| | | local ltier = string.lower(tier) |
| | | |
| | | local groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2} |
| | | local active_groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, not_in_creative_inventory=1} |
| | | 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 |
| | |
| | | "list[current_player;main;0,5;8,4;]" |
| | | |
| | | 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 = 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") |
| | | return |
| | | end |
| | | meta:set_int("burn_time", fuel.time) |
| | | meta:set_int("burn_totaltime", fuel.time) |
| | | local stack = inv:get_stack("src", 1) |
| | | stack:take_item() |
| | | inv:set_stack("src", 1, stack) |
| | | 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;]") |
| | | end |
| | | |
| | | minetest.register_node("technic:"..ltier.."_generator", { |
| | | description = desc, |
| | | tiles = {"technic_"..ltier.."_generator_top.png", "technic_machine_bottom.png", |
| | |
| | | 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, |
| | | }) |
| | | |
| | | minetest.register_node("technic:"..ltier.."_generator_active", { |
| | |
| | | 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.."_generator", |
| | | }) |
| | | minetest.register_abm({ |
| | | nodenames = {"technic:"..ltier.."_generator", "technic:"..ltier.."_generator_active"}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | 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 = 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") |
| | | return |
| | | end |
| | | meta:set_int("burn_time", fuel.time) |
| | | meta:set_int("burn_totaltime", fuel.time) |
| | | local stack = inv:get_stack("src", 1) |
| | | stack:take_item() |
| | | inv:set_stack("src", 1, stack) |
| | | 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;]") |
| | | end |
| | | }) |
| | | |
| | | technic.register_machine(tier, "technic:"..ltier.."_generator", technic.producer) |
| | | technic.register_machine(tier, "technic:"..ltier.."_generator_active", technic.producer) |
| | | end |
| | |
| | | local tier = data.tier |
| | | local ltier = string.lower(tier) |
| | | |
| | | local groups = {cracky = 2} |
| | | local active_groups = {cracky = 2, not_in_creative_inventory = 1} |
| | | 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 |
| | |
| | | "label[1,4;"..S("Upgrade Slots").."]" |
| | | 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 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) |
| | | return |
| | | end |
| | | |
| | | if eu_input < machine_demand[EU_upgrade+1] then |
| | | -- Unpowered - go idle |
| | | technic.swap_node(pos, machine_node) |
| | | meta:set_string("infotext", S("%s Unpowered"):format(machine_desc_tier)) |
| | | elseif eu_input >= machine_demand[EU_upgrade+1] then |
| | | -- Powered |
| | | technic.swap_node(pos, machine_node.."_active") |
| | | meta:set_string("infotext", S("%s Active"):format(machine_desc_tier)) |
| | | |
| | | meta:set_int("src_time", meta:get_int("src_time") + 1) |
| | | if meta:get_int("src_time") >= result.time / data.speed then |
| | | meta:set_int("src_time", 0) |
| | | local result_stack = ItemStack(result.output) |
| | | if inv:room_for_item("dst", result_stack) then |
| | | inv:set_list("src", result.new_input) |
| | | inv:add_item("dst", result_stack) |
| | | end |
| | | end |
| | | end |
| | | meta:set_int(tier.."_EU_demand", machine_demand[EU_upgrade+1]) |
| | | end |
| | | |
| | | minetest.register_node("technic:"..ltier.."_"..machine_name, { |
| | | description = machine_desc:format(tier), |
| | | tiles = {"technic_"..ltier.."_"..machine_name.."_top.png", |
| | |
| | | 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, |
| | | }) |
| | | |
| | | minetest.register_node("technic:"..ltier.."_"..machine_name.."_active",{ |
| | |
| | | allow_metadata_inventory_put = technic.machine_inventory_put, |
| | | allow_metadata_inventory_take = technic.machine_inventory_take, |
| | | allow_metadata_inventory_move = technic.machine_inventory_move, |
| | | }) |
| | | |
| | | minetest.register_abm({ |
| | | nodenames = {"technic:"..ltier.."_"..machine_name, |
| | | "technic:"..ltier.."_"..machine_name.."_active"}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | 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 |
| | | |
| | | -- Power off automatically if no longer connected to a switching station |
| | | technic.switching_station_timeout_count(pos, tier) |
| | | |
| | | 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 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) |
| | | return |
| | | end |
| | | |
| | | if eu_input < machine_demand[EU_upgrade+1] then |
| | | -- Unpowered - go idle |
| | | technic.swap_node(pos, machine_node) |
| | | meta:set_string("infotext", S("%s Unpowered"):format(machine_desc_tier)) |
| | | elseif eu_input >= machine_demand[EU_upgrade+1] then |
| | | -- Powered |
| | | technic.swap_node(pos, machine_node.."_active") |
| | | meta:set_string("infotext", S("%s Active"):format(machine_desc_tier)) |
| | | |
| | | meta:set_int("src_time", meta:get_int("src_time") + 1) |
| | | if meta:get_int("src_time") >= result.time / data.speed then |
| | | meta:set_int("src_time", 0) |
| | | local result_stack = ItemStack(result.output) |
| | | if inv:room_for_item("dst", result_stack) then |
| | | inv:set_list("src", result.new_input) |
| | | inv:add_item("dst", result_stack) |
| | | end |
| | | end |
| | | end |
| | | meta:set_int(tier.."_EU_demand", machine_demand[EU_upgrade+1]) |
| | | end |
| | | technic_run = run, |
| | | technic_disabled_machine_name = "technic:"..ltier.."_"..machine_name, |
| | | }) |
| | | |
| | | technic.register_machine(tier, "technic:"..ltier.."_"..machine_name, technic.receiver) |
| | |
| | | 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 |
| | | 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("%s Active"):format(machine_name).." ("..charge_to_give.."EU)") |
| | | 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}, |
| | | 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, |
| | |
| | | local name = minetest.get_node(pos).name |
| | | meta:set_int(tier.."_EU_supply", 0) |
| | | end, |
| | | }) |
| | | |
| | | minetest.register_abm({ |
| | | nodenames = {"technic:solar_array_"..ltier}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | -- The action here is to make the solar array produce power |
| | | -- Power is dependent on the light level and the height above ground |
| | | -- 130m and above is optimal as it would be above cloud level. |
| | | -- Height gives 1/4 of the effect, light 3/4. Max. effect is 2880EU for the array. |
| | | -- 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 -10m |
| | | 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 |
| | | 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("%s Active"):format(machine_name).." ("..charge_to_give.."EU)") |
| | | 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, |
| | | technic_run = run, |
| | | }) |
| | | |
| | | technic.register_machine(tier, "technic:solar_array_"..ltier, technic.producer) |
| | |
| | | |
| | | local S = technic.getter |
| | | |
| | | local run = function(pos, node) |
| | | local demand = 10000 |
| | | local remain = 0.9 |
| | | -- Machine information |
| | | local machine_name = S("Supply Converter") |
| | | local meta = minetest.get_meta(pos) |
| | | |
| | | local pos_up = {x=pos.x, y=pos.y+1, z=pos.z} |
| | | local pos_down = {x=pos.x, y=pos.y-1, z=pos.z} |
| | | local name_up = minetest.get_node(pos_up).name |
| | | local name_down = minetest.get_node(pos_down).name |
| | | |
| | | local from = technic.get_cable_tier(name_up) |
| | | local to = technic.get_cable_tier(name_down) |
| | | |
| | | if from and to then |
| | | technic.switching_station_timeout_count(pos, from) |
| | | local input = meta:get_int(from.."_EU_input") |
| | | meta:set_int(from.."_EU_demand", demand) |
| | | meta:set_int(from.."_EU_supply", 0) |
| | | meta:set_int(to.."_EU_demand", 0) |
| | | meta:set_int(to.."_EU_supply", input * remain) |
| | | meta:set_string("infotext", machine_name |
| | | .." ("..input.." "..from.." -> " |
| | | ..input * remain.." "..to..")") |
| | | else |
| | | meta:set_string("infotext", S("%s Has Bad Cabling"):format(machine_name)) |
| | | return |
| | | end |
| | | |
| | | end |
| | | |
| | | minetest.register_node("technic:supply_converter", { |
| | | description = S("Supply Converter"), |
| | | tiles = {"technic_supply_converter_top.png", "technic_supply_converter_bottom.png", |
| | | "technic_supply_converter_side.png", "technic_supply_converter_side.png", |
| | | "technic_supply_converter_side.png", "technic_supply_converter_side.png"}, |
| | | groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2}, |
| | | groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_machine=1}, |
| | | sounds = default.node_sound_wood_defaults(), |
| | | drawtype = "nodebox", |
| | | paramtype = "light", |
| | |
| | | meta:set_string("infotext", S("Supply Converter")) |
| | | meta:set_float("active", false) |
| | | end, |
| | | technic_run = run, |
| | | }) |
| | | |
| | | minetest.register_craft({ |
| | |
| | | {'technic:mv_transformer', 'technic:machine_casing', 'technic:lv_transformer'}, |
| | | {'technic:mv_cable0', 'technic:rubber', 'technic:lv_cable0'}, |
| | | } |
| | | }) |
| | | |
| | | minetest.register_abm({ |
| | | nodenames = {"technic:supply_converter"}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | local demand = 10000 |
| | | local remain = 0.9 |
| | | -- Machine information |
| | | local machine_name = S("Supply Converter") |
| | | local meta = minetest.get_meta(pos) |
| | | |
| | | local pos_up = {x=pos.x, y=pos.y+1, z=pos.z} |
| | | local pos_down = {x=pos.x, y=pos.y-1, z=pos.z} |
| | | local name_up = minetest.get_node(pos_up).name |
| | | local name_down = minetest.get_node(pos_down).name |
| | | |
| | | local from = technic.get_cable_tier(name_up) |
| | | local to = technic.get_cable_tier(name_down) |
| | | |
| | | if from and to then |
| | | technic.switching_station_timeout_count(pos, from) |
| | | local input = meta:get_int(from.."_EU_input") |
| | | meta:set_int(from.."_EU_demand", demand) |
| | | meta:set_int(from.."_EU_supply", 0) |
| | | meta:set_int(to.."_EU_demand", 0) |
| | | meta:set_int(to.."_EU_supply", input * remain) |
| | | meta:set_string("infotext", machine_name |
| | | .." ("..input.." "..from.." -> " |
| | | ..input * remain.." "..to..")") |
| | | else |
| | | meta:set_string("infotext", S("%s Has Bad Cabling"):format(machine_name)) |
| | | return |
| | | end |
| | | |
| | | end, |
| | | }) |
| | | |
| | | for tier, machines in pairs(technic.machines) do |
| | |
| | | on_construct = function(pos) |
| | | local meta = minetest.get_meta(pos) |
| | | meta:set_string("infotext", S("Switching Station")) |
| | | meta:set_string("active", 1) |
| | | end, |
| | | }) |
| | | |
| | | -------------------------------------------------- |
| | | -- Functions to help the machines on the electrical network |
| | | -------------------------------------------------- |
| | | -- This one provides a timeout for a node in case it was disconnected from the network |
| | | -- A node must be touched by the station continuously in order to function |
| | | function technic.switching_station_timeout_count(pos, tier) |
| | | local meta = minetest.get_meta(pos) |
| | | local timeout = meta:get_int(tier.."_EU_timeout") |
| | | if timeout == 0 then |
| | | meta:set_int(tier.."_EU_input", 0) |
| | | else |
| | | meta:set_int(tier.."_EU_timeout", timeout - 1) |
| | | end |
| | | end |
| | | |
| | | -------------------------------------------------- |
| | | -- Functions to traverse the electrical network |
| | |
| | | return true |
| | | end |
| | | |
| | | local load_position = function(pos) |
| | | local vm = VoxelManip() |
| | | local MinEdge, MaxEdge = vm:read_from_map(pos, pos) |
| | | end |
| | | |
| | | -- Generic function to add found connected nodes to the right classification array |
| | | local check_node_subp = function(PR_nodes, RE_nodes, BA_nodes, all_nodes, pos, machines, tier) |
| | | local check_node_subp = function(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, pos, machines, tier, sw_pos) |
| | | load_position(pos) |
| | | local meta = minetest.get_meta(pos) |
| | | local name = minetest.get_node(pos).name |
| | | |
| | |
| | | elseif machines[name] == technic.producer_receiver then |
| | | add_new_cable_node(PR_nodes, pos) |
| | | add_new_cable_node(RE_nodes, pos) |
| | | elseif machines[name] == "SPECIAL" and |
| | | (pos.x ~= sw_pos.x or pos.y ~= sw_pos.y or pos.z ~= sw_pos.z) then |
| | | -- Another switching station -> disable it |
| | | add_new_cable_node(SP_nodes, pos) |
| | | meta:set_int("active", 0) |
| | | meta:set_string("active_pos", minetest.serialize(sw_pos)) |
| | | elseif machines[name] == technic.battery then |
| | | add_new_cable_node(BA_nodes, pos) |
| | | end |
| | |
| | | end |
| | | |
| | | -- Traverse a network given a list of machines and a cable type name |
| | | local traverse_network = function(PR_nodes, RE_nodes, BA_nodes, all_nodes, i, machines, tier) |
| | | local traverse_network = function(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, i, machines, tier, sw_pos) |
| | | local pos = all_nodes[i] |
| | | local positions = { |
| | | {x=pos.x+1, y=pos.y, z=pos.z}, |
| | |
| | | {x=pos.x, y=pos.y, z=pos.z-1}} |
| | | --print("ON") |
| | | for i, cur_pos in pairs(positions) do |
| | | check_node_subp(PR_nodes, RE_nodes, BA_nodes, all_nodes, cur_pos, machines, tier) |
| | | check_node_subp(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, cur_pos, machines, tier, sw_pos) |
| | | end |
| | | end |
| | | |
| | |
| | | end |
| | | end |
| | | |
| | | local get_network = function(pos1, tier) |
| | | local get_network = function(sw_pos, pos1, tier) |
| | | local cached = technic.networks[minetest.hash_node_position(pos1)] |
| | | if cached and cached.tier == tier then |
| | | touch_nodes(cached.PR_nodes, tier) |
| | | touch_nodes(cached.BA_nodes, tier) |
| | | touch_nodes(cached.RE_nodes, tier) |
| | | for _, pos in ipairs(cached.SP_nodes) do |
| | | local meta = minetest.get_meta(pos) |
| | | meta:set_int("active", 0) |
| | | meta:set_string("active_pos", minetest.serialize(sw_pos)) |
| | | end |
| | | return cached.PR_nodes, cached.BA_nodes, cached.RE_nodes |
| | | end |
| | | local i = 1 |
| | | local PR_nodes = {} |
| | | local BA_nodes = {} |
| | | local RE_nodes = {} |
| | | local SP_nodes = {} |
| | | local all_nodes = {pos1} |
| | | repeat |
| | | traverse_network(PR_nodes, RE_nodes, BA_nodes, all_nodes, |
| | | i, technic.machines[tier], tier) |
| | | traverse_network(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, |
| | | i, technic.machines[tier], tier, sw_pos) |
| | | i = i + 1 |
| | | until all_nodes[i] == nil |
| | | technic.networks[minetest.hash_node_position(pos1)] = {tier = tier, PR_nodes = PR_nodes, RE_nodes = RE_nodes, BA_nodes = BA_nodes} |
| | | technic.networks[minetest.hash_node_position(pos1)] = {tier = tier, PR_nodes = PR_nodes, |
| | | RE_nodes = RE_nodes, BA_nodes = BA_nodes, SP_nodes = SP_nodes} |
| | | return PR_nodes, BA_nodes, RE_nodes |
| | | end |
| | | |
| | |
| | | local RE_nodes |
| | | local machine_name = S("Switching Station") |
| | | |
| | | if meta:get_int("active") ~= 1 then |
| | | meta:set_int("active", 1) |
| | | local active_pos = minetest.deserialize(meta:get_string("active_pos")) |
| | | if active_pos then |
| | | local meta1 = minetest.get_meta(active_pos) |
| | | meta:set_string("infotext", S("%s (Slave)"):format(meta1:get_string("infotext"))) |
| | | end |
| | | return |
| | | end |
| | | |
| | | -- Which kind of network are we on: |
| | | pos1 = {x=pos.x, y=pos.y-1, z=pos.z} |
| | | |
| | | local name = minetest.get_node(pos1).name |
| | | local tier = technic.get_cable_tier(name) |
| | | if tier then |
| | | PR_nodes, BA_nodes, RE_nodes = get_network(pos1, tier) |
| | | PR_nodes, BA_nodes, RE_nodes = get_network(pos, pos1, tier) |
| | | else |
| | | --dprint("Not connected to a network") |
| | | meta:set_string("infotext", S("%s Has No Network"):format(machine_name)) |
| | | return |
| | | end |
| | | --dprint("nodes="..table.getn(all_nodes) |
| | | -- .." PR="..table.getn(PR_nodes) |
| | | -- .." BA="..table.getn(BA_nodes) |
| | | -- .." RE="..table.getn(RE_nodes)) |
| | | |
| | | -- Run all the nodes |
| | | local function run_nodes(list) |
| | | for _, pos2 in ipairs(list) do |
| | | load_position(pos2) |
| | | local node2 = minetest.get_node(pos2) |
| | | local nodedef |
| | | if node2 and node2.name then |
| | | nodedef = minetest.registered_nodes[node2.name] |
| | | end |
| | | if nodedef and nodedef.technic_run then |
| | | nodedef.technic_run(pos2, node2) |
| | | end |
| | | end |
| | | end |
| | | |
| | | run_nodes(PR_nodes) |
| | | run_nodes(RE_nodes) |
| | | run_nodes(BA_nodes) |
| | | |
| | | -- Strings for the meta data |
| | | local eu_demand_str = tier.."_EU_demand" |
| | |
| | | end, |
| | | }) |
| | | |
| | | -- Timeout ABM |
| | | -- Timeout for a node in case it was disconnected from the network |
| | | -- A node must be touched by the station continuously in order to function |
| | | local function switching_station_timeout_count(pos, tier) |
| | | local meta = minetest.get_meta(pos) |
| | | local timeout = meta:get_int(tier.."_EU_timeout") |
| | | if timeout <= 0 then |
| | | --meta:set_int(tier.."_EU_input", 0) -- Not needed anymore |
| | | return true |
| | | else |
| | | meta:set_int(tier.."_EU_timeout", timeout - 1) |
| | | return false |
| | | end |
| | | end |
| | | minetest.register_abm({ |
| | | nodenames = {"group:technic_machine"}, |
| | | interval = 1, |
| | | chance = 1, |
| | | action = function(pos, node, active_object_count, active_object_count_wider) |
| | | for tier, machines in pairs(technic.machines) do |
| | | if machines[node.name] and switching_station_timeout_count(pos, tier) then |
| | | local nodedef = minetest.registered_nodes[node.name] |
| | | if nodedef and nodedef.technic_disabled_machine_name then |
| | | print(nodedef.technic_disabled_machine_name) |
| | | node.name = nodedef.technic_disabled_machine_name |
| | | minetest.swap_node(pos, node) |
| | | end |
| | | if nodedef then |
| | | local meta = minetest.get_meta(pos) |
| | | meta:set_string("infotext", S("%s Has No Network"):format(nodedef.description)) |
| | | end |
| | | end |
| | | end |
| | | end, |
| | | }) |
| | | |
| | | for tier, machines in pairs(technic.machines) do |
| | | -- SPECIAL will not be traversed |
| | | technic.register_machine(tier, "technic:switching_station", "SPECIAL") |