Merge branch 'indev'
authorShadowNinja <noreply@gmail.com>
Mon, 8 Jul 2013 20:53:44 +0000 (16:53 -0400)
committerShadowNinja <noreply@gmail.com>
Mon, 8 Jul 2013 20:57:56 +0000 (16:57 -0400)
Conflicts:
technic/alloy_furnace.lua
technic/alloy_furnaces_commons.lua
technic/battery_box.lua
technic/battery_box_hv.lua
technic/battery_box_mv.lua
technic/chainsaw.lua
technic/cnc.lua
technic/cnc_nodes.lua
technic/electric_furnace.lua
technic/grinder.lua
technic/init.lua
technic/solar_array_hv.lua
technic/solar_array_lv.lua
technic/solar_array_mv.lua
technic/solar_panel.lua
unified_inventory/api.lua
unified_inventory/depends.txt

24 files changed:
1  2 
technic/alloy_furnace.lua
technic/alloy_furnaces_commons.lua
technic/battery_box.lua
technic/battery_box_hv.lua
technic/battery_box_mv.lua
technic/chainsaw.lua
technic/cnc.lua
technic/electric_furnace.lua
technic/generator.lua
technic/grinder.lua
technic/init.lua
technic/items.lua
technic/mining_drill.lua
technic/mining_laser_mk1.lua
technic/music_player.lua
technic/solar_array_hv.lua
technic/solar_array_lv.lua
technic/solar_array_mv.lua
technic/solar_panel.lua
technic/tool_workshop.lua
technic/water_mill.lua
technic_worldgen/nodes.lua
unified_inventory/api.lua
unified_inventory/depends.txt

index 947963ea56859969e71b7ec0ef2220775d2108db,d36b93cbda344d6642aee9125270876fa0635f90..fcdb9c04cd104e2f3ba8dd948a4bf3e712fdf036
@@@ -381,6 -362,5 +362,6 @@@ minetest.register_abm(
                local stack = inv:get_stack("fuel", 1)
                stack:take_item()
                inv:set_stack("fuel", 1, stack)
-       
- end,          
- })
+            end,
+      })
++
index 16821b926b5d61a81c56cf4def3ce71824c8f4f1,5a6e65b4234273e878f29b603c4a0b1b7592e747..15996d017d7112bd831b69e1042f5007985b803c
@@@ -1,32 -1,77 +1,77 @@@
- alloy_recipes ={}
+ -- Register alloy recipes
+ technic.alloy_recipes = {}
  
- registered_recipes_count=1
+ -- Register recipe in a table
+ technic.register_alloy_recipe = function(metal1, count1, metal2, count2, result, count3)
+                                  technic.alloy_recipes[metal1..metal2] = { src1_count = count1, src2_count = count2, dst_name = result, dst_count = count3 }
+                                  if unified_inventory then
+                                     unified_inventory.register_craft(
+                                        {
+                                           type = "alloy",
+                                           output = result.." "..count3,
+                                           items = {metal1.." "..count1,metal2.." "..count2},
+                                           width = 2,
+                                        })
+                                  end
+                               end
+ -- Retrieve a recipe given the input metals.
+ -- Input parameters are a table from a StackItem
+ technic.get_alloy_recipe = function(metal1, metal2)
+                             -- Check for both combinations of metals and for the right amount in both
+                             if technic.alloy_recipes[metal1.name..metal2.name]
+                                and metal1.count >= technic.alloy_recipes[metal1.name..metal2.name].src1_count
+                                and metal2.count >= technic.alloy_recipes[metal1.name..metal2.name].src2_count then
+                                return technic.alloy_recipes[metal1.name..metal2.name]
+                             elseif technic.alloy_recipes[metal2.name..metal1.name]
+                                and metal2.count >= technic.alloy_recipes[metal2.name..metal1.name].src1_count
+                                and metal1.count >= technic.alloy_recipes[metal2.name..metal1.name].src2_count then
+                                return technic.alloy_recipes[metal2.name..metal1.name]
+                             else
+                                return nil
+                             end
+                          end
+ technic.register_alloy_recipe("technic:copper_dust",  3, "technic:tin_dust",      1, "technic:bronze_dust",          4)
+ technic.register_alloy_recipe("moreores:copper_ingot",3, "moreores:tin_ingot",    1, "moreores:bronze_ingot",        4)
+ technic.register_alloy_recipe("technic:iron_dust",    3, "technic:chromium_dust", 1, "technic:stainless_steel_dust", 4)
+ technic.register_alloy_recipe("default:steel_ingot",  3, "technic:chromium_ingot",1, "technic:stainless_steel_ingot",4)
+ technic.register_alloy_recipe("technic:copper_dust",  2, "technic:zinc_dust",     1, "technic:brass_dust",           3)
+ technic.register_alloy_recipe("moreores:copper_ingot",2, "technic:zinc_ingot",    1, "technic:brass_ingot",          3)
+ technic.register_alloy_recipe("default:sand",         2, "technic:coal_dust",     2, "technic:silicon_wafer",        1)
+ technic.register_alloy_recipe("technic:silicon_wafer",1, "technic:gold_dust",     1, "technic:doped_silicon_wafer",  1)
+ --------------------------------------
+ -- LEGACY CODE - some other mods might depend on this - Register the same recipes as above...
+ --------------------------------------
+ alloy_recipes = {}
+ registered_recipes_count = 1
  
  function register_alloy_recipe (string1,count1, string2,count2, string3,count3)
- alloy_recipes[registered_recipes_count]={}
- alloy_recipes[registered_recipes_count].src1_name=string1
- alloy_recipes[registered_recipes_count].src1_count=count1
- alloy_recipes[registered_recipes_count].src2_name=string2
- alloy_recipes[registered_recipes_count].src2_count=count2
- alloy_recipes[registered_recipes_count].dst_name=string3
- alloy_recipes[registered_recipes_count].dst_count=count3
- registered_recipes_count=registered_recipes_count+1
- alloy_recipes[registered_recipes_count]={}
- alloy_recipes[registered_recipes_count].src1_name=string2
- alloy_recipes[registered_recipes_count].src1_count=count2
- alloy_recipes[registered_recipes_count].src2_name=string1
- alloy_recipes[registered_recipes_count].src2_count=count1
- alloy_recipes[registered_recipes_count].dst_name=string3
- alloy_recipes[registered_recipes_count].dst_count=count3
- registered_recipes_count=registered_recipes_count+1
- if unified_inventory then
-       unified_inventory.register_craft({
-       type = "alloy",
-       output = string3.." "..count3,
-       items = {string1.." "..count1,string2.." "..count2},
-       width = 2,
-       })
-       end
+    alloy_recipes[registered_recipes_count]={}
+    alloy_recipes[registered_recipes_count].src1_name=string1
+    alloy_recipes[registered_recipes_count].src1_count=count1
+    alloy_recipes[registered_recipes_count].src2_name=string2
+    alloy_recipes[registered_recipes_count].src2_count=count2
+    alloy_recipes[registered_recipes_count].dst_name=string3
+    alloy_recipes[registered_recipes_count].dst_count=count3
+    registered_recipes_count=registered_recipes_count+1
+    alloy_recipes[registered_recipes_count]={}
+    alloy_recipes[registered_recipes_count].src1_name=string2
+    alloy_recipes[registered_recipes_count].src1_count=count2
+    alloy_recipes[registered_recipes_count].src2_name=string1
+    alloy_recipes[registered_recipes_count].src2_count=count1
+    alloy_recipes[registered_recipes_count].dst_name=string3
+    alloy_recipes[registered_recipes_count].dst_count=count3
+    registered_recipes_count=registered_recipes_count+1
+    if unified_inventory then
+       unified_inventory.register_craft({
 -                                        type = "alloy",
 -                                        output = string3.." "..count3,
 -                                        items = {string1.." "..count1,string2.." "..count2},
 -                                        width = 2,
 -                                     })
++                type = "alloy",
++                output = string3.." "..count3,
++                items = {string1.." "..count1,string2.." "..count2},
++                width = 2,
++             })
+    end
  end
  
  register_alloy_recipe ("technic:copper_dust",3, "technic:tin_dust",1, "technic:bronze_dust",4)
@@@ -34,6 -79,6 +79,7 @@@ register_alloy_recipe ("default:copper_
  register_alloy_recipe ("technic:iron_dust",3, "technic:chromium_dust",1, "technic:stainless_steel_dust",4)
  register_alloy_recipe ("default:steel_ingot",3, "technic:chromium_ingot",1, "technic:stainless_steel_ingot",4)
  register_alloy_recipe ("technic:copper_dust",2, "technic:zinc_dust",1, "technic:brass_dust",3)
 -register_alloy_recipe ("moreores:copper_ingot",2, "technic:zinc_ingot",1, "technic:brass_ingot",3)
 +register_alloy_recipe ("default:copper_ingot",2, "technic:zinc_ingot",1, "technic:brass_ingot",3)
  register_alloy_recipe ("default:sand",2, "technic:coal_dust",2, "technic:silicon_wafer",1)
  register_alloy_recipe ("technic:silicon_wafer",1, "technic:gold_dust",1, "technic:doped_silicon_wafer",1)
++
index 4921c472838d575740f74e6a600de58eda2d4146,1f0740d847b67772755b613d5f232e6e488aa351..3a2272abb609eb0d7de16e1031a1883730c5eb32
- -- register LV machines here
- local LV_machines = {}
- function register_LV_machine(string1,string2)
-    LV_machines[string1] = string2
- end
- power_tools ={}
- registered_power_tools_count=0
- function register_power_tool (string1,max_charge)
-    registered_power_tools_count=registered_power_tools_count+1
-    power_tools[registered_power_tools_count]={}
-    power_tools[registered_power_tools_count].tool_name=string1
-    power_tools[registered_power_tools_count].max_charge=max_charge
- end
- register_power_tool ("technic:battery",10000)
- register_power_tool ("technic:red_energy_crystal",100000)
- register_power_tool ("technic:green_energy_crystal",250000)
- register_power_tool ("technic:blue_energy_crystal",500000)
- minetest.register_craft({
-                          output = 'technic:battery 1',
-                          recipe = {
-                             {'default:wood', 'default:copper_ingot', 'default:wood'},
-                             {'default:wood', 'moreores:tin_ingot', 'default:wood'},
-                             {'default:wood', 'default:copper_ingot', 'default:wood'},
-                          }
-                       })
+ -- LV Battery box and some other nodes...
+ technic.register_LV_power_tool("technic:battery",10000)
+ technic.register_MV_power_tool("technic:red_energy_crystal",100000)
+ technic.register_HV_power_tool("technic:green_energy_crystal",250000)
+ technic.register_HV_power_tool("technic:blue_energy_crystal",500000)
  
  minetest.register_craft({
-                          output = 'technic:battery_box 1',
 -                         output = 'technic:battery 1',
--                         recipe = {
-                             {'technic:battery', 'default:wood', 'technic:battery'},
-                             {'technic:battery', 'moreores:copper_ingot', 'technic:battery'},
-                             {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
 -                            {'default:wood', 'moreores:copper_ingot', 'default:wood'},
 -                            {'default:wood', 'moreores:tin_ingot', 'default:wood'},
 -                            {'default:wood', 'moreores:copper_ingot', 'default:wood'},
--                         }
--                      })
- minetest.register_tool("technic:battery",
-                      {description = "RE Battery",
-                       inventory_image = "technic_battery.png",
-                       tool_capabilities = {load=0,max_drop_level=0, groupcaps={fleshy={times={}, uses=10000, maxlevel=0}}}})
++      output = 'technic:battery 1',
++      recipe = {
++              {'default:wood', 'default:copper_ingot', 'default:wood'},
++              {'default:wood', 'moreores:tin_ingot',   'default:wood'},
++              {'default:wood', 'default:copper_ingot', 'default:wood'},
++      }
++})
 -minetest.register_tool("technic:battery",
 -                     {description = "RE Battery",
 -                      inventory_image = "technic_battery.png",
 -                      tool_capabilities = {load=0,max_drop_level=0, groupcaps={fleshy={times={}, uses=10000, maxlevel=0}}}})
++minetest.register_tool("technic:battery", {
++      description = "RE Battery",
++      inventory_image = "technic_battery.png",
++      tool_capabilities = {
++              load=0,
++              max_drop_level=0,
++              groupcaps={
++                      fleshy={times={}, uses=10000, maxlevel=0}
++              }
++      }
++})
+ --------------------------------------------
+ -- The Battery box
+ --------------------------------------------
 -minetest.register_craftitem(
 -   "technic:battery_box",
 -   {
 -      description = "Battery box",
 -      stack_max = 99,
 -   })
 +minetest.register_craftitem("technic:battery_box", {
-                              description = "Battery box",
-                              stack_max = 99,
-                           })
++      description = "Battery box",
++      stack_max = 99,
++})
  
- battery_box_formspec =
 -minetest.register_craft(
 -   {
 -      output = 'technic:battery_box 1',
 -      recipe = {
 -       {'technic:battery', 'default:wood', 'technic:battery'},
 -       {'technic:battery', 'moreores:copper_ingot', 'technic:battery'},
 -       {'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
 -      }
 -   })
++minetest.register_craft({
++      output = 'technic:battery_box 1',
++      recipe = {
++              {'technic:battery',     'default:wood',         'technic:battery'},
++              {'technic:battery',     'default:copper_ingot', 'technic:battery'},
++              {'default:steel_ingot', 'default:steel_ingot',  'default:steel_ingot'},
++      }
++})
+ local battery_box_formspec =
 -   "invsize[8,9;]"..
 -   "image[1,1;1,2;technic_power_meter_bg.png]"..
 -   "list[current_name;src;3,1;1,1;]"..
 -   "image[4,1;1,1;technic_battery_reload.png]"..
 -   "list[current_name;dst;5,1;1,1;]"..
 -   "label[0,0;Battery box]"..
 -   "label[3,0;Charge]"..
 -   "label[5,0;Discharge]"..
 -   "label[1,3;Power level]"..
 -   "list[current_player;main;0,5;8,4;]"
 +      "invsize[8,9;]"..
 +      "image[1,1;1,2;technic_power_meter_bg.png]"..
 +      "list[current_name;src;3,1;1,1;]"..
++      "image[4,1;1,1;technic_battery_reload.png]"..
 +      "list[current_name;dst;5,1;1,1;]"..
-       "label[0,0;LV Battery Box]"..
++      "label[0,0;Battery box]"..
 +      "label[3,0;Charge]"..
 +      "label[5,0;Discharge]"..
 +      "label[1,3;Power level]"..
-       "list[current_player;main;0,5;8,4;]"..
-       "background[-0.19,-0.25;8.4,9.75;ui_form_bg.png]"..
-       "background[0,0;8,4;ui_lv_battery_box.png]"..
-       "background[0,5;8,4;ui_main_inventory.png]"
- minetest.register_node(
-    "technic:battery_box", {
-       description = "LV Battery Box",
-       tiles = {"technic_battery_box_top.png", "technic_battery_box_bottom.png", "technic_battery_box_side0.png",
-              "technic_battery_box_side0.png", "technic_battery_box_side0.png", "technic_battery_box_side0.png"},
-       groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
-       sounds = default.node_sound_wood_defaults(),
-       drop="technic:battery_box",
-       on_construct = function(pos)
-                            if pos == nil then return end
-                            local meta = minetest.env:get_meta(pos)
-                            local inv = meta:get_inventory()
-                            meta:set_string("infotext", "Battery box")
-                            meta:set_float("technic_power_machine", 1)
-                            meta:set_string("formspec", battery_box_formspec)
-                            meta:set_float("internal_EU_buffer", 0)
-                            meta:set_float("internal_EU_buffer_size", 60000)
-                            inv:set_size("src", 1)
-                            inv:set_size("dst", 1)
-                         end,
-       can_dig = function(pos,player)
-                       if pos == nil then return end
-                       local meta = minetest.env:get_meta(pos);
-                       local inv = meta:get_inventory()
-                       if not inv:is_empty("dst") then
-                          return false
-                       elseif not inv:is_empty("src") then
-                          return false
-                       end
++      "list[current_player;main;0,5;8,4;]"
 -minetest.register_node(
 -   "technic:battery_box", {
 -      description = "LV Battery Box",
 -      tiles = {"technic_battery_box_top.png", "technic_battery_box_bottom.png", "technic_battery_box_side0.png",
 -             "technic_battery_box_side0.png", "technic_battery_box_side0.png", "technic_battery_box_side0.png"},
 -      groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
 -      sounds = default.node_sound_wood_defaults(),
 -      drop="technic:battery_box",
 -      on_construct = function(pos)
 -                           local meta = minetest.env:get_meta(pos)
 -                           local inv = meta:get_inventory()
 -                           meta:set_string("infotext", "Battery box")
 -                           meta:set_float("technic_power_machine", 1)
 -                           meta:set_string("formspec", battery_box_formspec)
 -                           meta:set_int("LV_EU_demand", 0) -- How much can this node charge
 -                           meta:set_int("LV_EU_supply", 0) -- How much can this node discharge
 -                           meta:set_int("LV_EU_input",  0) -- How much power is this machine getting.
 -                           meta:set_float("internal_EU_charge", 0)
 -                           inv:set_size("src", 1)
 -                           inv:set_size("dst", 1)
 -                        end,
 -      can_dig = function(pos,player)
 -                 local meta = minetest.env:get_meta(pos);
 -                 local inv = meta:get_inventory()
 -                 if not inv:is_empty("src") or not inv:is_empty("dst") then
 -                    minetest.chat_send_player(player:get_player_name(), "Machine cannot be removed because it is not empty");
 -                    return false
 -                 else
 -                    return true
 -                 end
 -              end,
 -   })
++minetest.register_node("technic:battery_box", {
++      description = "LV Battery Box",
++      tiles = {"technic_battery_box_top.png", "technic_battery_box_bottom.png",
++               "technic_battery_box_side0.png", "technic_battery_box_side0.png",
++               "technic_battery_box_side0.png", "technic_battery_box_side0.png"},
++      groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
++      sounds = default.node_sound_wood_defaults(),
++      drop="technic:battery_box",
++      on_construct = function(pos)
++              local meta = minetest.env:get_meta(pos)
++              local inv = meta:get_inventory()
++              meta:set_string("infotext", "Battery box")
++              meta:set_float("technic_power_machine", 1)
++              meta:set_string("formspec", battery_box_formspec)
++              meta:set_int("LV_EU_demand", 0) -- How much can this node charge
++              meta:set_int("LV_EU_supply", 0) -- How much can this node discharge
++              meta:set_int("LV_EU_input",  0) -- How much power is this machine getting.
++              meta:set_float("internal_EU_charge", 0)
++              inv:set_size("src", 1)
++              inv:set_size("dst", 1)
++      end,
++      can_dig = function(pos,player)
++              local meta = minetest.env:get_meta(pos);
++              local inv = meta:get_inventory()
++              if not inv:is_empty("src") or not inv:is_empty("dst") then
++                      minetest.chat_send_player(player:get_player_name(),
++                              "Machine cannot be removed because it is not empty");
++                      return false
++              else
 +                      return true
-                    end,
-    })
++              end
++      end,
++})
  
  
  for i=1,8,1 do
     minetest.register_node(
        "technic:battery_box"..i, {
         description = "LV Battery Box",
--       tiles = {"technic_battery_box_top.png", "technic_battery_box_bottom.png", "technic_battery_box_side0.png^technic_power_meter"..i..".png",
--                "technic_battery_box_side0.png^technic_power_meter"..i..".png", "technic_battery_box_side0.png^technic_power_meter"..i..".png", "technic_battery_box_side0.png^technic_power_meter"..i..".png"},
++       tiles = {"technic_battery_box_top.png", "technic_battery_box_bottom.png",
++                "technic_battery_box_side0.png^technic_power_meter"..i..".png",
++                "technic_battery_box_side0.png^technic_power_meter"..i..".png",
++                "technic_battery_box_side0.png^technic_power_meter"..i..".png",
++                "technic_battery_box_side0.png^technic_power_meter"..i..".png"},
         groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1},
         sounds = default.node_sound_wood_defaults(),
         drop="technic:battery_box",
@@@ -331,65 -254,7 +262,8 @@@ minetest.register_abm
  
  -- Register as a battery type
  -- Battery type machines function as power reservoirs and can both receive and give back power
- register_LV_machine("technic:battery_box","BA")
technic.register_LV_machine("technic:battery_box","BA")
  for i=1,8,1 do
-    register_LV_machine("technic:battery_box"..i,"BA")
- end
- function add_new_cable_node (LV_nodes,pos1)
-    if LV_nodes == nil then return true end
-    local i=1
-    repeat
-       if LV_nodes[i]==nil then break end
-       if pos1.x==LV_nodes[i].x and pos1.y==LV_nodes[i].y and pos1.z==LV_nodes[i].z then return false end
-       i=i+1
-    until false
-    LV_nodes[i]={}
-    LV_nodes[i].x=pos1.x
-    LV_nodes[i].y=pos1.y
-    LV_nodes[i].z=pos1.z
-    return true
+    technic.register_LV_machine("technic:battery_box"..i,"BA")
  end
- function check_LV_node(PR_nodes,RE_nodes,BA_nodes,LV_nodes,i)
-    local pos1={}
-    pos1.x=LV_nodes[i].x
-    pos1.y=LV_nodes[i].y
-    pos1.z=LV_nodes[i].z
-    pos1.x=pos1.x+1
-    check_LV_node_subp (PR_nodes,RE_nodes,BA_nodes,LV_nodes,pos1)
-    pos1.x=pos1.x-2
-    check_LV_node_subp (PR_nodes,RE_nodes,BA_nodes,LV_nodes,pos1)
-    pos1.x=pos1.x+1
-    pos1.y=pos1.y+1
-    check_LV_node_subp (PR_nodes,RE_nodes,BA_nodes,LV_nodes,pos1)
-    pos1.y=pos1.y-2
-    check_LV_node_subp (PR_nodes,RE_nodes,BA_nodes,LV_nodes,pos1)
-    pos1.y=pos1.y+1
-    pos1.z=pos1.z+1
-    check_LV_node_subp (PR_nodes,RE_nodes,BA_nodes,LV_nodes,pos1)
-    pos1.z=pos1.z-2
-    check_LV_node_subp (PR_nodes,RE_nodes,BA_nodes,LV_nodes,pos1)
-    pos1.z=pos1.z+1
-    return new_node_added
- end
- function check_LV_node_subp (PR_nodes,RE_nodes,BA_nodes,LV_nodes,pos1)
-    local meta = minetest.env:get_meta(pos1)
-    local name = minetest.env:get_node(pos1).name
-    if meta:get_float("cablelike")==1 then
-       add_new_cable_node(LV_nodes,pos1)
-    elseif LV_machines[name] then
-       --print(name.." is a "..LV_machines[name])
-       if     LV_machines[name] == "PR" then
-        add_new_cable_node(PR_nodes,pos1)
-       elseif LV_machines[name] == "RE" then
-        add_new_cable_node(RE_nodes,pos1)
-       elseif LV_machines[name] == "BA" then
-        add_new_cable_node(BA_nodes,pos1)
-       end
-    end
- end
 +
index 16aead992b243abbd2c38cc4e454e41eed5a6c4e,8cd0e2f8d0b05dddfc25ba058cbbdade14bff069..5f9f77205fc7ffe890590332dd01addf7dc53dab
@@@ -268,64 -224,7 +224,8 @@@ minetest.register_abm
  
  -- Register as a battery type
  -- Battery type machines function as power reservoirs and can both receive and give back power
- register_HV_machine("technic:hv_battery_box","BA")
technic.register_HV_machine("technic:hv_battery_box","BA")
  for i=1,8,1 do
-    register_HV_machine("technic:hv_battery_box"..i,"BA")
- end
- function add_new_HVcable_node (HV_nodes,pos1)
-    if HV_nodes == nil then return true end
-    local i=1
-    repeat
-       if HV_nodes[i]==nil then break end
-       if pos1.x==HV_nodes[i].x and pos1.y==HV_nodes[i].y and pos1.z==HV_nodes[i].z then return false end
-       i=i+1
-    until false
-    HV_nodes[i]={}
-    HV_nodes[i].x=pos1.x
-    HV_nodes[i].y=pos1.y
-    HV_nodes[i].z=pos1.z
-    return true
+    technic.register_HV_machine("technic:hv_battery_box"..i,"BA")
  end
- function check_HV_node(PR_nodes,RE_nodes,BA_nodes,HV_nodes,i)
-    local pos1={}
-    pos1.x=HV_nodes[i].x
-    pos1.y=HV_nodes[i].y
-    pos1.z=HV_nodes[i].z
-    pos1.x=pos1.x+1
-    check_HV_node_subp (PR_nodes,RE_nodes,BA_nodes,HV_nodes,pos1)
-    pos1.x=pos1.x-2
-    check_HV_node_subp (PR_nodes,RE_nodes,BA_nodes,HV_nodes,pos1)
-    pos1.x=pos1.x+1
-    pos1.y=pos1.y+1
-    check_HV_node_subp (PR_nodes,RE_nodes,BA_nodes,HV_nodes,pos1)
-    pos1.y=pos1.y-2
-    check_HV_node_subp (PR_nodes,RE_nodes,BA_nodes,HV_nodes,pos1)
-    pos1.y=pos1.y+1
-    pos1.z=pos1.z+1
-    check_HV_node_subp (PR_nodes,RE_nodes,BA_nodes,HV_nodes,pos1)
-    pos1.z=pos1.z-2
-    check_HV_node_subp (PR_nodes,RE_nodes,BA_nodes,HV_nodes,pos1)
-    pos1.z=pos1.z+1
- end
- function check_HV_node_subp (PR_nodes,RE_nodes,BA_nodes,HV_nodes,pos1)
-    local meta = minetest.env:get_meta(pos1)
-    local name = minetest.env:get_node(pos1).name
-    if meta:get_float("hv_cablelike")==1 then
-       add_new_HVcable_node(HV_nodes,pos1)
-    elseif HV_machines[name] then
-       --print(name.." is a "..HV_machines[name])
-       if     HV_machines[name] == "PR" then
-        add_new_HVcable_node(PR_nodes,pos1)
-       elseif HV_machines[name] == "RE" then
-        add_new_HVcable_node(RE_nodes,pos1)
-       elseif HV_machines[name] == "BA" then
-        add_new_HVcable_node(BA_nodes,pos1)
-       end
-    end
- end
 +
index 86c445c79fc26a748654a1962f9de3864d3e20da,dfedc05c65ca240b64d84a6f625978cbb7ee3c10..a4136396965e9e410707ddea42d7d60c79445631
@@@ -275,64 -227,7 +227,8 @@@ minetest.register_abm
  
  -- Register as a battery type
  -- Battery type machines function as power reservoirs and can both receive and give back power
- register_MV_machine("technic:mv_battery_box","BA")
technic.register_MV_machine("technic:mv_battery_box","BA")
  for i=1,8,1 do
-    register_MV_machine("technic:mv_battery_box"..i,"BA")
+    technic.register_MV_machine("technic:mv_battery_box"..i,"BA")
  end
- function add_new_MVcable_node (MV_nodes,pos1)
-    if MV_nodes == nil then return true end
-    local i=1
-    repeat
-       if MV_nodes[i]==nil then break end
-       if pos1.x==MV_nodes[i].x and pos1.y==MV_nodes[i].y and pos1.z==MV_nodes[i].z then return false end
-       i=i+1
-    until false
-    MV_nodes[i]={}
-    MV_nodes[i].x=pos1.x
-    MV_nodes[i].y=pos1.y
-    MV_nodes[i].z=pos1.z
-    return true
- end
- function check_MV_node(PR_nodes,RE_nodes,BA_nodes,MV_nodes,i)
-    local pos1={}
-    pos1.x=MV_nodes[i].x
-    pos1.y=MV_nodes[i].y
-    pos1.z=MV_nodes[i].z
-    pos1.x=pos1.x+1
-    check_MV_node_subp(PR_nodes,RE_nodes,BA_nodes,MV_nodes,pos1)
-    pos1.x=pos1.x-2
-    check_MV_node_subp(PR_nodes,RE_nodes,BA_nodes,MV_nodes,pos1)
-    pos1.x=pos1.x+1
-    pos1.y=pos1.y+1
-    check_MV_node_subp(PR_nodes,RE_nodes,BA_nodes,MV_nodes,pos1)
-    pos1.y=pos1.y-2
-    check_MV_node_subp(PR_nodes,RE_nodes,BA_nodes,MV_nodes,pos1)
-    pos1.y=pos1.y+1
-    pos1.z=pos1.z+1
-    check_MV_node_subp(PR_nodes,RE_nodes,BA_nodes,MV_nodes,pos1)
-    pos1.z=pos1.z-2
-    check_MV_node_subp(PR_nodes,RE_nodes,BA_nodes,MV_nodes,pos1)
-    pos1.z=pos1.z+1
- end
- function check_MV_node_subp (PR_nodes,RE_nodes,BA_nodes,MV_nodes,pos1)
-    local meta = minetest.env:get_meta(pos1)
-    local name = minetest.env:get_node(pos1).name
-    if meta:get_float("mv_cablelike")==1 then
-       add_new_MVcable_node(MV_nodes,pos1)
-    elseif MV_machines[name] then
-       --print(name.." is a "..MV_machines[name])
-       if     MV_machines[name] == "PR" then
-        add_new_MVcable_node(PR_nodes,pos1)
-       elseif MV_machines[name] == "RE" then
-        add_new_MVcable_node(RE_nodes,pos1)
-       elseif MV_machines[name] == "BA" then
-        add_new_MVcable_node(BA_nodes,pos1)
-       end
-    end
- end
 +
index 5c10d7ce03de4357fdc35dec1b843452c38c947b,5c5de4ce7c6796d33f29ff0abeea160e7fb534c5..ae0c30c914163bca0b187f7054a89b1d09862bb6
@@@ -33,8 -33,8 +33,8 @@@ minetest.register_craft(
          output = 'technic:chainsaw',
          recipe = {
                  {'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot', 'technic:battery'},
--                {'technic:stainless_steel_ingot', 'technic:motor', 'technic:battery'},
-                 {'','','default:copper_ingot'},
 -                {'','','moreores:copper_ingot'},
++                {'technic:stainless_steel_ingot', 'technic:motor',                 'technic:battery'},
++                {'',                               '',                             'default:copper_ingot'},
          }
  })
  
@@@ -266,3 -266,3 +266,4 @@@ recursive_dig = function(pos, remaining
          -- Nothing sawed down
          return remaining_charge
  end
++
diff --cc technic/cnc.lua
index 49765026eaeabd0a3eddd5eb7137601b1303fb9b,ad3dc6792571438aa0593204f1903bd01fff9ea7..8e215ae4422317bf116fd38ab41af713601c760d
@@@ -6,6 -6,6 +6,8 @@@
  --   beyond what is available in the panel today.
  --   I could imagine some form of API allowing modders to come with their own node
  --   box definitions and easily stuff it in the this machine for production.
++
++
  local shape = {}
  local onesize_products = {
     slope                    = 2,
@@@ -221,92 -189,103 +191,103 @@@ minetest.register_node("technic:cnc_act
  
  -- 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.env:get_meta(pos)
-                 local charge= meta:get_float("internal_EU_buffer")
-                 local max_charge= meta:get_float("internal_EU_buffer_size")
-                 local cnc_cost=350
-                 
-                 local load = math.floor((charge/max_charge)*100)
-                 meta:set_string("formspec", cnc_formspec..
-                                 "image[0,1;1,2;technic_power_meter_bg.png^[lowpart:"..
-                                 (load)..":technic_power_meter_fg.png]"
-                           )
-                 
-                 local inv = meta:get_inventory()
-                 local srclist = inv:get_list("src")
-                 if inv:is_empty("src") then
-                    meta:set_float("cnc_on",0)
-                    meta:set_string("cnc_product", "") -- Reset the program
-                 end 
-                 
-                 if (meta:get_float("cnc_on") == 1) then
-                    if charge>=cnc_cost then
-                       charge=charge-cnc_cost;
-                       meta:set_float("internal_EU_buffer",charge)
-                       meta:set_float("src_time", meta:get_float("src_time") + 1)
-                       if meta:get_float("src_time") >= meta:get_float("cnc_time") then
-                          local product = meta:get_string("cnc_product")
-                          if inv:room_for_item("dst",product) then
-                             -- CNC does the transformation
-                             ------------------------------
-                             if minetest.registered_nodes[product] ~= nil then
-                                inv:add_item("dst",product .. " " .. meta:get_float("cnc_multiplier"))
-                                srcstack = inv:get_stack("src", 1)
-                                srcstack:take_item()
-                                inv:set_stack("src",1,srcstack)
-                                if inv:is_empty("src") then
-                                   meta:set_float("cnc_on",0)
-                                   meta:set_string("cnc_product", "") -- Reset the program
- --                                print("cnc product reset")
-                                end 
-                             else
-                                minetest.chat_send_player(meta:get_string("cnc_user"), "CNC machine does not know how to handle this material. Please remove it.");
-                             end
-                          else
-                             minetest.chat_send_player(meta:get_string("cnc_user"), "CNC inventory full!")
-                          end
-                          meta:set_float("src_time", 0)
-                       end
-                    end
-                 end
+    { nodenames = {"technic:cnc","technic:cnc_active"},
+      interval = 1,
+      chance   = 1,
+      action = function(pos, node, active_object_count, active_object_count_wider)
+                local meta         = minetest.env:get_meta(pos)
+                local eu_input     = meta:get_int("LV_EU_input")
+                local state        = meta:get_int("state")
+                local next_state   = state
  
-                 if (meta:get_float("cnc_on")==0) then
-                    if not inv:is_empty("src") then
-                       local product = meta:get_string("cnc_product")
-                       if minetest.registered_nodes[product] ~= nil then 
-                          meta:set_float("cnc_on",1)
-                          hacky_swap_node(pos,"technic:cnc_active")
-                          meta:set_string("infotext", "CNC Machine Active")
-                          cnc_time=3
-                          meta:set_float("cnc_time",cnc_time)
-                          meta:set_float("src_time", 0)
-                          return
-                       end
-                    else 
-                       hacky_swap_node(pos,"technic:cnc")
-                       meta:set_string("infotext", "CNC Machine Inactive")
-                    end
-                 end
-              end
-    }) 
+                -- Machine information
+                local machine_name         = "CNC"
+                local machine_node         = "technic:cnc"
+                local machine_state_demand = { 50, 450 }
+                        
+                -- Setup meta data if it does not exist. state is used as an indicator of this
+                if state == 0 then
+                   meta:set_int("state", 1)
+                   meta:set_int("LV_EU_demand", machine_state_demand[1])
+                   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")
+                        
+                -- State machine
+                if eu_input == 0 then
+                   -- Unpowered - go idle
+                   hacky_swap_node(pos, machine_node)
+                   meta:set_string("infotext", machine_name.." Unpowered")
+                   next_state = 1
+                elseif eu_input == machine_state_demand[state] then
+                   -- Powered - do the state specific actions
+                           
+                   local inv   = meta:get_inventory()
+                   local empty = inv:is_empty("src")
  
- register_LV_machine ("technic:cnc","RE")
- register_LV_machine ("technic:cnc_active","RE")
- -------------------------
+                   if state == 1 then
+                      hacky_swap_node(pos, machine_node)
+                      meta:set_string("infotext", machine_name.." Idle")
+                      local result = meta:get_string("cnc_product")
+                      if not empty and minetest.registered_nodes[result] ~= nil and inv:room_for_item("dst",result) then
+                         next_state = 2
+                      else
+                         meta:set_string("cnc_product", "") -- Reset the program
+                      end
+                      --minetest.chat_send_player(meta:get_string("cnc_user"), "CNC machine does not know how to handle this material. Please remove it.");
+                   elseif state == 2 then
+                      hacky_swap_node(pos, machine_node.."_active")
+                      meta:set_string("infotext", machine_name.." Active")
+                      if empty then
+                         next_state = 1
+                      else
+                         meta:set_int("src_time", meta:get_int("src_time") + 1)
+                         if meta:get_int("src_time") >= 3 then -- 3 ticks per output
+                            local result = meta:get_string("cnc_product")
+                            -- check if there's room for output in "dst" list
+                            if inv:room_for_item("dst",result) then
+                               -- CNC does the transformation
+                               ------------------------------
+                               meta:set_int("src_time", 0)
+                               -- take stuff from "src" list
+                               srcstack = inv:get_stack("src", 1)
+                               srcstack:take_item()
+                               inv:set_stack("src", 1, srcstack)
+                               -- Put result in "dst" list
+                               inv:add_item("dst",result .. " " .. meta:get_int("cnc_multiplier"))
+                            else
+                               next_state = 1
+                            end
+                         end
+                      end
+                   end
+                end
+                -- Change state?
+                if next_state ~= state then
+                   meta:set_int("LV_EU_demand", machine_state_demand[next_state])
+                   meta:set_int("state", next_state)
+                end
+             end
+   }) 
  
 --------------------------
+ technic.register_LV_machine ("technic:cnc","RE")
+ technic.register_LV_machine ("technic:cnc_active","RE")
++-------------------------
  -- CNC Machine Recipe
  -------------------------
  minetest.register_craft({
--                         output = 'technic:cnc',
--                         recipe = {
--                            {'default:glass',              'technic:diamond_drill_head', 'default:glass'},
--                            {'technic:control_logic_unit', 'technic:motor',              'default:steel_ingot'},
--                            {'default:steel_ingot',        'default:copper_ingot',       'default:steel_ingot'},         
--                         },
--                      })
---------------------------
++      output = 'technic:cnc',
++      recipe = {
++              {'default:glass',              'technic:diamond_drill_head', 'default:glass'},
++              {'technic:control_logic_unit', 'technic:motor',              'default:steel_ingot'},
++              {'default:steel_ingot',        'default:copper_ingot',       'default:steel_ingot'},         
++      },
++})
++
index df35fbe559ad704c5da456d76a43fac48d495427,4f2f11cc6bd0af2907a5310a36c0f4e5977f2071..0c1f43ebfe3ed9cc1ba959e6dc58ee912b6d5f8b
- minetest.register_craft({
-       output = 'technic:electric_furnace',
-       recipe = {
-               {'default:cobble', 'default:cobble', 'default:cobble'},
-               {'default:cobble', '', 'default:cobble'},
-               {'default:steel_ingot', 'moreores:copper_ingot', 'default:steel_ingot'},
-       }
- })
+ -- LV Electric Furnace
+ -- This is a faster version of the stone furnace which runs on EUs
  
+ -- FIXME: kpoppel I'd like to introduce an induction heating element here also
+ minetest.register_craft(
+    {output = 'technic:electric_furnace',
+     recipe = {
+        {'default:cobble',      'default:cobble',        'default:cobble'},
+        {'default:cobble',      '',                      'default:cobble'},
+        {'default:steel_ingot', 'moreores:copper_ingot', 'default:steel_ingot'},
+     }
+  })
  
- electric_furnace_formspec =
-       "invsize[8,9;]"..
-       "image[1,1;1,2;technic_power_meter_bg.png]"..
-       "list[current_name;src;3,1;1,1;]"..
-       "list[current_name;dst;5,1;2,2;]"..
-       "list[current_player;main;0,5;8,4;]"..
-       "label[0,0;LV Electric Furnace]"..
-       "label[1,3;Power level]"..
-       "background[-0.19,-0.25;8.4,9.75;ui_form_bg.png]"..
-       "background[0,0;8,4;ui_lv_electric_furnace.png]"..
-       "background[0,5;8,4;ui_main_inventory.png]"
-       
- minetest.register_node("technic:electric_furnace", {
-       description = "LV Electric Furnace",
-       tiles = {"technic_electric_furnace_top.png", "technic_electric_furnace_bottom.png", "technic_electric_furnace_side.png",
-               "technic_electric_furnace_side.png", "technic_electric_furnace_side.png", "technic_electric_furnace_front.png"},
-       paramtype2 = "facedir",
-       groups = {cracky=2},
-       legacy_facedir_simple = true,
-       sounds = default.node_sound_stone_defaults(),
-       technic_power_machine=1,
-       internal_EU_buffer=0;
-       interal_EU_buffer_size=2000;
-       on_construct = function(pos)
-               local meta = minetest.env:get_meta(pos)
-               meta:set_float("technic_power_machine", 1)
-               meta:set_string("formspec", electric_furnace_formspec)
-               meta:set_string("infotext", "Electric Furnace")
-               local inv = meta:get_inventory()
-               inv:set_size("src", 1)
-               inv:set_size("dst", 4)
-               local EU_used  = 0
-               local furnace_is_cookin = 0
-               local cooked = nil
-               meta:set_float("internal_EU_buffer",0)
-               meta:set_float("internal_EU_buffer_size",2000)
+ local electric_furnace_formspec =
+    "invsize[8,9;]"..
+    "list[current_name;src;3,1;1,1;]"..
+    "list[current_name;dst;5,1;2,2;]"..
+    "list[current_player;main;0,5;8,4;]"..
+    "label[0,0;Electric Furnace]"..
+    "label[1,3;Power level]"
  
-       end,
-       can_dig = function(pos,player)
-               local meta = minetest.env:get_meta(pos);
-               local inv = meta:get_inventory()
-               if not inv:is_empty("dst") then
-                       return false
-               elseif not inv:is_empty("src") then
-                       return false
-               end
-               return true
-       end,
- })
+ minetest.register_node(
+    "technic:electric_furnace",
+    {description = "Electric furnace",
+     tiles = {"technic_electric_furnace_top.png", "technic_electric_furnace_bottom.png", "technic_electric_furnace_side.png",
+            "technic_electric_furnace_side.png", "technic_electric_furnace_side.png", "technic_electric_furnace_front.png"},
+     paramtype2 = "facedir",
+     groups = {cracky=2},
+     legacy_facedir_simple = true,
+     sounds = default.node_sound_stone_defaults(),
+     on_construct = function(pos)
+                     local meta = minetest.env:get_meta(pos)
+                     meta:set_string("infotext", "Electric Furnace")
+                     meta:set_float("technic_power_machine", 1)
+                     meta:set_string("formspec", electric_furnace_formspec)
+                     local inv = meta:get_inventory()
+                     inv:set_size("src", 1)
+                     inv:set_size("dst", 4)
+                  end,
+     can_dig = function(pos,player)
+                local meta = minetest.env:get_meta(pos);
+                local inv = meta:get_inventory()
+                if not inv:is_empty("src") or not inv:is_empty("dst") then
+                   minetest.chat_send_player(player:get_player_name(), "Machine cannot be removed because it is not empty");
+                   return false
+                else
+                   return true
+                end
+             end,
+  })
  
- minetest.register_node("technic:electric_furnace_active", {
-       description = "LV Electric Furnace",
-       tiles = {"technic_electric_furnace_top.png", "technic_electric_furnace_bottom.png", "technic_electric_furnace_side.png",
-               "technic_electric_furnace_side.png", "technic_electric_furnace_side.png", "technic_electric_furnace_front_active.png"},
-       paramtype2 = "facedir",
-       light_source = 8,
-       drop = "technic:electric_furnace",
-       groups = {cracky=2, not_in_creative_inventory=1},
-       legacy_facedir_simple = true,
-       sounds = default.node_sound_stone_defaults(),
-       internal_EU_buffer=0;
-       interal_EU_buffer_size=2000;
-       technic_power_machine=1,
-       on_construct = function(pos)
-               local meta = minetest.env:get_meta(pos)
-               meta:set_float("technic_power_machine", 1)
-               meta:set_string("formspec", electric_furnace_formspec)
-               meta:set_string("infotext", "LV Electric Furnace");
-               local inv = meta:get_inventory()
-               inv:set_size("src", 1)
-               inv:set_size("dst", 4)
-               local EU_used  = 0
-               local furnace_is_cookin = 0
-               local cooked = nil
-       end,
-       can_dig = function(pos,player)
-               local meta = minetest.env:get_meta(pos);
-               local inv = meta:get_inventory()
-               if not inv:is_empty("dst") then
-                       return false
-               elseif not inv:is_empty("src") then
-                       return false
-               end
-               return true
-       end,
- })
+ minetest.register_node(
+    "technic:electric_furnace_active",
+    {description = "Electric Furnace",
+     tiles = {"technic_electric_furnace_top.png", "technic_electric_furnace_bottom.png", "technic_electric_furnace_side.png",
+            "technic_electric_furnace_side.png", "technic_electric_furnace_side.png", "technic_electric_furnace_front_active.png"},
+     paramtype2 = "facedir",
+     light_source = 8,
+     drop = "technic:electric_furnace",
+     groups = {cracky=2, not_in_creative_inventory=1},
+     legacy_facedir_simple = true,
+     sounds = default.node_sound_stone_defaults(),
+     can_dig = function(pos,player)
+                local meta = minetest.env:get_meta(pos);
+                local inv = meta:get_inventory()
+                if not inv:is_empty("src") or not inv:is_empty("dst") then
+                   minetest.chat_send_player(player:get_player_name(), "Machine cannot be removed because it is not empty");
+                   return false
+                else
+                   return true
+                end
+             end,
+  })
  
- minetest.register_abm({
-       nodenames = {"technic:electric_furnace","technic:electric_furnace_active"},
-       interval = 1,
-       chance = 1,
-       
-       action = function(pos, node, active_object_count, active_object_count_wider)
+ minetest.register_abm(
+    { nodenames = {"technic:electric_furnace","technic:electric_furnace_active"},
+      interval = 1,
+      chance   = 1,
+      action = function(pos, node, active_object_count, active_object_count_wider)
+                local meta         = minetest.env:get_meta(pos)
+                local eu_input     = meta:get_int("LV_EU_input")
+                local state        = meta:get_int("state")
+                local next_state   = state
  
-               local meta = minetest.env:get_meta(pos)
-               internal_EU_buffer=meta:get_float("internal_EU_buffer")
-               internal_EU_buffer_size=meta:get_float("internal_EU_buffer_size")
-               local load = math.floor(internal_EU_buffer/internal_EU_buffer_size * 100)
-               meta:set_string("formspec",
-                               electric_furnace_formspec..
-                               "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:"..
-                                       (load)..":technic_power_meter_fg.png]")
+                -- Machine information
+                local machine_name         = "Electric furnace"
+                local machine_node         = "technic:electric_furnace"
+                local machine_state_demand = { 50, 1000 }
+                        
+                -- Setup meta data if it does not exist. state is used as an indicator of this
+                if state == 0 then
+                   meta:set_int("state", 1)
+                   meta:set_int("LV_EU_demand", machine_state_demand[1])
+                   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")
+                        
+                -- State machine
+                if eu_input == 0 then
+                   -- Unpowered - go idle
+                   hacky_swap_node(pos, machine_node)
+                   meta:set_string("infotext", machine_name.." Unpowered")
+                   next_state = 1
+                elseif eu_input == machine_state_demand[state] then
+                   -- Powered - do the state specific actions
+                           
+                   -- Execute always if powered logic
+                   local inv    = meta:get_inventory()
+                   local empty  = inv:is_empty("src")
  
-               local inv = meta:get_inventory()
-               
-               local furnace_is_cookin = meta:get_float("furnace_is_cookin")
-               
-               
-               local srclist = inv:get_list("src")
-               local cooked=nil 
+                   if state == 1 then
+                      hacky_swap_node(pos, machine_node)
+                      meta:set_string("infotext", machine_name.." Idle")
  
-               if srclist then
-                cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
-               end
-               
-               
-               if (furnace_is_cookin == 1) then
-                       if internal_EU_buffer>=150 then
-                       internal_EU_buffer=internal_EU_buffer-150;
-                       meta:set_float("internal_EU_buffer",internal_EU_buffer)
-                       meta:set_float("src_time", meta:get_float("src_time") + 3)
-                       if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
-                               -- check if there's room for output in "dst" list
-                               if inv:room_for_item("dst",cooked.item) then
-                                       -- Put result in "dst" list
-                                       inv:add_item("dst", cooked.item)
-                                       -- take stuff from "src" list
-                                       srcstack = inv:get_stack("src", 1)
-                                       srcstack:take_item()
-                                       inv:set_stack("src", 1, srcstack)
-                               else
-                                       print("Furnace inventory full!")
-                               end
-                               meta:set_string("src_time", 0)
-                       end
-                       end
-               end
+                      local result = minetest.get_craft_result({method = "cooking", width = 1, items = inv:get_list("src")})
+                      if not empty and result and inv:room_for_item("dst",result) then
+                         next_state = 2
+                      end
  
+                   elseif state == 2 then
+                      hacky_swap_node(pos, machine_node.."_active")
+                      meta:set_string("infotext", machine_name.." Active")
  
-               if srclist then
-                       cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
-                       if cooked.time>0 then 
-                       hacky_swap_node(pos,"technic:electric_furnace_active")
-                       meta:set_string("infotext","Furnace active")
-                       meta:set_string("furnace_is_cookin",1)
-                       meta:set_string("src_time", 0)
-                       return
-                       end
+                      if empty then
+                         next_state = 1
+                      else
+                         meta:set_int("src_time", meta:get_int("src_time") + 3) -- Cooking time 3x
+                         local result = minetest.get_craft_result({method = "cooking", width = 1, items = inv:get_list("src")})
+                         if result and result.item and meta:get_int("src_time") >= result.time then
+                            -- check if there's room for output in "dst" list
+                            meta:set_int("src_time", 0)
+                            if inv:room_for_item("dst",result.item) then
+                               -- take stuff from "src" list
+                               srcstack = inv:get_stack("src", 1)
+                               srcstack:take_item()
+                               inv:set_stack("src", 1, srcstack)
+                               -- Put result in "dst" list
+                               inv:add_item("dst", result.item)
+                            else
+                               -- all full: go idle
+                               next_state = 1
+                            end
+                         end
+                      end
+                   end
+                end
+                -- Change state?
+                if next_state ~= state then
+                   meta:set_int("LV_EU_demand", machine_state_demand[next_state])
+                   meta:set_int("state", next_state)
+                end
+             end,
+   })
  
-               end
+ technic.register_LV_machine ("technic:electric_furnace","RE")
+ technic.register_LV_machine ("technic:electric_furnace_active","RE")
 +
-                               hacky_swap_node(pos,"technic:electric_furnace")
-                               meta:set_string("infotext","Furnace inactive")
-                               meta:set_string("furnace_is_cookin",0)
-                               meta:set_string("src_time", 0)
- end,
- })
- register_LV_machine ("technic:electric_furnace","RE")
- register_LV_machine ("technic:electric_furnace_active","RE")
Simple merge
index ff37aa0ca3184aca8308330fc11a6a01fccf4e1d,ba7871004c2aac526dfb6ee376d3152d4cb34691..baef12dc06594066d45f44a2edac551c78f1c2b0
- grinder_recipes ={}
- registered_grinder_recipes_count=1
- function register_grinder_recipe (string1,string2)
- grinder_recipes[registered_grinder_recipes_count]={}
- grinder_recipes[registered_grinder_recipes_count].src_name=string1
- grinder_recipes[registered_grinder_recipes_count].dst_name=string2
- registered_grinder_recipes_count=registered_grinder_recipes_count+1
- if unified_inventory then
-       unified_inventory.register_craft({
-       type = "grinding",
-       output = string2,
-       items = {string1},
-       width = 0,
-       })
-       end
- end
- register_grinder_recipe("default:stone","default:sand")
- register_grinder_recipe("default:cobble","default:gravel")
- register_grinder_recipe("default:gravel","default:dirt")
- register_grinder_recipe("default:desert_stone","default:desert_sand")
- register_grinder_recipe("default:iron_lump","technic:iron_dust 2")
- register_grinder_recipe("default:steel_ingot","technic:iron_dust 1")
- register_grinder_recipe("default:coal_lump","technic:coal_dust 2")
- register_grinder_recipe("default:copper_lump","technic:copper_dust 2")
- register_grinder_recipe("default:copper_ingot","technic:copper_dust 1")
- register_grinder_recipe("default:gold_lump","technic:gold_dust 2")
- register_grinder_recipe("default:gold_ingot","technic:gold_dust 1")
- --register_grinder_recipe("default:bronze_ingot","technic:bronze_dust 1")  -- Dust does not exist yet
- register_grinder_recipe("moreores:tin_lump","technic:tin_dust 2")
- register_grinder_recipe("moreores:tin_ingot","technic:tin_dust 1")
- register_grinder_recipe("moreores:silver_lump","technic:silver_dust 2")
- register_grinder_recipe("moreores:silver_ingot","technic:silver_dust 1")
- register_grinder_recipe("moreores:mithril_lump","technic:mithril_dust 2")
- register_grinder_recipe("moreores:mithril_ingot","technic:mithril_dust 1")
- register_grinder_recipe("technic:chromium_lump","technic:chromium_dust 2")
- register_grinder_recipe("technic:chromium_ingot","technic:chromium_dust 1")
- register_grinder_recipe("technic:stainless_steel_ingot","stainless_steel_dust 1")
- register_grinder_recipe("technic:brass_ingot","technic:brass_dust 1")
- register_grinder_recipe("homedecor:brass_ingot","technic:brass_dust 1") 
- register_grinder_recipe("technic:zinc_lump","technic:zinc_dust 2")
- register_grinder_recipe("technic:zinc_ingot","technic:zinc_dust 1")
- register_grinder_recipe("technic:coal_dust","dye:black 2")
- register_grinder_recipe("default:cactus","dye:green 2")
- register_grinder_recipe("default:dry_shrub","dye:brown 2")
- register_grinder_recipe("flowers:flower_geranium","dye:blue 2")
- register_grinder_recipe("flowers:flower_dandelion_white","dye:white 2")
- register_grinder_recipe("flowers:flower_dandelion_yellow","dye:yellow 2")
- register_grinder_recipe("flowers:flower_tulip","dye:orange 2")
- register_grinder_recipe("flowers:flower_rose","dye:red 2")
- register_grinder_recipe("flowers:flower_viola","dye:violet 2")
+ technic.grinder_recipes ={}
+ technic.register_grinder_recipe = function(src, dst)
+                                  technic.grinder_recipes[src] = dst
+                                  if unified_inventory then
+                                     unified_inventory.register_craft(
+                                        {
+                                           type = "grinding",
+                                           output = dst,
+                                           items = {src},
+                                           width = 0,
+                                        })
+                                  end
+                               end
+ -- Receive an ItemStack of result by an ItemStack input
+ technic.get_grinder_recipe = function(itemstack)
+                               local src_item  = itemstack:to_table()
+                               if src_item == nil then
+                                  return nil
+                               end
+                               local item_name = src_item["name"]
+                               if technic.grinder_recipes[item_name] then
+                                  return ItemStack(technic.grinder_recipes[item_name])
+                               else
+                                  return nil
+                               end
+                            end
+ technic.register_grinder_recipe("default:stone","default:sand")
+ technic.register_grinder_recipe("default:cobble","default:gravel")
+ technic.register_grinder_recipe("default:gravel","default:dirt")
+ technic.register_grinder_recipe("default:desert_stone","default:desert_sand")
+ technic.register_grinder_recipe("default:iron_lump","technic:iron_dust 2")
+ technic.register_grinder_recipe("default:steel_ingot","technic:iron_dust 1")
+ technic.register_grinder_recipe("default:coal_lump","technic:coal_dust 2")
+ technic.register_grinder_recipe("default:copper_lump","technic:copper_dust 2")
+ technic.register_grinder_recipe("default:copper_ingot","technic:copper_dust 1")
+ technic.register_grinder_recipe("default:gold_lump","technic:gold_dust 2")
+ technic.register_grinder_recipe("default:gold_ingot","technic:gold_dust 1")
+ --technic.register_grinder_recipe("default:bronze_ingot","technic:bronze_dust 1")  -- Dust does not exist yet
+ --technic.register_grinder_recipe("home_decor:brass_ingot","technic:brass_dust 1") -- needs check for the mod
+ technic.register_grinder_recipe("moreores:tin_lump","technic:tin_dust 2")
+ technic.register_grinder_recipe("moreores:tin_ingot","technic:tin_dust 1")
+ technic.register_grinder_recipe("moreores:silver_lump","technic:silver_dust 2")
+ technic.register_grinder_recipe("moreores:silver_ingot","technic:silver_dust 1")
+ technic.register_grinder_recipe("moreores:mithril_lump","technic:mithril_dust 2")
+ technic.register_grinder_recipe("moreores:mithril_ingot","technic:mithril_dust 1")
+ technic.register_grinder_recipe("technic:chromium_lump","technic:chromium_dust 2")
+ technic.register_grinder_recipe("technic:chromium_ingot","technic:chromium_dust 1")
+ technic.register_grinder_recipe("technic:stainless_steel_ingot","stainless_steel_dust 1")
+ technic.register_grinder_recipe("technic:brass_ingot","technic:brass_dust 1")
+ technic.register_grinder_recipe("technic:zinc_lump","technic:zinc_dust 2")
+ technic.register_grinder_recipe("technic:zinc_ingot","technic:zinc_dust 1")
  
  minetest.register_craftitem( "technic:coal_dust", {
-       description = "Coal Dust",
-       inventory_image = "technic_coal_dust.png",
-       on_place_on_ground = minetest.craftitem_place_item,
-       })
+                               description = "Coal Dust",
+                               inventory_image = "technic_coal_dust.png",
+                               on_place_on_ground = minetest.craftitem_place_item,
+                            })
  
  minetest.register_craftitem( "technic:iron_dust", {
-       description = "Iron Dust",
-       inventory_image = "technic_iron_dust.png",
-       on_place_on_ground = minetest.craftitem_place_item,
-       })
+                               description = "Iron Dust",
+                               inventory_image = "technic_iron_dust.png",
+                               on_place_on_ground = minetest.craftitem_place_item,
+                            })
  
  minetest.register_craft({
-     type = "cooking",
-     output = "default:steel_ingot",
-     recipe = "technic:iron_dust",
- })
+                          type = "cooking",
+                          output = "default:steel_ingot",
+                          recipe = "technic:iron_dust",
                      })
  
  minetest.register_craftitem( "technic:copper_dust", {
-       description = "Copper Dust",
-       inventory_image = "technic_copper_dust.png",
-       on_place_on_ground = minetest.craftitem_place_item,
-       })
+                               description = "Copper Dust",
+                               inventory_image = "technic_copper_dust.png",
+                               on_place_on_ground = minetest.craftitem_place_item,
+                            })
  minetest.register_craft({
-     type = "cooking",
-     output = "default:copper_ingot",
-     recipe = "technic:copper_dust",
- })
+                          type = "cooking",
+                          output = "moreores:copper_ingot",
+                          recipe = "technic:copper_dust",
                      })
  
  minetest.register_craftitem( "technic:tin_dust", {
-       description = "Tin Dust",
-       inventory_image = "technic_tin_dust.png",
-       on_place_on_ground = minetest.craftitem_place_item,
-       })
+                               description = "Tin Dust",
+                               inventory_image = "technic_tin_dust.png",
+                               on_place_on_ground = minetest.craftitem_place_item,
+                            })
  minetest.register_craft({
-     type = "cooking",
-     output = "moreores:tin_ingot",
-     recipe = "technic:tin_dust",
- })
+                          type = "cooking",
+                          output = "moreores:tin_ingot",
+                          recipe = "technic:tin_dust",
                      })
  
  minetest.register_craftitem( "technic:silver_dust", {
-       description = "Silver Dust",
-       inventory_image = "technic_silver_dust.png",
-       on_place_on_ground = minetest.craftitem_place_item,
-       })
+                               description = "Silver Dust",
+                               inventory_image = "technic_silver_dust.png",
+                               on_place_on_ground = minetest.craftitem_place_item,
+                            })
  minetest.register_craft({
-     type = "cooking",
-     output = "moreores:silver_ingot",
-     recipe = "technic:silver_dust",
- })
+                          type = "cooking",
+                          output = "moreores:silver_ingot",
+                          recipe = "technic:silver_dust",
                      })
  
  minetest.register_craftitem( "technic:gold_dust", {
-       description = "Gold Dust",
-       inventory_image = "technic_gold_dust.png",
-       on_place_on_ground = minetest.craftitem_place_item,
-       })
+                               description = "Gold Dust",
+                               inventory_image = "technic_gold_dust.png",
+                               on_place_on_ground = minetest.craftitem_place_item,
+                            })
  minetest.register_craft({
-     type = "cooking",
-     output = "default:gold_ingot",
-     recipe = "technic:gold_dust",
- })
+                          type = "cooking",
 -                         output = "moreores:gold_ingot",
++                         output = "default:gold_ingot",
+                          recipe = "technic:gold_dust",
+                       })
  
  minetest.register_craftitem( "technic:mithril_dust", {
-       description = "Mithril Dust",
-       inventory_image = "technic_mithril_dust.png",
-       on_place_on_ground = minetest.craftitem_place_item,
-       })
+                               description = "Mithril Dust",
+                               inventory_image = "technic_mithril_dust.png",
+                               on_place_on_ground = minetest.craftitem_place_item,
+                            })
  minetest.register_craft({
-     type = "cooking",
-     output = "moreores:mithril_ingot",
-     recipe = "technic:mithril_dust",
- })
+                          type = "cooking",
+                          output = "moreores:mithril_ingot",
+                          recipe = "technic:mithril_dust",
                      })
  
  minetest.register_craftitem( "technic:chromium_dust", {
-       description = "Chromium Dust",
-       inventory_image = "technic_chromium_dust.png",
-       on_place_on_ground = minetest.craftitem_place_item,
-       })
+                               description = "Chromium Dust",
+                               inventory_image = "technic_chromium_dust.png",
+                               on_place_on_ground = minetest.craftitem_place_item,
+                            })
  minetest.register_craft({
-     type = "cooking",
-     output = "technic:chromium_ingot",
-     recipe = "technic:chromium_dust",
- })
+                          type = "cooking",
+                          output = "technic:chromium_ingot",
+                          recipe = "technic:chromium_dust",
                      })
  
  minetest.register_craftitem( "technic:bronze_dust", {
-       description = "Bronze Dust",
-       inventory_image = "technic_bronze_dust.png",
-       on_place_on_ground = minetest.craftitem_place_item,
-       })
+                               description = "Bronze Dust",
+                               inventory_image = "technic_bronze_dust.png",
+                               on_place_on_ground = minetest.craftitem_place_item,
+                            })
  minetest.register_craft({
-     type = "cooking",
-     output = "default:bronze_ingot",
-     recipe = "technic:bronze_dust",
- })
+                          type = "cooking",
 -                         output = "moreores:bronze_ingot",
++                         output = "default:bronze_ingot",
+                          recipe = "technic:bronze_dust",
+                       })
  
  minetest.register_craftitem( "technic:brass_dust", {
-       description = "Brass Dust",
-       inventory_image = "technic_brass_dust.png",
-       on_place_on_ground = minetest.craftitem_place_item,
-       })
+                               description = "Brass Dust",
+                               inventory_image = "technic_brass_dust.png",
+                               on_place_on_ground = minetest.craftitem_place_item,
+                            })
  minetest.register_craft({
-     type = "cooking",
-     output = "technic:brass_ingot",
-     recipe = "technic:brass_dust",
- })
+                          type = "cooking",
+                          output = "technic:brass_ingot",
+                          recipe = "technic:brass_dust",
                      })
  
  minetest.register_craftitem( "technic:stainless_steel_dust", {
-       description = "Stainless Steel Dust",
-       inventory_image = "technic_stainless_steel_dust.png",
-       })
+                               description = "Stainless Steel Dust",
+                               inventory_image = "technic_stainless_steel_dust.png",
+                            })
  
  minetest.register_craft({
-     type = "cooking",
-     output = "technic:stainless_steel_ingot",
-     recipe = "technic:stainless_steel_dust",
- })
+                          type = "cooking",
+                          output = "technic:stainless_steel_ingot",
+                          recipe = "technic:stainless_steel_dust",
                      })
  
  minetest.register_craftitem( "technic:zinc_dust", {
-       description = "Zinc Dust",
-       inventory_image = "technic_zinc_dust.png",
-       })
+                               description = "Zinc Dust",
+                               inventory_image = "technic_zinc_dust.png",
+                            })
  
  minetest.register_craft({
-     type = "cooking",
-     output = "technic:zinc_ingot",
-     recipe = "technic:zinc_dust",
- })
+                          type = "cooking",
+                          output = "technic:zinc_ingot",
+                          recipe = "technic:zinc_dust",
                      })
  
  minetest.register_alias("grinder", "technic:grinder")
  minetest.register_craft({
-       output = 'technic:grinder',
-       recipe = {
-               {'default:desert_stone', 'default:desert_stone', 'default:desert_stone'},
-               {'default:desert_stone', 'default:diamond', 'default:desert_stone'},
-               {'default:stone', 'default:copper_ingot', 'default:stone'},
-       }
- })
+                          output = 'technic:grinder',
+                          recipe = {
+                             {'default:desert_stone', 'default:desert_stone', 'default:desert_stone'},
+                             {'default:desert_stone', 'default:diamond', 'default:desert_stone'},
+                             {'default:stone', 'moreores:copper_ingot', 'default:stone'},
+                          }
                      })
  
  minetest.register_craftitem("technic:grinder", {
-       description = "Grinder",
-       stack_max = 99,
- })
- grinder_formspec =
-       "invsize[8,9;]"..
-       "image[1,1;1,2;technic_power_meter_bg.png]"..
-       "label[0,0;LV Grinder]"..
-       "label[1,3;Power level]"..
-       "list[current_name;src;3,1;1,1;]"..
-       "list[current_name;dst;5,1;2,2;]"..
-       "list[current_player;main;0,5;8,4;]"..
-       "background[-0.19,-0.25;8.4,9.75;ui_form_bg.png]"..
-       "background[0,0;8,4;ui_lv_grinder.png]"..
-       "background[0,5;8,4;ui_main_inventory.png]"
- minetest.register_node("technic:grinder", {
-       description = "LV Grinder",
-       tiles = {"technic_lv_grinder_top.png", "technic_lv_grinder_bottom.png", "technic_lv_grinder_side.png",
-               "technic_lv_grinder_side.png", "technic_lv_grinder_side.png", "technic_lv_grinder_front.png"},
-       paramtype2 = "facedir",
-       groups = {cracky=2},
-       legacy_facedir_simple = true,
-       sounds = default.node_sound_wood_defaults(),
-       technic_power_machine=1,
-       internal_EU_buffer=0;
-       internal_EU_buffer_size=5000;
-       grind_time=0;
-       grinded = nil;
-       src_time = 0;
-       on_construct = function(pos)
-               local meta = minetest.env:get_meta(pos)
-               meta:set_string("infotext", "Grinder")
-               meta:set_float("technic_power_machine", 1)
-               meta:set_float("internal_EU_buffer", 0)
-               meta:set_float("internal_EU_buffer_size", 5000)
-               meta:set_string("formspec", grinder_formspec)
-               meta:set_float("grind_time", 0)
-               local inv = meta:get_inventory()
-               inv:set_size("src", 1)
-               inv:set_size("dst", 4)
+                              description = "Grinder",
+                              stack_max = 99,
+                           })
+ local grinder_formspec =
+    "invsize[8,9;]"..
+    "label[0,0;Grinder]"..
+    "list[current_name;src;3,1;1,1;]"..
+    "list[current_name;dst;5,1;2,2;]"..
+    "list[current_player;main;0,5;8,4;]"
+ minetest.register_node(
+    "technic:grinder",
+    {
+       description = "Grinder",
+       tiles = {"technic_lv_grinder_top.png", "technic_lv_grinder_bottom.png", "technic_lv_grinder_side.png",
+              "technic_lv_grinder_side.png", "technic_lv_grinder_side.png", "technic_lv_grinder_front.png"},
+       paramtype2 = "facedir",
+       groups = {cracky=2},
+       legacy_facedir_simple = true,
+       sounds = default.node_sound_wood_defaults(),
+       on_construct = function(pos)
+                       local meta = minetest.env:get_meta(pos)
+                       meta:set_string("infotext", "Grinder")
+                       meta:set_float("technic_power_machine", 1)
+                       meta:set_string("formspec", grinder_formspec)
+                       local inv = meta:get_inventory()
+                       inv:set_size("src", 1)
+                       inv:set_size("dst", 4)
+                    end,
+       can_dig = function(pos,player)
+                  local meta = minetest.env:get_meta(pos);
+                  local inv = meta:get_inventory()
+                  if not inv:is_empty("src") or not inv:is_empty("dst") then
+                     minetest.chat_send_player(player:get_player_name(), "Machine cannot be removed because it is not empty");
+                     return false
+                  else
+                     return true
+                  end
                end,
-       can_dig = function(pos,player)
-               local meta = minetest.env:get_meta(pos);
-               local inv = meta:get_inventory()
-               if not inv:is_empty("src") then
-                       return false
-               end
-               if not inv:is_empty("dst") then
-                       return false
-               end
-               return true
+    })
+ minetest.register_node(
+    "technic:grinder_active",
+    {
+       description = "Grinder",
+       tiles = {"technic_lv_grinder_top.png", "technic_lv_grinder_bottom.png", "technic_lv_grinder_side.png",
+              "technic_lv_grinder_side.png", "technic_lv_grinder_side.png", "technic_lv_grinder_front_active.png"},
+       paramtype2 = "facedir",
+       groups = {cracky=2,not_in_creative_inventory=1},
+       legacy_facedir_simple = true,
+       sounds = default.node_sound_wood_defaults(),
+       can_dig = function(pos,player)
+                  local meta = minetest.env:get_meta(pos);
+                  local inv = meta:get_inventory()
+                  if not inv:is_empty("src") or not inv:is_empty("dst") then
+                     minetest.chat_send_player(player:get_player_name(), "Machine cannot be removed because it is not empty");
+                     return false
+                  else
+                     return true
+                  end
                end,
- })
- minetest.register_node("technic:grinder_active", {
-       description = "Grinder",
-       tiles = {"technic_lv_grinder_top.png", "technic_lv_grinder_bottom.png", "technic_lv_grinder_side.png",
-               "technic_lv_grinder_side.png", "technic_lv_grinder_side.png", "technic_lv_grinder_front_active.png"},
-       paramtype2 = "facedir",
-       groups = {cracky=2,not_in_creative_inventory=1},
-       legacy_facedir_simple = true,
-       sounds = default.node_sound_wood_defaults(),
-       can_dig = function(pos,player)
-               local meta = minetest.env:get_meta(pos);
-               local inv = meta:get_inventory()
-               if not inv:is_empty("src") then
-                       return false
-               end
-               if not inv:is_empty("dst") then
-                       return false
-               end
-               return true
-               end,
- })
- minetest.register_abm({
-       nodenames = {"technic:grinder","technic:grinder_active"},
-       interval = 1,
-       chance = 1,
-       action = function(pos, node, active_object_count, active_object_count_wider)
-       local meta = minetest.env:get_meta(pos)
-       local charge= meta:get_float("internal_EU_buffer")
-       local max_charge= meta:get_float("internal_EU_buffer_size")
-       local grind_cost=200
-       local load = math.floor((charge/max_charge)*100)
-       meta:set_string("formspec",
-                               grinder_formspec..
-                               "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:"..
-                                               (load)..":technic_power_meter_fg.png]")
-               local inv = meta:get_inventory()
-               local srclist = inv:get_list("src")
-               if inv:is_empty("src") then meta:set_float("grinder_on",0) end
-               if (meta:get_float("grinder_on") == 1) then
-                       if charge>=grind_cost then
-                       charge=charge-grind_cost;
-                       meta:set_float("internal_EU_buffer",charge)
-                       meta:set_float("src_time", meta:get_float("src_time") + 1)
-                       if meta:get_float("src_time") >= meta:get_float("grind_time") then
-                               -- check if there's room for output in "dst" list
-                               grinded = get_grinded_item (inv:get_stack("src", 1))
-                               if inv:room_for_item("dst",grinded) then
-                                       -- Put result in "dst" list
-                                       inv:add_item("dst", grinded)
-                                       -- take stuff from "src" list
-                                       srcstack = inv:get_stack("src", 1)
-                                       srcstack:take_item()
-                                       inv:set_stack("src", 1, srcstack)
-                                       if inv:is_empty("src") then meta:set_float("grinder_on",0) end
-                               else
-                                       print("Grinder inventory full!")
-                               end
-                               meta:set_float("src_time", 0)
-                       end
-                       end
-               end
-               if (meta:get_float("grinder_on")==0) then
-               local grinded=nil
-               if not inv:is_empty("src") then
-                       grinded = get_grinded_item (inv:get_stack("src", 1))
-                       if grinded then
-                               meta:set_float("grinder_on",1)
-                               hacky_swap_node(pos,"technic:grinder_active")
-                               meta:set_string("infotext", "Grinder Active")
-                               grind_time=4
-                               meta:set_float("grind_time",grind_time)
-                               meta:set_float("src_time", 0)
-                               return
-                       end
-                       else
-                               hacky_swap_node(pos,"technic:grinder")
-                               meta:set_string("infotext", "Grinder Inactive")
-               end
-               end
-       end
- })
- function get_grinded_item (items)
- new_item =nil
- src_item=items:to_table()
- item_name=src_item["name"]
- local counter=registered_grinder_recipes_count-1
- for i=1, counter,1 do
-       if      grinder_recipes[i].src_name==item_name then return ItemStack(grinder_recipes[i].dst_name) end
- end
- return nil
- end
- register_LV_machine ("technic:grinder","RE")
- register_LV_machine ("technic:grinder_active","RE")
+    })
+ minetest.register_abm(
+    { nodenames = {"technic:grinder","technic:grinder_active"},
+      interval = 1,
+      chance   = 1,
+      action = function(pos, node, active_object_count, active_object_count_wider)
+                -- Run a machine through its states. Takes the same arguments as the ABM action
+                -- and adds the machine's states and any extra data which is needed by the machine.
+                -- A machine is characterized by running through a set number of states (usually 2:
+                -- Idle and active) in some order. A state decides when to move to the next one
+                -- and the machine only changes state if it is powered correctly.
+                -- The machine will automatically shut down if disconnected from power in some fashion.
+                local meta         = minetest.env:get_meta(pos)
+                local eu_input     = meta:get_int("LV_EU_input")
+                local state        = meta:get_int("state")
+                local next_state   = state
+                -- Machine information
+                local machine_name         = "Grinder"
+                local machine_node         = "technic:grinder"
+                local machine_state_demand = { 50, 300 }
+                        
+                -- Setup meta data if it does not exist. state is used as an indicator of this
+                if state == 0 then
+                   meta:set_int("state", 1)
+                   meta:set_int("LV_EU_demand", machine_state_demand[1])
+                   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")
+                        
+                -- State machine
+                if eu_input == 0 then
+                   -- unpowered - go idle
+                   hacky_swap_node(pos, machine_node)
+                   meta:set_string("infotext", machine_name.." Unpowered")
+                   next_state = 1
+                elseif eu_input == machine_state_demand[state] then
+                   -- Powered - do the state specific actions
+                           
+                   local inv    = meta:get_inventory()
+                   local empty  = inv:is_empty("src")
+                   if state == 1 then
+                      hacky_swap_node(pos, machine_node)
+                      meta:set_string("infotext", machine_name.." Idle")
+                      local result = technic.get_grinder_recipe(inv:get_stack("src", 1))
+                      if not empty and result and inv:room_for_item("dst",result) then
+                         meta:set_int("src_time", 0)
+                         next_state = 2
+                      end
+                   elseif state == 2 then
+                      hacky_swap_node(pos, machine_node.."_active")
+                      meta:set_string("infotext", machine_name.." Active")
+                      if empty then
+                         next_state = 1
+                      else
+                         meta:set_int("src_time", meta:get_int("src_time") + 1)
+                         if meta:get_int("src_time") == 4 then -- 4 ticks per output
+                            -- check if there's room for output in "dst" list
+                            local result = technic.get_grinder_recipe(inv:get_stack("src", 1))
+                            meta:set_int("src_time", 0)
+                            if inv:room_for_item("dst",result) then
+                               -- take stuff from "src" list
+                               srcstack = inv:get_stack("src", 1)
+                               srcstack:take_item()
+                               inv:set_stack("src", 1, srcstack)
+                               -- Put result in "dst" list
+                               inv:add_item("dst", result)
+                            else
+                               -- all full: go idle
+                               next_state = 1
+                            end
+                         end
+                      end
+                   end
+                end
+                -- Change state?
+                if next_state ~= state then
+                   meta:set_int("LV_EU_demand", machine_state_demand[next_state])
+                   meta:set_int("state", next_state)
+                end
+             end
+   })
+ technic.register_LV_machine ("technic:grinder","RE")
+ technic.register_LV_machine ("technic:grinder_active","RE")
++
index 2248295defcc727320b82506da028098eb58aace,2d748bc226c4904abbc5ec9ffc5798beffeea7dc..edb1c34737a6901f6c464e7f95d79ce938a2efd8
@@@ -4,7 -4,13 +4,13 @@@
  
  technic = {}
  
modpath=minetest.get_modpath("technic")
technic.dprint = function(string)
 -                  if technic.DBG == 1 then
 -                     print(string)
 -                  end
 -               end
++      if technic.DBG == 1 then
++              print(string)
++      end
++end
 -local modpath=minetest.get_modpath("technic")
++local modpath = minetest.get_modpath("technic")
  
  --Read technic config file
  dofile(modpath.."/config.lua")
@@@ -36,17 -50,19 +50,26 @@@ dofile(modpath.."/extractor.lua"
  dofile(modpath.."/wires_mv.lua")
  dofile(modpath.."/battery_box_mv.lua")
  dofile(modpath.."/solar_array_mv.lua")
- dofile(modpath.."/down_converter_mv.lua")
++--dofile(modpath.."/down_converter_mv.lua")
  dofile(modpath.."/electric_furnace_mv.lua")
  dofile(modpath.."/alloy_furnace_mv.lua")
  dofile(modpath.."/forcefield.lua")
+ ---- The power radiator supplies appliances with inductive coupled power:
+ ---- lighting and associated textures is taken directly from VanessaE's homedecor and made electric.
+ dofile(modpath.."/power_radiator.lua")
+ dofile(modpath.."/lighting.lua")
+ --
+ ----HV machines
+ dofile(modpath.."/wires_hv.lua")
+ dofile(modpath.."/battery_box_hv.lua")
+ dofile(modpath.."/solar_array_hv.lua")
  
- dofile(modpath.."/down_converter_hv.lua")
 +--HV machines
 +dofile(modpath.."/wires_hv.lua")
 +dofile(modpath.."/battery_box_hv.lua")
 +dofile(modpath.."/solar_array_hv.lua")
++--dofile(modpath.."/down_converter_hv.lua")
 +
  --Tools
  if technic.config:getBool("enable_mining_drill") then dofile(modpath.."/mining_drill.lua") end
  if technic.config:getBool("enable_mining_laser") then dofile(modpath.."/mining_laser_mk1.lua") end
Simple merge
Simple merge
Simple merge
Simple merge
index e1592481064ae028886f27799ebdfd9202d06d60,a2fb516f3c7c4cbf9782a21655e2ea0bceffa44a..73f6ee288b323af97c17ac846413b07291a2a607
@@@ -62,7 -55,7 +55,6 @@@ minetest.register_abm
                pos1.y=pos.y+1
                pos1.x=pos.x
                pos1.z=pos.z
 -              
                local light = minetest.env:get_node_light(pos1, nil)
                local time_of_day = minetest.env:get_timeofday()
                local meta = minetest.env:get_meta(pos)
                -- 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 > -10 then
-                       local internal_EU_buffer      = meta:get_float("internal_EU_buffer")
-                       local internal_EU_buffer_size = meta:get_float("internal_EU_buffer_size")
-                       local charge_to_give          = math.floor(light*(light*9.6+pos1.y/130*48))
-                       if charge_to_give<0   then charge_to_give=0 end
-                       if charge_to_give>2880 then charge_to_give=2880 end
-                       if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then
-                          charge_to_give=internal_EU_buffer_size-internal_EU_buffer
-                       end
-                       meta:set_string("infotext", "Solar Array is active ("..charge_to_give.."EU)")
-                       meta:set_float("active",1)
-                       internal_EU_buffer=internal_EU_buffer+charge_to_give
-                       meta:set_float("internal_EU_buffer",internal_EU_buffer)
-                       
+                  local charge_to_give          = math.floor(light*(light*9.6+pos1.y/130*48))
+                  if charge_to_give<0   then charge_to_give=0 end
+                  if charge_to_give>160 then charge_to_give=160 end
+                  meta:set_string("infotext", "Solar Array is active ("..charge_to_give.."EU)")
+                  meta:set_int("HV_EU_supply", charge_to_give)
                else
-                       meta:set_string("infotext", "Solar Array is inactive");
-                       meta:set_float("active",0)
+                  meta:set_string("infotext", "Solar Array is inactive");
+                  meta:set_int("HV_EU_supply", 0)
                end
-       end,
- }) 
+            end,
+  }) 
+ technic.register_HV_machine ("technic:solar_array_hv","PR")
 +
- register_HV_machine ("technic:solar_array_hv","PR")
index f6578143ebc001d072ce808ab308ce77c9ccc369,ecc55d9f74e087920b4bbc959443f1df8c6db5b8..e758eb8f3624f1e810bb1d31efd1b13e6cdf9287
@@@ -63,32 -55,24 +55,24 @@@ minetest.register_abm
                pos1.y=pos.y+1
                pos1.x=pos.x
                pos1.z=pos.z
 -              
                local light = minetest.env:get_node_light(pos1, nil)
                local time_of_day = minetest.env:get_timeofday()
                local meta = minetest.env:get_meta(pos)
                if light == nil then light = 0 end
                -- turn on array only during day time and if sufficient light
-                 -- I know this is counter intuitive when cheating by using other light sources.
+               -- 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 > -10 then
-                       local internal_EU_buffer      = meta:get_float("internal_EU_buffer")
-                       local internal_EU_buffer_size = meta:get_float("internal_EU_buffer_size")
-                       local charge_to_give          = math.floor(light*(light*0.5333+pos1.y/130*2.6667))
-                       if charge_to_give<0   then charge_to_give=0 end
-                       if charge_to_give>160 then charge_to_give=160 end
-                       if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then
-                          charge_to_give=internal_EU_buffer_size-internal_EU_buffer
-                       end
-                       meta:set_string("infotext", "Solar Array is active ("..charge_to_give.."EU)")
-                       meta:set_float("active",1)
-                       internal_EU_buffer=internal_EU_buffer+charge_to_give
-                       meta:set_float("internal_EU_buffer",internal_EU_buffer)
-                       
+                  local charge_to_give = math.floor(light*(light*0.5333+pos1.y/130*2.6667))
+                  if charge_to_give<0   then charge_to_give=0 end
+                  if charge_to_give>160 then charge_to_give=160 end
+                  meta:set_string("infotext", "Solar Array is active ("..charge_to_give.."EU)")
+                  meta:set_int("LV_EU_supply", charge_to_give)
                else
-                       meta:set_string("infotext", "Solar Array is inactive");
-                       meta:set_float("active",0)
+                  meta:set_string("infotext", "Solar Array is inactive");
+                  meta:set_int("LV_EU_supply", 0)
                end
-       end,
- }) 
+            end,
+  })
+ technic.register_LV_machine ("technic:solar_array_lv","PR")
 +
- register_LV_machine ("technic:solar_array_lv","PR")
index abcc027f418b6d75c39d2ed622bb19240f334571,3eba790a73ea14e80a20556a984662d8b0e3e9b6..f389a9fd1abdd96336627acff535460306a88329
@@@ -69,27 -63,19 +63,20 @@@ minetest.register_abm
                local meta = minetest.env:get_meta(pos)
                if light == nil then light = 0 end
                -- turn on array only during day time and if sufficient light
-                 -- I know this is counter intuitive when cheating by using other light sources.
+               -- 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 > -10 then
-                       local internal_EU_buffer      = meta:get_float("internal_EU_buffer")
-                       local internal_EU_buffer_size = meta:get_float("internal_EU_buffer_size")
-                       local charge_to_give          = math.floor(light*(light*2.4+pos1.y/130*12))
-                       if charge_to_give<0   then charge_to_give=0 end
-                       if charge_to_give>720 then charge_to_give=720 end
-                       if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then
-                          charge_to_give=internal_EU_buffer_size-internal_EU_buffer
-                       end
-                       meta:set_string("infotext", "Solar Array is active ("..charge_to_give.."EU)")
-                       meta:set_float("active",1)
-                       internal_EU_buffer=internal_EU_buffer+charge_to_give
-                       meta:set_float("internal_EU_buffer",internal_EU_buffer)
-                       -- Idea: How about letting solar panels provide power without battery boxes?
-                       -- This could provide an even distribution to all receivers.                    
+                  local charge_to_give = math.floor(light*(light*2.4+pos1.y/130*12))
+                  if charge_to_give<0   then charge_to_give=0 end
+                  if charge_to_give>160 then charge_to_give=160 end
+                  meta:set_string("infotext", "Solar Array is active ("..charge_to_give.."EU)")
+                  --                   meta:set_float("active",1)
+                  meta:set_int("MV_EU_supply", charge_to_give)
                else
-                       meta:set_string("infotext", "Solar Array is inactive");
-                       meta:set_float("active",0)
+                  meta:set_string("infotext", "Solar Array is inactive");
+                  meta:set_int("MV_EU_supply", 0)
                end
-       end,
- }) 
+            end,
+  }) 
+ technic.register_MV_machine ("technic:solar_array_mv","PR")
 +
- register_MV_machine ("technic:solar_array_mv","PR")
index 5b53f5fbee3e24aa4f2c852d6195f324e2dfbb14,96ee74495ffda7bbf416e2fa1a200133cb752804..ff3e34ab27f036aee39e9774e1752cc742319969
@@@ -88,4 -74,4 +74,5 @@@ minetest.register_abm
        end,
  }) 
  
- register_LV_machine ("technic:solar_panel","PR")
+ technic.register_LV_machine ("technic:solar_panel","PR")
++
Simple merge
Simple merge
Simple merge
index 5ff16fa65ecd579b3d6e4e5914513c472038c534,91681b1905f2d0ebeba88098572d403de4c26e6e..e386a767eb3c398f578d3803d5c1abf76031b9dd
@@@ -557,8 -560,8 +560,12 @@@ unified_inventory.update_recipe = funct
        local craft = crafts[alternate]
        inv:set_stack("output", 1, craft.output)
        local items=craft.items
--      -- cook, fuel, grinding recipes
-       if craft.type == "cooking" or craft.type == "fuel" or craft.type == "grinding" then
 -      if craft.type == "cooking" or craft.type == "fuel" or craft.type == "grinding" or craft.type == "extracting" then
++
++      -- cooking, fuel, grinding, and extracting recipes
++      if craft.type == "cooking" or
++         craft.type == "fuel" or
++         craft.type == "grinding" or
++         craft.type == "extracting" then
                def=unified_inventory.find_item_def(craft["items"][1])
                if def then
                        inv:set_stack("build", 1, def)
index 8b137891791fe96927ad78e64b0aad7bded08bdc,c327490a2ce0a016d87823105eb5fdf0cd691c1c..45b4a3328ac3dec9042de18e69362b7814e2d517
@@@ -1,1 -1,1 +1,2 @@@
+ creative
 +