From: Novatux Date: Fri, 11 Jul 2014 09:00:46 +0000 (+0200) Subject: Make switching station run all machines it is connected to, including those in unload... X-Git-Url: http://81.2.79.47:8989/gitweb/?a=commitdiff_plain;h=563a4c071d5a14905a8ee729705ababf8d46d9f6;p=zefram%2Fminetest%2Ftechnic.git Make switching station run all machines it is connected to, including those in unloaded blocks. --- diff --git a/technic/locale/template.txt b/technic/locale/template.txt index 28251f8..2735dbf 100644 --- a/technic/locale/template.txt +++ b/technic/locale/template.txt @@ -43,6 +43,7 @@ Inventory move disallowed due to protection = %s Unpowered = %s Out Of Fuel = %s Has Bad Cabling = +%s (Slave) = %s Has No Network = %s Finished = Enable/Disable = diff --git a/technic/machines/HV/forcefield.lua b/technic/machines/HV/forcefield.lua index c66ac7d..beb8e45 100644 --- a/technic/machines/HV/forcefield.lua +++ b/technic/machines/HV/forcefield.lua @@ -103,10 +103,45 @@ local mesecons = { } } +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) @@ -117,13 +152,14 @@ minetest.register_node("technic:forcefield_emitter_off", { 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) @@ -135,7 +171,9 @@ minetest.register_node("technic:forcefield_emitter_on", { 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", { @@ -156,52 +194,11 @@ 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) diff --git a/technic/machines/HV/nuclear_reactor.lua b/technic/machines/HV/nuclear_reactor.lua index 56dd7a4..580bd58 100644 --- a/technic/machines/HV/nuclear_reactor.lua +++ b/technic/machines/HV/nuclear_reactor.lua @@ -48,60 +48,6 @@ local nodebox = { { -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: @@ -188,57 +134,109 @@ local function damage_nearby_players(pos) 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 - - 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 - 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) +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 - return end 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) + -- 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 - 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) diff --git a/technic/machines/HV/quarry.lua b/technic/machines/HV/quarry.lua index a8c37bc..628c443 100644 --- a/technic/machines/HV/quarry.lua +++ b/technic/machines/HV/quarry.lua @@ -126,13 +126,43 @@ local function send_items(items, pos, node) 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}, }, @@ -150,43 +180,7 @@ minetest.register_node("technic:quarry", { 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) diff --git a/technic/machines/LV/cnc.lua b/technic/machines/LV/cnc.lua index 5cf458f..2a89a7a 100644 --- a/technic/machines/LV/cnc.lua +++ b/technic/machines/LV/cnc.lua @@ -125,6 +125,44 @@ local function form_handler(pos, formname, fields, sender) 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"), @@ -139,7 +177,7 @@ minetest.register_node("technic:cnc", { {-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) @@ -155,6 +193,7 @@ minetest.register_node("technic:cnc", { 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 @@ -164,61 +203,17 @@ minetest.register_node("technic:cnc_active", { "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) diff --git a/technic/machines/LV/geothermal.lua b/technic/machines/LV/geothermal.lua index c253c6c..e88d3c9 100644 --- a/technic/machines/LV/geothermal.lua +++ b/technic/machines/LV/geothermal.lua @@ -20,19 +20,78 @@ minetest.register_craftitem("technic:geothermal", { 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", { @@ -44,71 +103,9 @@ 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) diff --git a/technic/machines/LV/music_player.lua b/technic/machines/LV/music_player.lua index 38c542a..f51d29d 100644 --- a/technic/machines/LV/music_player.lua +++ b/technic/machines/LV/music_player.lua @@ -36,11 +36,51 @@ local function play_track(pos, track) {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) @@ -95,54 +135,7 @@ minetest.register_node("technic:music_player", { 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) diff --git a/technic/machines/LV/solar_panel.lua b/technic/machines/LV/solar_panel.lua index 6fc7c02..959de52 100644 --- a/technic/machines/LV/solar_panel.lua +++ b/technic/machines/LV/solar_panel.lua @@ -4,10 +4,38 @@ 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, @@ -23,6 +51,7 @@ minetest.register_node("technic:solar_panel", { 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({ @@ -34,40 +63,5 @@ 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) diff --git a/technic/machines/LV/water_mill.lua b/technic/machines/LV/water_mill.lua index 2a8bb8d..d1584fa 100644 --- a/technic/machines/LV/water_mill.lua +++ b/technic/machines/LV/water_mill.lua @@ -15,20 +15,72 @@ minetest.register_craft({ } }) +local function check_node_around_mill(pos) + local node = minetest.get_node(pos) + if node.name == "default:water_flowing" or + node.name == "default:water_source" then + return true + end + return false +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 + + 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") + 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}, + 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, + end, + technic_run, }) minetest.register_node("technic:water_mill_active", { @@ -37,68 +89,14 @@ minetest.register_node("technic:water_mill_active", { "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}, + 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", }) -local function check_node_around_mill(pos) - local node = minetest.get_node(pos) - if node.name == "default:water_flowing" or - node.name == "default:water_source" then - return true - end - 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 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") - end - end -}) - technic.register_machine("LV", "technic:water_mill", technic.producer) technic.register_machine("LV", "technic:water_mill_active", technic.producer) diff --git a/technic/machines/MV/tool_workshop.lua b/technic/machines/MV/tool_workshop.lua index 0cf5e72..1026718 100644 --- a/technic/machines/MV/tool_workshop.lua +++ b/technic/machines/MV/tool_workshop.lua @@ -20,11 +20,53 @@ local workshop_formspec = "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) @@ -36,57 +78,8 @@ minetest.register_node("technic:tool_workshop", { 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) diff --git a/technic/machines/MV/wind_mill.lua b/technic/machines/MV/wind_mill.lua index 1bc8e02..4d63ddc 100644 --- a/technic/machines/MV/wind_mill.lua +++ b/technic/machines/MV/wind_mill.lua @@ -29,11 +29,40 @@ minetest.register_node("technic:wind_mill_frame", { 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", @@ -50,41 +79,8 @@ minetest.register_node("technic:wind_mill", { 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) diff --git a/technic/machines/register/battery_box.lua b/technic/machines/register/battery_box.lua index c8b3337..4474dcf 100644 --- a/technic/machines/register/battery_box.lua +++ b/technic/machines/register/battery_box.lua @@ -80,8 +80,78 @@ function technic.register_battery_box(data) "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 @@ -124,93 +194,10 @@ function technic.register_battery_box(data) 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 for i = 0, 8 do diff --git a/technic/machines/register/cables.lua b/technic/machines/register/cables.lua index 4f7dcf5..9ec1cfa 100644 --- a/technic/machines/register/cables.lua +++ b/technic/machines/register/cables.lua @@ -59,7 +59,6 @@ function technic.register_cable(tier, size) 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 @@ -79,7 +78,6 @@ minetest.register_on_dignode(function(pos, node) end end) - function technic.get_cable_id(links) return (links[6] * 1) + (links[5] * 2) + (links[4] * 4) + (links[3] * 8) @@ -146,7 +144,7 @@ function technic.gen_cable_nodebox(x1, y1, z1, x2, y2, z2, size) 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- diff --git a/technic/machines/register/generator.lua b/technic/machines/register/generator.lua index 547ee2e..d481242 100644 --- a/technic/machines/register/generator.lua +++ b/technic/machines/register/generator.lua @@ -18,8 +18,8 @@ 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} - 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 @@ -35,6 +35,54 @@ function technic.register_generator(data) "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", @@ -59,6 +107,7 @@ function technic.register_generator(data) 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", { @@ -76,58 +125,10 @@ function technic.register_generator(data) 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 diff --git a/technic/machines/register/machine_base.lua b/technic/machines/register/machine_base.lua index 289314b..83c8740 100644 --- a/technic/machines/register/machine_base.lua +++ b/technic/machines/register/machine_base.lua @@ -23,8 +23,8 @@ function technic.register_base_machine(data) 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 @@ -46,6 +46,61 @@ function technic.register_base_machine(data) "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", @@ -75,6 +130,7 @@ function technic.register_base_machine(data) 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",{ @@ -95,70 +151,8 @@ function technic.register_base_machine(data) 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) diff --git a/technic/machines/register/solar_array.lua b/technic/machines/register/solar_array.lua index da1017f..615219b 100644 --- a/technic/machines/register/solar_array.lua +++ b/technic/machines/register/solar_array.lua @@ -5,11 +5,42 @@ 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 + 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, @@ -24,45 +55,7 @@ function technic.register_solar_array(data) 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) diff --git a/technic/machines/supply_converter.lua b/technic/machines/supply_converter.lua index 4ea7854..5cf999d 100644 --- a/technic/machines/supply_converter.lua +++ b/technic/machines/supply_converter.lua @@ -9,12 +9,44 @@ 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", @@ -27,6 +59,7 @@ minetest.register_node("technic:supply_converter", { meta:set_string("infotext", S("Supply Converter")) meta:set_float("active", false) end, + technic_run = run, }) minetest.register_craft({ @@ -38,43 +71,6 @@ minetest.register_craft({ } }) -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 technic.register_machine(tier, "technic:supply_converter", technic.producer_receiver) end diff --git a/technic/machines/switching_station.lua b/technic/machines/switching_station.lua index f71664b..8c31d5a 100644 --- a/technic/machines/switching_station.lua +++ b/technic/machines/switching_station.lua @@ -57,24 +57,10 @@ minetest.register_node("technic:switching_station",{ 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 -------------------------------------------------- @@ -93,8 +79,14 @@ local add_new_cable_node = function(nodes, pos) 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 @@ -109,6 +101,12 @@ local check_node_subp = function(PR_nodes, RE_nodes, BA_nodes, all_nodes, pos, m 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 @@ -118,7 +116,7 @@ local check_node_subp = function(PR_nodes, RE_nodes, BA_nodes, all_nodes, pos, m 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}, @@ -129,7 +127,7 @@ local traverse_network = function(PR_nodes, RE_nodes, BA_nodes, all_nodes, i, ma {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 @@ -140,25 +138,32 @@ local touch_nodes = function(list, tier) 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 @@ -184,22 +189,47 @@ minetest.register_abm({ 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" @@ -306,6 +336,42 @@ minetest.register_abm({ 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")