Make switching station run all machines it is connected to, including those in unload...
authorNovatux <nathanael.courant@laposte.net>
Fri, 11 Jul 2014 09:00:46 +0000 (11:00 +0200)
committerNovatux <nathanael.courant@laposte.net>
Fri, 11 Jul 2014 09:00:46 +0000 (11:00 +0200)
18 files changed:
technic/locale/template.txt
technic/machines/HV/forcefield.lua
technic/machines/HV/nuclear_reactor.lua
technic/machines/HV/quarry.lua
technic/machines/LV/cnc.lua
technic/machines/LV/geothermal.lua
technic/machines/LV/music_player.lua
technic/machines/LV/solar_panel.lua
technic/machines/LV/water_mill.lua
technic/machines/MV/tool_workshop.lua
technic/machines/MV/wind_mill.lua
technic/machines/register/battery_box.lua
technic/machines/register/cables.lua
technic/machines/register/generator.lua
technic/machines/register/machine_base.lua
technic/machines/register/solar_array.lua
technic/machines/supply_converter.lua
technic/machines/switching_station.lua

index 28251f8d40588f7a3709b5b599c77b1897c95b9d..2735dbfc7b0e43cd7b1663846bce9a1c469e694e 100644 (file)
@@ -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 =
index c66ac7da87d66837d65e118ebcfa513d137ef108..beb8e45ed8bf41cf34cd25cfd7670b80d4ef2bdf 100644 (file)
@@ -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)
index 56dd7a40701ded01359c22f2637317630b52324b..580bd581829bc6e1eee842eef524ccd766858f3c 100644 (file)
@@ -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)
index a8c37bc0bb2df3024b7769528d47b76cdd17c9d3..628c44395cd9415039d57f761954833d3b06a9c2 100644 (file)
@@ -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)
index 5cf458f77f88abbabd2934102f69c8d336025bb3..2a89a7acee161e5b7a0afa11fb191b2a5859904e 100644 (file)
@@ -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)
 
index c253c6c20fa87771f96566e1be50435c107f8819..e88d3c9d13ae663850e6a3f512ba38ecf224f770 100644 (file)
@@ -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)
 
index 38c542ad342faa93c5532d87a2ff912e762d25bd..f51d29d0e8fe33901ad3a3c6a125610acc252819 100644 (file)
@@ -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)
index 6fc7c02cb9a679269b3c8e3a817245950035312b..959de529e2c822bf5e88172dc88b2c8bd88b1c49 100644 (file)
@@ -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)
 
index 2a8bb8d34a14d5bdd4c341e294af78be586229bc..d1584fa44e606938bac3143525de2cb88f76aa2f 100644 (file)
@@ -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)
 
index 0cf5e722f5f192ec6721725e398e895a489d34fe..10267180ad85b8446666da70cfd0052f8a8e87a0 100644 (file)
@@ -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)
 
index 1bc8e026206c1876e8eefe794dd77a0156fdf5dc..4d63ddc2d9721fcfa5deb4e30afcd36e59ab319e 100644 (file)
@@ -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)
index c8b3337ea16a4225c4af66b8bf93c2de7238b09d..4474dcf6dd76d9f1a43316f49a4577a25ddc980c 100644 (file)
@@ -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
index 4f7dcf5bbed8bfdb894b06be76509328590bd9a5..9ec1cfa17a6b1850ffaa8b1d49e5d17884265239 100644 (file)
@@ -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-
index 547ee2e175c443106dffe842062c3f5e09e98231..d481242e46ed847d1a648e2fde16dbb9256b4f6f 100644 (file)
@@ -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
index 289314bb40307a196dd0f40a5fcfc9534ce25ccc..83c8740dd7303259712c65342899fe2b4eff133f 100644 (file)
@@ -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)
index da1017f105a59ed28cc0d10ddd6b25bc1ae33c20..615219b08403cad36f5806624e91f50ae3fe4fac 100644 (file)
@@ -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)
index 4ea7854fb1498c30891c4329683c7b808641fe22..5cf999de90521afd07300e1170cb54231c137a24 100644 (file)
@@ -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
index f71664b00509748ca6c860aff0d233057fa9bb5e..8c31d5a3201ca39fa334a9f5b7b33df8e2f8c2fd 100644 (file)
@@ -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")