From 69ae366f6084bcda08d74abb4d3577a42f27a93b Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Sun, 14 Apr 2013 06:12:49 +0200 Subject: [PATCH 01/57] changes to CraftingGuide --- aaa_recipeshook/depends.txt | 1 - aaa_recipeshook/init.lua | 29 ------- unified_inventory/api.lua | 168 ++++++++++++------------------------ 3 files changed, 54 insertions(+), 144 deletions(-) delete mode 100644 aaa_recipeshook/depends.txt delete mode 100644 aaa_recipeshook/init.lua diff --git a/aaa_recipeshook/depends.txt b/aaa_recipeshook/depends.txt deleted file mode 100644 index 8b13789..0000000 --- a/aaa_recipeshook/depends.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/aaa_recipeshook/init.lua b/aaa_recipeshook/init.lua deleted file mode 100644 index 733edd1..0000000 --- a/aaa_recipeshook/init.lua +++ /dev/null @@ -1,29 +0,0 @@ -crafts_table ={} -crafts_table_count=0 -UI_recipes_hook=true - --- override minetest.register_craft -local minetest_register_craft = minetest.register_craft -minetest.register_craft = function (options) - register_craft(options) - if options.type=="alloy" or options.type=="grinding" then return end - minetest_register_craft(options) -end - --- register_craft -register_craft = function(options) - if options.output == nil then - return - end - local itemstack = ItemStack(options.output) - if itemstack:is_empty() then - return - end - if crafts_table[itemstack:get_name()]==nil then - crafts_table[itemstack:get_name()] = {} - end - table.insert(crafts_table[itemstack:get_name()],options) - crafts_table_count=crafts_table_count+1 -end - - diff --git a/unified_inventory/api.lua b/unified_inventory/api.lua index 029ae68..2187f1a 100644 --- a/unified_inventory/api.lua +++ b/unified_inventory/api.lua @@ -10,6 +10,8 @@ unified_inventory.filtered_items_list = {} unified_inventory.activefilter = {} unified_inventory.alternate = {} unified_inventory.current_item = {} +unified_inventory.crafts_table ={} +unified_inventory.crafts_table_count=0 -- default inventory page unified_inventory.default = "craft" @@ -26,8 +28,18 @@ minetest.after(0.01, function() if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and def.description ~= "" then table.insert(unified_inventory.items_list, name) + local recipes=minetest.get_all_craft_recipes(name) + if unified_inventory.crafts_table[name]==nil then + unified_inventory.crafts_table[name] = {} + end + if recipes then + for i=1,#recipes,1 do + table.insert(unified_inventory.crafts_table[name],recipes[i]) + end + end end end + --print(dump(unified_inventory.crafts_table)) table.sort(unified_inventory.items_list) unified_inventory.items_list_size = #unified_inventory.items_list print ("Unified Inventory. inventory size: "..unified_inventory.items_list_size) @@ -37,7 +49,6 @@ end) minetest.register_on_joinplayer(function(player) local player_name = player:get_player_name() unified_inventory.players[player_name]={} - unified_inventory.players[player_name]["sound_volume"]=minetest.setting_get("sound_volume")*10 unified_inventory.current_index[player_name] = 1 unified_inventory.filtered_items_list[player_name] = {} unified_inventory.filtered_items_list[player_name] = unified_inventory.items_list @@ -48,7 +59,7 @@ minetest.register_on_joinplayer(function(player) unified_inventory.current_item[player_name] =nil unified_inventory.set_inventory_formspec(player,unified_inventory.get_formspec(player, unified_inventory.default)) ---crafting guide inventories +--crafting guide inventories local inv = minetest.create_detached_inventory(player:get_player_name().."craftrecipe",{ allow_put = function(inv, listname, index, stack, player) return 0 @@ -206,9 +217,9 @@ unified_inventory.get_formspec = function(player,page) formspec = formspec.."label[2,0;"..item_name.."]" local alternates = 0 local alternate = unified_inventory.alternate[player_name] - local crafts = crafts_table[item_name] + local crafts = unified_inventory.crafts_table[item_name] - if crafts ~= nil then + if crafts ~= nil and #crafts>0 then alternates = #crafts local craft = crafts[alternate] local method = "Crafting" @@ -440,7 +451,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if item_name then local alternates = 0 local alternate=unified_inventory.alternate[player_name] - local crafts = crafts_table[item_name] + local crafts = unified_inventory.crafts_table[item_name] if crafts ~= nil then alternates = #crafts end @@ -537,134 +548,63 @@ end -- update_recipe unified_inventory.update_recipe = function(player, stack_name, alternate) - --print("Lookup:"..stack_name) local inv = minetest.get_inventory({type="detached", name=player:get_player_name().."craftrecipe"}) for i=0,inv:get_size("build"),1 do inv:set_stack("build", i, nil) end - inv:set_stack("cook", 1, nil) - inv:set_stack("fuel", 1, nil) - - inv:set_stack("output", 1, stack_name) - local def + inv:set_stack("output", 1, nil) alternate = tonumber(alternate) or 1 - local crafts = crafts_table[stack_name] - if crafts == nil then - --minetest.chat_send_player(player:get_player_name(), "no recipe available for "..stack_name) - return - end + local crafts = unified_inventory.crafts_table[stack_name] + print(dump(crafts)) + local next=next + if next(crafts) == nil then return end -- no craft recipes if alternate < 1 or alternate > #crafts then alternate = 1 end local craft = crafts[alternate] - --print (dump(craft)) - --minetest.chat_send_player(player:get_player_name(), "recipe for "..stack_name..": "..dump(craft)) - - local itemstack = ItemStack(craft.output) - inv:set_stack("output", 1, itemstack) - + 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 - def=unified_inventory.find_item_def(craft.recipe) + def=unified_inventory.find_item_def(craft["items"][1]) if def then inv:set_stack("build", 1, def) end return end - - -- build (shaped or shapeless) - if craft.recipe[1] then - def=unified_inventory.find_item_def(craft.recipe[1]) - if def then - inv:set_stack("build", 1, def) - else - def=unified_inventory.find_item_def(craft.recipe[1][1]) - if def then - inv:set_stack("build", 1, def) - end - def=unified_inventory.find_item_def(craft.recipe[1][2]) - if def then - inv:set_stack("build", 2, def) - end - def=unified_inventory.find_item_def(craft.recipe[1][3]) - if def then - inv:set_stack("build", 3, def) - end + if craft.width==0 then + local build_table={1,2,3} + for i=1,3,1 do + if craft.items[i] then + def=unified_inventory.find_item_def(craft.items[i]) + if def then inv:set_stack("build", build_table[i], {name=def}) end end end - if craft.recipe[2] then - def=unified_inventory.find_item_def(craft.recipe[2]) - if def then - inv:set_stack("build", 2, def) - else - def=unified_inventory.find_item_def(craft.recipe[2][1]) - if def then - inv:set_stack("build", 4, def) + end + if craft.width==1 then + local build_table={1,4,7} + for i=1,3,1 do + if craft.items[i] then + def=unified_inventory.find_item_def(craft.items[i]) + if def then inv:set_stack("build", build_table[i], {name=def}) end + end + end + end + if craft.width==2 then + local build_table={1,2,4,5,7,8} + for i=1,6,1 do + if craft.items[i] then + def=unified_inventory.find_item_def(craft.items[i]) + if def then inv:set_stack("build", build_table[i], {name=def}) end + end + end + end + if craft.width==3 then + for i=1,9,1 do + if craft.items[i] then + def=unified_inventory.find_item_def(craft.items[i]) + if def then inv:set_stack("build", i, {name=def}) end end - def=unified_inventory.find_item_def(craft.recipe[2][2]) - if def then - inv:set_stack("build", 5, def) - end - def=unified_inventory.find_item_def(craft.recipe[2][3]) - if def then - inv:set_stack("build", 6, def) - end - end - end - - if craft.recipe[3] then - def=unified_inventory.find_item_def(craft.recipe[3]) - if def then - inv:set_stack("build", 3, def) - else - def=unified_inventory.find_item_def(craft.recipe[3][1]) - if def then - inv:set_stack("build", 7, def) - end - def=unified_inventory.find_item_def(craft.recipe[3][2]) - if def then - inv:set_stack("build", 8, def) - end - def=unified_inventory.find_item_def(craft.recipe[3][3]) - if def then - inv:set_stack("build", 9, def) - end - end - end - if craft.recipe[4] then - def=unified_inventory.find_item_def(craft.recipe[4]) - if def then - inv:set_stack("build", 4, def) - end - end - if craft.recipe[5] then - def=unified_inventory.find_item_def(craft.recipe[5]) - if def then - inv:set_stack("build", 5, def) - end - end - if craft.recipe[6] then - def=unified_inventory.find_item_def(craft.recipe[6]) - if def then - inv:set_stack("build", 6, def) - end - end - if craft.recipe[7] then - def=unified_inventory.find_item_def(craft.recipe[7]) - if def then - inv:set_stack("build", 7, def) - end - end - if craft.recipe[8] then - def=unified_inventory.find_item_def(craft.recipe[8]) - if def then - inv:set_stack("build", 8, def) - end - end - if craft.recipe[9] then - def=unified_inventory.find_item_def(craft.recipe[9]) - if def then - inv:set_stack("build", 9, def) end end end From 17fbd2c3353424a5dfdba1b4d92b0a9a2fce4356 Mon Sep 17 00:00:00 2001 From: Vanessa Ezekowitz Date: Sun, 14 Apr 2013 03:40:34 -0400 Subject: [PATCH 02/57] remove aaa_recipeshook from unified inventory depends (it isn't needed anymore) --- unified_inventory/depends.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/unified_inventory/depends.txt b/unified_inventory/depends.txt index 8b79558..c327490 100644 --- a/unified_inventory/depends.txt +++ b/unified_inventory/depends.txt @@ -1,2 +1 @@ -aaa_recipeshook creative From 05131f8b07bab8c8464d37de9d4d589de56ee118 Mon Sep 17 00:00:00 2001 From: Vanessa Ezekowitz Date: Sun, 14 Apr 2013 22:24:55 -0400 Subject: [PATCH 03/57] aliased diamong block back to default one. --- technic_worldgen/nodes.lua | 2 ++ technic_worldgen/nodes.lua~ | 58 +++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 technic_worldgen/nodes.lua~ diff --git a/technic_worldgen/nodes.lua b/technic_worldgen/nodes.lua index 5952d52..28514f4 100644 --- a/technic_worldgen/nodes.lua +++ b/technic_worldgen/nodes.lua @@ -56,3 +56,5 @@ minetest.register_craft({ {'technic:marble','technic:marble'} } }) + +minetest.register_alias("technic:diamond_block", "default:diamondblock") diff --git a/technic_worldgen/nodes.lua~ b/technic_worldgen/nodes.lua~ new file mode 100644 index 0000000..5952d52 --- /dev/null +++ b/technic_worldgen/nodes.lua~ @@ -0,0 +1,58 @@ +minetest.register_node( ":technic:mineral_uranium", { + description = "Uranium Ore", + tiles = { "default_stone.png^technic_mineral_uranium.png" }, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_stone_defaults(), + drop = 'craft "technic:uranium" 1', +}) + +minetest.register_node( ":technic:mineral_chromium", { + description = "Chromium Ore", + tiles = { "default_stone.png^technic_mineral_chromium.png" }, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_stone_defaults(), + drop = 'craft "technic:chromium_lump" 1', +}) + +minetest.register_node( ":technic:mineral_zinc", { + description = "Zinc Ore", + tile_images = { "default_stone.png^technic_mineral_zinc.png" }, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_stone_defaults(), + drop = 'craft "technic:zinc_lump" 1', +}) + +minetest.register_node( ":technic:granite", { + description = "Granite", + tiles = { "technic_granite.png" }, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node( ":technic:marble", { + description = "Marble", + tiles = { "technic_marble.png" }, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node( ":technic:marble_bricks", { + description = "Marble Bricks", + tiles = { "technic_marble_bricks.png" }, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + output = 'technic:marble_bricks 4', + recipe = { + {'technic:marble','technic:marble'}, + {'technic:marble','technic:marble'} + } +}) From 106e1816dcd3500b9fe730c16753ec379b92d77a Mon Sep 17 00:00:00 2001 From: Vanessa Ezekowitz Date: Sun, 14 Apr 2013 22:53:30 -0400 Subject: [PATCH 04/57] deleted undesired backup file --- .gitignore | 4 +++ technic_worldgen/nodes.lua~ | 58 ------------------------------------- 2 files changed, 4 insertions(+), 58 deletions(-) delete mode 100644 technic_worldgen/nodes.lua~ diff --git a/.gitignore b/.gitignore index 5ebd21a..716917d 100644 --- a/.gitignore +++ b/.gitignore @@ -161,3 +161,7 @@ pip-log.txt # Mac crap .DS_Store + +#gedit backup files +*~ + diff --git a/technic_worldgen/nodes.lua~ b/technic_worldgen/nodes.lua~ deleted file mode 100644 index 5952d52..0000000 --- a/technic_worldgen/nodes.lua~ +++ /dev/null @@ -1,58 +0,0 @@ -minetest.register_node( ":technic:mineral_uranium", { - description = "Uranium Ore", - tiles = { "default_stone.png^technic_mineral_uranium.png" }, - is_ground_content = true, - groups = {cracky=3}, - sounds = default.node_sound_stone_defaults(), - drop = 'craft "technic:uranium" 1', -}) - -minetest.register_node( ":technic:mineral_chromium", { - description = "Chromium Ore", - tiles = { "default_stone.png^technic_mineral_chromium.png" }, - is_ground_content = true, - groups = {cracky=3}, - sounds = default.node_sound_stone_defaults(), - drop = 'craft "technic:chromium_lump" 1', -}) - -minetest.register_node( ":technic:mineral_zinc", { - description = "Zinc Ore", - tile_images = { "default_stone.png^technic_mineral_zinc.png" }, - is_ground_content = true, - groups = {cracky=3}, - sounds = default.node_sound_stone_defaults(), - drop = 'craft "technic:zinc_lump" 1', -}) - -minetest.register_node( ":technic:granite", { - description = "Granite", - tiles = { "technic_granite.png" }, - is_ground_content = true, - groups = {cracky=3}, - sounds = default.node_sound_stone_defaults(), -}) - -minetest.register_node( ":technic:marble", { - description = "Marble", - tiles = { "technic_marble.png" }, - is_ground_content = true, - groups = {cracky=3}, - sounds = default.node_sound_stone_defaults(), -}) - -minetest.register_node( ":technic:marble_bricks", { - description = "Marble Bricks", - tiles = { "technic_marble_bricks.png" }, - is_ground_content = true, - groups = {cracky=3}, - sounds = default.node_sound_stone_defaults(), -}) - -minetest.register_craft({ - output = 'technic:marble_bricks 4', - recipe = { - {'technic:marble','technic:marble'}, - {'technic:marble','technic:marble'} - } -}) From cdb368913b471ef2d8a3c8dc681f848548803e13 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Mon, 15 Apr 2013 07:52:11 +0200 Subject: [PATCH 05/57] Update recipes --- technic/geothermal.lua | 4 ++-- technic/sonic_screwdriver.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/technic/geothermal.lua b/technic/geothermal.lua index 93aa423..dccabf4 100644 --- a/technic/geothermal.lua +++ b/technic/geothermal.lua @@ -4,8 +4,8 @@ minetest.register_craft({ output = 'technic:geothermal', recipe = { {'default:stone', 'default:stone', 'default:stone'}, - {'moreores:copper_ingot', 'technic:diamond', 'moreores:copper_ingot'}, - {'default:stone', 'moreores:copper_ingot', 'default:stone'}, + {'default:copper_ingot', 'default:diamond', 'default:copper_ingot'}, + {'default:stone', 'default:copper_ingot', 'default:stone'}, } }) diff --git a/technic/sonic_screwdriver.lua b/technic/sonic_screwdriver.lua index 523b253..97ec446 100644 --- a/technic/sonic_screwdriver.lua +++ b/technic/sonic_screwdriver.lua @@ -52,7 +52,7 @@ minetest.register_tool("technic:sonic_screwdriver", { minetest.register_craft({ output = "technic:sonic_screwdriver", recipe = { - {"technic:diamond"}, + {"default:diamond"}, {"technic:battery"}, {"technic:stainless_steel_ingot"} } From 3d8b2a365d2ed654e9b1309b72829281d9b2a694 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Mon, 15 Apr 2013 07:54:00 +0200 Subject: [PATCH 06/57] Bugfix --- technic/mining_drill.lua | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/technic/mining_drill.lua b/technic/mining_drill.lua index 86c18ac..33a8e5a 100644 --- a/technic/mining_drill.lua +++ b/technic/mining_drill.lua @@ -217,11 +217,11 @@ minetest.register_tool("technic:mining_drill", { stack_max = 1, on_use = function(itemstack, user, pointed_thing) if pointed_thing.type=="node" then - item=itemstack:to_table() + local item=itemstack:to_table() local meta=get_item_meta(item["metadata"]) if meta==nil then return end --tool not charghed if meta["charge"]==nil then return end - charge=meta["charge"] + local charge=meta["charge"] if charge-mining_drill_power_usage>0 then charge_to_take=drill_dig_it(minetest.get_pointed_thing_position(pointed_thing, above),user,1,1) charge =charge-mining_drill_power_usage; @@ -287,7 +287,7 @@ function mining_drill_mk2_handler (itemstack,user,pointed_thing) local keys=user:get_player_control() local player_name=user:get_player_name() local item=itemstack:to_table() - meta=get_item_meta(item["metadata"]) + local meta=get_item_meta(item["metadata"]) if meta==nil or keys["sneak"]==true then return mining_drill_mk2_setmode(user,itemstack) end if meta["mode"]==nil then return mining_drill_mk2_setmode(user,itemstack) end if pointed_thing.type~="node" then return end @@ -309,14 +309,13 @@ function mining_drill_mk3_handler (itemstack,user,pointed_thing) local keys=user:get_player_control() local player_name=user:get_player_name() local item=itemstack:to_table() - meta=get_item_meta(item["metadata"]) + local meta=get_item_meta(item["metadata"]) if meta==nil or keys["sneak"]==true then return mining_drill_mk3_setmode(user,itemstack) end if meta["mode"]==nil then return mining_drill_mk3_setmode(user,itemstack) end if pointed_thing.type~="node" then return end if meta["charge"]==nil then return end - charge=meta["charge"] + local charge=meta["charge"] if charge-mining_drill_power_usage>0 then - print(dump(meta)) local charge_to_take=drill_dig_it(minetest.get_pointed_thing_position(pointed_thing, above),user,3,meta["mode"]) charge=charge-charge_to_take; if charge<0 then charge=0 end From 41af016603f2f6dc0e08bddcec727efe1121c5ca Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Mon, 15 Apr 2013 07:56:31 +0200 Subject: [PATCH 07/57] change registering crafting recipes in UI --- technic/alloy_furnaces_commons.lua | 10 ++++------ technic/grinder.lua | 9 ++++----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/technic/alloy_furnaces_commons.lua b/technic/alloy_furnaces_commons.lua index e058d56..559d002 100644 --- a/technic/alloy_furnaces_commons.lua +++ b/technic/alloy_furnaces_commons.lua @@ -19,14 +19,12 @@ 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 UI_recipes_hook then - minetest.register_craft({ +if unified_inventory then + unified_inventory.register_craft({ type = "alloy", output = string3.." "..count3, - recipe = { - {string1.." "..count1}, - {string2.." "..count2}, - } + items = {string1.." "..count1,string2.." "..count2}, + width = 2, }) end end diff --git a/technic/grinder.lua b/technic/grinder.lua index 851352b..b4dbd90 100644 --- a/technic/grinder.lua +++ b/technic/grinder.lua @@ -7,11 +7,12 @@ 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 UI_recipes_hook then - minetest.register_craft({ +if unified_inventory then + unified_inventory.register_craft({ type = "grinding", output = string2, - recipe = string1, + items = {string1}, + width = 0, }) end end @@ -22,11 +23,9 @@ 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:coal_lump","technic:coal_dust 2") -register_grinder_recipe("moreores:copper_lump","technic:copper_dust 2") register_grinder_recipe("default:copper_lump","technic:copper_dust 2") register_grinder_recipe("moreores:tin_lump","technic:tin_dust 2") register_grinder_recipe("moreores:silver_lump","technic:silver_dust 2") -register_grinder_recipe("moreores:gold_lump","technic:gold_dust 2") register_grinder_recipe("default:gold_lump","technic:gold_dust 2") register_grinder_recipe("moreores:mithril_lump","technic:mithril_dust 2") register_grinder_recipe("technic:chromium_lump","technic:chromium_dust 2") From 642b8bec16ef56a6be1a5abbffb50f479b0fdb1b Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Mon, 15 Apr 2013 08:28:17 +0200 Subject: [PATCH 08/57] Update crafting guide --- unified_inventory/api.lua | 45 +++++++++++++++++++++++++++-------- unified_inventory/depends.txt | 1 + 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/unified_inventory/api.lua b/unified_inventory/api.lua index 2187f1a..ab55903 100644 --- a/unified_inventory/api.lua +++ b/unified_inventory/api.lua @@ -577,7 +577,7 @@ unified_inventory.update_recipe = function(player, stack_name, alternate) for i=1,3,1 do if craft.items[i] then def=unified_inventory.find_item_def(craft.items[i]) - if def then inv:set_stack("build", build_table[i], {name=def}) end + if def then inv:set_stack("build", build_table[i], def) end end end end @@ -586,7 +586,7 @@ unified_inventory.update_recipe = function(player, stack_name, alternate) for i=1,3,1 do if craft.items[i] then def=unified_inventory.find_item_def(craft.items[i]) - if def then inv:set_stack("build", build_table[i], {name=def}) end + if def then inv:set_stack("build", build_table[i], def) end end end end @@ -595,7 +595,7 @@ unified_inventory.update_recipe = function(player, stack_name, alternate) for i=1,6,1 do if craft.items[i] then def=unified_inventory.find_item_def(craft.items[i]) - if def then inv:set_stack("build", build_table[i], {name=def}) end + if def then inv:set_stack("build", build_table[i], def) end end end end @@ -603,7 +603,7 @@ unified_inventory.update_recipe = function(player, stack_name, alternate) for i=1,9,1 do if craft.items[i] then def=unified_inventory.find_item_def(craft.items[i]) - if def then inv:set_stack("build", i, {name=def}) end + if def then inv:set_stack("build", i, def) end end end end @@ -614,14 +614,39 @@ if type(def1)=="string" then if string.find(def1, "group:") then def1=string.gsub(def1, "group:", "") def1=string.gsub(def1, '\"', "") - for name,def in pairs(minetest.registered_items) do - if def.groups[def1] == 1 and def.groups.not_in_creative_inventory ~= 1 then - return def - end - end + local items=unified_inventory.items_in_group(def1) + return items[1] else - return def1 + return def1 end end return nil end + +unified_inventory.items_in_group = function(group) + local items = {} + for name, item in pairs(minetest.registered_items) do + for _, g in ipairs(group:split(',')) do + if item.groups[g] then + table.insert(items,name) + end + end + end + return items +end + +-- register_craft +unified_inventory.register_craft = function(options) + if options.output == nil then + return + end + local itemstack = ItemStack(options.output) + if itemstack:is_empty() then + return + end + if unified_inventory.crafts_table[itemstack:get_name()]==nil then + unified_inventory.crafts_table[itemstack:get_name()] = {} + end + table.insert(unified_inventory.crafts_table[itemstack:get_name()],options) + --crafts_table_count=crafts_table_count+1 +end diff --git a/unified_inventory/depends.txt b/unified_inventory/depends.txt index c327490..8b79558 100644 --- a/unified_inventory/depends.txt +++ b/unified_inventory/depends.txt @@ -1 +1,2 @@ +aaa_recipeshook creative From 595ed5045171ac45c92551e093fe582e0ca2508e Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Mon, 15 Apr 2013 08:33:01 +0200 Subject: [PATCH 09/57] avoid nil --- item_drop/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/item_drop/init.lua b/item_drop/init.lua index 8cd3b14..f51469b 100644 --- a/item_drop/init.lua +++ b/item_drop/init.lua @@ -8,7 +8,7 @@ minetest.register_globalstep(function(dtime) for _,object in ipairs(minetest.env:get_objects_inside_radius(pos, 1)) do if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then if inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then - if object:get_luaentity().timer > time_pick then + if object:get_luaentity() and object:get_luaentity().timer > time_pick then inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) if object:get_luaentity().itemstring ~= "" then minetest.sound_play("item_drop_pickup", { @@ -137,4 +137,4 @@ minetest.register_on_dieplayer(function(name, pos) end end) ]]-- -print("DROPS LOADED!") \ No newline at end of file +print("DROPS LOADED!") From a9f73e53d909f7a89539cc90cddf195a15004b2f Mon Sep 17 00:00:00 2001 From: Vanessa Ezekowitz Date: Mon, 15 Apr 2013 02:49:22 -0400 Subject: [PATCH 10/57] removed aaa_recipeshook from depends.txt as it is not used anymore. --- unified_inventory/depends.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/unified_inventory/depends.txt b/unified_inventory/depends.txt index 8b79558..c327490 100644 --- a/unified_inventory/depends.txt +++ b/unified_inventory/depends.txt @@ -1,2 +1 @@ -aaa_recipeshook creative From 76c2d8132c4b2828067d15bcd55eecca9627885f Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Thu, 18 Apr 2013 00:16:32 +0200 Subject: [PATCH 11/57] FIX THAT AGAIN :P --- unified_inventory/depends.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/unified_inventory/depends.txt b/unified_inventory/depends.txt index 8b79558..c327490 100644 --- a/unified_inventory/depends.txt +++ b/unified_inventory/depends.txt @@ -1,2 +1 @@ -aaa_recipeshook creative From 1cbe991a57945033cb38e727e59de8825b710310 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Sat, 20 Apr 2013 05:39:41 +0200 Subject: [PATCH 12/57] item pick-up overhaul --- item_drop/init.lua | 69 +++++++++------------------------------------- 1 file changed, 13 insertions(+), 56 deletions(-) diff --git a/item_drop/init.lua b/item_drop/init.lua index f51469b..131265c 100644 --- a/item_drop/init.lua +++ b/item_drop/init.lua @@ -5,64 +5,21 @@ minetest.register_globalstep(function(dtime) local pos = player:getpos() pos.y = pos.y+0.5 local inv = player:get_inventory() - for _,object in ipairs(minetest.env:get_objects_inside_radius(pos, 1)) do - if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then - if inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then - if object:get_luaentity() and object:get_luaentity().timer > time_pick then - inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) - if object:get_luaentity().itemstring ~= "" then - minetest.sound_play("item_drop_pickup", { - to_player = player:get_player_name(), - }) - end - object:get_luaentity().itemstring = "" - object:remove() - end - end - end - end - - for _,object in ipairs(minetest.env:get_objects_inside_radius(pos, 3)) do - if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then - --print(dump(object:getpos().y-player:getpos().y)) - if object:getpos().y-player:getpos().y > 0 then - if object:get_luaentity().collect then - if inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then - if object:get_luaentity().timer > time_pick then - local pos1 = pos - pos1.y = pos1.y+0.2 - local pos2 = object:getpos() - local vec = {x=pos1.x-pos2.x, y=pos1.y-pos2.y, z=pos1.z-pos2.z} - vec.x = vec.x*3 - vec.y = vec.y*3 - vec.z = vec.z*3 - object:setvelocity(vec) - - minetest.after(1, function(args) - local lua = object:get_luaentity() - if object == nil or lua == nil or lua.itemstring == nil then - return - end - if inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then - inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) - if object:get_luaentity().itemstring ~= "" then - minetest.sound_play("item_drop_pickup", { - to_player = player:get_player_name(), - }) - end - object:get_luaentity().itemstring = "" - object:remove() - else - object:setvelocity({x=0,y=0,z=0}) - end - end, {player, object}) + for _,object in ipairs(minetest.env:get_objects_inside_radius(pos, 2)) do + if not object:is_player() and object:get_luaentity() then + local obj=object:get_luaentity() + if obj.name == "__builtin:item" then + if inv:room_for_item("main", ItemStack(obj.itemstring)) then + if obj.timer > time_pick then + inv:add_item("main", ItemStack(obj.itemstring)) + if obj.itemstring ~= "" then + minetest.sound_play("item_drop_pickup") + end + if object:get_luaentity() then + object:get_luaentity().itemstring = "" + object:remove() end - end - else - minetest.after(0.5, function(entity) - entity.collect = true - end, object:get_luaentity()) end end end From 7a94e25e2b3248e3a00672c6c2c5bed39d38b44c Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Sat, 20 Apr 2013 06:51:49 +0200 Subject: [PATCH 13/57] item drop update --- item_drop/item_entity.lua | 92 +++++++++++++++--- item_drop/item_entity_old.lua | 126 +++++++++++++++++++++++++ item_drop/sounds/builtin_item_lava.ogg | Bin 0 -> 37367 bytes 3 files changed, 205 insertions(+), 13 deletions(-) create mode 100644 item_drop/item_entity_old.lua create mode 100644 item_drop/sounds/builtin_item_lava.ogg diff --git a/item_drop/item_entity.lua b/item_drop/item_entity.lua index 6e479a1..5c5076d 100644 --- a/item_drop/item_entity.lua +++ b/item_drop/item_entity.lua @@ -24,7 +24,7 @@ minetest.register_entity(":__builtin:item", { itemstring = '', physical_state = true, timer = 0, - + set_item = function(self, itemstring) self.itemstring = itemstring local stack = ItemStack(itemstring) @@ -62,15 +62,21 @@ minetest.register_entity(":__builtin:item", { return minetest.serialize({ itemstring = self.itemstring, always_collect = self.always_collect, + timer = self.timer, }) end, - on_activate = function(self, staticdata) + on_activate = function(self, staticdata, dtime_s) if string.sub(staticdata, 1, string.len("return")) == "return" then local data = minetest.deserialize(staticdata) if data and type(data) == "table" then self.itemstring = data.itemstring self.always_collect = data.always_collect + self.timer = data.timer + if not self.timer then + self.timer = 0 + end + self.timer = self.timer+dtime_s end else self.itemstring = staticdata @@ -80,18 +86,79 @@ minetest.register_entity(":__builtin:item", { self.object:setacceleration({x=0, y=-10, z=0}) self:set_item(self.itemstring) end, - + on_step = function(self, dtime) + local time = minetest.setting_get("remove_items") + if not time then + time = 300 + end + if not self.timer then + self.timer = 0 + end self.timer = self.timer + dtime - if (self.timer > 300) then + if time ~= 0 and (self.timer > time) then self.object:remove() end + local p = self.object:getpos() + + local name = minetest.env:get_node(p).name + if name == "default:lava_flowing" or name == "default:lava_source" then + minetest.sound_play("builtin_item_lava", {pos=self.object:getpos()}) + self.object:remove() + return + end + + if minetest.registered_nodes[name].liquidtype == "flowing" then + get_flowing_dir = function(self) + local pos = self.object:getpos() + local param2 = minetest.env:get_node(pos).param2 + for i,d in ipairs({-1, 1, -1, 1}) do + if i<3 then + pos.x = pos.x+d + else + pos.z = pos.z+d + end + + local name = minetest.env:get_node(pos).name + local par2 = minetest.env:get_node(pos).param2 + if name == "default:water_flowing" and par2 < param2 then + return pos + end + + if i<3 then + pos.x = pos.x-d + else + pos.z = pos.z-d + end + end + end + + local vec = get_flowing_dir(self) + if vec then + local v = self.object:getvelocity() + if vec and vec.x-p.x > 0 then + self.object:setvelocity({x=0.5,y=v.y,z=0}) + elseif vec and vec.x-p.x < 0 then + self.object:setvelocity({x=-0.5,y=v.y,z=0}) + elseif vec and vec.z-p.z > 0 then + self.object:setvelocity({x=0,y=v.y,z=0.5}) + elseif vec and vec.z-p.z < 0 then + self.object:setvelocity({x=0,y=v.y,z=-0.5}) + end + self.object:setacceleration({x=0, y=-10, z=0}) + self.physical_state = true + self.object:set_properties({ + physical = true + }) + return + end + end + p.y = p.y - 0.3 local nn = minetest.env:get_node(p).name - -- If node is not registered or node is walkably solid and resting on nodebox - local v = self.object:getvelocity() - if not minetest.registered_nodes[nn] or minetest.registered_nodes[nn].walkable and v.y == 0 then + -- If node is not registered or node is walkably solid + if not minetest.registered_nodes[nn] or minetest.registered_nodes[nn].walkable then if self.physical_state then self.object:setvelocity({x=0,y=0,z=0}) self.object:setacceleration({x=0, y=0, z=0}) @@ -114,13 +181,12 @@ minetest.register_entity(":__builtin:item", { on_punch = function(self, hitter) if self.itemstring ~= '' then - local left = hitter:get_inventory():add_item("main", self.itemstring) - if not left:is_empty() then - self.itemstring = left:to_string() - return - end + hitter:get_inventory():add_item("main", self.itemstring) end self.object:remove() end, }) -print("ITEM ENTITY LOADED") + +if minetest.setting_get("log_mods") then + minetest.log("action", "builtin_item loaded") +end diff --git a/item_drop/item_entity_old.lua b/item_drop/item_entity_old.lua new file mode 100644 index 0000000..6e479a1 --- /dev/null +++ b/item_drop/item_entity_old.lua @@ -0,0 +1,126 @@ +-- Minetest: builtin/item_entity.lua + +function minetest.spawn_item(pos, item) + -- Take item in any format + local stack = ItemStack(item) + local obj = minetest.env:add_entity(pos, "__builtin:item") + obj:get_luaentity():set_item(stack:to_string()) + return obj +end + +minetest.register_entity(":__builtin:item", { + initial_properties = { + hp_max = 1, + physical = true, + collisionbox = {-0.17,-0.17,-0.17, 0.17,0.17,0.17}, + visual = "sprite", + visual_size = {x=0.5, y=0.5}, + textures = {""}, + spritediv = {x=1, y=1}, + initial_sprite_basepos = {x=0, y=0}, + is_visible = false, + }, + + itemstring = '', + physical_state = true, + timer = 0, + + set_item = function(self, itemstring) + self.itemstring = itemstring + local stack = ItemStack(itemstring) + local itemtable = stack:to_table() + local itemname = nil + if itemtable then + itemname = stack:to_table().name + end + local item_texture = nil + local item_type = "" + if minetest.registered_items[itemname] then + item_texture = minetest.registered_items[itemname].inventory_image + item_type = minetest.registered_items[itemname].type + end + prop = { + is_visible = true, + visual = "sprite", + textures = {"unknown_item.png"} + } + if item_texture and item_texture ~= "" then + prop.visual = "sprite" + prop.textures = {item_texture} + prop.visual_size = {x=0.50, y=0.50} + else + prop.visual = "wielditem" + prop.textures = {itemname} + prop.visual_size = {x=0.20, y=0.20} + prop.automatic_rotate = math.pi * 0.25 + end + self.object:set_properties(prop) + end, + + get_staticdata = function(self) + --return self.itemstring + return minetest.serialize({ + itemstring = self.itemstring, + always_collect = self.always_collect, + }) + end, + + on_activate = function(self, staticdata) + if string.sub(staticdata, 1, string.len("return")) == "return" then + local data = minetest.deserialize(staticdata) + if data and type(data) == "table" then + self.itemstring = data.itemstring + self.always_collect = data.always_collect + end + else + self.itemstring = staticdata + end + self.object:set_armor_groups({immortal=1}) + self.object:setvelocity({x=0, y=2, z=0}) + self.object:setacceleration({x=0, y=-10, z=0}) + self:set_item(self.itemstring) + end, + + on_step = function(self, dtime) + self.timer = self.timer + dtime + if (self.timer > 300) then + self.object:remove() + end + local p = self.object:getpos() + p.y = p.y - 0.3 + local nn = minetest.env:get_node(p).name + -- If node is not registered or node is walkably solid and resting on nodebox + local v = self.object:getvelocity() + if not minetest.registered_nodes[nn] or minetest.registered_nodes[nn].walkable and v.y == 0 then + if self.physical_state then + self.object:setvelocity({x=0,y=0,z=0}) + self.object:setacceleration({x=0, y=0, z=0}) + self.physical_state = false + self.object:set_properties({ + physical = false + }) + end + else + if not self.physical_state then + self.object:setvelocity({x=0,y=0,z=0}) + self.object:setacceleration({x=0, y=-10, z=0}) + self.physical_state = true + self.object:set_properties({ + physical = true + }) + end + end + end, + + on_punch = function(self, hitter) + if self.itemstring ~= '' then + local left = hitter:get_inventory():add_item("main", self.itemstring) + if not left:is_empty() then + self.itemstring = left:to_string() + return + end + end + self.object:remove() + end, +}) +print("ITEM ENTITY LOADED") diff --git a/item_drop/sounds/builtin_item_lava.ogg b/item_drop/sounds/builtin_item_lava.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5c293fe9b4f694ede253f328c8283b69b3ebfad0 GIT binary patch literal 37367 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 n{VaahsQJ$ysm9P Date: Sat, 20 Apr 2013 01:21:23 -0400 Subject: [PATCH 14/57] new "sizzling" sound for dropping items into lava --- item_drop/sounds/builtin_item_lava.ogg | Bin 37367 -> 19225 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/item_drop/sounds/builtin_item_lava.ogg b/item_drop/sounds/builtin_item_lava.ogg index 5c293fe9b4f694ede253f328c8283b69b3ebfad0..7a53071f244256f1bde49acf894b83b31b3f6cb2 100644 GIT binary patch delta 17866 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

*$3-CBQpyb+_T(wOKZGygpg?l?VEovrJrXZV zVZAUnQHngO!LT20y3_2q%DoJ{z~~nCk?{w)!7sKfUUb*Fe_1VEsskHedQpV`lq{WL zd(0O@=Duf8V?C1T_f+_0i$lMRoJc{x*AcNHMr{oSkG7eH+geI7@-6P>SIH9??-V0T zeuV@5x^@wQ=3cTBRU=Elk$(SL-{Ot-?X5!%=GxPngLf~GY*C9Zv<8*Hip7L(DvC1b z`Pv8e%Tl5{=R*!cVVK$16?Mm|k5&N!erBZ|qA~-+EaMB3cc&&~+^U3CKASLPHwy6M zRMbD5-qx1l@M7ONZBi4Kw*KHRupF_w%X{99T3;KO+41Zyp1t|FEdrH>BKu8To)b>E ztS5*%6uZcMCWyJv)l~rKToq^(%5q4t!1%ek2U#~7r5ynsW5K_v>L`f5k2mbaH;oEF zQL{efsJ`;a`6K?a)~6!8=40bS-Xl#O3)iwUtJhTbb2j*})ckAX%WdC83E)wd0ck1P zzH!)R4{!_$mU$P{^`bH0o@(>rb1T5E!^>cNLLd%7h0*w~D=`l2afOW#`Gd!auh&nyuAcyHOW;Iy#@iQUv>EUj2I? zXd4EEAki?gFb-@ohR$b#<}n;ATmyVmx&zA zvD?E(LOoSN{cO+Mi#dC&iA$LL?sAi@=5Z`$DhaLA+}D0_&Z^dBPW}9(AO=P>+sD~QE^x6b>IyD=}-e-D$(;G6nqlpn8FX~rd6 z56AiYYr^yn-AUhs@ds#yEQ%HQ5?_buBCzvpynB9LWD%++Nuj=t!yQc6^WgdYnUL#J zldt4v>E@1^QIwfE2JgiELqfnu#I%r26zVyaj$|z|Vb11qJ^(&7tT+4z2LS|)2f?;~ zIYCto1xQW`Op{RnWt)ulo(#G5?0etwuljh9TYbG$xtKjN)sL#Ww-x%kb@QI<+$@pY zqhjgTb%eHFUH|s)>K_3o9>`T&{Os8et$oO&)znp>yr0ok6T;8+sjCr$RU79Wml$`o zg}=FTNT+y3qGeds*Vy*z@0|3r_=ux_pmTwFu^5ZRaz{j*`$LDww*dTME{=iQ*MP~> zWr~CXR}JXyJ< zTY_^e(Dd3UOveUy&hi$F$Z@fGt&?Ln!2w=1++XI4RFDLy5jg`I6w)1r}9J! z03u*5h~AZx1zqMt(|_>T@f@E(E1f=S?D(ko;IpslcK5>7-b^-)pbb$k`+z>ULD=~1 z-*hcyuHekORhdQF7RS2W7t4!qaAs}Fk1rqVS|dj_>`!o?L%u6Jy1x~rQARV@4~n{7GR zS#FklMoaClK9kptiYE40c&6KpJD2%wsn}Lxd}$aT$~2Jg8no$8q(WgKhUIa4(*e*T E0K^0W-~a#s literal 37367 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 n{VaahsQJ$ysm9P Date: Sat, 20 Apr 2013 07:43:49 +0200 Subject: [PATCH 15/57] Item drop sounds range fix --- item_drop/init.lua | 2 +- item_drop/item_entity.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/item_drop/init.lua b/item_drop/init.lua index 131265c..5033eca 100644 --- a/item_drop/init.lua +++ b/item_drop/init.lua @@ -13,7 +13,7 @@ minetest.register_globalstep(function(dtime) if obj.timer > time_pick then inv:add_item("main", ItemStack(obj.itemstring)) if obj.itemstring ~= "" then - minetest.sound_play("item_drop_pickup") + minetest.sound_play("item_drop_pickup",gain = 1.0, max_hear_distance = 10) end if object:get_luaentity() then object:get_luaentity().itemstring = "" diff --git a/item_drop/item_entity.lua b/item_drop/item_entity.lua index 5c5076d..83c7ba1 100644 --- a/item_drop/item_entity.lua +++ b/item_drop/item_entity.lua @@ -104,7 +104,7 @@ minetest.register_entity(":__builtin:item", { local name = minetest.env:get_node(p).name if name == "default:lava_flowing" or name == "default:lava_source" then - minetest.sound_play("builtin_item_lava", {pos=self.object:getpos()}) + minetest.sound_play("builtin_item_lava", {pos=self.object:getpos()},gain = 1.0, max_hear_distance = 10) self.object:remove() return end From 0992a6a6fc1a5331ee6cea5ce42adb5cc71c8a86 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Sat, 20 Apr 2013 07:53:35 +0200 Subject: [PATCH 16/57] bug fix --- item_drop/init.lua | 2 +- item_drop/item_entity.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/item_drop/init.lua b/item_drop/init.lua index 5033eca..8a7afe8 100644 --- a/item_drop/init.lua +++ b/item_drop/init.lua @@ -13,7 +13,7 @@ minetest.register_globalstep(function(dtime) if obj.timer > time_pick then inv:add_item("main", ItemStack(obj.itemstring)) if obj.itemstring ~= "" then - minetest.sound_play("item_drop_pickup",gain = 1.0, max_hear_distance = 10) + minetest.sound_play("item_drop_pickup",{pos, gain = 1.0, max_hear_distance = 10}) end if object:get_luaentity() then object:get_luaentity().itemstring = "" diff --git a/item_drop/item_entity.lua b/item_drop/item_entity.lua index 83c7ba1..3d1a83b 100644 --- a/item_drop/item_entity.lua +++ b/item_drop/item_entity.lua @@ -104,7 +104,7 @@ minetest.register_entity(":__builtin:item", { local name = minetest.env:get_node(p).name if name == "default:lava_flowing" or name == "default:lava_source" then - minetest.sound_play("builtin_item_lava", {pos=self.object:getpos()},gain = 1.0, max_hear_distance = 10) + minetest.sound_play("builtin_item_lava", {pos=self.object:getpos(),gain = 1.0, max_hear_distance = 10}) self.object:remove() return end From 0518993e5db94766b3f921d918dc32161b4e2922 Mon Sep 17 00:00:00 2001 From: Vanessa Ezekowitz Date: Sat, 20 Apr 2013 02:02:46 -0400 Subject: [PATCH 17/57] converted item drop sounds to mono, normalized to -3.0dB --- item_drop/sounds/item_drop_pickup.1 | Bin 0 -> 7584 bytes item_drop/sounds/item_drop_pickup.2 | Bin 0 -> 7635 bytes item_drop/sounds/item_drop_pickup.3 | Bin 0 -> 7146 bytes item_drop/sounds/item_drop_pickup.4 | Bin 0 -> 7250 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 item_drop/sounds/item_drop_pickup.1 create mode 100644 item_drop/sounds/item_drop_pickup.2 create mode 100644 item_drop/sounds/item_drop_pickup.3 create mode 100644 item_drop/sounds/item_drop_pickup.4 diff --git a/item_drop/sounds/item_drop_pickup.1 b/item_drop/sounds/item_drop_pickup.1 new file mode 100644 index 0000000000000000000000000000000000000000..f5ea6b9ed51a61a5d369e670599f50f0087aa9fa GIT binary patch literal 7584 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 ah1L52;DIWwyBX!I^H!-{E<4qb8u%|AyN|;F literal 0 HcmV?d00001 diff --git a/item_drop/sounds/item_drop_pickup.3 b/item_drop/sounds/item_drop_pickup.3 new file mode 100644 index 0000000000000000000000000000000000000000..3e2d1e0b1f88257bd2c8e11db00524d7d17fd547 GIT binary patch literal 7146 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 J^YBIBzW{3r#Z~|S literal 0 HcmV?d00001 From 85f2692ef04fd11de9b21d10f67e352052eb381e Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Sat, 20 Apr 2013 08:13:58 +0200 Subject: [PATCH 18/57] range fix again --- item_drop/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/item_drop/init.lua b/item_drop/init.lua index 8a7afe8..a25a3b5 100644 --- a/item_drop/init.lua +++ b/item_drop/init.lua @@ -13,7 +13,7 @@ minetest.register_globalstep(function(dtime) if obj.timer > time_pick then inv:add_item("main", ItemStack(obj.itemstring)) if obj.itemstring ~= "" then - minetest.sound_play("item_drop_pickup",{pos, gain = 1.0, max_hear_distance = 10}) + minetest.sound_play("item_drop_pickup",{pos = pos, gain = 1.0, max_hear_distance = 10}) end if object:get_luaentity() then object:get_luaentity().itemstring = "" From a594c5feefa795cd1e1d2764b36482e47d4d9c45 Mon Sep 17 00:00:00 2001 From: Vanessa Ezekowitz Date: Sat, 20 Apr 2013 02:28:24 -0400 Subject: [PATCH 19/57] item pickup files were wrongly named. --- item_drop/sounds/builtin_item_lava.ogg | Bin 19225 -> 0 bytes item_drop/sounds/item_drop_pickup.1 | Bin 7584 -> 0 bytes item_drop/sounds/item_drop_pickup.1.ogg | Bin 9981 -> 7584 bytes item_drop/sounds/item_drop_pickup.2 | Bin 7635 -> 0 bytes item_drop/sounds/item_drop_pickup.2.ogg | Bin 10477 -> 7635 bytes item_drop/sounds/item_drop_pickup.3 | Bin 7146 -> 0 bytes item_drop/sounds/item_drop_pickup.3.ogg | Bin 9586 -> 7146 bytes item_drop/sounds/item_drop_pickup.4 | Bin 7250 -> 0 bytes item_drop/sounds/item_drop_pickup.4.ogg | Bin 9696 -> 7250 bytes 9 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 item_drop/sounds/builtin_item_lava.ogg delete mode 100644 item_drop/sounds/item_drop_pickup.1 delete mode 100644 item_drop/sounds/item_drop_pickup.2 delete mode 100644 item_drop/sounds/item_drop_pickup.3 delete mode 100644 item_drop/sounds/item_drop_pickup.4 diff --git a/item_drop/sounds/builtin_item_lava.ogg b/item_drop/sounds/builtin_item_lava.ogg deleted file mode 100644 index 7a53071f244256f1bde49acf894b83b31b3f6cb2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19225 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 diff --git a/item_drop/sounds/item_drop_pickup.1 b/item_drop/sounds/item_drop_pickup.1 deleted file mode 100644 index f5ea6b9ed51a61a5d369e670599f50f0087aa9fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7584 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 diff --git a/item_drop/sounds/item_drop_pickup.2 b/item_drop/sounds/item_drop_pickup.2 deleted file mode 100644 index 0ed4869c6dd1cb1329924d9782de08769ac82054..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7635 zcmb7I2{@G9+kfn98oLUO5MwDL6j2OfhAAdv89Uh{Yo$^uJ0XVb*~T(<*=4Kj`!<%8 zB>PfCw(vcp_x*qG_5ZH#|6Sj?&YU^(+|Rl1b1%Ph-)C;v+1&&vfxlWNP-IA+j-7v- zMZr&T_l~=jg9rHmg<3xO3ji92D2~3XC~lBf{;QE!k}2`1+sBS89saY;Q~lv136c#R zTJ_wc-=MJ*^qZSnK1=R#JUUDEyI66ys zyZeQ1tV`&!%l2PTzp01Dg3Zg+;I7TcU9XY5K1Ol=##KH>RsP1K{-#_0mOKG}^=+TY zEpk6n9ZCVD3d+Y$!_v>3O#dpMPURPnPYK*2n*_=bbp{rdfy}aXEObb$u+OV-?ktt) zEM-1=1)u<5A-7bAgslJ3ZH;1W{_n1A-zEkqgSKpS<85^lQpX6jx=YXE+yL&_X_}@+-yBz?O;k?amyzQVhFp`7rvIZVXBOd4x&=h2g z{O9)cC|*EC1d?rI9ewF9L|Pu1#TR7DlSZ$~{6`Y_LQvW_XhL7Y&u)2^gqhS_j>N&H zV7)|<>fE@*BM;v0IWZ0T64nvloEqPk;L(F*P9Xf5d9x+b732kR=e!?-{`ooeFP*W%9oWzlO?vu7f!tLhyWcq&XA- z{2)hB{P%Da%73CbGb%)^L-b9Tbf*M)$ba9XuvGjWqRI>hqgX-~jN%vNvnd{h@|sSB zauQCQfXARr3ADmqJ>lLg)dB?sb_PKV|ya)pcdiH#trFIlTtCY;MY#4$9gLVr_=++Kg4$ z7+3ljRs02*Kd_k`@%jgH$PhUrA3m)aMg8B%NfizMdMR8G86{*Cb=Eu9E;u1KK4l>{ zo$=q0V;_f=kUA`b9+UwM8v_6* z0N_^B7Ss>Ik}-skQnBw+q0Rl4s)8g8lb+8)E`-T{kMWB_qLd7KR6a!hgbK8BSfd=o zC2fXynv~}z+-4xu;IT&y=mLN*JOKWI$Gr#Ho~hOYhb80N04@UPzzeEu+OD zti`T=gTrQo9c>UR)6F5PtB37m#}4aZKXRe56~btCb@YZFmR%joi5-kZW6Pa;Wt_+K zOh0j9v6VI-fB6_x_)lIy8*yQWN$BBnuaQ_E^9nE1IGJu4GAlF(cGwg9Ne(+wA*<_Y zs*ANT(!(0*+l+DP8V2f?#Jg-z@nJE6T z2BeA;i4vhiu}A%`X-Klk|dM7(oKcL9(372_@OWfx4_P(G;h7c0lAlMR#NaV_9222T9~DxP$zkjS zCy}fQz!e~?7`&CXG6C28Cmegol>= zEnKW5CJLurGCYdQmo4YAb}S)rSr@=b=#>5=f4q<|oO* z*^EVV$-+TH90|w$E!@z_QL^P|SBBPwO0D|VHwwUA<(HT1JLSvH8Cn;CRTJ|iFh9lV z&@vt~VgS@A0EnMxa}u6bpfxE25B(7L952=i#Sh?`dGQ$BQd0B)CM@|mhOEF4F04Ej zj{~&;D^f;Yu>QK;hd1O+C7(fmaE}O6v5(a4fYZNFL4h8^guv%A)ll%+BzzZqPAC%( zpX0^j5%h%20StW_9*+?R3zs9@)1rf$DZmY}k~ajjKwBWz^a^wW(QNWUSNb3CqCX#B*(;P)>vxN}!R27yL;0fhQRy;0;y^aI#zvS^)wt zn4zCXV!FUIZ3S)!>Zb#1iSvLU+IT%!z+82!OP)@^528ROAn21p0=)npJgWr2&;m~= z2m(d`cS%V;;!df{iSRIp$=nhKBI&>o&%k?NFphXIdc+FU8R4{PnIy56r06J27^ig) z5=o9)7#JT;bfB)dymEXL=63n42^iBYIFIX~@0<#ivcd3^ott0+8cjjKTrSqVfcH*BT(cbSrc|tDQA)sYD*k>;PJSAR6WbL@>qkWO(GZ5U?oB(faM5SR+DRzFpvQL z1eGP1DF2HRkTc|h!6EagYLFq94o9>9&masM3C#HrM!@Z@E3gs&PbG56IfYT4CfQH# zBq8Z}BnkzSMahc@fKu|vmU1d-Hk20;CXjIXCE(A{a#Dhah%g9=f^slZd-Mqq zxSYB{BWXF6fF3=5C2rKJpl&PWp$?p6@_bc=KFum$9`w}ldH{%~rvpCFoYL301Utzj zLB3T$r~oNyKt(ix0`O&E0dFk&#o}+u95bqNqu!bbywy+;goPgN94Cem6g3+bTB!C&tJyxp~bcb%fu&3q; z>H@z$n14`uEKWR4wGG(;Zy~{GLG7VHqq1KYH6@LX1(XV4fv{x)zV9eiTU}Wpky>q{ zQlh-~1fHLIF1+_C)a82zT+K`Y1z{2gRz-d5QMsDETxztX8+tY32DdZW%56VTS zqfE(iy=p4>qT&>-$UH}k!k-G98n_PtnsUBDLH4tk6cn#0Bh;>GqO`B;{JB8V16Keb ziUWG)OoDtkOT_U=$V=8JwrF-dSY`idP$=|h0^ZyJDD>zCNj(Oh7UV|0L6Z5zbvgEO zp2ry)V-L9(R~I+e7Z-nQ{rLHNT}zFkS8bIM*;4C538A1cTd<)z0AIq#~77@#AW3TEc|NV?q-iGHoxws52yH6Zr#9|W7+4= zr7Swd^zFr?T<&@~;&z3156U9vV^6Ldq(uY@)&%UVEQmw%A9Gu7yVaZfD?T}xSZZJR zv3p3NM|momN89;Qr^xHc&v*HY!VQ)-2QR-LZocx(ZG9)kst)608n}OV{wl_~&W38@ zjnZ1Gp;cdiBlpIy+Nlj?kI+Kf&BH-q_Z=eAm>D?8)u0O`)dmUzA8;a0OJdv_Wpexn zo&(<1CM`>|3rdT@t+zj1uAuY1U-tR30)L^t!OI_$hnDZB z=gckN_^-u2^xoP1{(J8UfE%FLdaAm9?ydwSp#3a6$q>5T=Cgj;_X6(G?j9l_C1Vc5 zT$i!ysx`V#4XIb@wmNw8PW#1Y!Ig-f@h1&S3%jlq5xev4=&_~KuXk%!e~)iNDZ+CN zPoMo6@#{9X`Z-{n-nrC>*^&JTqMS?j z!T>O#%{LAwrzUMee-}B_PpvgvH6U1fWD}QH9|n)kJqbLH>4)l{ayp;7RC;CSI$x|2 z%gsavhPNdJp)82o(&v3fh6@az#5M;Z8`h>K(67{oCk_kqib++u+!2e9xH;UaM%Jv- z4ptV~RSX0znXxv+OaW7$nanOsZS5b?48?!{^))eS5o0N9Spt3d{dLQ6m zuKc7N(Vf-vD(9Ri4Sn&35|tjmdMs7X7loHKmcZw2lhJQLrWi!Lm;sO~b%Es4{4kNX zPFiiF_2mZ|L*IUQTv0o5xlaB~{$MrDrZHNu{#AUAj?-jwJ|irC;~BJxqkyi`!7Mu! z$3J?0Qy3#@F7>HG=XZ2=uR7iLL*m9&X|ZvM>t`I^N530+(W*VCzN;FMMwor^6kNb8wn&1wsLdYC=Va?ysGgDP&jvUG2L$oaHr=Z5rro}K@a zi}70_BJfyLX-)B*THM-kUp~Osrcxh}1r!aWqlGybfqfbvDz#azh8g89QEgFNqsA+K z<_Y>u_DFG^r{9C^olV{$WE^q!+%@sb(KbIdIF*(%^jEh#O?kD7LhHI8`rOxvcDpE` z2+I&tD=dmZMzb<_y+KV0iW7X5{1(6P=ix7)CZ9=L-5D2k-3-6_*nEcPYVy7+T{Uz& z%`m$i=w!O^R{xlM6^#09@cVbN@#$e*j3M-+@Q8~abt-YH^L=#1eBSB0P?sr&^0CTG zX(WU2aIJBJsFiTJ;tIaL)mWdN_GpV6hpI^`DGn{_boDU6tWB{|v0}=(DHzl?m7Rem zXC34Il(-`b@B+S`-D5#_5^O`qg@N$FyoT32(bqQh7}EJY$JHa!cxCXqv6oPC`j4rK zxmrpnpOrCvTFqkNzW!N$pY!4G^*5$#<+TSl)U6l$t84g0SmIYt7n+rjYz{IuFMh=! zAB@$eN^xj(#4i!rB|fH2PR-5Ud7Ed5#*Jw(EJ<}{T^^+?Xdzfk7`tWD@ghx{UT(Y! z(};bM5}>6rNq_9iJ|ympQK5v zcXdwb-T6m7z3xoN}>trT`Pm197d{1jVDSb*!^X7P^) z8+Dsk&tLheHaBjEWz9r~+DqCypZ*^Db*;W)q&3uJbDhy*YQaEoQ2#e-sl;&fQWq)u z{5EdgfsMLv&stbHB27eQX)rc~Ik$k{IcgrsXN_k6oaP^tb6Zi~ouW$6OfE0g@pi46 zVeS5#^L(E^1d877;4*}ofr?2*?rbytU(S;={cu&%u4-{-p zgPtWjzawSS5kJ!Ja-J=TN1h<+i@|IY(kJ$pJ0^B77$U`6u9#I99OfddnP&0|$A;yU z>8v!|=@F!}{zXy0)H90x52vSM$CJw)7NdToMNtlYjSnGC#0X8l@~#rBc(nJBuVYKL zo72p)w8&unGe!Shf%rNnGvkX-eIrFo-Y=HzP-T)(gy&jKwc{IC%qidA_tEE|Yy9L> zY88XCCJM08Fm5te3k(X&pq=L=e^*p*$AXKD0GBD*_ zOW)pG`O$4i)<7Zd+*|L8C-zFnME?}l<8s7DZlR{fb$Ul?U9A)Z^v(L*AR0!Y;d0P% z!pgmpo;6|H(+tnp;6C)nDke-7pS*c+@p<0VSjcy()8ASwHH})-?{vSoQSeo;`V-Rx zy?Mof-{QN~&QyhTw5h@Ues)1jh*Zt}&B}L(plZbZS;NShDF)WwGLe%ODFW=qpO->I zLcO`htN~U^v%t4I-X`yF9|EJ)0R6>XKd}oOm$(fROn^QBAijREvpnZKWoe`7I(Iyx z@(h7@h|S6e(6(O8`o!C1;j-yHnorNQIMRF}W4|gK2hgoulYEe@G&;8Vx)^qDymxip z#pb4RgjuS#uABDs{hVoA#GbjVji;ICl%0|p#IItoC_>}9KR%AB#s_IzP-6aY_* zS~W)?BGw^68fcUSEHLF3rRZJk1(ymVrig{lBIBn5)QBc|9NKhFSvEswHg%_11uJwO zd)}{8eLeGphUg2s(i{BjX3wvWr%wiZl;kJ$Y-69i4ycxS?7?wg2>T))KSZzDdLzPs zCB>pPa{GDR`AJF>p_bF{K1JXj`hKDRy+GqI`R!%9$93D;qB18*Z3gM0F!aj2yEv_( zYr>DntKNK91d>mGf0>!t(|yKSL6i61r>i1aLBlEAb8aJa^!j$guF>nV;kcY>gHhp! zR6@DfYks8|6658q9;#nX`oO`j%cz1x+wjU+_5d_^zY$L(Mu}U~_Ot^4H{d%X`}oi? z<_S40nchHGAhZ8i=VEI--5`%3O+PPuvk<|ghw9FfZ8<^x z{b#*}?o-jZyRW9=q1zO-vAgRgxF*KOt#^FtWYQ#{(uRA)?9<`P!F_u&F+H<(k!NcB z7&}pHD=A2OBZHW9$AHb35!1eY{a&7Y5)K=uh=WaPjrAty3ipnm9iNe2ax(Qc^%SCBIkHQipFdkq_>rRoczpqAevfTP(+@^?V zpt?TVcf7zT!*7Y@gxda{Y(jT&__Vc|kH?jo6P1_dj~VAEtR4?rc=X}r;?wsEHC^T2 zwxuq|SYLEN0@CcT>cGOe@b`Q@4@`@^mg}VoQ!PB&I5ot(6@?l$X0ow5JDh4?&3n@W z+@HT7ER2V)A|5v-PSJ6H>Axp(iy`J){vks0~MUx*vnpaFi5tsA$z-$UMgGo&d(g6XRLczVn62gq~P6>x1fwSuGUz1sjZ>RCY>1o|RrP_PaGELzlgr z|1@Kmbtz)P$75dK`t`bPN{^!2{h5f8neZ%%R_5WZgCW`VkHJr|af1CGxa4)=$x^C_ zJ#5vwz?B}DY)G6csp9*EtLtjNSULC&hb(JMR0jARk$F;Xv8UT!j;>siv1>q|w>@k! zZ4yCqok#+HT=qm=J2E06<35ut@=C zoWHm7%^{5xejmtxA^^(Lvb8j{9|NPm>wOnEq4zLqMM-Gv*-NeccXdpWH;@&*4pMtl ah1L52;DIWwyBX!I^H!-{E<4qb8u%|AyN|;F diff --git a/item_drop/sounds/item_drop_pickup.2.ogg b/item_drop/sounds/item_drop_pickup.2.ogg index f58bf08e00f206d3e433b28ddf2297d1ada1a853..0ed4869c6dd1cb1329924d9782de08769ac82054 100644 GIT binary patch delta 6215 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 W1ft68uf+RU)aiUy&±pW*5Cu@EH literal 10477 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 I^7ShC4+bz0#sB~S diff --git a/item_drop/sounds/item_drop_pickup.3 b/item_drop/sounds/item_drop_pickup.3 deleted file mode 100644 index 3e2d1e0b1f88257bd2c8e11db00524d7d17fd547..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7146 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 literal 9586 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 U1v_AG(2P=Jc3}msD^mdf2RBqq4gdfE diff --git a/item_drop/sounds/item_drop_pickup.4 b/item_drop/sounds/item_drop_pickup.4 deleted file mode 100644 index 13430e2046c4f79fb27277fddd7bb22ada811c4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7250 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 J^YBIBzW{3r#Z~|S diff --git a/item_drop/sounds/item_drop_pickup.4.ogg b/item_drop/sounds/item_drop_pickup.4.ogg index bfe99d9a37181071db8a5fa22214535ef850c31b..13430e2046c4f79fb27277fddd7bb22ada811c4c 100644 GIT binary patch delta 5827 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 literal 9696 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 Date: Thu, 25 Apr 2013 18:45:15 +0200 Subject: [PATCH 20/57] Add framedglass mod that uses new drawtype --- framedglass/depends.txt | 1 + framedglass/init.lua | 77 ++++++++++++++++++ .../textures/framedglass_glass_face_clean.png | Bin 0 -> 926 bytes .../framedglass_glass_face_streaks.png | Bin 0 -> 951 bytes .../textures/framedglass_steel_frame.png | Bin 0 -> 740 bytes .../textures/framedglass_wooden_frame.png | Bin 0 -> 387 bytes 6 files changed, 78 insertions(+) create mode 100644 framedglass/depends.txt create mode 100644 framedglass/init.lua create mode 100644 framedglass/textures/framedglass_glass_face_clean.png create mode 100644 framedglass/textures/framedglass_glass_face_streaks.png create mode 100644 framedglass/textures/framedglass_steel_frame.png create mode 100644 framedglass/textures/framedglass_wooden_frame.png diff --git a/framedglass/depends.txt b/framedglass/depends.txt new file mode 100644 index 0000000..4ad96d5 --- /dev/null +++ b/framedglass/depends.txt @@ -0,0 +1 @@ +default diff --git a/framedglass/init.lua b/framedglass/init.lua new file mode 100644 index 0000000..ebe88ea --- /dev/null +++ b/framedglass/init.lua @@ -0,0 +1,77 @@ +-- Minetest 0.4.5 mod: framedglass + +minetest.register_craft({ + output = 'framedglass:wooden_framed_glass 4', + recipe = { + {'default:glass', 'default:glass', 'default:stick'}, + {'default:glass', 'default:glass', 'default:stick'}, + {'default:stick', 'default:stick', ''}, + } +}) + +minetest.register_craft({ + output = 'framedglass:steel_framed_glass 4', + recipe = { + {'default:glass', 'default:glass', 'default:steel_ingot'}, + {'default:glass', 'default:glass', 'default:steel_ingot'}, + {'default:steel_ingot', 'default:steel_ingot', ''}, + } +}) + +minetest.register_craft({ + output = 'framedglass:wooden_framed_obsidian_glass 4', + recipe = { + {'default:obsidian_glass', 'default:obsidian_glass', 'default:stick'}, + {'default:obsidian_glass', 'default:obsidian_glass', 'default:stick'}, + {'default:stick', 'default:stick', ''}, + } +}) + +minetest.register_craft({ + output = 'framedglass:steel_framed_obsidian_glass 4', + recipe = { + {'default:obsidian_glass', 'default:obsidian_glass', 'default:steel_ingot'}, + {'default:obsidian_glass', 'default:obsidian_glass', 'default:steel_ingot'}, + {'default:steel_ingot', 'default:steel_ingot', ''}, + } +}) + +minetest.register_node("framedglass:wooden_framed_glass", { + description = "Wooden-framed Glass", + drawtype = "glasslike_framed", + tiles = {"framedglass_wooden_frame.png","framedglass_glass_face_streaks.png"}, + paramtype = "light", + sunlight_propagates = true, + groups = {cracky=3,oddly_breakable_by_hand=3}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_node("framedglass:steel_framed_glass", { + description = "Steel-framed Glass", + drawtype = "glasslike_framed", + tiles = {"framedglass_steel_frame.png","framedglass_glass_face_streaks.png"}, + paramtype = "light", + sunlight_propagates = true, + groups = {cracky=3,oddly_breakable_by_hand=3}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_node("framedglass:wooden_framed_obsidian_glass", { + description = "Wooden-framed Obsidian Glass", + drawtype = "glasslike_framed", + tiles = {"framedglass_wooden_frame.png","framedglass_glass_face_clean.png"}, + paramtype = "light", + sunlight_propagates = true, + groups = {cracky=3,oddly_breakable_by_hand=3}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_node("framedglass:steel_framed_obsidian_glass", { + description = "Steel-framed Obsidian Glass", + drawtype = "glasslike_framed", + tiles = {"framedglass_steel_frame.png","framedglass_glass_face_clean.png"}, + paramtype = "light", + sunlight_propagates = true, + groups = {cracky=3,oddly_breakable_by_hand=3}, + sounds = default.node_sound_glass_defaults(), +}) diff --git a/framedglass/textures/framedglass_glass_face_clean.png b/framedglass/textures/framedglass_glass_face_clean.png new file mode 100644 index 0000000000000000000000000000000000000000..385d6d277307bd70b896b2a374077964b42376f1 GIT binary patch literal 926 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GA|hznEnR%gt#tS za&p;{b1RpfT(RuTsugD!FTS#9(bXl3udH2rYwOm#J9gaLwd?+Y1CNg!d3@~H(=%sY zT)g<|`t>(=?!3Ey|HH$FAD=$`^!oMJj~{=2{rda+_g_DL{Q33k@1H;a{{8z8v~CoP zhQMGB0md&g=L6lxSQ6wH%;50sMjD8d?NMQuIzVNL^%z$9 literal 0 HcmV?d00001 diff --git a/framedglass/textures/framedglass_glass_face_streaks.png b/framedglass/textures/framedglass_glass_face_streaks.png new file mode 100644 index 0000000000000000000000000000000000000000..eb169d177c3da69cb7f4d1e874681c20d47df6db GIT binary patch literal 951 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GA|hznEnR%gt#tS za&p;{b1RpfT(RuTsugD!FTS#9(bXl3udH2rYwOm#J9gaLwd?+Y1CNg!d3@~H(=%sY zT)g<|`t>(=?!3Ey|HH$FAD=$`^!oMJj~{=2{rda+_g_DL{Q33k@1H;a{{8z8v~CoP zhQMGB0md&g=L6lxSQ6wH%;50sMjD8d?NMQuIzVNL^%!Fm*3`H1Qb&9ba4!kxSX7zz|G;PA=tvf&&A60N5E@FV->??p*SAF dL>@t4hD?%V*mzO-;dG!522WQ%mvv4FO#sqFc3%Jh literal 0 HcmV?d00001 diff --git a/framedglass/textures/framedglass_steel_frame.png b/framedglass/textures/framedglass_steel_frame.png new file mode 100644 index 0000000000000000000000000000000000000000..383eab7b132ed8158fc98e87a056a0b7fc0b1550 GIT binary patch literal 740 zcmVPx#32;bRa{vGf6951U69E94oEQKA00(qQO+^RY1Q`Jy7<>xWIsgCyc1c7*R4C5{ z!CRA}I2ZuXF9{d91tMZA(qm1(ZSBmT+p4YosZ-Va(6iWzfXZFyK$1NN{r%5hflt#@ z8i(P%9X#p@DTNRSA)nHsER!V3&KK&_;rY}w4HH7@rv3THpSP+Gd~cp-B_#`jm1XtA zkR0~s^V#$1IF0~dSr+y@4`c086wyAO_za-pIKJIV17iTl^U`tb=P&?36h(DilOI2S zIF2)pPa%Yqa%EX<+it=z&kLPkg^-krV2lZ=>-unr@ga`7uJK%tb8ebu-}gi#r}PvC zju2wKUK2t9A%qZPEc^V#r}Q&oLEp6mW81cMO`FDPWg7S98E#*ysuDs(QG^icy3RBV z><2;J_e9e?&nvFkA&#Y#K!{7-G)+OldcDrC*Ke<{7$E@&&x=qB0!G`eO}-t|(~0^X zCS>L_LWHs4e!p*`=>6Y!#sUR^rIbMsJRZ$4Ib@ehz}Pr`DW#NB$?M^ED|aC~XPM{G z`=bH?ObA()zPpSvA|xubako902J0 z9us03no#hvd%>H{rYv&XwxyJYu8-4~Wm#p_?zh{=3?Z^To2v z{CcH30|_z*Ff>8EDPVddq?jc zV$pGHPc5&#`sUp1esklKze@Y0&(;5DkXxZ{)?6Q4&eK9$| z_Tt}z9=npJ{t<4n3A(Jg&~KB8&;cjropvcZO4dYsp4_xZfUounSHMFz<~i#a`(0ms z+g$yB<*7Gu6HI6AuwNN5H8N!Nnn{bgQk(M%E^B6+ob9sNm9Wfgu2s#pn$|rHM{M6~ e+?mZ@z$o;%?DXGEPj_GlF?hQAxvX Date: Sat, 27 Apr 2013 10:04:17 +0200 Subject: [PATCH 21/57] Add HV wireing --- technic/init.lua | 3 + technic/textures/technic_hv_cable.png | Bin 0 -> 1705 bytes technic/textures/technic_hv_cable_wield.png | Bin 0 -> 601 bytes technic/textures/technic_mv_cable_wield.png | Bin 2996 -> 531 bytes technic/wires_hv.lua | 398 ++++++++++++++++++++ 5 files changed, 401 insertions(+) create mode 100644 technic/textures/technic_hv_cable.png create mode 100644 technic/textures/technic_hv_cable_wield.png create mode 100644 technic/wires_hv.lua diff --git a/technic/init.lua b/technic/init.lua index 58e0488..2b85d26 100644 --- a/technic/init.lua +++ b/technic/init.lua @@ -34,6 +34,9 @@ dofile(modpath.."/electric_furnace_mv.lua") dofile(modpath.."/alloy_furnace_mv.lua") dofile(modpath.."/forcefield.lua") +--HV machines +dofile(modpath.."/wires_hv.lua") + --Tools if enable_mining_drill==true then dofile(modpath.."/mining_drill.lua") end if enable_mining_laser==true then dofile(modpath.."/mining_laser_mk1.lua") end diff --git a/technic/textures/technic_hv_cable.png b/technic/textures/technic_hv_cable.png new file mode 100644 index 0000000000000000000000000000000000000000..7cb368d46053c2dbc0f68e14ba5900ec59015597 GIT binary patch literal 1705 zcmV;a23GlrP)Px#32;bRa{vGf6951U69E94oEQKA00(qQO+^RY1RDoBECSMZ5C8xMJ4r-AR9M4Z zS4n%@I1^xB17z3>}@;t|5o8a4vLO&^7 zMuq1u5vr<^JDN7dkNbJ``Du@$D4?}QRaFRGipxlk53_;~iCkXSHCi9zJW%X1Dmb@? zwHA4vLu-xhnBezC;rc=G<0(Z^6fnlX7=zOvDb9n!{I2l*r-I@@Q50|?Mn5SGS9&0H zsT?%MAan_aSz){>y!CXs)*9AYSZfiEboqFr>Ya~JmL;mHf-wfZi!sa!^9NP$L$)N~ zyBL>|g8ii6Lxe2Lq`LLv!>r(31g$lUF-VdGt=r);DopP*me%bg@ia{lj&%NVAB*!b zj4@DUS;B_|{X~bytAY^2?Ho;}2U_U7wkBQ9FT8r+K(9ExNx$`l!*7AV!5&B8tJW}O8#K`j; zWm&>n3l}K4@wOz#V6N*L>g6W|&cia(s;cPmV@gP#Xl8A@M_t!)d3Rirzkblnxhq<0 zI2YlqUn&n>Du6e};J=^uP)wx|D6_IG>9CJ5-RSZ8U7>XmilUGUoR9GPLY?U+1@HIL znX)W}P25@MW9h6h1}?-Ht_o_n11`^Vq-hGq#4s;xa6Xcm^I^sWp*fO=t+fapb%xLL z{bgCAC<=7P6w{58Q(yl|kY$;){q#pJRAMx5D!ZfkcTbNWPbnTA9#GfyJ-NMLqMztI zCsvjv9-AGp>8kMKRY6&61(B`a<1*6YgjP~89!+=JR_1&xBhy;LcUwR=?GANaOY2>T zgvysup=o2Hp|uvyNAmbE6C1c{tu?w+hPQsoXJ07b!AXjl{loQrTCsI8ZA5hEikA3b3Sb%gn8{XdP94 z9$6%fuTl(_Mbu9(kT4NfMN0iPr6fEyJwv@Bi$e zilRW8rf`n5|Lwl*G|gV5mo4=?toMaQLGwJv@w6BhV}ikItre;+@=TVmXeR%!-3ih( zmFilz%zP~}VoYJ7^4ijw&b;h!az3P@BkHl)9{%*W6HC@wqjfvc_P2haT9S}nbf;xg zB21(kK)VoQyi(`ZJ0jb<`rmgt*iQ=GF%idF8xJodK17=ZbItR9QfQig$^KVW75u%k ztdP73F%f}SO+fS>eF&pPzJ4fd8GiibRI(L>ov9wRb^3}_-49{O8sOyKq%d5iUW3+L-&rgwTuiw5aG;Ok>(w9Fex$&y- z`itW0ed6gk64(3rs?fSr98qhHFJEJvM}>a?6YArLvYKQW00000NkvXXu0mjfG!sCl literal 0 HcmV?d00001 diff --git a/technic/textures/technic_hv_cable_wield.png b/technic/textures/technic_hv_cable_wield.png new file mode 100644 index 0000000000000000000000000000000000000000..7b9ca5888de17da6042d4dd96b2a06b84a511475 GIT binary patch literal 601 zcmV-f0;c_mP)Px#32;bRa{vGf6951U69E94oEQKA00(qQO+^RY1RDo611_6Zh5!Ho>q$gGR9M69 zl+A9_P!NUB+?1wC?TCf%xN5iX2)qO00qTSuD;C6&*v0M+K@$n_3f&;2rm*D|cnBnR ztXP1Q(AfE@4-4D*p+u;Af0Csu9cj+Fb7u@xR8&+{RP5m7#G|#A)>?)=my1leWd22w zL*LIewU%M8wWaqXhraL8SEaRgX3!ga$ICmZ^U z(53JD)WWff$3v!98@I z&dsaWxp^`L;=Y5?WgQ{{00`PC&WFD@%$;?(j0igORX7sZKWxI(YJf2iBey&7>-!HN z4~RWu@b=vpA{)g=4FCj5oEGL~XQIA?kD~^F3?vYA<~ZN#jDzP7ej?8tF zizLN-I>RzaAyVGl#nq?*5rHuVK|95uFi(nS$;|-~vwD_I{r!hJZ_*hS$!z8GUzW@V zuH1xjpvHd>ocdI?^gNH<(Eazos=fOb#AgoGTB<6Kjx76;vs$x7CJcM)aK3LD#kY0U nd`*v!Jyt)qii(Pgie3Bx#KS2Eb2~;<00000NkvXXu0mjf25=5J literal 0 HcmV?d00001 diff --git a/technic/textures/technic_mv_cable_wield.png b/technic/textures/technic_mv_cable_wield.png index aca9fd45afbb97f1028dfe97d278db7de734b73d..2d41e27d56b50246421c251ff99b877cc95a9988 100644 GIT binary patch literal 531 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 then hacky_swap_node(pos1,"technic:hv_cable"..rule) end + meta=minetest.env:get_meta(pos1) + meta:set_float("x2",x2) + end + + pos1.x=pos1.x-2 + if minetest.env:get_meta(pos1):get_float("hv_cablelike")==1 then + x1=0 + x2=minetest.env:get_meta(pos1):get_float("x2") + y1=minetest.env:get_meta(pos1):get_float("y1") + y2=minetest.env:get_meta(pos1):get_float("y2") + z1=minetest.env:get_meta(pos1):get_float("z1") + z2=minetest.env:get_meta(pos1):get_float("z2") + rule=make_rule_number(x1,x2,y1,y2,z1,z2) + if rule==0 then hacky_swap_node(pos1,"technic:hv_cable") end + if rule>0 then hacky_swap_node(pos1,"technic:hv_cable"..rule) end + meta=minetest.env:get_meta(pos1) + meta:set_float("x1",x1) + end + pos1.x=pos1.x+1 + + pos1.y=pos1.y+1 + if minetest.env:get_meta(pos1):get_float("hv_cablelike")==1 then + y2=0 + x1=minetest.env:get_meta(pos1):get_float("x1") + x2=minetest.env:get_meta(pos1):get_float("x2") + y1=minetest.env:get_meta(pos1):get_float("y1") + z1=minetest.env:get_meta(pos1):get_float("z1") + z2=minetest.env:get_meta(pos1):get_float("z2") + rule=make_rule_number(x1,x2,y1,y2,z1,z2) + if rule==0 then hacky_swap_node(pos1,"technic:hv_cable") end + if rule>0 then hacky_swap_node(pos1,"technic:hv_cable"..rule) end + meta=minetest.env:get_meta(pos1) + meta:set_float("y2",y2) + end + + pos1.y=pos1.y-2 + if minetest.env:get_meta(pos1):get_float("hv_cablelike")==1 then + y1=0 + x1=minetest.env:get_meta(pos1):get_float("x1") + x2=minetest.env:get_meta(pos1):get_float("x2") + y2=minetest.env:get_meta(pos1):get_float("y2") + z1=minetest.env:get_meta(pos1):get_float("z1") + z2=minetest.env:get_meta(pos1):get_float("z2") + rule=make_rule_number(x1,x2,y1,y2,z1,z2) + if rule==0 then hacky_swap_node(pos1,"technic:hv_cable") end + if rule>0 then hacky_swap_node(pos1,"technic:hv_cable"..rule) end + meta=minetest.env:get_meta(pos1) + meta:set_float("y1",y1) + end + pos1.y=pos1.y+1 + + pos1.z=pos1.z+1 + if minetest.env:get_meta(pos1):get_float("hv_cablelike")==1 then + z2=0 + x1=minetest.env:get_meta(pos1):get_float("x1") + x2=minetest.env:get_meta(pos1):get_float("x2") + y1=minetest.env:get_meta(pos1):get_float("y1") + y2=minetest.env:get_meta(pos1):get_float("y2") + z1=minetest.env:get_meta(pos1):get_float("z1") + rule=make_rule_number(x1,x2,y1,y2,z1,z2) + if rule==0 then hacky_swap_node(pos1,"technic:hv_cable") end + if rule>0 then hacky_swap_node(pos1,"technic:hv_cable"..rule) end + meta=minetest.env:get_meta(pos1) + meta:set_float("z2",z2) + end + + pos1.z=pos1.z-2 + if minetest.env:get_meta(pos1):get_float("hv_cablelike")==1 then + z1=0 + x1=minetest.env:get_meta(pos1):get_float("x1") + x2=minetest.env:get_meta(pos1):get_float("x2") + y1=minetest.env:get_meta(pos1):get_float("y1") + y2=minetest.env:get_meta(pos1):get_float("y2") + z2=minetest.env:get_meta(pos1):get_float("z2") + rule=make_rule_number(x1,x2,y1,y2,z1,z2) + if rule==0 then hacky_swap_node(pos1,"technic:hv_cable") end + if rule>0 then hacky_swap_node(pos1,"technic:hv_cable"..rule) end + meta=minetest.env:get_meta(pos1) + meta:set_float("z1",z1) + end + pos1.y=pos1.y+1 + +end + From 00328622d9cc38a7768a7bf449f5c52ddba666f7 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Thu, 25 Apr 2013 21:39:08 -0400 Subject: [PATCH 22/57] Store configuration in the world directory. --- item_drop/depends.txt | 1 + item_drop/init.lua | 104 ++++++++++++++++++----------------- technic/config.lua | 49 ++++++++++++++--- technic/depends.txt | 2 - technic/init.lua | 8 ++- technic/rubber.lua | 26 +++++---- technic_worldgen/depends.txt | 1 + technic_worldgen/oregen.lua | 4 ++ 8 files changed, 122 insertions(+), 73 deletions(-) create mode 100644 item_drop/depends.txt diff --git a/item_drop/depends.txt b/item_drop/depends.txt new file mode 100644 index 0000000..b88d3ff --- /dev/null +++ b/item_drop/depends.txt @@ -0,0 +1 @@ +technic diff --git a/item_drop/init.lua b/item_drop/init.lua index a25a3b5..db1f2a3 100644 --- a/item_drop/init.lua +++ b/item_drop/init.lua @@ -1,66 +1,72 @@ dofile(minetest.get_modpath("item_drop").."/item_entity.lua") time_pick = 3 -minetest.register_globalstep(function(dtime) - for _,player in ipairs(minetest.get_connected_players()) do - local pos = player:getpos() - pos.y = pos.y+0.5 - local inv = player:get_inventory() - for _,object in ipairs(minetest.env:get_objects_inside_radius(pos, 2)) do - if not object:is_player() and object:get_luaentity() then - local obj=object:get_luaentity() - if obj.name == "__builtin:item" then - if inv:room_for_item("main", ItemStack(obj.itemstring)) then - if obj.timer > time_pick then - inv:add_item("main", ItemStack(obj.itemstring)) - if obj.itemstring ~= "" then - minetest.sound_play("item_drop_pickup",{pos = pos, gain = 1.0, max_hear_distance = 10}) - end - if object:get_luaentity() then - object:get_luaentity().itemstring = "" - object:remove() + +if technic.config:getBool("enable_item_pickup") then + minetest.register_globalstep(function(dtime) + for _,player in ipairs(minetest.get_connected_players()) do + local pos = player:getpos() + pos.y = pos.y+0.5 + local inv = player:get_inventory() + for _,object in ipairs(minetest.env:get_objects_inside_radius(pos, 2)) do + if not object:is_player() and object:get_luaentity() then + local obj=object:get_luaentity() + if obj.name == "__builtin:item" then + if inv:room_for_item("main", ItemStack(obj.itemstring)) then + if obj.timer > time_pick then + inv:add_item("main", ItemStack(obj.itemstring)) + if obj.itemstring ~= "" then + minetest.sound_play("item_drop_pickup",{pos = pos, gain = 1.0, max_hear_distance = 10}) + end + if object:get_luaentity() then + object:get_luaentity().itemstring = "" + object:remove() + end end end end end end end - end -end) + end) +end -function minetest.handle_node_drops(pos, drops, digger) - for _,item in ipairs(drops) do - local count, name - if type(item) == "string" then - count = 1 - name = item - else - count = item:get_count() - name = item:get_name() - end - for i=1,count do - local obj = minetest.env:add_item(pos, name) - if obj ~= nil then - obj:get_luaentity().collect = true - local x = math.random(1, 5) - if math.random(1,2) == 1 then - x = -x - end - local z = math.random(1, 5) - if math.random(1,2) == 1 then - z = -z - end - obj:setvelocity({x=1/x, y=obj:getvelocity().y, z=1/z}) - obj:get_luaentity().timer = time_pick - -- FIXME this doesnt work for deactiveted objects - if minetest.setting_get("remove_items") and tonumber(minetest.setting_get("remove_items")) then - minetest.after(tonumber(minetest.setting_get("remove_items")), function(obj) - obj:remove() - end, obj) +if technic.config:getBool("enable_item_drop") then + function minetest.handle_node_drops(pos, drops, digger) + for _,item in ipairs(drops) do + local count, name + if type(item) == "string" then + count = 1 + name = item + else + count = item:get_count() + name = item:get_name() + end + for i=1,count do + local obj = minetest.env:add_item(pos, name) + if obj ~= nil then + obj:get_luaentity().collect = true + local x = math.random(1, 5) + if math.random(1,2) == 1 then + x = -x + end + local z = math.random(1, 5) + if math.random(1,2) == 1 then + z = -z + end + obj:setvelocity({x=1/x, y=obj:getvelocity().y, z=1/z}) + obj:get_luaentity().timer = time_pick + -- FIXME this doesnt work for deactiveted objects + if minetest.setting_get("remove_items") and tonumber(minetest.setting_get("remove_items")) then + minetest.after(tonumber(minetest.setting_get("remove_items")), function(obj) + obj:remove() + end, obj) + end end end end end end + --[[ minetest.register_on_dieplayer(function(name, pos) local inv = name:get_inventory() diff --git a/technic/config.lua b/technic/config.lua index f237968..f546cf6 100644 --- a/technic/config.lua +++ b/technic/config.lua @@ -1,7 +1,42 @@ -enable_technic_inventory=true -enable_mining_drill=true -enable_mining_laser=true -enable_flashlight=true -enable_rubber_tree_generation=true -enable_marble_generation=true -enable_granite_generation=true +technic.config = {} + +technic.config.loaded = {} + +technic.config.default = { + enable_mining_drill = "true", + enable_mining_laser = "true", + enable_flashlight = "true", + enable_item_drop = "true", + enable_item_pickup = "true", + enable_rubber_tree_generation = "true", + enable_marble_generation = "true", + enable_granite_generation = "true" +} + +function technic.config:load(filename) + file, error = io.open(filename, "r") + if error then return end + local line = file:read("*l") + while line do + local found, _, setting, value = line:find("^([^#%s=]+)%s?=%s?([^%s#]+)") + if found then + self.loaded[setting] = value + end + line = file:read("*l") + end + file:close() +end + +technic.config:load(minetest.get_worldpath().."/technic.conf") + +function technic.config:get(setting) + if self.loaded[setting] then + return self.loaded[setting] + else + return self.default[setting] + end +end + +function technic.config:getBool(setting) + return string.lower(self:get(setting)) == "true" +end diff --git a/technic/depends.txt b/technic/depends.txt index f034c60..3859f8a 100644 --- a/technic/depends.txt +++ b/technic/depends.txt @@ -2,5 +2,3 @@ default moreores pipeworks mesecons -technic_worldgen - diff --git a/technic/init.lua b/technic/init.lua index 2b85d26..7f303c1 100644 --- a/technic/init.lua +++ b/technic/init.lua @@ -2,6 +2,8 @@ -- namespace: technic -- (c) 2012-2013 by RealBadAngel +technic = {} + modpath=minetest.get_modpath("technic") --Read technic config file @@ -38,9 +40,9 @@ dofile(modpath.."/forcefield.lua") dofile(modpath.."/wires_hv.lua") --Tools -if enable_mining_drill==true then dofile(modpath.."/mining_drill.lua") end -if enable_mining_laser==true then dofile(modpath.."/mining_laser_mk1.lua") end -if enable_flashlight==true then dofile(modpath.."/flashlight.lua") end +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 +if technic.config:getBool("enable_flashlight") then dofile(modpath.."/flashlight.lua") end dofile(modpath.."/cans.lua") dofile(modpath.."/chainsaw.lua") dofile(modpath.."/tree_tap.lua") diff --git a/technic/rubber.lua b/technic/rubber.lua index 0e530ff..6ec9731 100644 --- a/technic/rubber.lua +++ b/technic/rubber.lua @@ -88,14 +88,12 @@ minetest.register_abm({ end }) -minetest.register_on_generated(function(minp, maxp, blockseed) - if math.random(1, 100) > 5 then - return - end - local tmp = {x=(maxp.x-minp.x)/2+minp.x, y=(maxp.y-minp.y)/2+minp.y, z=(maxp.z-minp.z)/2+minp.z} - local pos = minetest.env:find_node_near(tmp, maxp.x-minp.x, {"default:dirt_with_grass"}) - if pos ~= nil then - rubber_tree={ +if technic.config:getBool("enable_rubber_tree_generation") then + minetest.register_on_generated(function(minp, maxp, blockseed) + if math.random(1, 100) > 5 then + return + end + local rubber_tree={ axiom="FFFFA", rules_a="[&FFBFA]////[&BFFFA]////[&FBFFA]", rules_b="[&FFA]////[&FFA]////[&FFA]", @@ -107,10 +105,14 @@ minetest.register_on_generated(function(minp, maxp, blockseed) thin_trunks=false; fruit_tree=false, fruit="" - } - minetest.env:spawn_tree({x=pos.x, y=pos.y+1, z=pos.z},rubber_tree) - end -end) + } + local tmp = {x=(maxp.x-minp.x)/2+minp.x, y=(maxp.y-minp.y)/2+minp.y, z=(maxp.z-minp.z)/2+minp.z} + local pos = minetest.env:find_node_near(tmp, maxp.x-minp.x, {"default:dirt_with_grass"}) + if pos ~= nil then + minetest.env:spawn_tree({x=pos.x, y=pos.y+1, z=pos.z}, rubber_tree) + end + end) +end -- ========= FUEL ========= diff --git a/technic_worldgen/depends.txt b/technic_worldgen/depends.txt index 4ad96d5..d684218 100644 --- a/technic_worldgen/depends.txt +++ b/technic_worldgen/depends.txt @@ -1 +1,2 @@ default +technic diff --git a/technic_worldgen/oregen.lua b/technic_worldgen/oregen.lua index b17e438..50f5415 100644 --- a/technic_worldgen/oregen.lua +++ b/technic_worldgen/oregen.lua @@ -28,6 +28,7 @@ minetest.register_ore({ height_min = -31000, height_max = 2, }) +if technic.config:getBool("enable_marble_generation") then minetest.register_ore({ ore_type = "sheet", ore = "technic:marble", @@ -40,6 +41,8 @@ minetest.register_ore({ noise_threshhold = 0.4, noise_params = {offset=0, scale=15, spread={x=150, y=150, z=150}, seed=23, octaves=3, persist=0.70} }) +end +if technic.config:getBool("enable_granite_generation") then minetest.register_ore({ ore_type = "sheet", ore = "technic:granite", @@ -52,4 +55,5 @@ minetest.register_ore({ noise_threshhold = 0.4, noise_params = {offset=0, scale=15, spread={x=130, y=130, z=130}, seed=24, octaves=3, persist=0.70} }) +end From 6463b77e60639f4012b702fef344cc7e201d3e3a Mon Sep 17 00:00:00 2001 From: kpoppel Date: Mon, 6 May 2013 20:00:00 +0200 Subject: [PATCH 23/57] Add milling machine from non cubic to technic mod. Next step is to make sure it only works if powered. --- technic/chainsaw.lua | 304 +++++- technic/cnc.lua | 208 ++++ technic/cnc_api.lua | 970 ++++++++++++++++++ technic/cnc_nodes.lua | 354 +++++++ technic/init.lua | 14 +- technic/textures/technic_cnc_bottom.png | Bin 0 -> 2006 bytes technic/textures/technic_cnc_cylinder.png | Bin 0 -> 456 bytes .../technic_cnc_cylinder_horizontal.png | Bin 0 -> 463 bytes .../textures/technic_cnc_element_cross.png | Bin 0 -> 415 bytes technic/textures/technic_cnc_element_edge.png | Bin 0 -> 409 bytes technic/textures/technic_cnc_element_end.png | Bin 0 -> 391 bytes .../textures/technic_cnc_element_straight.png | Bin 0 -> 412 bytes technic/textures/technic_cnc_element_t.png | Bin 0 -> 389 bytes technic/textures/technic_cnc_front.png | Bin 0 -> 2000 bytes technic/textures/technic_cnc_full.png | Bin 0 -> 372 bytes technic/textures/technic_cnc_half.png | Bin 0 -> 460 bytes .../technic_cnc_milling_background.png | Bin 0 -> 78748 bytes .../textures/technic_cnc_onecurvededge.png | Bin 0 -> 507 bytes technic/textures/technic_cnc_pyramid.png | Bin 0 -> 480 bytes technic/textures/technic_cnc_side.png | Bin 0 -> 1922 bytes technic/textures/technic_cnc_slope.png | Bin 0 -> 437 bytes technic/textures/technic_cnc_slope_edge.png | Bin 0 -> 419 bytes .../technic_cnc_slope_edge_upsdwn.png | Bin 0 -> 486 bytes .../textures/technic_cnc_slope_inner_edge.png | Bin 0 -> 497 bytes .../technic_cnc_slope_inner_edge_upsdwn.png | Bin 0 -> 605 bytes technic/textures/technic_cnc_slope_lying.png | Bin 0 -> 548 bytes technic/textures/technic_cnc_slope_upsdwn.png | Bin 0 -> 440 bytes technic/textures/technic_cnc_sphere.png | Bin 0 -> 532 bytes technic/textures/technic_cnc_spike.png | Bin 0 -> 556 bytes technic/textures/technic_cnc_stick.png | Bin 0 -> 320 bytes technic/textures/technic_cnc_top.png | Bin 0 -> 2137 bytes .../textures/technic_cnc_twocurvededge.png | Bin 0 -> 768 bytes 32 files changed, 1794 insertions(+), 56 deletions(-) create mode 100644 technic/cnc.lua create mode 100644 technic/cnc_api.lua create mode 100644 technic/cnc_nodes.lua create mode 100644 technic/textures/technic_cnc_bottom.png create mode 100644 technic/textures/technic_cnc_cylinder.png create mode 100644 technic/textures/technic_cnc_cylinder_horizontal.png create mode 100644 technic/textures/technic_cnc_element_cross.png create mode 100644 technic/textures/technic_cnc_element_edge.png create mode 100644 technic/textures/technic_cnc_element_end.png create mode 100644 technic/textures/technic_cnc_element_straight.png create mode 100644 technic/textures/technic_cnc_element_t.png create mode 100644 technic/textures/technic_cnc_front.png create mode 100644 technic/textures/technic_cnc_full.png create mode 100644 technic/textures/technic_cnc_half.png create mode 100644 technic/textures/technic_cnc_milling_background.png create mode 100644 technic/textures/technic_cnc_onecurvededge.png create mode 100644 technic/textures/technic_cnc_pyramid.png create mode 100644 technic/textures/technic_cnc_side.png create mode 100644 technic/textures/technic_cnc_slope.png create mode 100644 technic/textures/technic_cnc_slope_edge.png create mode 100644 technic/textures/technic_cnc_slope_edge_upsdwn.png create mode 100644 technic/textures/technic_cnc_slope_inner_edge.png create mode 100644 technic/textures/technic_cnc_slope_inner_edge_upsdwn.png create mode 100644 technic/textures/technic_cnc_slope_lying.png create mode 100644 technic/textures/technic_cnc_slope_upsdwn.png create mode 100644 technic/textures/technic_cnc_sphere.png create mode 100644 technic/textures/technic_cnc_spike.png create mode 100644 technic/textures/technic_cnc_stick.png create mode 100644 technic/textures/technic_cnc_top.png create mode 100644 technic/textures/technic_cnc_twocurvededge.png diff --git a/technic/chainsaw.lua b/technic/chainsaw.lua index 2c3fbf5..c31d9a8 100644 --- a/technic/chainsaw.lua +++ b/technic/chainsaw.lua @@ -1,63 +1,261 @@ -chainsaw_max_charge=30000 +-- Configuration +local chainsaw_max_charge = 30000 -- 30000 - Maximum charge of the saw +local chainsaw_charge_per_node = 12 -- 12 - Gives 2500 nodes on a single charge (about 50 complete normal trees) +local chainsaw_leaves = true -- true - Cut down entire trees, leaves and all + register_power_tool ("technic:chainsaw",chainsaw_max_charge) minetest.register_tool("technic:chainsaw", { - description = "Chainsaw", - inventory_image = "technic_chainsaw.png", - stack_max = 1, - on_use = function(itemstack, user, pointed_thing) - if pointed_thing.type=="node" then - item=itemstack:to_table() - local meta=get_item_meta(item["metadata"]) - if meta==nil then return end --tool not charghed - if meta["charge"]==nil then return end - charge=meta["charge"] - charge_to_take=600; - if charge-charge_to_take>0 then - charge_to_take=chainsaw_dig_it(minetest.get_pointed_thing_position(pointed_thing, above),user,charge_to_take) - charge=charge-charge_to_take; - set_RE_wear(item,charge,chainsaw_max_charge) - meta["charge"]=charge - item["metadata"]=set_item_meta(meta) - itemstack:replace(item) - return itemstack - end - end - end, + description = "Chainsaw", + inventory_image = "technic_chainsaw.png", + stack_max = 1, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type=="node" then + item=itemstack:to_table() + local meta=get_item_meta(item["metadata"]) + if meta==nil then return end --tool not charged + if meta["charge"]==nil then return end + -- Send current charge to digging function so that the chainsaw will stop after digging a number of nodes. + local charge=meta["charge"] + if charge < chainsaw_charge_per_node then return end -- only cut if charged + + charge=chainsaw_dig_it(minetest.get_pointed_thing_position(pointed_thing, above),user,charge) + set_RE_wear(item,charge,chainsaw_max_charge) + meta["charge"]=charge + item["metadata"]=set_item_meta(meta) + itemstack:replace(item) + return itemstack + end + end, }) 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'}, - {'','','moreores:copper_ingot'}, - } + output = 'technic:chainsaw', + recipe = { + {'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot', 'technic:battery'}, + {'technic:stainless_steel_ingot', 'technic:motor', 'technic:battery'}, + {'','','moreores:copper_ingot'}, + } }) +-- The default stuff +local timber_nodenames={["default:jungletree"] = true, + ["default:papyrus"] = true, + ["default:cactus"] = true, + ["default:tree"] = true, + ["default:apple"] = true +} - - -timber_nodenames={"default:jungletree", "default:papyrus", "default:cactus", "default:tree"} - -function chainsaw_dig_it (pos, player,charge_to_take) - charge_to_take=0 - local node=minetest.env:get_node(pos) - local i=1 - while timber_nodenames[i]~=nil do - if node.name==timber_nodenames[i] then - charge_to_take=600 - np={x=pos.x, y=pos.y, z=pos.z} - while minetest.env:get_node(np).name==timber_nodenames[i] do - minetest.env:remove_node(np) - minetest.env:add_item(np, timber_nodenames[i]) - np={x=np.x, y=np.y+1, z=np.z} - end - minetest.sound_play("chainsaw", {pos = pos, gain = 1.0, max_hear_distance = 10,}) - return charge_to_take - end - i=i+1 - end - -return charge_to_take +if chainsaw_leaves == true then + timber_nodenames["default:leaves"] = true +end + +-- Support moretrees if it is there +if( minetest.get_modpath("moretrees") ~= nil ) then + timber_nodenames["moretrees:apple_tree_trunk"] = true + timber_nodenames["moretrees:apple_tree_trunk_sideways"] = true + timber_nodenames["moretrees:beech_trunk"] = true + timber_nodenames["moretrees:beech_trunk_sideways"] = true + timber_nodenames["moretrees:birch_trunk"] = true + timber_nodenames["moretrees:birch_trunk_sideways"] = true + timber_nodenames["moretrees:fir_trunk"] = true + timber_nodenames["moretrees:fir_trunk_sideways"] = true + timber_nodenames["moretrees:oak_trunk"] = true + timber_nodenames["moretrees:oak_trunk_sideways"] = true + timber_nodenames["moretrees:palm_trunk"] = true + timber_nodenames["moretrees:palm_trunk_sideways"] = true + timber_nodenames["moretrees:pine_trunk"] = true + timber_nodenames["moretrees:pine_trunk_sideways"] = true + timber_nodenames["moretrees:rubber_tree_trunk"] = true + timber_nodenames["moretrees:rubber_tree_trunk_sideways"] = true + timber_nodenames["moretrees:rubber_tree_trunk_empty"] = true + timber_nodenames["moretrees:rubber_tree_trunk_sideways_empty"] = true + timber_nodenames["moretrees:sequoia_trunk"] = true + timber_nodenames["moretrees:sequoia_trunk_sideways"] = true + timber_nodenames["moretrees:spruce_trunk"] = true + timber_nodenames["moretrees:spruce_trunk_sideways"] = true + timber_nodenames["moretrees:willow_trunk"] = true + timber_nodenames["moretrees:willow_trunk_sideways"] = true + timber_nodenames["moretrees:jungletree_trunk"] = true + timber_nodenames["moretrees:jungletree_trunk_sideways"] = true + + if chainsaw_leaves == true then + timber_nodenames["moretrees:apple_tree_leaves"] = true + timber_nodenames["moretrees:oak_leaves"] = true + timber_nodenames["moretrees:sequoia_leaves"] = true + timber_nodenames["moretrees:birch_leaves"] = true + timber_nodenames["moretrees:birch_leaves"] = true + timber_nodenames["moretrees:palm_leaves"] = true + timber_nodenames["moretrees:spruce_leaves"] = true + timber_nodenames["moretrees:spruce_leaves"] = true + timber_nodenames["moretrees:pine_leaves"] = true + timber_nodenames["moretrees:willow_leaves"] = true + timber_nodenames["moretrees:rubber_tree_leaves"] = true + timber_nodenames["moretrees:jungletree_leaves_green"] = true + timber_nodenames["moretrees:jungletree_leaves_yellow"] = true + timber_nodenames["moretrees:jungletree_leaves_red"] = true + end +end + +-- Support growing_trees if it is there +if( minetest.get_modpath("growing_trees") ~= nil ) then + timber_nodenames["growing_trees:trunk"] = true + timber_nodenames["growing_trees:medium_trunk"] = true + timber_nodenames["growing_trees:big_trunk"] = true + timber_nodenames["growing_trees:trunk_top"] = true + timber_nodenames["growing_trees:trunk_sprout"] = true + timber_nodenames["growing_trees:branch_sprout"] = true + timber_nodenames["growing_trees:branch"] = true + timber_nodenames["growing_trees:branch_xmzm"] = true + timber_nodenames["growing_trees:branch_xpzm"] = true + timber_nodenames["growing_trees:branch_xmzp"] = true + timber_nodenames["growing_trees:branch_xpzp"] = true + timber_nodenames["growing_trees:branch_zz"] = true + timber_nodenames["growing_trees:branch_xx"] = true + + if chainsaw_leaves == true then + timber_nodenames["growing_trees:leaves"] = true + end +end + +-- Support growing_cactus if it is there +if( minetest.get_modpath("growing_cactus") ~= nil ) then + timber_nodenames["growing_cactus:sprout"] = true + timber_nodenames["growing_cactus:branch_sprout_vertical"] = true + timber_nodenames["growing_cactus:branch_sprout_vertical_fixed"] = true + timber_nodenames["growing_cactus:branch_sprout_xp"] = true + timber_nodenames["growing_cactus:branch_sprout_xm"] = true + timber_nodenames["growing_cactus:branch_sprout_zp"] = true + timber_nodenames["growing_cactus:branch_sprout_zm"] = true + timber_nodenames["growing_cactus:trunk"] = true + timber_nodenames["growing_cactus:branch_trunk"] = true + timber_nodenames["growing_cactus:branch"] = true + timber_nodenames["growing_cactus:branch_xp"] = true + timber_nodenames["growing_cactus:branch_xm"] = true + timber_nodenames["growing_cactus:branch_zp"] = true + timber_nodenames["growing_cactus:branch_zm"] = true + timber_nodenames["growing_cactus:branch_zz"] = true + timber_nodenames["growing_cactus:branch_xx"] = true +end + +-- Table for saving what was sawed down +local produced + +-- Saw down trees entry point +chainsaw_dig_it = function(pos, player,current_charge) + local remaining_charge=current_charge + + -- A bit of trickery here: use a different node drop callback + -- and restore the original afterwards. + minetest.handle_node_drops = chainsaw_handle_node_drops + + -- clear result and start sawing things down + produced = {} + remaining_charge = recursive_dig(pos, remaining_charge, player) + minetest.sound_play("chainsaw", {pos = pos, gain = 1.0, max_hear_distance = 10,}) + + -- Restore the original noder drop handler + minetest.handle_node_drops = original_handle_node_drops + + -- Now drop items for the player + local number, produced_item, p + for produced_item,number in pairs(produced) do + --print("ADDING ITEM: " .. produced_item .. " " .. number) + -- Drop stacks of 99 or less + p = { + x = pos.x + math.random()*4, + y = pos.y, + z = pos.z + math.random()*4 + } + while number > 99 do + minetest.env:add_item(p, produced_item .. " 99") + p = { + x = pos.x + math.random()*4, + y = pos.y, + z = pos.z + math.random()*4 + } + number = number - 99 + end + minetest.env:add_item(p, produced_item .. " " .. number) + end + return remaining_charge +end + +-- Override the default handling routine to be able to count up the +-- items sawed down so that we can drop them i an nice single stack +chainsaw_handle_node_drops = function(pos, drops, digger) + -- Add dropped items to list of collected nodes + local _, dropped_item + for _, dropped_item in ipairs(drops) do + if produced[dropped_item] == nil then + produced[dropped_item] = 1 + else + produced[dropped_item] = produced[dropped_item] + 1 + end + end +end + +-- Save the currently installed dropping mechanism so we can restore it. +local original_handle_node_drops = minetest.handle_node_drops + +-- This function does all the hard work. Recursively we dig the node at hand +-- if it is in the table and then search the surroundings for more stuff to dig. +recursive_dig = function(pos, remaining_charge, player) + local node=minetest.env:get_node(pos) + local i=1 + -- Lookup node name in timber table: + if timber_nodenames[node.name] ~= nil then + -- Return if we are out of power + if remaining_charge < chainsaw_charge_per_node then + return 0 + end + local np + -- wood found - cut it. + minetest.env:dig_node(pos) + + remaining_charge=remaining_charge-chainsaw_charge_per_node + -- check surroundings and run recursively if any charge left + np={x=pos.x+1, y=pos.y, z=pos.z} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + np={x=pos.x+1, y=pos.y, z=pos.z+1} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + np={x=pos.x+1, y=pos.y, z=pos.z-1} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + + np={x=pos.x-1, y=pos.y, z=pos.z} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + np={x=pos.x-1, y=pos.y, z=pos.z+1} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + np={x=pos.x-1, y=pos.y, z=pos.z-1} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + + np={x=pos.x, y=pos.y+1, z=pos.z} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + + np={x=pos.x, y=pos.y, z=pos.z+1} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + np={x=pos.x, y=pos.y, z=pos.z-1} + if timber_nodenames[minetest.env:get_node(np).name] ~= nil then + remaining_charge = recursive_dig(np, remaining_charge) + end + return remaining_charge + end + -- Nothing sawed down + return remaining_charge end diff --git a/technic/cnc.lua b/technic/cnc.lua new file mode 100644 index 0000000..6e763ef --- /dev/null +++ b/technic/cnc.lua @@ -0,0 +1,208 @@ +-- Technic CNC v1.0 by kpo +-- Based on the NonCubic Blocks MOD v1.4 by yves_de_beck +local shape = {} +local size = 0 +local onesize_products = { + slope = 2, + slope_edge = 1, + slope_inner_edge = 1, + pyramid = 2, + spike = 1, + cylinder = 2, + sphere = 1, + stick = 8, + slope_upsdwn = 2, + slope_edge_upsdwn = 1, + slope_inner_edge_upsdwn = 1, + cylinder_hor = 2, + slope_lying = 2, + onecurvededge = 1, + twocurvededge = 1, +} +local twosize_products = { + element_straight = 4, + element_end = 2, + element_cross = 1, + element_t = 1, + element_edge = 2, +} + +local showbackground = "--" +local max_cncruns = 99 +local max_products = 99 + +--showlabelin = "" +--showlabelout = "label[4.5,5.5;Out:]" + +-- I want the CNC machine to be a two block thing +minetest.register_node("technic:cnc", { + description = "CNC Milling Machine", + tiles = {"technic_cnc_top.png", "technic_cnc_bottom.png", "technic_cnc_side.png", + "technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front.png"}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + + }, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + groups = {oddly_breakable_by_hand=2, cracky=3, dig_immediate=1}, + + can_dig = function(pos,player) + local meta = minetest.env:get_meta(pos); + local inv = meta:get_inventory() + if not inv:is_empty("input") or not inv:is_empty("output") then + minetest.chat_send_player(player:get_player_name(), "CNC machine cannot be removed because it is not empty"); + return false + end + return true + end, + + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + if technic_cnc_api.allow_menu_background == true or technic_cnc_api.allow_menu_background == 1 then + showbackground = "background[-0.15,-0.25;8.40,11.75;technic_cnc_background.png]" + end + + meta:set_string("formspec", "invsize[8,11;]".. + "label[0,0;Choose Milling Program:]".. + "image_button[0,0.5;1,1;technic_cnc_slope.png;slope; ]".. + "image_button[1,0.5;1,1;technic_cnc_slope_edge.png;slope_edge; ]".. + "image_button[2,0.5;1,1;technic_cnc_slope_inner_edge.png;slope_inner_edge; ]".. + "image_button[3,0.5;1,1;technic_cnc_pyramid.png;pyramid; ]".. + "image_button[4,0.5;1,1;technic_cnc_spike.png;spike; ]".. + "image_button[5,0.5;1,1;technic_cnc_cylinder.png;cylinder; ]".. + "image_button[6,0.5;1,1;technic_cnc_sphere.png;sphere; ]".. + "image_button[7,0.5;1,1;technic_cnc_stick.png;stick; ]".. + + "image_button[0,1.5;1,1;technic_cnc_slope_upsdwn.png;slope_upsdwn; ]".. + "image_button[1,1.5;1,1;technic_cnc_slope_edge_upsdwn.png;slope_upsdwn_edge; ]".. + "image_button[2,1.5;1,1;technic_cnc_slope_inner_edge_upsdwn.png;slope_upddown_inner_edge; ]".. + "image_button[5,1.5;1,1;technic_cnc_cylinder_horizontal.png;cylinder_horizontal; ]".. + + "image_button[0,2.5;1,1;technic_cnc_slope_lying.png;slope_lying; ]".. + "image_button[1,2.5;1,1;technic_cnc_onecurvededge.png;onecurvededge; ]".. + "image_button[2,2.5;1,1;technic_cnc_twocurvededge.png;twocurvededge; ]".. + + "label[0,3.5;Slim Elements half / normal height:]".. + + "image_button[0,4;1,0.5;technic_cnc_full.png;full; ]".. + "image_button[0,4.5;1,0.5;technic_cnc_half.png;half; ]".. + "image_button[1,4;1,1;technic_cnc_element_straight.png;element_straight; ]".. + "image_button[2,4;1,1;technic_cnc_element_end.png;element_end; ]".. + "image_button[3,4;1,1;technic_cnc_element_cross.png;element_cross; ]".. + "image_button[4,4;1,1;technic_cnc_element_t.png;element_t; ]".. + "image_button[5,4;1,1;technic_cnc_element_edge.png;element_edge; ]".. + + "label[0, 5.5;In:]".. -- showlabelin.. + "list[current_name;input;0.5,5.5;1,1;]".. + "field[3, 6;1,1;num_cncruns;Repeat program:;${num_cncruns}]".. -- Fill default with meta data num_cncruns + "label[4, 5.5;Out:]".. -- showlabelout.. + "list[current_name;output;4.5,5.5;1,1;]".. + + "list[current_player;main;0,7;8,4;]".. + showbackground) + meta:set_string("infotext", "CNC Milling Machine") + meta:set_string("num_cncruns", 1 ); + + local inv = meta:get_inventory() + inv:set_size("input", 1) + inv:set_size("output", 1) + end, + + on_receive_fields = function(pos, formname, fields, sender) + -- REGISTER MILLING PROGRAMMS AND OUTPUTS: + ------------------------------------------ + -- Program for half/full size + if fields["full"] then + size = 1 + return + end + + if fields["half"] then + size = 2 + return + end + + local meta = minetest.env:get_meta(pos) + local inv = meta:get_inventory() + + -- Limit the number entered + if( fields.num_cncruns and tonumber( fields.num_cncruns) > 0 and tonumber(fields.num_cncruns) < 100 ) then + meta:set_string( "num_cncruns", fields.num_cncruns ); + else + minetest.chat_send_player(sender:get_player_name(), "CNC machine runs set to a bad value. Machine resets."); + meta:set_string( "num_cncruns", 1 ); + fields.num_cncruns = 1 + end + + -- Do nothing if the machine is empty + if inv:is_empty("input") then + return + end + + -- Do nothing if the output is not empty and the product used is not the same as what is already there + + -- Resolve the node name and the number of items to make and the number of items to take + local product = "" + local produces = 1 + local input_used = 1 + local inputstack = inv:get_stack("input", 1) + local inputname = inputstack:get_name() + local multiplier = 1 + for k, _ in pairs(fields) do + -- Set a multipier for the half/full size capable blocks + if twosize_products[k] ~= nil then + multiplier = size*twosize_products[k] + else + multiplier = onesize_products[k] + end + + if onesize_products[k] ~= nil or twosize_products[k] ~= nil then + product = inputname .. "_technic_cnc_" .. k + produces = math.min( fields.num_cncruns*multiplier, max_products) -- produce at most max_products + input_used = math.min( math.floor(produces/multiplier), inputstack:get_count()) -- use at most what we got + produces = input_used*multiplier -- final production + print(size) + print(fields.num_cncruns) + print(product) + print(produces) + print(input_used) + print("------------------") + break + end + end + + -- CNC does the transformation + ------------------------------ + if minetest.registered_nodes[product] ~= nil then + inv:add_item("output",product .. " " .. produces) + inputstack:take_item(input_used) + inv:set_stack("input",1,inputstack) + else + minetest.chat_send_player(sender:get_player_name(), "CNC machine does not know how to mill this material. Please remove it."); + end + return; + end, -- callback function + }) +---------- + + +-- Milling 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'}, + }, + }) +------------------------- \ No newline at end of file diff --git a/technic/cnc_api.lua b/technic/cnc_api.lua new file mode 100644 index 0000000..390a996 --- /dev/null +++ b/technic/cnc_api.lua @@ -0,0 +1,970 @@ +-- API for the technic CNC machine +-- Again code is adapted from the NonCubic Blocks MOD v1.4 by yves_de_beck +technic_cnc_api = {} + +-- HERE YOU CAN CHANGE THE DETAIL-LEVEL: +---------------------------------------- +technic_cnc_api.detail_level = 16 -- 16; 1-32 + +-- HERE YOU CAN DE/ACTIVATE BACKGROUND FOR CNC MENU: +-------------------------------------------------------- +technic_cnc_api.allow_menu_background = false + +-- REGISTER NONCUBIC FORMS, CREATE MODELS AND RECIPES: +------------------------------------------------------ + +-- SLOPE +-------- +function technic_cnc_api.register_slope(recipeitem, groups, images, description) + +local slopebox = {} +local detail = technic_cnc_api.detail_level +for i = 0, detail-1 do + slopebox[i+1]={-0.5, (i/detail)-0.5, (i/detail)-0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} +end + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = slopebox, + }, + groups = groups, + }) +end + + +-- SLOPE Lying +---------------- +function technic_cnc_api.register_slope_lying(recipeitem, groups, images, description) + +local slopeboxlying = {} +local detail = technic_cnc_api.detail_level +for i = 0, detail-1 do + slopeboxlying[i+1]={(i/detail)-0.5, -0.5, (i/detail)-0.5, (i/detail)-0.5+(1/detail), 0.5 , 0.5} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_lying", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = slopeboxlying, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_slope_lying 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_slope", ""}, + {"", "", ""}, + }, + }) + +end + + +-- SLOPE UPSIDE DOWN +-------------------- +function technic_cnc_api.register_slope_upsdown(recipeitem, groups, images, description) + +if subname == "dirt" then +return +end + +local slopeupdwnbox = {} +local detail = technic_cnc_api.detail_level +for i = 0, detail-1 do + slopeupdwnbox[i+1]={-0.5, (i/detail)-0.5, (-1*(i/detail))+0.5-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_upsdown", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = slopeupdwnbox, + }, + groups = groups, + }) +end + + +-- SLOPE EDGE +------------- +function technic_cnc_api.register_slope_edge(recipeitem, groups, images, description) + +local slopeboxedge = {} +local detail = technic_cnc_api.detail_level +for i = 0, detail-1 do + slopeboxedge[i+1]={(i/detail)-0.5, -0.5, (i/detail)-0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_edge", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = slopeboxedge, + }, + groups = groups, + }) +end + + +-- SLOPE INNER EDGE +------------------- +function technic_cnc_api.register_slope_inner_edge(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_inner_edge", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = { + -- PART 1 + {-0.5, -0.5, -0.5, 0.5, -0.45, 0.5}, + {-0.45, -0.5, -0.5, 0.5, -0.4, 0.5}, + {-0.4, -0.5, -0.5, 0.5, -0.35, 0.5}, + {-0.35, -0.5, -0.5, 0.5, -0.3, 0.5}, + {-0.3, -0.5, -0.5, 0.5, -0.25, 0.5}, + {-0.25, -0.5, -0.5, 0.5, -0.2, 0.5}, + {-0.2, -0.5, -0.5, 0.5, -0.15, 0.5}, + {-0.15, -0.5, -0.5, 0.5, -0.1, 0.5}, + {-0.1, -0.5, -0.5, 0.5, -0.05, 0.5}, + {-0.05, -0.5, -0.5, 0.5, 0, 0.5}, + {0, -0.5, -0.5, 0.5, 0.05, 0.5}, + {0.05, -0.5, -0.5, 0.5, 0.1, 0.5}, + {0.1, -0.5, -0.5, 0.5, 0.15, 0.5}, + {0.15, -0.5, -0.5, 0.5, 0.2, 0.5}, + {0.2, -0.5, -0.5, 0.5, 0.25, 0.5}, + {0.25, -0.5, -0.5, 0.5, 0.3, 0.5}, + {0.3, -0.5, -0.5, 0.5, 0.35, 0.5}, + {0.35, -0.5, -0.5, 0.5, 0.4, 0.5}, + {0.4, -0.5, -0.5, 0.5, 0.45, 0.5}, + {0.45, -0.5, -0.5, 0.5, 0.5, 0.5}, + -- PART 2 + {-0.5, -0.5, -0.45, 0.5, -0.45, 0.5}, + {-0.5, -0.5, -0.4, 0.5, -0.4, 0.5}, + {-0.5, -0.5, -0.35, 0.5, -0.35, 0.5}, + {-0.5, -0.5, -0.3, 0.5, -0.3, 0.5}, + {-0.5, -0.5, -0.25, 0.5, -0.25, 0.5}, + {-0.5, -0.5, -0.2, 0.5, -0.2, 0.5}, + {-0.5, -0.5, -0.15, 0.5, -0.15, 0.5}, + {-0.5, -0.5, -0.1, 0.5, -0.1, 0.5}, + {-0.5, -0.5, -0.05, 0.5, -0.05, 0.5}, + {-0.5, -0.5, 0, 0.5, 0, 0.5}, + {-0.5, -0.5, 0.05, 0.5, 0.05, 0.5}, + {-0.5, -0.5, 0.1, 0.5, 0.1, 0.5}, + {-0.5, -0.5, 0.15, 0.5, 0.15, 0.5}, + {-0.5, -0.5, 0.2, 0.5, 0.2, 0.5}, + {-0.5, -0.5, .25, 0.5, 0.25, 0.5}, + {-0.5, -0.5, 0.3, 0.5, 0.3, 0.5}, + {-0.5, -0.5, 0.35, 0.5, 0.35, 0.5}, + {-0.5, -0.5, 0.4, 0.5, 0.4, 0.5}, + {-0.5, -0.5, 0.45, 0.5, 0.45, 0.5}, + {-0.5, -0.5, 0.5, 0.5, 0.5, 0.5}, + }, + }, + groups = groups, + }) +end + + +-- SLOPE EDGE UPSIDE DOWN +------------------------- +function technic_cnc_api.register_slope_upsdown_edge(recipeitem, groups, images, description) + +if recipeitem == "default:dirt" then + return +end + +local slopeupdwnboxedge = {} +local detail = technic_cnc_api.detail_level +for i = 0, detail-1 do + slopeupdwnboxedge[i+1]={(-1*(i/detail))+0.5-(1/detail), (i/detail)-0.5, (-1*(i/detail))+0.5-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_upsdown_edge", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = slopeupdwnboxedge, + }, + groups = groups, + }) +end + + +-- SLOPE INNER EDGE UPSIDE DOWN +------------------------------- +function technic_cnc_api.register_slope_upsdown_inner_edge(recipeitem, groups, images, description) + +if recipename == "default:dirt" then +return +end + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_upsdown_inner_edge", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = { + {0.45, -0.5, -0.5, 0.5, -0.45, 0.5}, + {0.4, -0.45, -0.5, 0.5, -0.4, 0.5}, + {0.35, -0.4, -0.5, 0.5, -0.35, 0.5}, + {0.3, -0.35, -0.5, 0.5, -0.3, 0.5}, + {0.25, -0.3, -0.5, 0.5, -0.25, 0.5}, + {0.2, -0.25, -0.5, 0.5, -0.2, 0.5}, + {0.15, -0.2, -0.5, 0.5, -0.15, 0.5}, + {0.1, -0.15, -0.5, 0.5, -0.1, 0.5}, + {0.05, -0.1, -0.5, 0.5, -0.05, 0.5}, + {0, -0.05, -0.5, 0.5, 0, 0.5}, + {-0.05, 0, -0.5, 0.5, 0.05, 0.5}, + {-0.1, 0.05, -0.5, 0.5, 0.1, 0.5}, + {-0.15, 0.1, -0.5, 0.5, 0.15, 0.5}, + {-0.2, 0.15, -0.5, 0.5, 0.2, 0.5}, + {-0.25, 0.2, -0.5, 0.5, 0.25, 0.5}, + {-0.3, 0.25, -0.5, 0.5, 0.3, 0.5}, + {-0.35, 0.3, -0.5, 0.5, 0.35, 0.5}, + {-0.4, 0.35, -0.5, 0.5, 0.4, 0.5}, + {-0.45, 0.4, -0.5, 0.5, 0.45, 0.5}, + {-0.5, 0.45, -0.5, 0.5, 0.5, 0.5}, + + {-0.5, -0.5, 0.45, 0.5, -0.45, 0.5}, + {-0.5, -0.45, 0.4, 0.5, -0.4, 0.5}, + {-0.5, -0.4, 0.35, 0.5, -0.35, 0.5}, + {-0.5, -0.35, 0.3, 0.5, -0.3, 0.5}, + {-0.5, -0.3, 0.25, 0.5, -0.25, 0.5}, + {-0.5, -0.25, 0.2, 0.5, -0.2, 0.5}, + {-0.5, -0.2, 0.15, 0.5, -0.15, 0.5}, + {-0.5, -0.15, 0.1, 0.5, -0.1, 0.5}, + {-0.5, -0.1, 0.05, 0.5, -0.05, 0.5}, + {-0.5, -0.05, 0, 0.5, 0, 0.5}, + {-0.5, 0, -0.05, 0.5, 0.05, 0.5}, + {-0.5, 0.05, -0.1, 0.5, 0.1, 0.5}, + {-0.5, 0.1, -0.15, 0.5, 0.15, 0.5}, + {-0.5, 0.15, -0.2, 0.5, 0.2, 0.5}, + {-0.5, 0.2, -0.25, 0.5, 0.25, 0.5}, + {-0.5, 0.25, -0.3, 0.5, 0.3, 0.5}, + {-0.5, 0.3, -0.35, 0.5, 0.35, 0.5}, + {-0.5, 0.35, -0.4, 0.5, 0.4, 0.5}, + {-0.5, 0.4, -0.45, 0.5, 0.45, 0.5}, + {-0.5, 0.45, -0.5, 0.5, 0.5, 0.5}, + + }, + }, + groups = groups, + }) +end + + +-- PYRAMID +---------- +function technic_cnc_api.register_pyramid(recipeitem, groups, images, description) + +local pyrabox = {} +local detail = technic_cnc_api.detail_level/2 +for i = 0, detail-1 do + pyrabox[i+1]={(i/detail/2)-0.5, (i/detail/2)-0.5, (i/detail/2)-0.5, 0.5-(i/detail/2), (i/detail/2)-0.5+(1/detail), 0.5-(i/detail/2)} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_pyramid", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + node_box = { + type = "fixed", + fixed = pyrabox, + }, + groups = groups, + }) +end + + +-- SPIKE +-------- +function technic_cnc_api.register_spike(recipeitem, groups, images, description) + +if recipename == "default:dirt" then + return +end + +local spikebox = {} +local detail = technic_cnc_api.detail_level +for i = 0, detail-1 do + spikebox[i+1]={(i/detail/2)-0.5, (i/detail/2)-0.5, (i/detail/2)-0.5, 0.5-(i/detail/2), (i/detail)-0.5+(1/detail), 0.5-(i/detail/2)} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_spike", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = spikebox, + }, + groups = groups, + }) +end + + +-- Block one curved edge +------------------------ +function technic_cnc_api.register_onecurvededge(recipeitem, groups, images, description) + +local quartercyclebox = {} +local detail = technic_cnc_api.detail_level*2 +local sehne +for i = (detail/2)-1, detail-1 do + sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) + quartercyclebox[i]={-0.5, -0.5, -sehne, 0.5, (i/detail)+(1/detail)-0.5, 0.5} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_onecurvededge", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = quartercyclebox, + }, + groups = groups, + }) +end + + +-- Block two curved edges +------------------------- +function technic_cnc_api.register_twocurvededge(recipeitem, groups, images, description) + +local quartercyclebox2 = {} +local detail = technic_cnc_api.detail_level*2 +local sehne +for i = (detail/2)-1, detail-1 do + sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) + quartercyclebox2[i]={-sehne, -0.5, -sehne, 0.5, (i/detail)+(1/detail)-0.5, 0.5} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_twocurvededge", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = quartercyclebox2, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_twocurvededge 3", + recipe = { + {"", "", ""}, + {recipeitem .. "_technic_cnc_onecurvededge", "", ""}, + {recipeitem .. "_technic_cnc_onecurvededge", recipeitem .. "_technic_cnc_onecurvededge", ""}, + }, + }) + +end + +-- Cylinder +----------- +function technic_cnc_api.register_cylinder(recipeitem, groups, images, description) + +if recipename == "default:dirt" then +return +end + +local cylbox = {} +local detail = technic_cnc_api.detail_level +local sehne +for i = 1, detail-1 do + sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) + cylbox[i]={(i/detail)-0.5, -0.5, -sehne, (i/detail)+(1/detail)-0.5, 0.5, sehne} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_cylinder", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = cylbox, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_cylinder 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_cylinder_horizontal", ""}, + {"", "", ""}, + }, + }) + +end + + +-- Cylinder Horizontal +---------------------- +function technic_cnc_api.register_cylinder_horizontal(recipeitem, groups, images, description) + +if recipename == "default:dirt" then + return +end + +local cylbox_horizontal = {} +local detail = technic_cnc_api.detail_level +local sehne +for i = 1, detail-1 do + sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) + cylbox_horizontal[i]={-0.5, (i/detail)-0.5, -sehne, 0.5, (i/detail)+(1/detail)-0.5, sehne} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_cylinder_horizontal", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = cylbox_horizontal, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_cylinder_horizontal 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_cylinder", ""}, + {"", "", ""}, + }, + }) +end + + +-- Sphere +--------- +function technic_cnc_api.register_sphere(recipeitem, groups, images, description) + +if recipename == "default:dirt" then + return +end + +local spherebox = {} +local detail = technic_cnc_api.detail_level +local sehne +for i = 1, detail-1 do + sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) + spherebox[i]={-sehne, (i/detail)-0.5, -sehne, sehne, (i/detail)+(1/detail)-0.5, sehne} +end +minetest.register_node(":" .. recipeitem .. "_technic_cnc_cylinder_sphere", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = spherebox, + }, + groups = groups, + }) +end + + +-- Element straight +------------------- +function technic_cnc_api.register_element_straight(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_straight", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.5, 0.3, 0, 0.5}, + }, + node_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0, 0.5}, + }, + }, + groups = groups, + }) +end + + +-- Element Edge +--------------- +function technic_cnc_api.register_element_edge(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_edge", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, + }, + }, + node_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, + }, + }, + groups = groups, + }) +end + + +-- Element T +------------ +function technic_cnc_api.register_element_t(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_t", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, + {0.3, -0.5, -0.3, 0.5, 0, 0.3}, + }, + }, + node_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, + {0.3, -0.5, -0.3, 0.5, 0, 0.3}, + }, + }, + groups = groups, + }) +end + + +-- Element Cross +---------------- +function technic_cnc_api.register_element_cross(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_cross", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = { + {0.3, -0.5, -0.3, 0.5, 0, 0.3}, + {-0.3, -0.5, -0.5, 0.3, 0, 0.5}, + {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, + }, + }, + node_box = { + type = "fixed", + fixed = { + {0.3, -0.5, -0.3, 0.5, 0, 0.3}, + {-0.3, -0.5, -0.5, 0.3, 0, 0.5}, + {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, + }, + }, + groups = groups, + }) +end + + +-- Element End +-------------- +function technic_cnc_api.register_element_end(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_end", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0, 0.5}, + }, + node_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0, 0.5}, + }, + groups = groups, + }) +end + + +-- Element straight DOUBLE +-------------------------- +function technic_cnc_api.register_element_straight_double(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_straight_double", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5}, + }, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_element_straight_double 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_element_straight", ""}, + {"", recipeitem .. "_technic_cnc_element_straight", ""}, + }, + }) +end + + +-- Element Edge DOUBLE +---------------------- +function technic_cnc_api.register_element_edge_double(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_edge_double", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, + }, + }, + node_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, + }, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_element_edge_double 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_element_edge", ""}, + {"", recipeitem .. "_technic_cnc_element_edge", ""}, + }, + }) +end + + +-- Element T DOUBLE +------------------- +function technic_cnc_api.register_element_t_double(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_t_double", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, + {0.3, -0.5, -0.3, 0.5, 0.5, 0.3}, + }, + }, + node_box = { + type = "fixed", + fixed = { + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, + {0.3, -0.5, -0.3, 0.5, 0.5, 0.3}, + }, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_element_t_double 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_element_t", ""}, + {"", recipeitem .. "_technic_cnc_element_t", ""}, + }, + }) +end + + +-- Element Cross Double +----------------------- +function technic_cnc_api.register_element_cross_double(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_cross_double", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = { + {0.3, -0.5, -0.3, 0.5, 0.5, 0.3}, + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5}, + {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, + }, + }, + node_box = { + type = "fixed", + fixed = { + {0.3, -0.5, -0.3, 0.5, 0.5, 0.3}, + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5}, + {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, + }, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_element_cross_double 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_element_cross", ""}, + {"", recipeitem .. "_technic_cnc_element_cross", ""}, + }, + }) + +end + + +-- Element End Double +--------------------- +function technic_cnc_api.register_element_end_double(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_end_double", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.5}, + }, + node_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.5}, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_element_end_double 1", + recipe = { + {"", "", ""}, + {"", recipeitem .. "_technic_cnc_element_end", ""}, + {"", recipeitem .. "_technic_cnc_element_end", ""}, + }, + }) +end + + +-- STICK +-------- +function technic_cnc_api.register_stick(recipeitem, groups, images, description) + +minetest.register_node(":" .. recipeitem .. "_technic_cnc_stick", { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15}, + }, + node_box = { + type = "fixed", + fixed = {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15}, + }, + groups = groups, + }) + minetest.register_craft({ + output = recipeitem .. "_technic_cnc_stick 8", + recipe = { + {'default:stick', "", ""}, + {"", "", ""}, + {recipeitem, "", ""}, + }, + }) +end + + + +-- REGISTER NEW TECHNIC_CNC_API's PART 2: technic_cnc_api.register_element_end(subname, recipeitem, groups, images, desc_element_xyz) +----------------------------------------------------------------------------------------------------------------------- +function technic_cnc_api.register_slope_edge_etc(recipeitem, groups, images, desc_slope, desc_slope_lying, desc_slope_upsdown, desc_slope_edge, desc_slope_inner_edge, desc_slope_upsdwn_edge, desc_slope_upsdwn_inner_edge, desc_pyramid, desc_spike, desc_onecurvededge, desc_twocurvededge, desc_cylinder, desc_cylinder_horizontal, desc_sphere, desc_element_straight, desc_element_edge, desc_element_t, desc_element_cross, desc_element_end) + + technic_cnc_api.register_slope(recipeitem, groups, images, desc_slope) + technic_cnc_api.register_slope_lying(recipeitem, groups, images, desc_slope_lying) + technic_cnc_api.register_slope_upsdown(recipeitem, groups, images, desc_slope_upsdown) + technic_cnc_api.register_slope_edge(recipeitem, groups, images, desc_slope_edge) + technic_cnc_api.register_slope_inner_edge(recipeitem, groups, images, desc_slope_inner_edge) + technic_cnc_api.register_slope_upsdown_edge(recipeitem, groups, images, desc_slope_upsdwn_edge) + technic_cnc_api.register_slope_upsdown_inner_edge(recipeitem, groups, images, desc_slope_upsdwn_inner_edge) + technic_cnc_api.register_pyramid(recipeitem, groups, images, desc_pyramid) + technic_cnc_api.register_spike(recipeitem, groups, images, desc_spike) + technic_cnc_api.register_onecurvededge(recipeitem, groups, images, desc_onecurvededge) + technic_cnc_api.register_twocurvededge(recipeitem, groups, images, desc_twocurvededge) + technic_cnc_api.register_cylinder(recipeitem, groups, images, desc_cylinder) + technic_cnc_api.register_cylinder_horizontal(recipeitem, groups, images, desc_cylinder_horizontal) + technic_cnc_api.register_sphere(recipeitem, groups, images, desc_sphere) + technic_cnc_api.register_element_straight(recipeitem, groups, images, desc_element_straight) + technic_cnc_api.register_element_edge(recipeitem, groups, images, desc_element_edge) + technic_cnc_api.register_element_t(recipeitem, groups, images, desc_element_t) + technic_cnc_api.register_element_cross(recipeitem, groups, images, desc_element_cross) + technic_cnc_api.register_element_end(recipeitem, groups, images, desc_element_end) +end + +-- REGISTER STICKS: noncubic.register_xyz(recipeitem, groups, images, desc_element_xyz) +------------------------------------------------------------------------------------------------------------ +function technic_cnc_api.register_stick_etc(recipeitem, groups, images, desc_stick) + technic_cnc_api.register_stick(recipeitem, groups, images, desc_stick) +end + +function technic_cnc_api.register_elements(recipeitem, groups, images, desc_element_straight_double, desc_element_edge_double, desc_element_t_double, desc_element_cross_double, desc_element_end_double) + technic_cnc_api.register_element_straight_double(recipeitem, groups, images, desc_element_straight_double) + technic_cnc_api.register_element_edge_double(recipeitem, groups, images, desc_element_edge_double) + technic_cnc_api.register_element_t_double(recipeitem, groups, images, desc_element_t_double) + technic_cnc_api.register_element_cross_double(recipeitem, groups, images, desc_element_cross_double) + technic_cnc_api.register_element_end_double(recipeitem, groups, images, desc_element_end_double) +end diff --git a/technic/cnc_nodes.lua b/technic/cnc_nodes.lua new file mode 100644 index 0000000..2f375a5 --- /dev/null +++ b/technic/cnc_nodes.lua @@ -0,0 +1,354 @@ +-- REGISTER MATERIALS AND PROPERTIES FOR NONCUBIC ELEMENTS: +----------------------------------------------------------- + +-- WOOD +------- +technic_cnc_api.register_slope_edge_etc("default:wood", + {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, + {"default_wood.png"}, + "Wooden Slope", + "Wooden Slope Lying", + "Wooden Slope Upside Down", + "Wooden Slope Edge", + "Wooden Slope Inner Edge", + "Wooden Slope Upside Down Edge", + "Wooden Slope Upside Down Inner Edge", + "Wooden Pyramid", + "Wooden Spike", + "Wooden One Curved Edge Block", + "Wooden Two Curved Edge Block", + "Wooden Cylinder", + "Wooden Cylinder Horizontal", + "Wooden Sphere", + "Wooden Element Straight", + "Wooden Element Edge", + "Wooden Element T", + "Wooden Element Cross", + "Wooden Element End") +-- STONE +-------- +technic_cnc_api.register_slope_edge_etc("default:stone", + {cracky=3,not_in_creative_inventory=1}, + {"default_stone.png"}, + "Stone Slope", + "Stone Slope Lying", + "Stone Slope Upside Down", + "Stone Slope Edge", + "Stone Slope Inner Edge", + "Stone Slope Upside Down Edge", + "Stone Slope Upside Down Inner Edge", + "Stone Pyramid", + "Stone Spike", + "Stone One Curved Edge Block", + "Stone Two Curved Edge Block", + "Stone Cylinder", + "Stote Cylinder Horizontal", + "Stone Sphere", + "Stone Element Straight", + "Stone Element Edge", + "Stone Element T", + "Stone Element Cross", + "Stone Element End") +-- COBBLE +--------- +technic_cnc_api.register_slope_edge_etc("default:cobble", + {cracky=3,not_in_creative_inventory=1}, + {"default_cobble.png"}, + "Cobble Slope", + "Cobble Slope Lying", + "Cobble Slope Upside Down", + "Cobble Slope Edge", + "Cobble Slope Inner Edge", + "Cobble Slope Upside Down Edge", + "Cobble Slope Upside Down Inner Edge", + "Cobble Pyramid", + "Cobble Spike", + "Cobble One Curved Edge Block", + "Cobble Two Curved Edge Block", + "Cobble Cylinder", + "Cobble Cylinder Horizontal", + "Cobble Sphere", + "Cobble Element Straight", + "Cobble Element Edge", + "Cobble Element T", + "Cobble Element Cross", + "Cobble Element End") +-- BRICK +-------- +technic_cnc_api.register_slope_edge_etc("default:brick", + {cracky=3,not_in_creative_inventory=1}, + {"default_brick.png"}, + "Brick Slope", + "Brick Slope Upside Down", + "Brick Slope Edge", + "Brick Slope Inner Edge", + "Brick Slope Upside Down Edge", + "Brick Slope Upside Down Inner Edge", + "Brick Pyramid", + "Brick Spike", + "Brick One Curved Edge Block", + "Brick Two Curved Edge Block", + "Brick Cylinder", + "Brick Cylinder Horizontal", + "Brick Sphere", + "Brick Element Straight", + "Brick Element Edge", + "Brick Element T", + "Brick Element Cross", + "Brick Element End") +-- SANDSTONE +------------ +technic_cnc_api.register_slope_edge_etc("default:sandstone", + {crumbly=2,cracky=2,not_in_creative_inventory=1}, + {"default_sandstone.png"}, + "Sandstone Slope", + "Sandstone Slope Lying", + "Sandstone Slope Upside Down", + "Sandstone Slope Edge", + "Sandstone Slope Inner Edge", + "Sandstone Slope Upside Down Edge", + "Sandstone Slope Upside Down Inner Edge", + "Sandstone Pyramid", + "Sandstone Spike", + "Sandstone One Curved Edge Block", + "Sandstone Two Curved Edge Block", + "Sandstone Cylinder", + "Sandstone Cylinder Horizontal", + "Sandstone Sphere", + "Sandstone Element Straight", + "Sandstone Element Edge", + "Sandstone Element T", + "Sandstone Element Cross", + "Sandstone Element End") +-- LEAVES +--------- +technic_cnc_api.register_slope_edge_etc("default:leaves", + {snappy=2,choppy=2,oddly_breakable_by_hand=3,not_in_creative_inventory=1}, + {"bucharest_tree.png"}, + "Leaves Slope", + "Leaves Slope Lying", + "Leaves Slope Upside Down", + "Leaves Slope Edge", + "Leaves Slope Inner Edge", + "Leaves Slope Upside Down Edge", + "Leaves Slope Upside Down Inner Edge", + "Leaves Pyramid", + "Leaves Spike", + "Leaves One Curved Edge Block", + "Leaves Two Curved Edge Block", + "Leaves Cylinder", + "Leaves Cylinder Horizontal", + "Leaves Sphere", + "Leaves Element Straight", + "Leaves Element Edge", + "Leaves Element T", + "Leaves Element Cross", + "Leaves Element End") +-- DIRT +------- +technic_cnc_api.register_slope_edge_etc("default:dirt", + {snappy=2,choppy=2,oddly_breakable_by_hand=3,not_in_creative_inventory=1}, + {"default_grass.png", "default_dirt.png", "default_grass.png"}, + "Dirt Slope", + "Dirt Slope Lying", + "Dirt Slope Upside Down", + "Dirt Slope Edge", + "Dirt Slope Inner Edge", + "Dirt Slope Upside Down Edge", + "Dirt Slope Upside Down Inner Edge", + "Dirt Pyramid", + "Dirt Spike", + "Dirt One Curved Edge Block", + "Dirt Two Curved Edge Block", + "Dirt Cylinder", + "Dirt Cylinder Horizontal", + "Dirt Sphere", + "Dirt Element Straight", + "Dirt Element Edge", + "Dirt Element T", + "Dirt Element Cross", + "Dirt Element End") +-- TREE +------- +technic_cnc_api.register_slope_edge_etc("default:tree", + {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,not_in_creative_inventory=1}, + {"default_tree.png"}, + "Tree Slope", + "Tree Slope Lying", + "Tree Slope Upside Down", + "Tree Slope Edge", + "Tree Slope Inner Edge", + "Tree Slope Upside Down Edge", + "Tree Slope Upside Down Inner Edge", + "Tree Pyramid", + "Tree Spike", + "Tree One Curved Edge Block", + "Tree Two Curved Edge Block", + "Tree Cylinder", + "Tree Cylinder Horizontal", + "Tree Sphere", + "Tree Element Straight", + "Tree Element Edge", + "Tree Element T", + "Tree Element Cross", + "Tree Element End") +-- STEEL +-------- +technic_cnc_api.register_slope_edge_etc("default:steelblock", + {snappy=1,bendy=2,cracky=1,melty=2,level=2,not_in_creative_inventory=1}, + {"default_steel_block.png"}, + "Steel Slope", + "Steel Slope Lying", + "Steel Slope Upside Down", + "Steel Slope Edge", + "Steel Slope Inner Edge", + "Steel Slope Upside Down Edge", + "Steel Slope Upside Down Inner Edge", + "Steel Pyramid", + "Steel Spike", + "Steel One Curved Edge Block", + "Steel Two Curved Edge Block", + "Steel Cylinder", + "Steel Cylinder Horizontal", + "Steel Sphere", + "Steel Element Straight", + "Steel Element Edge", + "Steel Element T", + "Steel Element Cross", + "Steel Element End") + +-- REGISTER MATERIALS AND PROPERTIES FOR STICKS: +------------------------------------------------ + +-- WOOD +------- +technic_cnc_api.register_stick_etc("default:wood", + {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, + {"default_wood.png"}, + "Wooden Stick") +-- STONE +-------- +technic_cnc_api.register_stick_etc("default:stone", + {cracky=3,not_in_creative_inventory=1}, + {"default_stone.png"}, + "Stone Stick") +-- COBBLE +--------- +technic_cnc_api.register_stick_etc("default:cobble", + {cracky=3,not_in_creative_inventory=1}, + {"default_cobble.png"}, + "Cobble Stick") +-- BRICK +-------- +technic_cnc_api.register_stick_etc("default:brick", + {cracky=3,not_in_creative_inventory=1}, + {"default_brick.png"}, + "Brick Stick") +-- SANDSTONE +------------ +technic_cnc_api.register_stick_etc("default:sandstone", + {crumbly=2,cracky=2,not_in_creative_inventory=1}, + {"default_sandstone.png"}, + "Sandstone Stick") +-- LEAVES +--------- +technic_cnc_api.register_stick_etc("default:leaves", + {snappy=2,choppy=2,oddly_breakable_by_hand=3,not_in_creative_inventory=1}, + {"bucharest_tree.png"}, + "Leaves Stick") +-- TREE +------- +technic_cnc_api.register_stick_etc("default:tree", + {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1,not_in_creative_inventory=1}, + {"default_tree.png"}, + "Tree Stick") +-- STEEL +-------- +technic_cnc_api.register_stick_etc("default:steelblock", + {snappy=1,bendy=2,cracky=1,melty=2,level=2,not_in_creative_inventory=1}, + {"default_steel_block.png"}, + "Steel Stick") + +-- REGISTER MATERIALS AND PROPERTIES FOR HALF AND NORMAL HEIGHT ELEMENTS: +------------------------------------------------------------------------- + +-- WOOD +------- +technic_cnc_api.register_elements("default:wood", + {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, + {"default_wood.png"}, + "Wooden Element Straight Double", + "Wooden Element Edge Double", + "Wooden Element T Double", + "Wooden Element Cross Double", + "Wooden Element End Double") +-- STONE +-------- +technic_cnc_api.register_elements("default:stone", + {cracky=3,not_in_creative_inventory=1}, + {"default_stone.png"}, + "Stone Element Straight Double", + "Stone Element Edge Double", + "Stone Element T Double", + "Stone Element Cross Double", + "Stone Element End Double") +-- COBBLE +--------- +technic_cnc_api.register_elements("default:cobble", + {cracky=3,not_in_creative_inventory=1}, + {"default_cobble.png"}, + "Cobble Element Straight Double", + "Cobble Element Edge Double", + "Cobble Element T Double", + "Cobble Element Cross Double", + "Cobble Element End Double") +-- BRICK +-------- +technic_cnc_api.register_elements("default:brick", + {cracky=3,not_in_creative_inventory=1}, + {"default_brick.png"}, + "Brick Element Straight Double", + "Brick Element Edge Double", + "Brick Element T Double", + "Brick Element Cross Double", + "Brick Element End Double") +-- SANDSTONE +------------ +technic_cnc_api.register_elements("default:sandstone", + {crumbly=2,cracky=2,not_in_creative_inventory=1}, + {"default_sandstone.png"}, + "Sandstone Element Straight Double", + "Sandstone Element Edge Double", + "Sandstone Element T Double", + "Sandstone Element Cross Double", + "Sandstone Element End Double") +-- LEAVES +--------- +technic_cnc_api.register_elements("default:leaves", + {snappy=2,choppy=2,oddly_breakable_by_hand=3,not_in_creative_inventory=1}, + {"bucharest_tree.png"}, + "Leaves Element Straight Double", + "Leaves Element Edge Double", + "Leaves Element T Double", + "Leaves Element Cross Double", + "Leaves Element End Double") +-- TREE +------- +technic_cnc_api.register_elements("default:tree", + {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1,not_in_creative_inventory=1}, + {"default_tree.png"}, + "Tree Element Straight Double", + "Tree Element Edge Double", + "Tree Element T Double", + "Tree Element Cross Double", + "Tree Element End Double") +-- STEEL +-------- +technic_cnc_api.register_elements("default:steel", + {snappy=1,bendy=2,cracky=1,melty=2,level=2,not_in_creative_inventory=1}, + {"default_steel_block.png"}, + "Steel Element Straight Double", + "Steel Element Edge Double", + "Steel Element T Double", + "Steel Element Cross Double", + "Steel Element End Double") diff --git a/technic/init.lua b/technic/init.lua index 58e0488..ff904e2 100644 --- a/technic/init.lua +++ b/technic/init.lua @@ -2,6 +2,8 @@ -- namespace: technic -- (c) 2012-2013 by RealBadAngel +technic = {} + modpath=minetest.get_modpath("technic") --Read technic config file @@ -25,6 +27,9 @@ dofile(modpath.."/tool_workshop.lua") dofile(modpath.."/music_player.lua") dofile(modpath.."/generator.lua") dofile(modpath.."/grinder.lua") +dofile(modpath.."/cnc.lua") +dofile(modpath.."/cnc_api.lua") +dofile(modpath.."/cnc_nodes.lua") --MV machines dofile(modpath.."/wires_mv.lua") @@ -34,10 +39,13 @@ dofile(modpath.."/electric_furnace_mv.lua") dofile(modpath.."/alloy_furnace_mv.lua") dofile(modpath.."/forcefield.lua") +--HV machines +dofile(modpath.."/wires_hv.lua") + --Tools -if enable_mining_drill==true then dofile(modpath.."/mining_drill.lua") end -if enable_mining_laser==true then dofile(modpath.."/mining_laser_mk1.lua") end -if enable_flashlight==true then dofile(modpath.."/flashlight.lua") end +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 +if technic.config:getBool("enable_flashlight") then dofile(modpath.."/flashlight.lua") end dofile(modpath.."/cans.lua") dofile(modpath.."/chainsaw.lua") dofile(modpath.."/tree_tap.lua") diff --git a/technic/textures/technic_cnc_bottom.png b/technic/textures/technic_cnc_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..e600cb1de24947b81b8bdc0111b8efa44becf544 GIT binary patch literal 2006 zcmV;{2Pyc8P){yZmA))XA8$k7>e}Zi^~&|*Y(24ND_c*?8teR>QtoT5eHo{I8*hEv z_Wtg(TkCnv>^1lEaq&C%Ii7S@53bW2RR^- zjk*#gXfub1e9in`6W>cOnaGzE|D~3`meSjGL>8A-&}0Q*0@`@KwWDVMB*2Wr#QH73 ze`R3hM`4rUZRpc&>N5)ysl4AG&@lFok2_f+ZDe6Tj(%Qyf4jYr3DZCKykrh1LQ-A; zkO5f%Rts4Z1kvV9)MQ6W%yi}Z7XTwJpqk*Y5cyU}c_Dr9beu=%qSYP#=2(}}gdEno zaou#bpk;)%3VlW|t%d8-DVUS&x_3fbW@UJPe*riTxM9N$#CIYrA_qWiXQcduGqbd? zW|`~CiON3G{QT{HD^;_x&&u@`@b3Krz-Fdb zF-_wLLjH+h0Zjg)q@WEVAzSS@p@B3bE;-)!gH6{ss35?u` z%K9Y{tR>7IUjQ}^Rd_282w<9qrwF}nREm` zSR71c6rO7bV5EU8x!*ScPi{1jV&ntqCsheLRBmR2hMBlVg-2CrDu~RKCM$vsXEM1U zxCuH1yOVNj-h-RfuvW_aGdKW$0r0Rw4Y#ZH`+t8&dP9I5rj5$q%9;btEjcrmmZ_iT z6?UD~&!=%o$9ca8s6>TGlhvZ}C}=ad>AZmY0&q~HMpalGY2^S@nBeNVU)<9d^od)) z9%pD^BU8HM?fu3B7 zZ!4CB)9u$4SrCjVHTCMiL#-Iax^Ztt%x1%~ZMzMK%DT;z=@1#q>V*3TmGcE46ZMRX znVJC=S2Mza+YT)U(Zkoa(j|#*rz37;Nox_NdzqDKc|vqV?X$DIziAnd&;NCBg> zJ0)y&p_Ok&q_I#^az*WLp?}kAD*-CiFIj;~BvC=Pg9L z1HvrYoMzVAZ53_BxYShn*^cE7gTZ<=kqeXxr|oB?Dk)OX>v{rkgF{uru}w@HHgf6O z>59@+andj|o_%1?H@v^tv;ebY^a2g9ZfGfCBzCnhp3lL=jV@?VKvB!o_=vLQTKBWe zvcl4);Wn|cbAxu?PQU_Y)Kj#1%*cwcvTVb3>IWKMonz z@I2u0h-!l``?=0&e`wGWDQ9}Jq#pnKO^G>fX~&w4osrUHO`(*1CbR;@t`W?SUZAaN zMpl3+TS2Gas|gKef(lC~(hqtKC9V;%uIXlx6%QaI0@i$V!i%XY_~%}Wy%);!q-T8V zhAYiR3cRU-EX;n2an?4WpxUT7EP6a5TASSwF%k6=>zwtVi6}>m$WNmckOw&@%ur~* z(3q;@9aZ)cA&1PQGq@ol1tHDK*=}^r2IL4J4yNcb0UUHDaJ1R7u+Xr5*Ml>w*XH5BiQ1{qLzq)O{S;wEfx zef;J@#K+rGc)Cr*IUfG)Xx8(}eGiH{C%sln@Xd7XI<4E8(rL;ep$~{;vQ314^xHi%raM*#H0l07*qoM6N<$f@Pk|5dZ)H literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_cylinder.png b/technic/textures/technic_cnc_cylinder.png new file mode 100644 index 0000000000000000000000000000000000000000..06da024b91b5839c9135c2c8b87fb6a53ee01ffd GIT binary patch literal 456 zcmV;(0XP1MP)lv6%>6+Xs-rb=2S|pb%5=fmEZV)>HuoPfj>3C9&qUM7H2wc z^&##F_woIwfX{}iU5J8h1uxce@XC}o2MFQzP}FRNn85+4KH$SE09HE$sG#6ED)~J? zKk3c`at*8m*A?(C=vNB}V8r?;C;`$6&8f%W0Q3M%@(#0*D<~+3VYZ>5IY3^$2Oyo4 zp@NsH_@@fC02V^quSgESaGpwgGr6{hxFOI|@D!Ik{dsT~fOKO(R}Z|$?UYm`pd7Jn z3dU?m2Ph~30@UsSnR?;>Hyzw*qX*Slqo4q$*ZSa)TLHUuw|Fm(=O)cTS{&IXV|<_& y;?jrkIEl~;P)SfqIXI4^-3EGGO$>MVJ=+^lMa9`J4O<-m00003ieY#{#}~Tsofn@i`E593TTW9uUA_69579(*d3>Anj(Pc~bO# zCRVgZE%pU8z+JH240_<8V7dT$;f4T`TS+|UlE=*rme_kR5g+B9Xy;w$5YTFFhhuLu z)c_Uux@4?iP6Dg~S!ge7kS^M;XmPc$M0=V;dul+pO$!`cTLO4>7nb6&04Cr}22<^M zHu?&1a{v-^bnc1$pyq)_EF{UI09S1A)}F`n(*Vc`5g(eYCci4415}u+9x+=)F(gy1 zT@Bu%r;ubB)1=cRV$Bb0ulXIobzSHE1O3yqlIC#2{Wm>>$%zVH-L(J!002ovPDHLk FV1leSym0^k literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_element_cross.png b/technic/textures/technic_cnc_element_cross.png new file mode 100644 index 0000000000000000000000000000000000000000..f2ad0b79ddafba3d275341800bd610a429ff2b4a GIT binary patch literal 415 zcmV;Q0bu@#P)>makflA+Lf$RqS z23QYh7vKyyDLh zBx_hX=%5IUZ2_J$o@Qm~&Zy=UeEcHBTrzTiH8}E32Mp@jO~nQ{TtKTF!C?XhaCm?T z-2Vdl_Pbm>E>F)S5kjkK`HMBK1+WoJ1$Z9D=F|)UZD$hQTxKdWHn&GaBP=f#f002ov JPDHLkV1kXQqt^fc literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_element_edge.png b/technic/textures/technic_cnc_element_edge.png new file mode 100644 index 0000000000000000000000000000000000000000..e6104cf3b258057fe1cb99d52c780222d53540c7 GIT binary patch literal 409 zcmV;K0cQS*P)G}BwEvoe(^A$4Pn4F%< z5!eJa_RLIBJDz8PGeK zD8P*cp23jh#&_{!fq61OVs$-kp=Qk35=R{v#9JMECm|MMEIE_Y%q5gqh&id1U~z&! zjq_0+#g;&1+zmfb{~-Zb;JB!631S~Spv79(0)sZHE+%JQ>U!dIBE^~jr3jN*+!Mh9 luIuXe0{wfj@A!s4+CGrJX;{@Do!9^X002ovPDHLkV1i4boGJhS literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_element_straight.png b/technic/textures/technic_cnc_element_straight.png new file mode 100644 index 0000000000000000000000000000000000000000..1648b7b2a5d4702f3ba5c0dbfa7e834f78f61f8b GIT binary patch literal 412 zcmV;N0b~A&P)P~J!5VsBbS(asU&TTIE_AjG00tV+u z?Hkwx7FK2^XzkB4!I_{n0qga%5B^1hVXCL;UJGtkVnRtr6xsxs!)X$&3PfS)d3R}6 z1D4`)X_|mm6nA}^W)ZLj%)R|xeKP}F;!MEmu$UMnw;x}H30B92$94+zxaWafYB9Nh zdk!eU65KOD1+E|P4n@Dkl2U2=l^DS>rR@Vma6)p!1EmE6G}Xb+!CZo1zx&1Z12Q;d z(b@-Ch&y%!# z`6)$V(WynLM=|mTJCs=wBiBMNP3yXjyMca;55Qw0Wt42BK%rBb1rvgavVH!XCdMm$S!=y9#vAa(H(Cnb@dk|ql%g;DLfi7o?jXZ%tir|VS!TToR%s@wGd-+>oOIeFFs6AEBhHZTtOPh;gI zQp*Xx{?WyNs{va$`0VFE#8E&7PA@Pd2RNO;6HXtnz&#g;i)Z(-Yh;pix;Ebv&nric z->Og!kO>n3<6&(27k8-#ft-g{)?VDY5CtTML}eN2A;rK8CL~DRF#ZT)m+0Y+WAo4! jigQly0s4VVQl<45wk-ZGPM&bL00000NkvXXu0mjflC7KR literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_front.png b/technic/textures/technic_cnc_front.png new file mode 100644 index 0000000000000000000000000000000000000000..6cc049004708b6f0c262a99e1818838300d2efd6 GIT binary patch literal 2000 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 literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_onecurvededge.png b/technic/textures/technic_cnc_onecurvededge.png new file mode 100644 index 0000000000000000000000000000000000000000..46779fd6167b3b844183f90ba4997afbbb192ff6 GIT binary patch literal 507 zcmVPx#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy7<5HgbW?9;ba!ELWdKlNX>N2bPDNB8b~7$AGPjWzeE%1YST7KQjex!t)c`ptY#(l_YG4m89m_$Afg@m&(u;r=I4Vsx&=QxQ zyDmEm=!JuzBya|2bDuJdKw|h`qT6bV8CFs4+S;sh_pSocs z)|NKm+<=nwa-0iLf{XjQ0()`h2}*!5jfKXxj-zrR)T5i*EQX6fDPPhFk6#Q zKm?~+7poE#0@HfBo**##sZDX;xz`4!re{Z=l59CA8bNv;FBB& xmG9FHMDI@kD8&^C?)$!O1N|;@_TOv4?LT5tyL}w(&U*j=002ovPDHLkV1lmk#v%X! literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_pyramid.png b/technic/textures/technic_cnc_pyramid.png new file mode 100644 index 0000000000000000000000000000000000000000..5dc3322e5f729cb43591f4b8a999e7ced0ecbf09 GIT binary patch literal 480 zcmV<60U!Q}P)l3-W5--?a|+v_q)+@9UO^U_W!X5*T0wBBW46A2;BF9 z^h1MyfMNb(Kw54e0l*x`ksR8VrUR(Ka^M$B6U+8Q8-OJk))NL3Ui&<-n3tgyKr4*i z$5X@e9A`rsfi*Y@NSGY>JkrEmPO|{4h4J^JynxXD(jx;ep z(-eRaIGz?y5T6Zb4*OW4d=jroB7joA5egISL&9O-K;B+7d7x6S5spwA>^(UY`4110 zyx;g2)=GOll8vXC{R*}2kpqF^!UMwv8a5)Soz|w85M`SlTJ!V#c1}JkR~!K;M5&I=;id+I|3p W0^oF6IUle90000Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy7<5HgbW?9;ba!ELWdKlNX>N2bPDNB8b~7$AGPjWzeEj=)?2wU^4=(x^fy^o#Z|JjBnb4(boUJZ z`1c;ij z=B2cuA6n*Ko-%ul?6JmonP;9^ShKXLAKT9Q^X)CxChmLoC;v++wPnsNkC_8Xo2IFa zX=>9rw(Ire-rTzHT^l)|l+tDn$gC+j2Y_|k0z};ap6RGZEx3Wn|W>=QyYhg z0Jm0;`UJ48L^n=t*+2@2KJ~5ddNu-#kt}oky|B(q?Z?h$na$1C%H~^}vr!G~u>x`; zN)MXb1Q>%l4%VzoTiJ7*xSsM8z-*fMj7B~Tt^fYLy}iFjv_|zSjoZGoLKenxX#2KD ziZ{xWhMs3rWFcMpcI*eylR@@NBftTY$YvqS0lZSyWqJar>mFrDY!Zvv(DaSN2x?Mp zeMz@Ktlvrrj97kL-%jpvjpt13&~<#1Apj(TS>(-J_!!{8GxuN%S$S|^r_P%fSrpkY z<$c#?4ye27%|V*;IHE+~zI|(|=ih#OE_234IVztAfSiepjW-x>YWCaN&hrRBxez%l z-T*bi4LAAx`SXAN2-;GsvQ6f(_JpC zuN>~W#Kv%fb^Q+rSNP4L%5)F_Tngz%dCj8ozRURmpc36K+cgp*Qf4bz*df)%W=1(v ziiL+J2=@^VNYrr@(2EKRy4(S=RgmWdy4=nyDWpydIv-&3PBs?Y@ON-vgV@8X6Y6xy z^iqb614B9hT8ZA2W$*KV`qt4hdJZcl-Ew2)_k;(`TvwtxV`lw;Ukp6~!3||=nRM3$ z&S+SV5_qwv=GHQk8V}J_RDlQme7kYK3*sI0ht+zr?ux~(a6$(R;QXG3)H>Gcs;<*N zy33!j=W#vS0$CR_yCdnR3UD*Yk|m4HM+*hi!6M6JGue=(hn=_Uhd5w)6QI^tA6SU0 z*82e~>Dgp8ht6D|7apKI=j|5S{T&>L(gNZsLk?F~rfGtqp=D||p$Zi;V9B9-x>-R& zDxu&BE14UU-=v$`?`U7J%2`FJpoJ2q9^>J@*6#BM&a2v90AMVpS*zv2gbi1sKS;Zp zR{LQ{dIIHfKA30B1yDQS{adq15YBH8D=(yTPS6J;pn3;)5b)EAy@BjjSS%3-=L4d- z-t>O6ayOM^^ssw&I3WXt@>mf>(BQW4q&|}>9*12XeN*bIf`0BtwgP!H63efi}t>stg(b&tZ?Q&DG55WR}3T< zh>OGrCaM_Y09F9zEb-(3>?{nT_<>hIKv<(&ufzF%NRc%maz$ zGO>xx%XbFHw~cI7-X~lagDoU0n2a(G*2@vHV{aJ=>|oxIAFAmAAW%`$-mzMDgY}~i z5}_09jz^3%88dMLtc#HyGda%~REshs_1+hpe2|#lw>0;b-UWEGwlY!6gXfEhEt7g4 zOvl}&gY~{(sAFW~Fd_&@WwX+3^n|t4`Y6+KJ`obZdnv@Aa)?#bvM06sF~|Bh$>2HIyn1UV!Z07*qo IM6N<$g7Jiq4gdfE literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_slope.png b/technic/textures/technic_cnc_slope.png new file mode 100644 index 0000000000000000000000000000000000000000..083ae18cead58a9184bd67530aeafe610e9d7298 GIT binary patch literal 437 zcmV;m0ZRUfP)4D zo3T!BIziXKRXD7*@%zu{fAK0@tcw97?sXuA8v(P&c@0uUs5Ajr?rl_6<~7)FM4OreXIS^Ssm1%g%ZJ`M@xCjT*G+9! foXV%WVb%8!Ki5#NA|S~n00000NkvXXu0mjf9OS!A literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_slope_edge.png b/technic/textures/technic_cnc_slope_edge.png new file mode 100644 index 0000000000000000000000000000000000000000..785adf6531fb5a95b387869ed590d354d071666b GIT binary patch literal 419 zcmV;U0bKrxP)=13A3=}IIiuvm3S2Fm2Y?DFyD)N zV3N{y0Y~BhW&(P^YUxp&s>Gf+u49;h-Y^Z0O>hKCTiR+HoC&-tEB>rH%y>g#@P%^? zcb;Zdrk!3$iYxE=PC;jZ!g+BIwv}FeVk!i}MYK?iyB>&J^JXRRSd5VG9I(aueQy9t z)1)0jj>5m}0JfkQXu~-#9^t~DpXuy8SlwFJ)o%g)cpCOT+%M<~`~W~B_g~(faa{la N002ovPDHLkV1jjZu+9Jg literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_slope_edge_upsdwn.png b/technic/textures/technic_cnc_slope_edge_upsdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..5adb788b795553448a74f32234eb12a0b152343b GIT binary patch literal 486 zcmV@P)-G35m*7E zDXP~xv;o+O`wdL#^)j*o*a^e*RG{3O1>hixm$n*t+&?owW1KoLa_NNd=I!sm z6?^kqpjhe;!2wbQ(&;ivGYjOf>I8G+ZvYKQK+#1@I|PhfF?1%t9Bdef$+j|iVx`iW z0b9~U9DJz#IwW~&f;B_Ldkujeb}f*Xox=(PAtIZ$8U0ts{|@ZU5|Wj*h&&C*OOH^g z-%PiemNens3g98dSL-)PE2^}~LsD=`Wd__WKsrd7l7`Ibb>JROh>QAlxGVA=u|e>=5CKlk|uIGXR1piP47y2dEy cT~p(>FB3e%#bcOwwEzGB07*qoM6N<$f*QunI{*Lx literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_slope_inner_edge.png b/technic/textures/technic_cnc_slope_inner_edge.png new file mode 100644 index 0000000000000000000000000000000000000000..906dd2548b63cd146bcb3374293ddb3a7543e1e0 GIT binary patch literal 497 zcmVjl1O?K=K^ASUKmfXf-`}Di^3={f`jk! z^i*ILmIcmmBCv{s>m%t&xFvuZ&K!f4Bs~e*$>CaAS(9Xu7Em8^d=c+lG)1r)P@b*Q z?t&ADmwTYrBkcJov$m0fKqzM+JwS`~`aA)&(&WHcV#zV6{bHWz4Cqg64&3*>zUht7 n=enX^_ul?!+?BuouD7-yOl{;`+yuDy00000NkvXXu0mjfjFa2c literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_slope_inner_edge_upsdwn.png b/technic/textures/technic_cnc_slope_inner_edge_upsdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..0ae0e14ddd6400f190469173534ae2fb8e8f45ee GIT binary patch literal 605 zcmV-j0;2tiP)SC+y6v1=45!R_Tg|K!GA0^zOqx02;X32S?}ONCyy1 z4Fck&2Z12&Hb{``#%T_KNaHil=|elf;7wg6?%k_}w!qYQ^aj!E>r7Cf_XMNJ5b*Z^ z(WU|UTo%Pb^CFd*YmsTXFx{BI8Uz9+6m2p&v&0IJ z<~R=MbpaE|aaww2i3dpSp}-9r;bs7PtA;wLWNH=;28scrjY^qbh4x?wZZ`1NKTlYO zqkYab&B%4pvHVF?bF7Wn-tUL=U;vmB>z3GqbCnnv(YJ}0m6Z~#XcX#7(1YysIT!Bd z__}F(6G#sLIn5(Mdan-#DOG}nfXK9CEMv`5$;&+rXd$gNmZ6%`zY0VL!ddQI@~;93 zR?`gkL2E=i(vzt*$Va1?PvF|>f&yhp*>Ns;7^n>v1USHnMJz#^f4|8^&OVk&T0jlg zztabR;|L}IWvR6U`_qV3p-DiFM1U6S`uqi8JFnriDWkae+$a;go=m*BQkS%C+g5g> rTN=^rAK&pd&pB~cLj@T9qT>30-TN_gAA!CT00000NkvXXu0mjfP2CS$ literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_slope_lying.png b/technic/textures/technic_cnc_slope_lying.png new file mode 100644 index 0000000000000000000000000000000000000000..377769a7f2d0c28cf411134146fb6d5e9d13b89c GIT binary patch literal 548 zcmV+<0^9wGP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy7<5HgbW?9;ba!ELWdKlNX>N2bPDNB8b~7$AGPjWzeEE32oCLI7gvtt_B>i;!gOxBfdJV%cg%G9y zzQ;|gMnG`3WQ$-Ou+TFv3eGQDyIzu{9&irh<+sOfCX4H~)Ns77-EkMd7?^!m23p}_ z0{khLdO$J9e-#3HLEg>tL1qH(0hZ_b48SAcwi9Us@JJ|M#wP&n;*vz*9+#>liU4xs zTfxR$`%|%YUFZ{lfP-o@y=ag>=XjN8LSckKIji2c%stEaWyX^{f6gO}?VsugA9Z^L zXWiQYMZH56q00Yzx^`C=Gxlr@YPiDze`mR2u_Wn$o-D3akY$A)@RS$Kb(a|r zpss(|oG}Qv4%iix`k?EdI|iwqEif&+ literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_slope_upsdwn.png b/technic/textures/technic_cnc_slope_upsdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..b802b60db0e329dddc96884da31bd597d8e8c925 GIT binary patch literal 440 zcmV;p0Z0CcP)w5W*3X?{nhyK)`5p zwf!Zi)5T(Zcio+!wILAW;9QS10G43%w{hqokb|mSBf|~=H8^?c1wad!y!1@q3>+`b z25=^dKjI6(t6}Z3I|QCfUn%jb6rXV&f+J5yj{4vW;S#b7{H=y_^Q16#f~6VXikeXP zz@=Rd?7>t(P1$K`wbGgZ^Z4TLfJ-glyi``vDCRzOw3swC0QPXAQ9J@Im6MyCS&4h2 zyoThYHzh#~#$}f#H#I?;s$@{$WFL~1gxd#O*FmBQk@i-Z6Yg>#oj+?pz%2vf`I90s zZYdCV1={aiBv=|qG(9&7(y7U1g0)2153Cl`%=kT+@5SSPplx{r?*z38XxryLxbM5) i59s;j-SHRxXnO-cQtO1vAaX7M00003v?#Bj2nR*28_Y2?M-;+mSo0uB>$2druzw4i1^)78bZP}A1n4DioMaNqZJ|ABr@)inPvc>M{6 W_hHLH!dDsq0000?H^6s{au38*-x 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 Date: Mon, 6 May 2013 23:14:27 +0200 Subject: [PATCH 24/57] Fixes to te machine level of service. --- technic/cnc.lua | 352 ++++++++++++++++++++++++++++---------------- technic/cnc_api.lua | 14 +- 2 files changed, 229 insertions(+), 137 deletions(-) diff --git a/technic/cnc.lua b/technic/cnc.lua index 6e763ef..71b78b0 100644 --- a/technic/cnc.lua +++ b/technic/cnc.lua @@ -1,40 +1,94 @@ -- Technic CNC v1.0 by kpo -- Based on the NonCubic Blocks MOD v1.4 by yves_de_beck local shape = {} -local size = 0 local onesize_products = { - slope = 2, - slope_edge = 1, - slope_inner_edge = 1, - pyramid = 2, - spike = 1, - cylinder = 2, - sphere = 1, - stick = 8, - slope_upsdwn = 2, - slope_edge_upsdwn = 1, - slope_inner_edge_upsdwn = 1, - cylinder_hor = 2, - slope_lying = 2, - onecurvededge = 1, - twocurvededge = 1, + slope = 2, + slope_edge = 1, + slope_inner_edge = 1, + pyramid = 2, + spike = 1, + cylinder = 2, + sphere = 1, + stick = 8, + slope_upsdown = 2, + slope_edge_upsdown = 1, + slope_inner_edge_upsdown = 1, + cylinder_horizontal = 2, + slope_lying = 2, + onecurvededge = 1, + twocurvededge = 1, } local twosize_products = { - element_straight = 4, - element_end = 2, - element_cross = 1, - element_t = 1, - element_edge = 2, + element_straight = 4, + element_end = 2, + element_cross = 1, + element_t = 1, + element_edge = 2, } -local showbackground = "--" -local max_cncruns = 99 -local max_products = 99 +--cnc_recipes ={} +--registered_cnc_recipes_count=1 +-- +--function register_cnc_recipe (string1,string2) +-- cnc_recipes[registered_cnc_recipes_count]={} +-- cnc_recipes[registered_cnc_recipes_count].src_name=string1 +-- cnc_recipes[registered_cnc_recipes_count].dst_name=string2 +-- registered_cnc_recipes_count=registered_cnc_recipes_count+1 +-- if unified_inventory then +-- unified_inventory.register_craft({ +-- type = "cnc milling", +-- output = string2, +-- items = {string1}, +-- width = 0, +-- }) +-- end +--end ---showlabelin = "" ---showlabelout = "label[4.5,5.5;Out:]" +local cnc_formspec = + "invsize[9,11;]".. + "label[1,0;Choose Milling Program:]".. + "image_button[1,0.5;1,1;technic_cnc_slope.png;slope; ]".. + "image_button[2,0.5;1,1;technic_cnc_slope_edge.png;slope_edge; ]".. + "image_button[3,0.5;1,1;technic_cnc_slope_inner_edge.png;slope_inner_edge; ]".. + "image_button[4,0.5;1,1;technic_cnc_pyramid.png;pyramid; ]".. + "image_button[5,0.5;1,1;technic_cnc_spike.png;spike; ]".. + "image_button[6,0.5;1,1;technic_cnc_cylinder.png;cylinder; ]".. + "image_button[7,0.5;1,1;technic_cnc_sphere.png;sphere; ]".. + "image_button[8,0.5;1,1;technic_cnc_stick.png;stick; ]".. + + "image_button[1,1.5;1,1;technic_cnc_slope_upsdwn.png;slope_upsdown; ]".. + "image_button[2,1.5;1,1;technic_cnc_slope_edge_upsdwn.png;slope_edge_upsdown; ]".. + "image_button[3,1.5;1,1;technic_cnc_slope_inner_edge_upsdwn.png;slope_inner_edge_upsdown; ]".. + "image_button[4,1.5;1,1;technic_cnc_cylinder_horizontal.png;cylinder_horizontal; ]".. + + "image_button[1,2.5;1,1;technic_cnc_slope_lying.png;slope_lying; ]".. + "image_button[2,2.5;1,1;technic_cnc_onecurvededge.png;onecurvededge; ]".. + "image_button[3,2.5;1,1;technic_cnc_twocurvededge.png;twocurvededge; ]".. + + "label[1,3.5;Slim Elements half / normal height:]".. + + "image_button[1,4;1,0.5;technic_cnc_full.png;full; ]".. + "image_button[1,4.5;1,0.5;technic_cnc_half.png;half; ]".. + "image_button[2,4;1,1;technic_cnc_element_straight.png;element_straight; ]".. + "image_button[3,4;1,1;technic_cnc_element_end.png;element_end; ]".. + "image_button[4,4;1,1;technic_cnc_element_cross.png;element_cross; ]".. + "image_button[5,4;1,1;technic_cnc_element_t.png;element_t; ]".. + "image_button[6,4;1,1;technic_cnc_element_edge.png;element_edge; ]".. + + "label[0, 5.5;In:]".. + "list[current_name;src;0.5,5.5;1,1;]".. + "label[4, 5.5;Out:]".. + "list[current_name;dst;5,5.5;4,1;]".. + + "list[current_player;main;0,7;8,4;]" + + +local cnc_power_formspec= + "label[0,3;Power]".. + "image[0,1;1,2;technic_power_meter_bg.png]" + +local size = 1; --- I want the CNC machine to be a two block thing minetest.register_node("technic:cnc", { description = "CNC Milling Machine", tiles = {"technic_cnc_top.png", "technic_cnc_bottom.png", "technic_cnc_side.png", @@ -53,72 +107,44 @@ minetest.register_node("technic:cnc", { type = "fixed", fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, }, - groups = {oddly_breakable_by_hand=2, cracky=3, dig_immediate=1}, + groups = {cracky=2}, + legacy_facedir_simple = true, + technic_power_machine=1, + internal_EU_buffer=0; + internal_EU_buffer_size=5000; + cnc_time = 0; + src_time = 0; -- fixme + + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_string("infotext", "CNC machine") + 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", cnc_formspec..cnc_power_formspec) + meta:set_float("cnc_time", 0) + + local inv = meta:get_inventory() + inv:set_size("src", 1) + inv:set_size("dst", 4) + + meta:set_string("formspec", cnc_formspec) + meta:set_string("infotext", "CNC Milling Machine") + end, can_dig = function(pos,player) local meta = minetest.env:get_meta(pos); local inv = meta:get_inventory() - if not inv:is_empty("input") or not inv:is_empty("output") then + if not inv:is_empty("src") or not inv:is_empty("dst") then minetest.chat_send_player(player:get_player_name(), "CNC machine cannot be removed because it is not empty"); return false end return true end, - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - if technic_cnc_api.allow_menu_background == true or technic_cnc_api.allow_menu_background == 1 then - showbackground = "background[-0.15,-0.25;8.40,11.75;technic_cnc_background.png]" - end - - meta:set_string("formspec", "invsize[8,11;]".. - "label[0,0;Choose Milling Program:]".. - "image_button[0,0.5;1,1;technic_cnc_slope.png;slope; ]".. - "image_button[1,0.5;1,1;technic_cnc_slope_edge.png;slope_edge; ]".. - "image_button[2,0.5;1,1;technic_cnc_slope_inner_edge.png;slope_inner_edge; ]".. - "image_button[3,0.5;1,1;technic_cnc_pyramid.png;pyramid; ]".. - "image_button[4,0.5;1,1;technic_cnc_spike.png;spike; ]".. - "image_button[5,0.5;1,1;technic_cnc_cylinder.png;cylinder; ]".. - "image_button[6,0.5;1,1;technic_cnc_sphere.png;sphere; ]".. - "image_button[7,0.5;1,1;technic_cnc_stick.png;stick; ]".. - "image_button[0,1.5;1,1;technic_cnc_slope_upsdwn.png;slope_upsdwn; ]".. - "image_button[1,1.5;1,1;technic_cnc_slope_edge_upsdwn.png;slope_upsdwn_edge; ]".. - "image_button[2,1.5;1,1;technic_cnc_slope_inner_edge_upsdwn.png;slope_upddown_inner_edge; ]".. - "image_button[5,1.5;1,1;technic_cnc_cylinder_horizontal.png;cylinder_horizontal; ]".. - - "image_button[0,2.5;1,1;technic_cnc_slope_lying.png;slope_lying; ]".. - "image_button[1,2.5;1,1;technic_cnc_onecurvededge.png;onecurvededge; ]".. - "image_button[2,2.5;1,1;technic_cnc_twocurvededge.png;twocurvededge; ]".. - - "label[0,3.5;Slim Elements half / normal height:]".. - - "image_button[0,4;1,0.5;technic_cnc_full.png;full; ]".. - "image_button[0,4.5;1,0.5;technic_cnc_half.png;half; ]".. - "image_button[1,4;1,1;technic_cnc_element_straight.png;element_straight; ]".. - "image_button[2,4;1,1;technic_cnc_element_end.png;element_end; ]".. - "image_button[3,4;1,1;technic_cnc_element_cross.png;element_cross; ]".. - "image_button[4,4;1,1;technic_cnc_element_t.png;element_t; ]".. - "image_button[5,4;1,1;technic_cnc_element_edge.png;element_edge; ]".. - - "label[0, 5.5;In:]".. -- showlabelin.. - "list[current_name;input;0.5,5.5;1,1;]".. - "field[3, 6;1,1;num_cncruns;Repeat program:;${num_cncruns}]".. -- Fill default with meta data num_cncruns - "label[4, 5.5;Out:]".. -- showlabelout.. - "list[current_name;output;4.5,5.5;1,1;]".. - - "list[current_player;main;0,7;8,4;]".. - showbackground) - meta:set_string("infotext", "CNC Milling Machine") - meta:set_string("num_cncruns", 1 ); - - local inv = meta:get_inventory() - inv:set_size("input", 1) - inv:set_size("output", 1) - end, - on_receive_fields = function(pos, formname, fields, sender) - -- REGISTER MILLING PROGRAMMS AND OUTPUTS: + -- REGISTER MILLING PROGRAMS AND OUTPUTS: ------------------------------------------ -- Program for half/full size if fields["full"] then @@ -131,32 +157,12 @@ minetest.register_node("technic:cnc", { return end - local meta = minetest.env:get_meta(pos) - local inv = meta:get_inventory() - - -- Limit the number entered - if( fields.num_cncruns and tonumber( fields.num_cncruns) > 0 and tonumber(fields.num_cncruns) < 100 ) then - meta:set_string( "num_cncruns", fields.num_cncruns ); - else - minetest.chat_send_player(sender:get_player_name(), "CNC machine runs set to a bad value. Machine resets."); - meta:set_string( "num_cncruns", 1 ); - fields.num_cncruns = 1 - end - - -- Do nothing if the machine is empty - if inv:is_empty("input") then - return - end - - -- Do nothing if the output is not empty and the product used is not the same as what is already there - - -- Resolve the node name and the number of items to make and the number of items to take - local product = "" - local produces = 1 - local input_used = 1 - local inputstack = inv:get_stack("input", 1) + -- Resolve the node name and the number of items to make + local meta = minetest.env:get_meta(pos) + local inv = meta:get_inventory() + local inputstack = inv:get_stack("src", 1) local inputname = inputstack:get_name() - local multiplier = 1 + local multiplier = 0 for k, _ in pairs(fields) do -- Set a multipier for the half/full size capable blocks if twosize_products[k] ~= nil then @@ -164,38 +170,124 @@ minetest.register_node("technic:cnc", { else multiplier = onesize_products[k] end - + if onesize_products[k] ~= nil or twosize_products[k] ~= nil then - product = inputname .. "_technic_cnc_" .. k - produces = math.min( fields.num_cncruns*multiplier, max_products) -- produce at most max_products - input_used = math.min( math.floor(produces/multiplier), inputstack:get_count()) -- use at most what we got - produces = input_used*multiplier -- final production - print(size) - print(fields.num_cncruns) - print(product) - print(produces) - print(input_used) - print("------------------") + meta:set_float( "cnc_multiplier", multiplier) + meta:set_string("cnc_user", sender:get_player_name()) + end + + if onesize_products[k] ~= nil or (twosize_products[k] ~= nil and size==2) then + meta:set_string("cnc_product", inputname .. "_technic_cnc_" .. k) + break + end + + if twosize_products[k] ~= nil and size==1 then + meta:set_string("cnc_product", inputname .. "_technic_cnc_" .. k .. "_double") break end end - - -- CNC does the transformation - ------------------------------ - if minetest.registered_nodes[product] ~= nil then - inv:add_item("output",product .. " " .. produces) - inputstack:take_item(input_used) - inv:set_stack("input",1,inputstack) - else - minetest.chat_send_player(sender:get_player_name(), "CNC machine does not know how to mill this material. Please remove it."); - end - return; + return end, -- callback function }) ----------- +minetest.register_node("technic:cnc_active", { + description = "CNC Machine", + tiles = {"technic_cnc_top.png", "technic_cnc_bottom.png", "technic_cnc_side.png", + "technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front_active.png"}, + paramtype2 = "facedir", + groups = {cracky=2,not_in_creative_inventory=1}, + legacy_facedir_simple = true, + 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(), "CNC machine cannot be removed because it is not empty"); + return false + end + return true + end, +}) --- Milling Machine Recipe +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 + + 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 + }) + +register_LV_machine ("technic:cnc","RE") +register_LV_machine ("technic:cnc_active","RE") +------------------------- + +-- CNC Machine Recipe ------------------------- minetest.register_craft({ output = 'technic:cnc', diff --git a/technic/cnc_api.lua b/technic/cnc_api.lua index 390a996..2d5dcfe 100644 --- a/technic/cnc_api.lua +++ b/technic/cnc_api.lua @@ -212,7 +212,7 @@ end -- SLOPE EDGE UPSIDE DOWN ------------------------- -function technic_cnc_api.register_slope_upsdown_edge(recipeitem, groups, images, description) +function technic_cnc_api.register_slope_edge_upsdown(recipeitem, groups, images, description) if recipeitem == "default:dirt" then return @@ -223,7 +223,7 @@ local detail = technic_cnc_api.detail_level for i = 0, detail-1 do slopeupdwnboxedge[i+1]={(-1*(i/detail))+0.5-(1/detail), (i/detail)-0.5, (-1*(i/detail))+0.5-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5} end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_upsdown_edge", { +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_edge_upsdown", { description = description, drawtype = "nodebox", tiles = images, @@ -245,13 +245,13 @@ end -- SLOPE INNER EDGE UPSIDE DOWN ------------------------------- -function technic_cnc_api.register_slope_upsdown_inner_edge(recipeitem, groups, images, description) +function technic_cnc_api.register_slope_inner_edge_upsdown(recipeitem, groups, images, description) if recipename == "default:dirt" then return end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_upsdown_inner_edge", { +minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_inner_edge_upsdown", { description = description, drawtype = "nodebox", tiles = images, @@ -548,7 +548,7 @@ for i = 1, detail-1 do sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) spherebox[i]={-sehne, (i/detail)-0.5, -sehne, sehne, (i/detail)+(1/detail)-0.5, sehne} end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_cylinder_sphere", { +minetest.register_node(":" .. recipeitem .. "_technic_cnc_sphere", { description = description, drawtype = "nodebox", tiles = images, @@ -939,8 +939,8 @@ function technic_cnc_api.register_slope_edge_etc(recipeitem, groups, images, des technic_cnc_api.register_slope_upsdown(recipeitem, groups, images, desc_slope_upsdown) technic_cnc_api.register_slope_edge(recipeitem, groups, images, desc_slope_edge) technic_cnc_api.register_slope_inner_edge(recipeitem, groups, images, desc_slope_inner_edge) - technic_cnc_api.register_slope_upsdown_edge(recipeitem, groups, images, desc_slope_upsdwn_edge) - technic_cnc_api.register_slope_upsdown_inner_edge(recipeitem, groups, images, desc_slope_upsdwn_inner_edge) + technic_cnc_api.register_slope_edge_upsdown(recipeitem, groups, images, desc_slope_upsdwn_edge) + technic_cnc_api.register_slope_inner_edge_upsdown(recipeitem, groups, images, desc_slope_upsdwn_inner_edge) technic_cnc_api.register_pyramid(recipeitem, groups, images, desc_pyramid) technic_cnc_api.register_spike(recipeitem, groups, images, desc_spike) technic_cnc_api.register_onecurvededge(recipeitem, groups, images, desc_onecurvededge) From 7f2be244f2f7f2497cba33ba1e2bd5a599f23bfb Mon Sep 17 00:00:00 2001 From: kpoppel Date: Tue, 7 May 2013 22:34:06 +0200 Subject: [PATCH 25/57] Add textures for active mode of CNC. Correct two typing bug in battery_box.lua --- technic/textures/technic_cnc_front_active.png | Bin 0 -> 2216 bytes technic/textures/technic_cnc_top_active.png | Bin 0 -> 2214 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 technic/textures/technic_cnc_front_active.png create mode 100644 technic/textures/technic_cnc_top_active.png diff --git a/technic/textures/technic_cnc_front_active.png b/technic/textures/technic_cnc_front_active.png new file mode 100644 index 0000000000000000000000000000000000000000..f7a3c7f7822a0186e2ac6f7e9adc55a05dfeeccc GIT binary patch literal 2216 zcmV;Z2v_%sP)&C-N(90r3iJj6k#M01(M0d$AMnOR z{s%%LV&jd}MjK*6NsPuQQD}kk5fFw#$7(^QwWsIoefEAoz1ZWNL4zbp;(K@Up0(Dq zpXXWYUE-mK9!hLFYinyf_0&^*Qs>S)?__>{{v+@8+S(dlxcMf6^9Tf|PoL(;ufD|V zXa4d(7r$crr8G^$u3bCv)}l;?vks{x0yuW;I2xcH4iQFSqQZO6sXx8N=~JsDnNShN z)`E|qAv7)dR3DHeEZ9U43WY=F86iO&d(eU{S2?`*SmzPa;9bBJ86qTthyX|cZ3>bH z7dkb90B>uM0vpEcy6$RBuE>gvJvZHmlo}}o-X(OukJ1963_==0n=oa8HaRhNMUrzA z{hSoQwH{BTsoPEh0HXw1p3}BnK!2(SO5t0}j%)Vu&WkT&@{ENmFX!#&UqnfTPlyjZ=#;I3cBPO_X?-iVS<#pP|A(BA! z4Z1YoJW467^#myiDxve7>cSYM4N@5d0sy5mq>!|2LzD_3C9|`$69CbB%A!YW#{k6W zaCOD*rK@@O#ETFjB1VdSNvIvcwIDU#da7zfVG1-F=R7*s*m_KG4c>+hfDsTu35gL2 zqNJ`y69C236xC=*o);ZeA+dY^4V--b1!77h0!n9$E>x&2Lz#khRFOnr>-O!aOcR0t zBEfoG+oFnsBs=Q0G_)}yWTN$nER!guHc3#`NG+*HRTrQnr(S*qfkK3cAGe4CiY$ZR zsXjOdN)yH&-_$503CW?Pz?6o(*CSewHeC_#Jh>J~B@r=TLj)-%ZP=UckrL#hGmQ%o zV=}x*geXbT5p6^&gEC->jC`sfMgb`?I=4o#Wh>3O8X*M^MWzK=mUWV*L}oPAu%##r zu5AfgP5{V|u(m}h)6pU{d-v>NJRDL^PebaA+AB+ZfGN zTU&w;#OTS&0;4rCd9*I5s}bHO@=SwJs9X^mOKV$PYbOATJfls5m=cAS_@HUp7NaEE z7bmB}{Wl<`B%dlbg4zaRsyKEp zK!ZQ_O~SzP<=s83tvU8p!L|iBai63=ojCoSPjhy7hP89&$x4HLf4Gq=giZTE2oWg^ z!{Lx8zxx|TqY>6QM5d8(!az*0ZGIci+|i9#z4SO>*m}#4I#2v8@xj3H%iA={%=5$x zXGz_M;@7`;B7v9ykU}CA)OF4B_pYR>Duj?kFGxmi1kKLQ@&4dFZa->4!27?tA8?%g z?frn}%?ArExv1dwqm~Q9HNLjgXS&xpD1O+>c|qbuN&=h_HTcu-<#bisx|>Adc~%Fpq$3J z7Vjf@W-xh;mtj+7)tuZPMFMOmPX!H+$K$u@$j2Apqs?SZN8 z_n9#V7A^N)t2wY}dHPgFGw5Eqt+zbJXjF0c@1N!9&DV0*v(K^e_B#^~tmoALS|~i0 z;5L}*DfZkgWFNiY)=a(;%m8{9gp_ELVaH=k*~4f}LgLz%yx#>KJa~}Zd-rrvpZWLszOb<4 zKhFP4wqFdu>gp_y&s`uy_l75lR1zfxA$nwjkOV>~gh+VrF_|HHN0JJe5<)3b q2&4oOflmpeyX{LXFE1zlkLMrn-v`#0NHfd;0000j) literal 0 HcmV?d00001 diff --git a/technic/textures/technic_cnc_top_active.png b/technic/textures/technic_cnc_top_active.png new file mode 100644 index 0000000000000000000000000000000000000000..2bc9d81511116b0c4bb0b3ad5a2addb1d918f2de GIT binary patch literal 2214 zcmV;X2wC@uP)ZgE2TGv?kO#$jPDB(rY8-h`}H#3;`LP-F~91gLFZ|>5cL;!Y*4N*7NLwqlSHAz``@eUkzy0>x zgbrE!g4Msot!2BzWFzQO$eUWI@T%6T*xufRmd?hbTH2=IR=ck z)KbYlVw^`1#^^Zj7;W&*KmQ9MM;L>&ODv@!;;?FOZ5X1XbptwXFgM=)=w}$9FO_h} zy!Pl3AHVx9YiT_E#@G4e!;cUd2%B^IWnuq?1MOTf+G$OA>&-U+klJz1L-a)L)Vh+U z{jCP(dBGbPBHQb02T@|qcyD;^(Ifuj2R}lL(vB{`NV& zR0O5>j>x9;yqgdml;>xRb)*;(t+xOS%2F#91ArQbvyNUG55D$QK6vtP7*)Rf)}Qn7 zd++0-2b8{6y!DtEX=8HUWyXv_St{#wMU5dG0x`#p(V{pD ztyioKw5763yIT#k(g`Vm+<4O}U;c})^2?uoK+F?={HI^pzT8<*!Fp(GVOTIC?52sb zG~zBYTE~PyKUbFX0)R^a6CBnx=!1ORb2FU{fMT&IrEeOr#_^x;eSk{m!5feG^d}#p z3S%jZ(lJpPT|pq74y?-=;{!^kk4iE?3b?qLU3;T-A*D>K4L1h;W;`CiIlwr)Y1_=K z!Dq*-uRr3~AAW>7h}N_AhVhPQ9J1?Jm#E7EYH3TwXvDifIXBcaf_(vC&<)h5*W7>Q z4_MC&+V6CMb(Y{g@x~gxR9=1k;byz*E2K26btoPN#M2hR<@%a19SJFsb`j?dLk($4 zXsfi^J|96$p2O+D_0vn%>lwG{eFGqUP|8BTIUsfLiyyy_^$Dy)?O<8Y7!|Bj%2M%D z0u0g%Vg@dFqzFbjqYHUDqGk)5(Uf&wXid=3wvM=QoCSy}W3a@ysrKUjX`}M$3?j(V z$a#lP9v=eUdqxvn_QTi32iAXMM%dT%jKEr-ULoCn(=PX*FsxXRE2sj#OOChjUmTO zsRIM(7~t-VV1GQ&M#tayHpYatJFInB2Fv9c866iRhcBE6(Q>%ICk2Od6T?)}X~HNN zW3k4wfB7X;ZeF5;G6qOzmnU|o1225IX<#TR1=j0pUf2@XFevL>@ZK?QQ1>8zKPVPU8e zQY1|~VhDIM(7G~u!-Pn=yaE}7UBu*wNJVtuy&^Y_*G)x+MV->eV44#4W+mHlzN>NQtsuO&1RJTXvOax^ah}WHJfl^`ScixprBRlJdOmY} z`DLUxYU!A0Df5bYw=E!mwodekRy(FQLUy$EP8q4S7Vq+>?L9@UQZ7O8`}G%yCK!rEu7bquwrbj;YEC!^tWpe_xS!RdIx zQkGi=N~u`g_5y(Qx}y&Keqve9#GNNh8Bs+>!+A@2zF-`rT|m3yb{1nnhJbX!A%E_I zH0|)lV~yawXD!Q%t$YLEQb4RQUu~#jcGS6$_j?W(C)TTLtcAX;tmm0l3e)`~F=g7? zK*9KJ*S8AJWn`|TywP0GE4>vgp1G_TYw#i7ae=jX>xdV}?ZDc}hY3cbl$lW)H7(@h zo?1KBdivU_%a##wij*dZ3h|V&2=R2J-!PD;%n+qXV@jE(15@iQ0IX-Ie%@Y22cvex z8C;k+y)vOgSg$)SIKVTc5RVyT+apvu42yQ5u0ory2!Hg&ZKU&xI)`_L-jxs|YVYKL zl*aCuknZr_^Wfp@EEk9W^Z&pXUwIYpJvcB%QQh{rX#Flyl~<-h2z* oeCzk}Q}VAl^T{Wl{;&7{2dVVSpbqYpQvd(}07*qoM6N<$g1)&UPyhe` literal 0 HcmV?d00001 From fef948c5ac919082fa30d441ec62d6d1d0d2c98b Mon Sep 17 00:00:00 2001 From: kpoppel Date: Tue, 7 May 2013 22:51:03 +0200 Subject: [PATCH 26/57] CNC can now change programs while it is working. --- technic/battery_box.lua | 4 +- technic/cnc.lua | 128 ++++++++++++++++++++++------------------ 2 files changed, 72 insertions(+), 60 deletions(-) diff --git a/technic/battery_box.lua b/technic/battery_box.lua index 0e08d74..9c91821 100644 --- a/technic/battery_box.lua +++ b/technic/battery_box.lua @@ -218,7 +218,7 @@ minetest.register_abm({ end end --- dischargin registered power tools +-- discharging registered power tools if inv:is_empty("dst") == false then srcstack = inv:get_stack("dst", 1) src_item=srcstack:to_table() @@ -297,7 +297,7 @@ table_index=1 local pos1={} i=1 repeat - if PR_nodes[i]==nil then break end -- gettin power from all connected producers + if PR_nodes[i]==nil then break end -- getting power from all connected producers pos1.x=PR_nodes[i].x pos1.y=PR_nodes[i].y pos1.z=PR_nodes[i].z diff --git a/technic/cnc.lua b/technic/cnc.lua index 71b78b0..4976502 100644 --- a/technic/cnc.lua +++ b/technic/cnc.lua @@ -1,5 +1,11 @@ -- Technic CNC v1.0 by kpo -- Based on the NonCubic Blocks MOD v1.4 by yves_de_beck + +-- Idea: +-- Somehw have a tabbed/paged panel if the number of shapes should expand +-- 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, @@ -89,61 +95,9 @@ local cnc_power_formspec= local size = 1; -minetest.register_node("technic:cnc", { - description = "CNC Milling Machine", - tiles = {"technic_cnc_top.png", "technic_cnc_bottom.png", "technic_cnc_side.png", - "technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front.png"}, - drawtype = "nodebox", - paramtype = "light", - paramtype2 = "facedir", - node_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - - }, - }, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - groups = {cracky=2}, - legacy_facedir_simple = true, - technic_power_machine=1, - internal_EU_buffer=0; - internal_EU_buffer_size=5000; - cnc_time = 0; - src_time = 0; -- fixme - - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_string("infotext", "CNC machine") - 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", cnc_formspec..cnc_power_formspec) - meta:set_float("cnc_time", 0) - - local inv = meta:get_inventory() - inv:set_size("src", 1) - inv:set_size("dst", 4) - - meta:set_string("formspec", cnc_formspec) - meta:set_string("infotext", "CNC Milling Machine") - 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(), "CNC machine cannot be removed because it is not empty"); - return false - end - return true - end, - - - on_receive_fields = function(pos, formname, fields, sender) +-- The form handler is declared here because we need it in both the inactive and active modes +-- in order to be able to change programs wile it is running. +local form_handler = function(pos, formname, fields, sender) -- REGISTER MILLING PROGRAMS AND OUTPUTS: ------------------------------------------ -- Program for half/full size @@ -178,22 +132,78 @@ minetest.register_node("technic:cnc", { if onesize_products[k] ~= nil or (twosize_products[k] ~= nil and size==2) then meta:set_string("cnc_product", inputname .. "_technic_cnc_" .. k) + print(inputname .. "_technic_cnc_" .. k) break end if twosize_products[k] ~= nil and size==1 then meta:set_string("cnc_product", inputname .. "_technic_cnc_" .. k .. "_double") + print(inputname .. "_technic_cnc_" .. k .. "_double") break end end return - end, -- callback function + end -- callback function + +-- The actual block inactive state +minetest.register_node("technic:cnc", { + description = "CNC Milling Machine", + tiles = {"technic_cnc_top.png", "technic_cnc_bottom.png", "technic_cnc_side.png", + "technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front.png"}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + + }, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + groups = {cracky=2}, + legacy_facedir_simple = true, + technic_power_machine=1, + internal_EU_buffer=0; + internal_EU_buffer_size=5000; + cnc_time = 0; + src_time = 0; -- fixme + + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_string("infotext", "CNC Machine Inactive") + 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", cnc_formspec..cnc_power_formspec) + meta:set_float("cnc_time", 0) + + 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(), "CNC machine cannot be removed because it is not empty"); + return false + end + return true + end, + + on_receive_fields = form_handler, }) +-- Active state block minetest.register_node("technic:cnc_active", { description = "CNC Machine", - tiles = {"technic_cnc_top.png", "technic_cnc_bottom.png", "technic_cnc_side.png", - "technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front_active.png"}, + tiles = {"technic_cnc_top_active.png", "technic_cnc_bottom.png", "technic_cnc_side.png", + "technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front_active.png"}, paramtype2 = "facedir", groups = {cracky=2,not_in_creative_inventory=1}, legacy_facedir_simple = true, @@ -206,8 +216,10 @@ minetest.register_node("technic:cnc_active", { end return true end, + on_receive_fields = form_handler, }) +-- Action code performing the transformation minetest.register_abm( { nodenames = {"technic:cnc","technic:cnc_active"}, From 5940f5bda421add111a881b4df82b793121738a9 Mon Sep 17 00:00:00 2001 From: kpoppel Date: Wed, 8 May 2013 00:06:54 +0200 Subject: [PATCH 27/57] Slope box fixes. From Bas080. --- technic/cnc_api.lua | 109 +++++++------------------------------------- 1 file changed, 16 insertions(+), 93 deletions(-) diff --git a/technic/cnc_api.lua b/technic/cnc_api.lua index 2d5dcfe..aecfadb 100644 --- a/technic/cnc_api.lua +++ b/technic/cnc_api.lua @@ -6,10 +6,6 @@ technic_cnc_api = {} ---------------------------------------- technic_cnc_api.detail_level = 16 -- 16; 1-32 --- HERE YOU CAN DE/ACTIVATE BACKGROUND FOR CNC MENU: --------------------------------------------------------- -technic_cnc_api.allow_menu_background = false - -- REGISTER NONCUBIC FORMS, CREATE MODELS AND RECIPES: ------------------------------------------------------ @@ -146,6 +142,12 @@ end -- SLOPE INNER EDGE ------------------- function technic_cnc_api.register_slope_inner_edge(recipeitem, groups, images, description) + local slopeboxedge = {} + local detail = technic_cnc_api.detail_level + for i = 0, detail-1 do + slopeboxedge[i+1]={(i/detail)-0.5, -0.5, -0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} + slopeboxedge[i+detail+1]={-0.5, -0.5, (i/detail)-0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} + end minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_inner_edge", { description = description, @@ -159,51 +161,8 @@ minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_inner_edge", { fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, }, node_box = { - type = "fixed", - fixed = { - -- PART 1 - {-0.5, -0.5, -0.5, 0.5, -0.45, 0.5}, - {-0.45, -0.5, -0.5, 0.5, -0.4, 0.5}, - {-0.4, -0.5, -0.5, 0.5, -0.35, 0.5}, - {-0.35, -0.5, -0.5, 0.5, -0.3, 0.5}, - {-0.3, -0.5, -0.5, 0.5, -0.25, 0.5}, - {-0.25, -0.5, -0.5, 0.5, -0.2, 0.5}, - {-0.2, -0.5, -0.5, 0.5, -0.15, 0.5}, - {-0.15, -0.5, -0.5, 0.5, -0.1, 0.5}, - {-0.1, -0.5, -0.5, 0.5, -0.05, 0.5}, - {-0.05, -0.5, -0.5, 0.5, 0, 0.5}, - {0, -0.5, -0.5, 0.5, 0.05, 0.5}, - {0.05, -0.5, -0.5, 0.5, 0.1, 0.5}, - {0.1, -0.5, -0.5, 0.5, 0.15, 0.5}, - {0.15, -0.5, -0.5, 0.5, 0.2, 0.5}, - {0.2, -0.5, -0.5, 0.5, 0.25, 0.5}, - {0.25, -0.5, -0.5, 0.5, 0.3, 0.5}, - {0.3, -0.5, -0.5, 0.5, 0.35, 0.5}, - {0.35, -0.5, -0.5, 0.5, 0.4, 0.5}, - {0.4, -0.5, -0.5, 0.5, 0.45, 0.5}, - {0.45, -0.5, -0.5, 0.5, 0.5, 0.5}, - -- PART 2 - {-0.5, -0.5, -0.45, 0.5, -0.45, 0.5}, - {-0.5, -0.5, -0.4, 0.5, -0.4, 0.5}, - {-0.5, -0.5, -0.35, 0.5, -0.35, 0.5}, - {-0.5, -0.5, -0.3, 0.5, -0.3, 0.5}, - {-0.5, -0.5, -0.25, 0.5, -0.25, 0.5}, - {-0.5, -0.5, -0.2, 0.5, -0.2, 0.5}, - {-0.5, -0.5, -0.15, 0.5, -0.15, 0.5}, - {-0.5, -0.5, -0.1, 0.5, -0.1, 0.5}, - {-0.5, -0.5, -0.05, 0.5, -0.05, 0.5}, - {-0.5, -0.5, 0, 0.5, 0, 0.5}, - {-0.5, -0.5, 0.05, 0.5, 0.05, 0.5}, - {-0.5, -0.5, 0.1, 0.5, 0.1, 0.5}, - {-0.5, -0.5, 0.15, 0.5, 0.15, 0.5}, - {-0.5, -0.5, 0.2, 0.5, 0.2, 0.5}, - {-0.5, -0.5, .25, 0.5, 0.25, 0.5}, - {-0.5, -0.5, 0.3, 0.5, 0.3, 0.5}, - {-0.5, -0.5, 0.35, 0.5, 0.35, 0.5}, - {-0.5, -0.5, 0.4, 0.5, 0.4, 0.5}, - {-0.5, -0.5, 0.45, 0.5, 0.45, 0.5}, - {-0.5, -0.5, 0.5, 0.5, 0.5, 0.5}, - }, + type = "fixed", + fixed = slopeboxedge, }, groups = groups, }) @@ -251,6 +210,13 @@ if recipename == "default:dirt" then return end +local slopeboxedge = {} +local detail = technic_cnc_api.detail_level +for i = 0, detail-1 do + slopeboxedge[i+1]={0.5-(i/detail)-(1/detail), (i/detail)-0.5, -0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} + slopeboxedge[i+detail+1]={-0.5, (i/detail)-0.5, 0.5-(i/detail)-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5} +end + minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_inner_edge_upsdown", { description = description, drawtype = "nodebox", @@ -264,50 +230,7 @@ minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_inner_edge_upsdo }, node_box = { type = "fixed", - fixed = { - {0.45, -0.5, -0.5, 0.5, -0.45, 0.5}, - {0.4, -0.45, -0.5, 0.5, -0.4, 0.5}, - {0.35, -0.4, -0.5, 0.5, -0.35, 0.5}, - {0.3, -0.35, -0.5, 0.5, -0.3, 0.5}, - {0.25, -0.3, -0.5, 0.5, -0.25, 0.5}, - {0.2, -0.25, -0.5, 0.5, -0.2, 0.5}, - {0.15, -0.2, -0.5, 0.5, -0.15, 0.5}, - {0.1, -0.15, -0.5, 0.5, -0.1, 0.5}, - {0.05, -0.1, -0.5, 0.5, -0.05, 0.5}, - {0, -0.05, -0.5, 0.5, 0, 0.5}, - {-0.05, 0, -0.5, 0.5, 0.05, 0.5}, - {-0.1, 0.05, -0.5, 0.5, 0.1, 0.5}, - {-0.15, 0.1, -0.5, 0.5, 0.15, 0.5}, - {-0.2, 0.15, -0.5, 0.5, 0.2, 0.5}, - {-0.25, 0.2, -0.5, 0.5, 0.25, 0.5}, - {-0.3, 0.25, -0.5, 0.5, 0.3, 0.5}, - {-0.35, 0.3, -0.5, 0.5, 0.35, 0.5}, - {-0.4, 0.35, -0.5, 0.5, 0.4, 0.5}, - {-0.45, 0.4, -0.5, 0.5, 0.45, 0.5}, - {-0.5, 0.45, -0.5, 0.5, 0.5, 0.5}, - - {-0.5, -0.5, 0.45, 0.5, -0.45, 0.5}, - {-0.5, -0.45, 0.4, 0.5, -0.4, 0.5}, - {-0.5, -0.4, 0.35, 0.5, -0.35, 0.5}, - {-0.5, -0.35, 0.3, 0.5, -0.3, 0.5}, - {-0.5, -0.3, 0.25, 0.5, -0.25, 0.5}, - {-0.5, -0.25, 0.2, 0.5, -0.2, 0.5}, - {-0.5, -0.2, 0.15, 0.5, -0.15, 0.5}, - {-0.5, -0.15, 0.1, 0.5, -0.1, 0.5}, - {-0.5, -0.1, 0.05, 0.5, -0.05, 0.5}, - {-0.5, -0.05, 0, 0.5, 0, 0.5}, - {-0.5, 0, -0.05, 0.5, 0.05, 0.5}, - {-0.5, 0.05, -0.1, 0.5, 0.1, 0.5}, - {-0.5, 0.1, -0.15, 0.5, 0.15, 0.5}, - {-0.5, 0.15, -0.2, 0.5, 0.2, 0.5}, - {-0.5, 0.2, -0.25, 0.5, 0.25, 0.5}, - {-0.5, 0.25, -0.3, 0.5, 0.3, 0.5}, - {-0.5, 0.3, -0.35, 0.5, 0.35, 0.5}, - {-0.5, 0.35, -0.4, 0.5, 0.4, 0.5}, - {-0.5, 0.4, -0.45, 0.5, 0.45, 0.5}, - {-0.5, 0.45, -0.5, 0.5, 0.5, 0.5}, - - }, + fixed = slopeboxedge, }, groups = groups, }) From 2d68498dc10bc74a35a5cc0ff4e81b6640807511 Mon Sep 17 00:00:00 2001 From: kpoppel Date: Wed, 8 May 2013 01:42:22 +0200 Subject: [PATCH 28/57] Massive change to the way CNC programs are registered. Now the API is open for adding new nodes and inhibiting some nodes for some materials. No more recipes outside of the CNC machine. Code length also greatly reduced. --- technic/cnc_api.lua | 1155 +++++++++++------------------------------ technic/cnc_nodes.lua | 340 +----------- 2 files changed, 345 insertions(+), 1150 deletions(-) diff --git a/technic/cnc_api.lua b/technic/cnc_api.lua index aecfadb..2d5e305 100644 --- a/technic/cnc_api.lua +++ b/technic/cnc_api.lua @@ -8,850 +8,329 @@ technic_cnc_api.detail_level = 16 -- 16; 1-32 -- REGISTER NONCUBIC FORMS, CREATE MODELS AND RECIPES: ------------------------------------------------------ - --- SLOPE --------- -function technic_cnc_api.register_slope(recipeitem, groups, images, description) - -local slopebox = {} -local detail = technic_cnc_api.detail_level -for i = 0, detail-1 do - slopebox[i+1]={-0.5, (i/detail)-0.5, (i/detail)-0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} -end - -minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - node_box = { - type = "fixed", - fixed = slopebox, - }, - groups = groups, - }) -end - - --- SLOPE Lying ----------------- -function technic_cnc_api.register_slope_lying(recipeitem, groups, images, description) - -local slopeboxlying = {} -local detail = technic_cnc_api.detail_level -for i = 0, detail-1 do - slopeboxlying[i+1]={(i/detail)-0.5, -0.5, (i/detail)-0.5, (i/detail)-0.5+(1/detail), 0.5 , 0.5} -end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_lying", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - node_box = { - type = "fixed", - fixed = slopeboxlying, - }, - groups = groups, - }) - minetest.register_craft({ - output = recipeitem .. "_technic_cnc_slope_lying 1", - recipe = { - {"", "", ""}, - {"", recipeitem .. "_technic_cnc_slope", ""}, - {"", "", ""}, - }, - }) - -end - - --- SLOPE UPSIDE DOWN --------------------- -function technic_cnc_api.register_slope_upsdown(recipeitem, groups, images, description) - -if subname == "dirt" then -return -end - -local slopeupdwnbox = {} -local detail = technic_cnc_api.detail_level -for i = 0, detail-1 do - slopeupdwnbox[i+1]={-0.5, (i/detail)-0.5, (-1*(i/detail))+0.5-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5} -end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_upsdown", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - node_box = { - type = "fixed", - fixed = slopeupdwnbox, - }, - groups = groups, - }) -end - - --- SLOPE EDGE -------------- -function technic_cnc_api.register_slope_edge(recipeitem, groups, images, description) - -local slopeboxedge = {} -local detail = technic_cnc_api.detail_level -for i = 0, detail-1 do - slopeboxedge[i+1]={(i/detail)-0.5, -0.5, (i/detail)-0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} -end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_edge", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - node_box = { - type = "fixed", - fixed = slopeboxedge, - }, - groups = groups, - }) -end - - --- SLOPE INNER EDGE -------------------- -function technic_cnc_api.register_slope_inner_edge(recipeitem, groups, images, description) - local slopeboxedge = {} - local detail = technic_cnc_api.detail_level - for i = 0, detail-1 do - slopeboxedge[i+1]={(i/detail)-0.5, -0.5, -0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} - slopeboxedge[i+detail+1]={-0.5, -0.5, (i/detail)-0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} +local cnc_sphere = + function() + local nodebox = {} + local detail = technic_cnc_api.detail_level + local sehne + for i = 1, detail-1 do + sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) + nodebox[i]={-sehne, (i/detail)-0.5, -sehne, sehne, (i/detail)+(1/detail)-0.5, sehne} + end + return nodebox end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_inner_edge", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - node_box = { - type = "fixed", - fixed = slopeboxedge, - }, - groups = groups, - }) +local cnc_cylinder_horizontal = + function() + local nodebox = {} + local detail = technic_cnc_api.detail_level + local sehne + for i = 1, detail-1 do + sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) + nodebox[i]={-0.5, (i/detail)-0.5, -sehne, 0.5, (i/detail)+(1/detail)-0.5, sehne} + end + return nodebox + end + +local cnc_cylinder = + function() + local nodebox = {} + local detail = technic_cnc_api.detail_level + local sehne + for i = 1, detail-1 do + sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) + nodebox[i]={(i/detail)-0.5, -0.5, -sehne, (i/detail)+(1/detail)-0.5, 0.5, sehne} + end + return nodebox + end + +local cnc_twocurvededge = + function() + local nodebox = {} + local detail = technic_cnc_api.detail_level*2 + local sehne + for i = (detail/2)-1, detail-1 do + sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) + nodebox[i]={-sehne, -0.5, -sehne, 0.5, (i/detail)+(1/detail)-0.5, 0.5} + end + return nodebox + end + +local cnc_onecurvededge = + function() + local nodebox = {} + local detail = technic_cnc_api.detail_level*2 + local sehne + for i = (detail/2)-1, detail-1 do + sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) + nodebox[i]={-0.5, -0.5, -sehne, 0.5, (i/detail)+(1/detail)-0.5, 0.5} + end + return nodebox + end + +local cnc_spike = + function() + local nodebox = {} + local detail = technic_cnc_api.detail_level + for i = 0, detail-1 do + nodebox[i+1]={(i/detail/2)-0.5, (i/detail/2)-0.5, (i/detail/2)-0.5, 0.5-(i/detail/2), (i/detail)-0.5+(1/detail), 0.5-(i/detail/2)} +end + return nodebox + end + +local cnc_pyramid = + function() + local nodebox = {} + local detail = technic_cnc_api.detail_level/2 + for i = 0, detail-1 do + nodebox[i+1]={(i/detail/2)-0.5, (i/detail/2)-0.5, (i/detail/2)-0.5, 0.5-(i/detail/2), (i/detail/2)-0.5+(1/detail), 0.5-(i/detail/2)} + end + return nodebox + end + +local cnc_slope_inner_edge_upsdown = + function() + local nodebox = {} + local detail = technic_cnc_api.detail_level + for i = 0, detail-1 do + nodebox[i+1]={0.5-(i/detail)-(1/detail), (i/detail)-0.5, -0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} + nodebox[i+detail+1]={-0.5, (i/detail)-0.5, 0.5-(i/detail)-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5} + end + return nodebox + end + +local cnc_slope_edge_upsdown = + function() + local nodebox = {} + local detail = technic_cnc_api.detail_level + for i = 0, detail-1 do + nodebox[i+1]={(-1*(i/detail))+0.5-(1/detail), (i/detail)-0.5, (-1*(i/detail))+0.5-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5} + end + return nodebox + end + +local cnc_slope_inner_edge = + function() + local nodebox = {} + local detail = technic_cnc_api.detail_level + for i = 0, detail-1 do + nodebox[i+1]={(i/detail)-0.5, -0.5, -0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} + nodebox[i+detail+1]={-0.5, -0.5, (i/detail)-0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} + end + return nodebox + end + +local cnc_slope_edge = + function() + local nodebox = {} + local detail = technic_cnc_api.detail_level + for i = 0, detail-1 do + nodebox[i+1]={(i/detail)-0.5, -0.5, (i/detail)-0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} + end + return nodebox + end + +local cnc_slope_upsdown = + function() + local nodebox = {} + local detail = technic_cnc_api.detail_level + for i = 0, detail-1 do + nodebox[i+1]={-0.5, (i/detail)-0.5, (-1*(i/detail))+0.5-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5} + end + return nodebox + end + +local cnc_slope_lying = + function() + local nodebox = {} + local detail = technic_cnc_api.detail_level + for i = 0, detail-1 do + nodebox[i+1]={(i/detail)-0.5, -0.5, (i/detail)-0.5, (i/detail)-0.5+(1/detail), 0.5 , 0.5} + end + return nodebox + end + +local cnc_slope = + function() + local nodebox = {} + local detail = technic_cnc_api.detail_level + for i = 0, detail-1 do + nodebox[i+1]={-0.5, (i/detail)-0.5, (i/detail)-0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} + end + return nodebox + end + +-- Define slope boxes for the various nodes +------------------------------------------- +technic_cnc_api.cnc_programs = { + {suffix = "technic_cnc_stick", + nodebox = {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15}, + desc = "Stick"}, + + {suffix = "technic_cnc_element_end_double", + nodebox = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.5}, + desc = "Element End Double"}, + + {suffix = "technic_cnc_element_cross_double", + nodebox = { + {0.3, -0.5, -0.3, 0.5, 0.5, 0.3}, + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5}, + {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}}, + desc = "Element Cross Double"}, + + {suffix = "technic_cnc_element_t_double", + nodebox = { + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, + {0.3, -0.5, -0.3, 0.5, 0.5, 0.3}}, + desc = "Element T Double"}, + + {suffix = "technic_cnc_element_edge_double", + nodebox = { + {-0.3, -0.5, -0.5, 0.3, 0.5, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}}, + desc = "Element Edge Double"}, + + {suffix = "technic_cnc_element_straight_double", + nodebox = {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5}, + desc = "Element Straight Double"}, + + {suffix = "technic_cnc_element_end", + nodebox = {-0.3, -0.5, -0.3, 0.3, 0, 0.5}, + desc = "Element End"}, + + {suffix = "technic_cnc_element_cross", + nodebox = { + {0.3, -0.5, -0.3, 0.5, 0, 0.3}, + {-0.3, -0.5, -0.5, 0.3, 0, 0.5}, + {-0.5, -0.5, -0.3, -0.3, 0, 0.3}}, + desc = "Element Cross"}, + + {suffix = "technic_cnc_element_t", + nodebox = { + {-0.3, -0.5, -0.5, 0.3, 0, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, + {0.3, -0.5, -0.3, 0.5, 0, 0.3}}, + desc = "Element T"}, + + {suffix = "technic_cnc_element_edge", + nodebox = { + {-0.3, -0.5, -0.5, 0.3, 0, 0.3}, + {-0.5, -0.5, -0.3, -0.3, 0, 0.3}}, + desc = "Element Edge"}, + + {suffix = "technic_cnc_element_straight", + nodebox = {-0.3, -0.5, -0.5, 0.3, 0, 0.5}, + desc = "Element Straight"}, + + {suffix = "technic_cnc_sphere", + nodebox = cnc_sphere(), + desc = "Sphere"}, + + {suffix = "technic_cnc_cylinder_horizontal", + nodebox = cnc_cylinder_horizontal(), + desc = "Cylinder Horizontal"}, + + {suffix = "technic_cnc_cylinder", + nodebox = cnc_cylinder(), + desc = ""}, + + {suffix = "technic_cnc_twocurvededge", + nodebox = cnc_twocurvededge(), + desc = "One Curved Edge Block"}, + + {suffix = "technic_cnc_onecurvededge", + nodebox = cnc_onecurvededge(), + desc = "Two Curved Edge Block"}, + + {suffix = "technic_cnc_spike", + nodebox = cnc_spike(), + desc = "Spike"}, + + {suffix = "technic_cnc_pyramid", + nodebox = cnc_pyramid(), + desc = "Pyramid"}, + + {suffix = "technic_cnc_slope_inner_edge_upsdown", + nodebox = cnc_slope_inner_edge_upsdown(), + desc = "Slope Upside Down Inner Edge"}, + + {suffix = "technic_cnc_slope_edge_upsdown", + nodebox = cnc_slope_edge_upsdown(), + desc = "Slope Upside Down Edge"}, + + {suffix = "technic_cnc_slope_inner_edge", + nodebox = cnc_slope_inner_edge(), + desc = "Slope Inner Edge"}, + + {suffix = "technic_cnc_slope_edge", + nodebox = cnc_slope_edge(), + desc = "Slope Edge"}, + + {suffix = "technic_cnc_slope_upsdown", + nodebox = cnc_slope_upsdown(), + desc = "Slope Upside Down"}, + + {suffix = "technic_cnc_slope_lying", + nodebox = cnc_slope_lying(), + desc = "Slope Lying"}, + + {suffix = "technic_cnc_slope", + nodebox = cnc_slope(), + desc = "Slope"}, +-- {suffix = "", +-- nodebox =}, +} + +-- Allow disabling certain programs for some node. Default is allowing all types for all nodes +technic_cnc_api.cnc_programs_disable = { + -- ["default:brick"] = {"technic_cnc_stick"}, -- Example: Disallow the stick for brick + -- ... + ["default:dirt"] = {"technic_cnc_sphere", "technic_cnc_slope_upsdown", "technic_cnc_edge", + "technic_cnc_inner_edge", "technic_cnc_slope_edge_upsdown", "technic_cnc_slope_inner_edge_upsdown", + "technic_cnc_stick", "technic_cnc_cylinder_horizontal"} +} + +-- Generic function for registering all the different node types +function technic_cnc_api.register_cnc_program(recipeitem, suffix, nodebox, groups, images, description) + minetest.register_node(":" .. recipeitem .. "_" .. suffix, { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + selection_box = { + type = "fixed", + fixed = nodebox + }, + node_box = { + type = "fixed", + fixed = nodebox + }, + groups = groups, + }) end - --- SLOPE EDGE UPSIDE DOWN -------------------------- -function technic_cnc_api.register_slope_edge_upsdown(recipeitem, groups, images, description) - -if recipeitem == "default:dirt" then - return +-- function to iterate over all the programs the CNC machine knows +function technic_cnc_api.register_all(recipeitem, groups, images, description) + for _, data in ipairs(technic_cnc_api.cnc_programs) do + -- Disable node creation for disabled node types for some material + local do_register = true + if technic_cnc_api.cnc_programs_disable[recipeitem] ~= nil then + for __, disable in ipairs(technic_cnc_api.cnc_programs_disable[recipeitem]) do + if disable == data.suffix then + do_register = false + end + end + end + -- Create the node if it passes the test + if do_register then + technic_cnc_api.register_cnc_program(recipeitem, data.suffix, data.nodebox, groups, images, description.." "..data.desc) + end + end end -local slopeupdwnboxedge = {} -local detail = technic_cnc_api.detail_level -for i = 0, detail-1 do - slopeupdwnboxedge[i+1]={(-1*(i/detail))+0.5-(1/detail), (i/detail)-0.5, (-1*(i/detail))+0.5-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5} -end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_edge_upsdown", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - node_box = { - type = "fixed", - fixed = slopeupdwnboxedge, - }, - groups = groups, - }) -end - - --- SLOPE INNER EDGE UPSIDE DOWN -------------------------------- -function technic_cnc_api.register_slope_inner_edge_upsdown(recipeitem, groups, images, description) - -if recipename == "default:dirt" then -return -end - -local slopeboxedge = {} -local detail = technic_cnc_api.detail_level -for i = 0, detail-1 do - slopeboxedge[i+1]={0.5-(i/detail)-(1/detail), (i/detail)-0.5, -0.5, 0.5, (i/detail)-0.5+(1/detail), 0.5} - slopeboxedge[i+detail+1]={-0.5, (i/detail)-0.5, 0.5-(i/detail)-(1/detail), 0.5, (i/detail)-0.5+(1/detail), 0.5} -end - -minetest.register_node(":" .. recipeitem .. "_technic_cnc_slope_inner_edge_upsdown", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - node_box = { - type = "fixed", - fixed = slopeboxedge, - }, - groups = groups, - }) -end - - --- PYRAMID ----------- -function technic_cnc_api.register_pyramid(recipeitem, groups, images, description) - -local pyrabox = {} -local detail = technic_cnc_api.detail_level/2 -for i = 0, detail-1 do - pyrabox[i+1]={(i/detail/2)-0.5, (i/detail/2)-0.5, (i/detail/2)-0.5, 0.5-(i/detail/2), (i/detail/2)-0.5+(1/detail), 0.5-(i/detail/2)} -end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_pyramid", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, - }, - node_box = { - type = "fixed", - fixed = pyrabox, - }, - groups = groups, - }) -end - - --- SPIKE --------- -function technic_cnc_api.register_spike(recipeitem, groups, images, description) - -if recipename == "default:dirt" then - return -end - -local spikebox = {} -local detail = technic_cnc_api.detail_level -for i = 0, detail-1 do - spikebox[i+1]={(i/detail/2)-0.5, (i/detail/2)-0.5, (i/detail/2)-0.5, 0.5-(i/detail/2), (i/detail)-0.5+(1/detail), 0.5-(i/detail/2)} -end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_spike", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - node_box = { - type = "fixed", - fixed = spikebox, - }, - groups = groups, - }) -end - - --- Block one curved edge ------------------------- -function technic_cnc_api.register_onecurvededge(recipeitem, groups, images, description) - -local quartercyclebox = {} -local detail = technic_cnc_api.detail_level*2 -local sehne -for i = (detail/2)-1, detail-1 do - sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) - quartercyclebox[i]={-0.5, -0.5, -sehne, 0.5, (i/detail)+(1/detail)-0.5, 0.5} -end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_onecurvededge", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - node_box = { - type = "fixed", - fixed = quartercyclebox, - }, - groups = groups, - }) -end - - --- Block two curved edges -------------------------- -function technic_cnc_api.register_twocurvededge(recipeitem, groups, images, description) - -local quartercyclebox2 = {} -local detail = technic_cnc_api.detail_level*2 -local sehne -for i = (detail/2)-1, detail-1 do - sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) - quartercyclebox2[i]={-sehne, -0.5, -sehne, 0.5, (i/detail)+(1/detail)-0.5, 0.5} -end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_twocurvededge", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - node_box = { - type = "fixed", - fixed = quartercyclebox2, - }, - groups = groups, - }) - minetest.register_craft({ - output = recipeitem .. "_technic_cnc_twocurvededge 3", - recipe = { - {"", "", ""}, - {recipeitem .. "_technic_cnc_onecurvededge", "", ""}, - {recipeitem .. "_technic_cnc_onecurvededge", recipeitem .. "_technic_cnc_onecurvededge", ""}, - }, - }) - -end - --- Cylinder ------------ -function technic_cnc_api.register_cylinder(recipeitem, groups, images, description) - -if recipename == "default:dirt" then -return -end - -local cylbox = {} -local detail = technic_cnc_api.detail_level -local sehne -for i = 1, detail-1 do - sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) - cylbox[i]={(i/detail)-0.5, -0.5, -sehne, (i/detail)+(1/detail)-0.5, 0.5, sehne} -end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_cylinder", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - node_box = { - type = "fixed", - fixed = cylbox, - }, - groups = groups, - }) - minetest.register_craft({ - output = recipeitem .. "_technic_cnc_cylinder 1", - recipe = { - {"", "", ""}, - {"", recipeitem .. "_technic_cnc_cylinder_horizontal", ""}, - {"", "", ""}, - }, - }) - -end - - --- Cylinder Horizontal ----------------------- -function technic_cnc_api.register_cylinder_horizontal(recipeitem, groups, images, description) - -if recipename == "default:dirt" then - return -end - -local cylbox_horizontal = {} -local detail = technic_cnc_api.detail_level -local sehne -for i = 1, detail-1 do - sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) - cylbox_horizontal[i]={-0.5, (i/detail)-0.5, -sehne, 0.5, (i/detail)+(1/detail)-0.5, sehne} -end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_cylinder_horizontal", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - node_box = { - type = "fixed", - fixed = cylbox_horizontal, - }, - groups = groups, - }) - minetest.register_craft({ - output = recipeitem .. "_technic_cnc_cylinder_horizontal 1", - recipe = { - {"", "", ""}, - {"", recipeitem .. "_technic_cnc_cylinder", ""}, - {"", "", ""}, - }, - }) -end - - --- Sphere ---------- -function technic_cnc_api.register_sphere(recipeitem, groups, images, description) - -if recipename == "default:dirt" then - return -end - -local spherebox = {} -local detail = technic_cnc_api.detail_level -local sehne -for i = 1, detail-1 do - sehne = math.sqrt(0.25 - (((i/detail)-0.5)^2)) - spherebox[i]={-sehne, (i/detail)-0.5, -sehne, sehne, (i/detail)+(1/detail)-0.5, sehne} -end -minetest.register_node(":" .. recipeitem .. "_technic_cnc_sphere", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - node_box = { - type = "fixed", - fixed = spherebox, - }, - groups = groups, - }) -end - - --- Element straight -------------------- -function technic_cnc_api.register_element_straight(recipeitem, groups, images, description) - -minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_straight", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.3, -0.5, -0.5, 0.3, 0, 0.5}, - }, - node_box = { - type = "fixed", - fixed = { - {-0.3, -0.5, -0.5, 0.3, 0, 0.5}, - }, - }, - groups = groups, - }) -end - - --- Element Edge ---------------- -function technic_cnc_api.register_element_edge(recipeitem, groups, images, description) - -minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_edge", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = { - {-0.3, -0.5, -0.5, 0.3, 0, 0.3}, - {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, - }, - }, - node_box = { - type = "fixed", - fixed = { - {-0.3, -0.5, -0.5, 0.3, 0, 0.3}, - {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, - }, - }, - groups = groups, - }) -end - - --- Element T ------------- -function technic_cnc_api.register_element_t(recipeitem, groups, images, description) - -minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_t", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = { - {-0.3, -0.5, -0.5, 0.3, 0, 0.3}, - {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, - {0.3, -0.5, -0.3, 0.5, 0, 0.3}, - }, - }, - node_box = { - type = "fixed", - fixed = { - {-0.3, -0.5, -0.5, 0.3, 0, 0.3}, - {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, - {0.3, -0.5, -0.3, 0.5, 0, 0.3}, - }, - }, - groups = groups, - }) -end - - --- Element Cross ----------------- -function technic_cnc_api.register_element_cross(recipeitem, groups, images, description) - -minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_cross", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = { - {0.3, -0.5, -0.3, 0.5, 0, 0.3}, - {-0.3, -0.5, -0.5, 0.3, 0, 0.5}, - {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, - }, - }, - node_box = { - type = "fixed", - fixed = { - {0.3, -0.5, -0.3, 0.5, 0, 0.3}, - {-0.3, -0.5, -0.5, 0.3, 0, 0.5}, - {-0.5, -0.5, -0.3, -0.3, 0, 0.3}, - }, - }, - groups = groups, - }) -end - - --- Element End --------------- -function technic_cnc_api.register_element_end(recipeitem, groups, images, description) - -minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_end", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.3, -0.5, -0.3, 0.3, 0, 0.5}, - }, - node_box = { - type = "fixed", - fixed = {-0.3, -0.5, -0.3, 0.3, 0, 0.5}, - }, - groups = groups, - }) -end - - --- Element straight DOUBLE --------------------------- -function technic_cnc_api.register_element_straight_double(recipeitem, groups, images, description) - -minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_straight_double", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5}, - }, - node_box = { - type = "fixed", - fixed = { - {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5}, - }, - }, - groups = groups, - }) - minetest.register_craft({ - output = recipeitem .. "_technic_cnc_element_straight_double 1", - recipe = { - {"", "", ""}, - {"", recipeitem .. "_technic_cnc_element_straight", ""}, - {"", recipeitem .. "_technic_cnc_element_straight", ""}, - }, - }) -end - - --- Element Edge DOUBLE ----------------------- -function technic_cnc_api.register_element_edge_double(recipeitem, groups, images, description) - -minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_edge_double", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = { - {-0.3, -0.5, -0.5, 0.3, 0.5, 0.3}, - {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, - }, - }, - node_box = { - type = "fixed", - fixed = { - {-0.3, -0.5, -0.5, 0.3, 0.5, 0.3}, - {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, - }, - }, - groups = groups, - }) - minetest.register_craft({ - output = recipeitem .. "_technic_cnc_element_edge_double 1", - recipe = { - {"", "", ""}, - {"", recipeitem .. "_technic_cnc_element_edge", ""}, - {"", recipeitem .. "_technic_cnc_element_edge", ""}, - }, - }) -end - - --- Element T DOUBLE -------------------- -function technic_cnc_api.register_element_t_double(recipeitem, groups, images, description) - -minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_t_double", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = { - {-0.3, -0.5, -0.5, 0.3, 0.5, 0.3}, - {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, - {0.3, -0.5, -0.3, 0.5, 0.5, 0.3}, - }, - }, - node_box = { - type = "fixed", - fixed = { - {-0.3, -0.5, -0.5, 0.3, 0.5, 0.3}, - {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, - {0.3, -0.5, -0.3, 0.5, 0.5, 0.3}, - }, - }, - groups = groups, - }) - minetest.register_craft({ - output = recipeitem .. "_technic_cnc_element_t_double 1", - recipe = { - {"", "", ""}, - {"", recipeitem .. "_technic_cnc_element_t", ""}, - {"", recipeitem .. "_technic_cnc_element_t", ""}, - }, - }) -end - - --- Element Cross Double ------------------------ -function technic_cnc_api.register_element_cross_double(recipeitem, groups, images, description) - -minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_cross_double", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = { - {0.3, -0.5, -0.3, 0.5, 0.5, 0.3}, - {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5}, - {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, - }, - }, - node_box = { - type = "fixed", - fixed = { - {0.3, -0.5, -0.3, 0.5, 0.5, 0.3}, - {-0.3, -0.5, -0.5, 0.3, 0.5, 0.5}, - {-0.5, -0.5, -0.3, -0.3, 0.5, 0.3}, - }, - }, - groups = groups, - }) - minetest.register_craft({ - output = recipeitem .. "_technic_cnc_element_cross_double 1", - recipe = { - {"", "", ""}, - {"", recipeitem .. "_technic_cnc_element_cross", ""}, - {"", recipeitem .. "_technic_cnc_element_cross", ""}, - }, - }) - -end - - --- Element End Double ---------------------- -function technic_cnc_api.register_element_end_double(recipeitem, groups, images, description) - -minetest.register_node(":" .. recipeitem .. "_technic_cnc_element_end_double", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.5}, - }, - node_box = { - type = "fixed", - fixed = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.5}, - }, - groups = groups, - }) - minetest.register_craft({ - output = recipeitem .. "_technic_cnc_element_end_double 1", - recipe = { - {"", "", ""}, - {"", recipeitem .. "_technic_cnc_element_end", ""}, - {"", recipeitem .. "_technic_cnc_element_end", ""}, - }, - }) -end - - --- STICK --------- -function technic_cnc_api.register_stick(recipeitem, groups, images, description) - -minetest.register_node(":" .. recipeitem .. "_technic_cnc_stick", { - description = description, - drawtype = "nodebox", - tiles = images, - paramtype = "light", - paramtype2 = "facedir", - walkable = true, - selection_box = { - type = "fixed", - fixed = {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15}, - }, - node_box = { - type = "fixed", - fixed = {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15}, - }, - groups = groups, - }) - minetest.register_craft({ - output = recipeitem .. "_technic_cnc_stick 8", - recipe = { - {'default:stick', "", ""}, - {"", "", ""}, - {recipeitem, "", ""}, - }, - }) -end - - -- REGISTER NEW TECHNIC_CNC_API's PART 2: technic_cnc_api.register_element_end(subname, recipeitem, groups, images, desc_element_xyz) ----------------------------------------------------------------------------------------------------------------------- diff --git a/technic/cnc_nodes.lua b/technic/cnc_nodes.lua index 2f375a5..df82385 100644 --- a/technic/cnc_nodes.lua +++ b/technic/cnc_nodes.lua @@ -1,354 +1,70 @@ -- REGISTER MATERIALS AND PROPERTIES FOR NONCUBIC ELEMENTS: ----------------------------------------------------------- - --- WOOD -------- -technic_cnc_api.register_slope_edge_etc("default:wood", - {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, - {"default_wood.png"}, - "Wooden Slope", - "Wooden Slope Lying", - "Wooden Slope Upside Down", - "Wooden Slope Edge", - "Wooden Slope Inner Edge", - "Wooden Slope Upside Down Edge", - "Wooden Slope Upside Down Inner Edge", - "Wooden Pyramid", - "Wooden Spike", - "Wooden One Curved Edge Block", - "Wooden Two Curved Edge Block", - "Wooden Cylinder", - "Wooden Cylinder Horizontal", - "Wooden Sphere", - "Wooden Element Straight", - "Wooden Element Edge", - "Wooden Element T", - "Wooden Element Cross", - "Wooden Element End") --- STONE --------- -technic_cnc_api.register_slope_edge_etc("default:stone", - {cracky=3,not_in_creative_inventory=1}, - {"default_stone.png"}, - "Stone Slope", - "Stone Slope Lying", - "Stone Slope Upside Down", - "Stone Slope Edge", - "Stone Slope Inner Edge", - "Stone Slope Upside Down Edge", - "Stone Slope Upside Down Inner Edge", - "Stone Pyramid", - "Stone Spike", - "Stone One Curved Edge Block", - "Stone Two Curved Edge Block", - "Stone Cylinder", - "Stote Cylinder Horizontal", - "Stone Sphere", - "Stone Element Straight", - "Stone Element Edge", - "Stone Element T", - "Stone Element Cross", - "Stone Element End") --- COBBLE ---------- -technic_cnc_api.register_slope_edge_etc("default:cobble", - {cracky=3,not_in_creative_inventory=1}, - {"default_cobble.png"}, - "Cobble Slope", - "Cobble Slope Lying", - "Cobble Slope Upside Down", - "Cobble Slope Edge", - "Cobble Slope Inner Edge", - "Cobble Slope Upside Down Edge", - "Cobble Slope Upside Down Inner Edge", - "Cobble Pyramid", - "Cobble Spike", - "Cobble One Curved Edge Block", - "Cobble Two Curved Edge Block", - "Cobble Cylinder", - "Cobble Cylinder Horizontal", - "Cobble Sphere", - "Cobble Element Straight", - "Cobble Element Edge", - "Cobble Element T", - "Cobble Element Cross", - "Cobble Element End") --- BRICK --------- -technic_cnc_api.register_slope_edge_etc("default:brick", - {cracky=3,not_in_creative_inventory=1}, - {"default_brick.png"}, - "Brick Slope", - "Brick Slope Upside Down", - "Brick Slope Edge", - "Brick Slope Inner Edge", - "Brick Slope Upside Down Edge", - "Brick Slope Upside Down Inner Edge", - "Brick Pyramid", - "Brick Spike", - "Brick One Curved Edge Block", - "Brick Two Curved Edge Block", - "Brick Cylinder", - "Brick Cylinder Horizontal", - "Brick Sphere", - "Brick Element Straight", - "Brick Element Edge", - "Brick Element T", - "Brick Element Cross", - "Brick Element End") --- SANDSTONE ------------- -technic_cnc_api.register_slope_edge_etc("default:sandstone", - {crumbly=2,cracky=2,not_in_creative_inventory=1}, - {"default_sandstone.png"}, - "Sandstone Slope", - "Sandstone Slope Lying", - "Sandstone Slope Upside Down", - "Sandstone Slope Edge", - "Sandstone Slope Inner Edge", - "Sandstone Slope Upside Down Edge", - "Sandstone Slope Upside Down Inner Edge", - "Sandstone Pyramid", - "Sandstone Spike", - "Sandstone One Curved Edge Block", - "Sandstone Two Curved Edge Block", - "Sandstone Cylinder", - "Sandstone Cylinder Horizontal", - "Sandstone Sphere", - "Sandstone Element Straight", - "Sandstone Element Edge", - "Sandstone Element T", - "Sandstone Element Cross", - "Sandstone Element End") --- LEAVES ---------- -technic_cnc_api.register_slope_edge_etc("default:leaves", - {snappy=2,choppy=2,oddly_breakable_by_hand=3,not_in_creative_inventory=1}, - {"bucharest_tree.png"}, - "Leaves Slope", - "Leaves Slope Lying", - "Leaves Slope Upside Down", - "Leaves Slope Edge", - "Leaves Slope Inner Edge", - "Leaves Slope Upside Down Edge", - "Leaves Slope Upside Down Inner Edge", - "Leaves Pyramid", - "Leaves Spike", - "Leaves One Curved Edge Block", - "Leaves Two Curved Edge Block", - "Leaves Cylinder", - "Leaves Cylinder Horizontal", - "Leaves Sphere", - "Leaves Element Straight", - "Leaves Element Edge", - "Leaves Element T", - "Leaves Element Cross", - "Leaves Element End") -- DIRT ------- -technic_cnc_api.register_slope_edge_etc("default:dirt", +technic_cnc_api.register_all("default:dirt", {snappy=2,choppy=2,oddly_breakable_by_hand=3,not_in_creative_inventory=1}, {"default_grass.png", "default_dirt.png", "default_grass.png"}, - "Dirt Slope", - "Dirt Slope Lying", - "Dirt Slope Upside Down", - "Dirt Slope Edge", - "Dirt Slope Inner Edge", - "Dirt Slope Upside Down Edge", - "Dirt Slope Upside Down Inner Edge", - "Dirt Pyramid", - "Dirt Spike", - "Dirt One Curved Edge Block", - "Dirt Two Curved Edge Block", - "Dirt Cylinder", - "Dirt Cylinder Horizontal", - "Dirt Sphere", - "Dirt Element Straight", - "Dirt Element Edge", - "Dirt Element T", - "Dirt Element Cross", - "Dirt Element End") + "Dirt") +technic_cnc_api.cnc_programs_disable["default:dirt"] = {"technic_cnc_sphere", "technic_cnc_slope_upsdown", + "technic_cnc_edge", "technic_cnc_inner_edge", + "technic_cnc_slope_edge_upsdown", "technic_cnc_slope_inner_edge_upsdown", + "technic_cnc_stick", "technic_cnc_cylinder_horizontal"} + -- TREE ------- -technic_cnc_api.register_slope_edge_etc("default:tree", - {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,not_in_creative_inventory=1}, +technic_cnc_api.register_all("default:tree", + {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, {"default_tree.png"}, - "Tree Slope", - "Tree Slope Lying", - "Tree Slope Upside Down", - "Tree Slope Edge", - "Tree Slope Inner Edge", - "Tree Slope Upside Down Edge", - "Tree Slope Upside Down Inner Edge", - "Tree Pyramid", - "Tree Spike", - "Tree One Curved Edge Block", - "Tree Two Curved Edge Block", - "Tree Cylinder", - "Tree Cylinder Horizontal", - "Tree Sphere", - "Tree Element Straight", - "Tree Element Edge", - "Tree Element T", - "Tree Element Cross", - "Tree Element End") --- STEEL --------- -technic_cnc_api.register_slope_edge_etc("default:steelblock", - {snappy=1,bendy=2,cracky=1,melty=2,level=2,not_in_creative_inventory=1}, - {"default_steel_block.png"}, - "Steel Slope", - "Steel Slope Lying", - "Steel Slope Upside Down", - "Steel Slope Edge", - "Steel Slope Inner Edge", - "Steel Slope Upside Down Edge", - "Steel Slope Upside Down Inner Edge", - "Steel Pyramid", - "Steel Spike", - "Steel One Curved Edge Block", - "Steel Two Curved Edge Block", - "Steel Cylinder", - "Steel Cylinder Horizontal", - "Steel Sphere", - "Steel Element Straight", - "Steel Element Edge", - "Steel Element T", - "Steel Element Cross", - "Steel Element End") - --- REGISTER MATERIALS AND PROPERTIES FOR STICKS: ------------------------------------------------- + "Wooden") -- WOOD ------- -technic_cnc_api.register_stick_etc("default:wood", +technic_cnc_api.register_all("default:wood", {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, {"default_wood.png"}, - "Wooden Stick") + "Wooden") -- STONE -------- -technic_cnc_api.register_stick_etc("default:stone", +technic_cnc_api.register_all("default:stone", {cracky=3,not_in_creative_inventory=1}, {"default_stone.png"}, - "Stone Stick") + "Stone") -- COBBLE --------- -technic_cnc_api.register_stick_etc("default:cobble", +technic_cnc_api.register_all("default:cobble", {cracky=3,not_in_creative_inventory=1}, {"default_cobble.png"}, - "Cobble Stick") + "Cobble") -- BRICK -------- -technic_cnc_api.register_stick_etc("default:brick", +technic_cnc_api.register_all("default:brick", {cracky=3,not_in_creative_inventory=1}, {"default_brick.png"}, - "Brick Stick") + "Brick") + -- SANDSTONE ------------ -technic_cnc_api.register_stick_etc("default:sandstone", +technic_cnc_api.register_all("default:sandstone", {crumbly=2,cracky=2,not_in_creative_inventory=1}, {"default_sandstone.png"}, - "Sandstone Stick") + "Sandstone") + -- LEAVES --------- -technic_cnc_api.register_stick_etc("default:leaves", +technic_cnc_api.register_all("default:leaves", {snappy=2,choppy=2,oddly_breakable_by_hand=3,not_in_creative_inventory=1}, {"bucharest_tree.png"}, - "Leaves Stick") + "Leaves") -- TREE ------- -technic_cnc_api.register_stick_etc("default:tree", +technic_cnc_api.register_all("default:tree", {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1,not_in_creative_inventory=1}, {"default_tree.png"}, - "Tree Stick") + "Tree") -- STEEL -------- -technic_cnc_api.register_stick_etc("default:steelblock", +technic_cnc_api.register_all("default:steel", {snappy=1,bendy=2,cracky=1,melty=2,level=2,not_in_creative_inventory=1}, {"default_steel_block.png"}, - "Steel Stick") - --- REGISTER MATERIALS AND PROPERTIES FOR HALF AND NORMAL HEIGHT ELEMENTS: -------------------------------------------------------------------------- - --- WOOD -------- -technic_cnc_api.register_elements("default:wood", - {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, - {"default_wood.png"}, - "Wooden Element Straight Double", - "Wooden Element Edge Double", - "Wooden Element T Double", - "Wooden Element Cross Double", - "Wooden Element End Double") --- STONE --------- -technic_cnc_api.register_elements("default:stone", - {cracky=3,not_in_creative_inventory=1}, - {"default_stone.png"}, - "Stone Element Straight Double", - "Stone Element Edge Double", - "Stone Element T Double", - "Stone Element Cross Double", - "Stone Element End Double") --- COBBLE ---------- -technic_cnc_api.register_elements("default:cobble", - {cracky=3,not_in_creative_inventory=1}, - {"default_cobble.png"}, - "Cobble Element Straight Double", - "Cobble Element Edge Double", - "Cobble Element T Double", - "Cobble Element Cross Double", - "Cobble Element End Double") --- BRICK --------- -technic_cnc_api.register_elements("default:brick", - {cracky=3,not_in_creative_inventory=1}, - {"default_brick.png"}, - "Brick Element Straight Double", - "Brick Element Edge Double", - "Brick Element T Double", - "Brick Element Cross Double", - "Brick Element End Double") --- SANDSTONE ------------- -technic_cnc_api.register_elements("default:sandstone", - {crumbly=2,cracky=2,not_in_creative_inventory=1}, - {"default_sandstone.png"}, - "Sandstone Element Straight Double", - "Sandstone Element Edge Double", - "Sandstone Element T Double", - "Sandstone Element Cross Double", - "Sandstone Element End Double") --- LEAVES ---------- -technic_cnc_api.register_elements("default:leaves", - {snappy=2,choppy=2,oddly_breakable_by_hand=3,not_in_creative_inventory=1}, - {"bucharest_tree.png"}, - "Leaves Element Straight Double", - "Leaves Element Edge Double", - "Leaves Element T Double", - "Leaves Element Cross Double", - "Leaves Element End Double") --- TREE -------- -technic_cnc_api.register_elements("default:tree", - {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1,not_in_creative_inventory=1}, - {"default_tree.png"}, - "Tree Element Straight Double", - "Tree Element Edge Double", - "Tree Element T Double", - "Tree Element Cross Double", - "Tree Element End Double") --- STEEL --------- -technic_cnc_api.register_elements("default:steel", - {snappy=1,bendy=2,cracky=1,melty=2,level=2,not_in_creative_inventory=1}, - {"default_steel_block.png"}, - "Steel Element Straight Double", - "Steel Element Edge Double", - "Steel Element T Double", - "Steel Element Cross Double", - "Steel Element End Double") + "Steel") From ad8c6e3731dd70ad6d11fe720249eb0df8772586 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Thu, 9 May 2013 16:00:43 +0200 Subject: [PATCH 29/57] Add stained glass textures --- framedglass/textures/framedglass_blackglass.png | Bin 0 -> 346 bytes framedglass/textures/framedglass_blueglass.png | Bin 0 -> 432 bytes framedglass/textures/framedglass_brownglass.png | Bin 0 -> 403 bytes framedglass/textures/framedglass_cyanglass.png | Bin 0 -> 442 bytes .../textures/framedglass_darkgreenglass.png | Bin 0 -> 414 bytes .../textures/framedglass_darkgreyglass.png | Bin 0 -> 436 bytes framedglass/textures/framedglass_greenglass.png | Bin 0 -> 445 bytes framedglass/textures/framedglass_greyglass.png | Bin 0 -> 349 bytes framedglass/textures/framedglass_orangeglass.png | Bin 0 -> 410 bytes framedglass/textures/framedglass_pinkglass.png | Bin 0 -> 412 bytes framedglass/textures/framedglass_redglass.png | Bin 0 -> 444 bytes framedglass/textures/framedglass_violetglass.png | Bin 0 -> 418 bytes framedglass/textures/framedglass_whiteglass.png | Bin 0 -> 348 bytes framedglass/textures/framedglass_yellowglass.png | Bin 0 -> 400 bytes framedglass/textures/stained_glass_lime.png | Bin 0 -> 444 bytes framedglass/textures/stained_glass_magenta.png | Bin 0 -> 313 bytes 16 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 framedglass/textures/framedglass_blackglass.png create mode 100644 framedglass/textures/framedglass_blueglass.png create mode 100644 framedglass/textures/framedglass_brownglass.png create mode 100644 framedglass/textures/framedglass_cyanglass.png create mode 100644 framedglass/textures/framedglass_darkgreenglass.png create mode 100644 framedglass/textures/framedglass_darkgreyglass.png create mode 100644 framedglass/textures/framedglass_greenglass.png create mode 100644 framedglass/textures/framedglass_greyglass.png create mode 100644 framedglass/textures/framedglass_orangeglass.png create mode 100644 framedglass/textures/framedglass_pinkglass.png create mode 100644 framedglass/textures/framedglass_redglass.png create mode 100644 framedglass/textures/framedglass_violetglass.png create mode 100644 framedglass/textures/framedglass_whiteglass.png create mode 100644 framedglass/textures/framedglass_yellowglass.png create mode 100644 framedglass/textures/stained_glass_lime.png create mode 100644 framedglass/textures/stained_glass_magenta.png diff --git a/framedglass/textures/framedglass_blackglass.png b/framedglass/textures/framedglass_blackglass.png new file mode 100644 index 0000000000000000000000000000000000000000..4e820278cb22a199f97a6cbeeefb170d9f798e7c GIT binary patch literal 346 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6;RN#5=* z4F5rJ!QSPQfg+p*9+AZi4BWyX%*Zfnjs#GUy~NYkmHjS@3?Dns!62CcpwM+s7sn8b z)2)-d`3@QIxWo&KYn6Gd*(vzlo`XAJf6lQ>E4Fy4XlL5~J6Cdmdq&FUn@l#1ycG;{ z@2%dTY`|JDaWk_MLxa|Ru9`2gWf4p-L<4kooCvt;Y3Cng>?o>{Z{M9W?fzN@)3V08 z^bbp{SEpUKz0iKZayol{SnV~Axo@9wxp0K!KD%1B@vYF)|M~_D&L;|uXYHvf3p-=4 zeNcKwd)gPluEbP0l+XkK4K#t# literal 0 HcmV?d00001 diff --git a/framedglass/textures/framedglass_blueglass.png b/framedglass/textures/framedglass_blueglass.png new file mode 100644 index 0000000000000000000000000000000000000000..2768017a4d268241dc2c1e61255faa8732284b8b GIT binary patch literal 432 zcmV;h0Z;ykP)HK~y-)g_65&!!Qg*j~-^Ut6lp?UHkt_r$AeaIJ6~o5S^w& zEdewHnBwD}>-hM32R4hHkal1PD!0!!BzNxD7o2xU?r3S2tH2fkL5oAOBcw=O8{-5d z3(#=>hU5Tvz*$7>vmhBl^1$)fTL5$(-o{^)En&M)+~080cqbv^bvMy^jq4pAGDoi!A+T+k9DTI!QP z*shKH6`b!+1xJyPpsp*D6Izl-@@~}xSkN-oy1Wj>N7qCB4s3+M)IjoB3e#4qotks#Lqa- aeDVXce$DX!lvI6;RN#5=* z4F5rJ!QSPQfg+p*9+AZi4BWyX%*Zfnjs#GUy~NYkmHjS@46l)apO=gU0|TRgr;B5V z#p%{b-g$=&cwFQ)&3JcdUno6)q5F&7&T?_yr0N^3D;+cvPBZ9AJxez+F8lpRIzlVV zJS>5ATWHO$iC%ULt7AfcGfZR9^E$&@th|b0!OlWPmOr~LGO({vT5-KwddI_1AJM9( zFOLQNpC!HSh?csR=hHeSjf1=mYm-7Rt=e`_*th%Fi{6{t`ObDvTAN`0v~QO?L*#^< zhCRH_Rx68cw~OSj_fndY!|Zq^c4>{$OXlAKQ|{c|p|!J3diA93j?2#G=D&Ky^CsQ1 zmc4Gu9`{VExPw#uMHdOAK7V=t^NSXlS20iIeyOBc9oBm}(LZTfv984z&od?SegcKA re{-JS@+l@=)#@`)sLVOt?kDr2iO1&Oi4=4O1{Z^;tDnm{r-UW|RG6KU literal 0 HcmV?d00001 diff --git a/framedglass/textures/framedglass_cyanglass.png b/framedglass/textures/framedglass_cyanglass.png new file mode 100644 index 0000000000000000000000000000000000000000..31edcc60e3a73ade2ef966398c2269252b095dfa GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6;RN#5=* z4F5rJ!QSPQfg+p*9+AZi4BWyX%*Zfnjs#GUy~NYkmHjS@46lej!<$D@n-$ez!?8^z>R%5}?AyIvO|Dyx7 zCpT)p;}u+5&bo!Mxg&Rd?vtmjDZ*Qm!!|u^`OW(MT0wjqi&FVp8#x7|IF4|k(2gGm z-*o*BHJCj)mr3M%>Dt@5p*3%Jt+a1&xElDE>DjbJA}*)iHT-_&bh`7{y37AR$K=|4 zkbIz_{`O3I!{RwxVl%(ba-DilTWM4D8mo>KEBfYisKnozc|P4TGu!lvI6;RN#5=* z4F5rJ!QSPQfg+p*9+AZi4BWyX%*Zfnjs#GUy~NYkmHjS@46mrgtPr()1_nlHPZ!4! zi_@)>Z1WBq@U+^`>XCNHey(ThuYX0m{FTF&4%gMqD~`w}aV~H@_^0wo^`Ym#**7c= z_0bAwe6V|8;FgCUxjcSVAG_CZwn3DC;fjQ$E88yj2bHjvJ!oIVrPHuP^5@O~5ua&1 zYRuEWNV{(Tvs@(h!-Ow}4u+XmuH`fEYj6o*tHkty`Ioi5J0 z8unn4!0$~~rA0UDn9Y1-ChISVDyou6Jea&8p>xIE?_d7kIp#F))0{OnS3A#EuvuIN zk+)|0mdKI;Vst E04vO^MF0Q* literal 0 HcmV?d00001 diff --git a/framedglass/textures/framedglass_darkgreyglass.png b/framedglass/textures/framedglass_darkgreyglass.png new file mode 100644 index 0000000000000000000000000000000000000000..78c394b836f3317323bc407080d6dd43d3e90c9d GIT binary patch literal 436 zcmV;l0ZaagP)~0MQvd4 z7l{EG1}upZ$#}h9zkt0*&CCi^;CR2^KP9zwU4KMGNNTpvp1T2i0*mdC6q%W|)|3Bd zlC%J4MEsF70R@O2Nxx=EWM%|BQL-Mc-WqS2{?Lewl~`w zu(#HZF=h6|22g8l1NEbLw|(@nC)*hjb8Bq|<^)=;b?h}pK0cZZQcp?I0TkkgZ@`|JYi9liYIag0 zBE|~E_D~`FL~Zc&?Q99mS2_b+`6Taj2DtJ`xzqX1CwZsyolo*kXGxbnN!yn?+di*+ eQtouV^T|KsyZ{{P7(e>}0000) literal 0 HcmV?d00001 diff --git a/framedglass/textures/framedglass_greenglass.png b/framedglass/textures/framedglass_greenglass.png new file mode 100644 index 0000000000000000000000000000000000000000..0886c74a05cd4f89cb798e2d8b9e4c1ecdb3a406 GIT binary patch literal 445 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6;RN#5=* z4F5rJ!QSPQfg+p*9+AZi4BWyX%*Zfnjs#GUy~NYkmHjS@43Dwa>W}+O7#J9>JY5_^ zEKavh@?9lnDB$Y!I{a+&)sdeE@|hJv1z(Aca?=fBmcp7Odx!N@2mgI z7IV5iRQdqJqhFP^VV8Tpf8^A5^);?~@~fI@I@%`KNs)_f;cowW%L%Vl!mzrrGL+WpG~E+NZSQRXKN z4V)9w&&7UK{m~`2@mAQEf;BQvY#I(X&P;!|v+VT8Nh$iKS3|-MO4-`E@PB_HsL!2r zcGgF`1E*>{EgH6DJ(;=x>K8HFdp^F&sjCkN+R99@+r^j~diVDH1F2Vch5lybVb?1X zTk}Rxrz(eQpVh2t|Nl2$9whKy9z$TjGI+ZBxvX!lvI6;RN#5=* z4F5rJ!QSPQfg+p*9+AZi4BWyX%*Zfnjs#GUy~NYkmHjS@3?BnepK#Z7pwKN(7sn8b z)2)-v@--OZg=8yde?jx{rS(vmcU`D=QcU~ z{JE~5>8ce>*Dv(gIT?CKU7yR!TvMdjZu45^l}eP&?VDFUw^VHVR$eNkJ1^R*Q|!F% nT$k?WXY>A*00mg>uAJnT&&+fCqnmI5=t~AqS3j3^P6!lvI6;RN#5=* z4F5rJ!QSPQfg+p*9+AZi4BWyX%*Zfnjs#GUy~NYkmHjS@46mNYBB;*ag^Plrr^ZNlj~>ntSpnYeZwbIFs0dP>HXF;wv_W7>4c$ zv5Rr}JGonRQkW&1NAJYs+l)#FSslW@c!W%6v6hOIWpn7uUH^HH%*2#~VNcqs+8C9O z+g)#&lg(4M`nNn)OMf-YxwxxMp9JIuExYeMtx?rfFoM_t$Fi67uz6eIok z>#LM{hK0v`d-E4WXa2G|B(!sNLTiT4ynkztt2|kHZs{rS`8Q^s+u-@@lzQ1RV}rh$ zq;#wKKaZR%DU!lvI6;RN#5=* z4F5rJ!QSPQfg+p*9+AZi4BWyX%*Zfnjs#GUy~NYkmHjS@46nREC|{a90|TR^r;B5V z#p%{b-dQY$JTCL?*Unrj7Wv$5XZeXhwb{2?SiT>RbZJXd$ZhU9uqkBKsxJqBOK)(? zY0Evp_J&_>eP8)PaRt{pmt5v+Tr&cSY$U^^-#&ORa-7$qA^$k{ghr9T&g?>&!$l&( zt(KqO{gBE(`cY?!k~*`hnsfnko)dRKgY6qP^>5Z2q`sxzP~UJ>;prYHF)6Jp4p-Ry{g?AP{ktmp;FNmlGUEeN{Xh9U xpXvV!LZlzpuMKL|D;2X^S2HQy>U_;7?$1g`)F<~&+zt#k22WQ%mvv4FO#m@(oZ|oh literal 0 HcmV?d00001 diff --git a/framedglass/textures/framedglass_redglass.png b/framedglass/textures/framedglass_redglass.png new file mode 100644 index 0000000000000000000000000000000000000000..1d209207b3d69f2e217bfa7f3d39ebc0702dfb65 GIT binary patch literal 444 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6;RN#5=* z4F5rJ!QSPQfg+p*9+AZi4BWyX%*Zfnjs#GUy~NYkmHjS@439BGfmit>1_nk;PZ!4! zi_@)>Hs&2R;BlF+ag%4_)?$10=>PwfccmCc9Nl*1;Fj5X+Zv2nB5Wp=PyhA!BkP$) z)~l=$4O5?g7T$c$q*h^)!RsB{D}FOQW9r$Venx0jYn1fulQVi9oR1iuZeY+1=s4dX zxq@qhxHrRsWV7S@duBeE_o$D-(yG6Ksp~gGN&@emg8K}{YuEmsqAFL$koDI6`u<0f z-%XF5+ad147A4)VkYR4r_r2dHUN@f%WAu!++Ig=pHmih3yKdzOA?`Jk%CA{kXfgq;e$~g# z?p3#Ap7V4`%uk+zX_JdI-p*UBaXHG(g|9o*dTUxpwU5h$^-oVdUp;4v_IyL@vz`b4 kUP-@mJJRn7NbC=j!{^hJ-~2lj1q@dPPgg&ebxsLQ02qt9DgXcg literal 0 HcmV?d00001 diff --git a/framedglass/textures/framedglass_violetglass.png b/framedglass/textures/framedglass_violetglass.png new file mode 100644 index 0000000000000000000000000000000000000000..aec8ce01844fe225ebe5bccdfc6dced9518ca601 GIT binary patch literal 418 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6;RN#5=* z4F5rJ!QSPQfg+p*9+AZi4BWyX%*Zfnjs#GUy~NYkmHjS@46l@VZ?U=|0|TSHr;B5V z#p%{b-hM|7cwGBs_kU=UG;qu5Xx%J2qoT>-?+u=UC0sAJPK>e4dKB|Jrt;}u-Uw~8 zh4}~A-dM})pE_}1KI2N8S8tfsuzfk;DydZBJ?%lhX=;f=Lw>4>1LI1ASH;0>PS>q` zWUrhGmdyT}ed@x2rA0g$PUllHo%|aP1hO57+sJzFRS@&CS!r868&XdGeD&~?)Q`AL z(GS?}q)ALTY4m&6r0>oXEw2Q$U1_%cu>8PTru+QNi>i7LET0rv!0hxw<#fN%yT<#W zlF^~B53E%&OU+m~`S2Ivh}M6qU;Gm`CspM*GS3%TBl2|4<^5aFG}=6g36cACWSzzT znU6O5zv(ibkZ!k8`&>APIA!s*leO-Y!lvI6;RN#5=* z4F5rJ!QSPQfg+p*9+AZi4BWyX%*Zfnjs#GUy~NYkmHjS@46h|y5=%f9Q0S(oi(`nz z>DEbS`I-y_TI_GR_L>Wy-#797e+4;{hAXFYj2t~?=S1DOd4J}@t>0MEZYF(Wm2+Tz zcVNMHtv4)Z80S2ZX%JvoaB4eKe(iMLX$)?xBHVgLA*IvKPrl+4z8%s&!~4m^~nw?-#A-q z?Pu{*9!lvI6;RN#5=* z4F5rJ!QSPQfg+p*9+AZi4BWyX%*Zfnjs#GUy~NYkmHjS@46l*_O9x*j0|O(kr;B5V z#p%|`dxMS`@U-l|p%n8_DC%Cv_j(Q~uDdeDg-Kkwbs9akk0XpHhF^MDwd(C(;fO8T z5xtW|_t`Hn`Cy(9v`6zhrw-eh2f|Z0&n(D0aw;G#fmtrVXaZ9Qr@@!XMy7}$BQKvW z=_#)Nji!jOo($N)vBvQ#=K~gv)n%;bcP*LBlES#4d+XfL{?pt)R&6uhv8yk4V$AoQ z-=LD%x2=z+uA!K7s#_LjNC5KT*fHU!T6Q^6z`vD3qls2y*TZ*r&!SQg#AZ7 z%GiH1t@6D5nuD_@{NR;9>&jo7=UFSp&RyztUES=GW!QZX$@Qf+NqMfj-NuRMJ~sTa oGyG6r+IRi>cTcI8HlI%FXJzopr08TxeK>z>% literal 0 HcmV?d00001 diff --git a/framedglass/textures/stained_glass_lime.png b/framedglass/textures/stained_glass_lime.png new file mode 100644 index 0000000000000000000000000000000000000000..782edc993fa745817d11bf8a8b1cdc44a9ddf0ed GIT binary patch literal 444 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6;RN#5=* z4F5rJ!QSPQfg+p*9+AZi4BWyX%*Zfnjs#GUy~NYkmHjS@439e7_IB1L1_nk;PZ!4! zi_@)>Hs&2R;BlF+ag%4_)?$10=>PwfccmCc9Nl*1;Fj5X+Zv2nB5Wp=PyhA!BkP$) z)~l=$4O5?g7T$c$q*h^)!RsB{D}FOQW9r$Venx0jYn1fulQVi9oR1iuZeY+1=s4dX zxq@qhxHrRsWV7S@duBeE_o$D-(yG6Ksp~gGN&@emg8K}{YuEmsqAFL$koDI6`u<0f z-%XF5+ad147A4)VkYR4r_r2dHUN@f%WAu!++Ig=pHmih3yKdzOA?`Jk%CA{kXfgq;e$~g# z?p3#Ap7V4`%uk+zX_JdI-p*UBaXHG(g|9o*dTUxpwU5h$^-oVdUp;4v_IyL@vz`b4 kUP-@mJJRn7NbC=j!{^hJ-~2lj1q@dPPgg&ebxsLQ0IE&7)&Kwi literal 0 HcmV?d00001 diff --git a/framedglass/textures/stained_glass_magenta.png b/framedglass/textures/stained_glass_magenta.png new file mode 100644 index 0000000000000000000000000000000000000000..43e28b7f190ea3bc8717f15bee3e61a9fe854d8e GIT binary patch literal 313 zcmWkoy=uZ>0K8y}tr9A9k>XyLPT$t46@#YOAnMXhD0D99)UjKipisJY^&NClgn~bq zDn^Z(Xw)QXjQ?Oihr8qM;JA;d5Mo_dE&wba4#uc@jyQ8r_TOB@sW7QnD1gkbPow51 z8cA>_%qga0j1?#{1umssl12N;MDE2z{_H()44F^I9k zN+xm>O_P{I4C(&ia7bN?56AcEm=MRE`u9T3`D^$o1-LJdVDR Date: Thu, 9 May 2013 16:01:18 +0200 Subject: [PATCH 30/57] Add stained glass code --- framedglass/init.lua | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/framedglass/init.lua b/framedglass/init.lua index ebe88ea..6bb92ae 100644 --- a/framedglass/init.lua +++ b/framedglass/init.lua @@ -75,3 +75,33 @@ minetest.register_node("framedglass:steel_framed_obsidian_glass", { groups = {cracky=3,oddly_breakable_by_hand=3}, sounds = default.node_sound_glass_defaults(), }) + +function add_coloured_framedglass(name, desc, dye, texture) +minetest.register_node( "framedglass:steel_framed_obsidian_glass"..name, { + description = "Steel-framed "..desc.." Obsidian Glass", + tiles = {"framedglass_steel_frame.png",texture}, + drawtype = "glasslike_framed", + paramtype = "light", + sunlight_propagates = true, + is_ground_content = true, + use_texture_alpha = true, + groups = {cracky=3}, + sounds = default.node_sound_glass_defaults(), +}) +end + +add_coloured_framedglass ("red","Red","","framedglass_redglass.png") +add_coloured_framedglass ("green","Green","","framedglass_greenglass.png") +add_coloured_framedglass ("blue","Blue","","framedglass_blueglass.png") +add_coloured_framedglass ("cyan","Cyan","","framedglass_cyanglass.png") +add_coloured_framedglass ("darkgreen","Dark Green","","framedglass_darkgreenglass.png") +add_coloured_framedglass ("violet","Violet","","framedglass_violetglass.png") +add_coloured_framedglass ("pink","Pink","","framedglass_pinkglass.png") +add_coloured_framedglass ("yellow","Yellow","","framedglass_yellowglass.png") +add_coloured_framedglass ("orange","Orange","","framedglass_orangeglass.png") +add_coloured_framedglass ("brown","Brown","","framedglass_brownglass.png") +add_coloured_framedglass ("white","White","","framedglass_whiteglass.png") +add_coloured_framedglass ("grey","Grey","","framedglass_greyglass.png") +add_coloured_framedglass ("darkgrey","Dark Grey","","framedglass_darkgreyglass.png") +add_coloured_framedglass ("black","Black","","framedglass_blackglass.png") + From 64207baa4563db90fa80ed23f3b8f41f96f0260d Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Thu, 9 May 2013 16:02:02 +0200 Subject: [PATCH 31/57] Add HV battery box --- technic/battery_box_hv.lua | 357 +++++++++++++++++++++++++++++++++++++ technic/init.lua | 1 + 2 files changed, 358 insertions(+) create mode 100644 technic/battery_box_hv.lua diff --git a/technic/battery_box_hv.lua b/technic/battery_box_hv.lua new file mode 100644 index 0000000..05166eb --- /dev/null +++ b/technic/battery_box_hv.lua @@ -0,0 +1,357 @@ +HV_machines = {} + +registered_HV_machines_count=0 + +function register_HV_machine (string1,string2) +registered_HV_machines_count=registered_HV_machines_count+1 +HV_machines[registered_HV_machines_count]={} +HV_machines[registered_HV_machines_count].machine_name=string1 +HV_machines[registered_HV_machines_count].machine_type=string2 +end + +minetest.register_craft({ + output = 'technic:hv_battery_box 1', + recipe = { + {'technic:mv_battery_box', 'technic:mv_battery_box', 'mv_technic:battery_box'}, + {'technic:mv_battery_box', 'technic:transformer', 'mv_technic:battery_box'}, + {'', 'technic:hv_cable', ''}, + } +}) + +hv_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;HV Battery Box]".. + "label[3,0;Charge]".. + "label[5,0;Discharge]".. + "label[1,3;Power level]".. + "list[current_player;main;0,5;8,4;]" + +minetest.register_node("technic:hv_battery_box", { + description = "HV Battery Box", + tiles = {"technic_hv_battery_box_top.png", "technic_hv_battery_box_bottom.png", "technic_hv_battery_box_side0.png", + "technic_hv_battery_box_side0.png", "technic_hv_battery_box_side0.png", "technic_hv_battery_box_side0.png"}, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), + technic_mv_power_machine=1, + last_side_shown=0, + drop="technic:hv_battery_box", + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_string("infotext", "HV Battery Box") + meta:set_float("technic_hv_power_machine", 1) + meta:set_string("formspec", battery_box_formspec) + local inv = meta:get_inventory() + inv:set_size("src", 1) + inv:set_size("dst", 1) + battery_charge = 0 + max_charge = 1500000 + last_side_shown=0 + 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, +}) + + +for i=1,8,1 do +minetest.register_node("technic:hv_battery_box"..i, { + description = "HV Battery Box", + tiles = {"technic_hv_battery_box_top.png", "technic_hv_battery_box_bottom.png", "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", + "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_hv_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(), + paramtype="light", + light_source=9, + technic_power_machine=1, + last_side_shown=0, + drop="technic:hv_battery_box", + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_string("infotext", "hv Battery box") + meta:set_float("technic_hv_power_machine", 1) + meta:set_string("formspec", battery_box_formspec) + local inv = meta:get_inventory() + inv:set_size("src", 1) + inv:set_size("dst", 1) + battery_charge = 0 + max_charge = 1500000 + last_side_shown=0 + 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, +}) +end + + +HV_nodes_visited = {} + + +minetest.register_abm({ + nodenames = {"technic:hv_battery_box","technic:hv_battery_box1","technic:hv_battery_box2","technic:hv_battery_box3","technic:hv_battery_box4", + "technic:hv_battery_box5","technic:hv_battery_box6","technic:hv_battery_box7","technic:hv_battery_box8" + }, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.env:get_meta(pos) + charge= meta:get_int("battery_charge") + max_charge= 1500000 + local i=math.ceil((charge/max_charge)*8) + if i>8 then i=8 end + j=meta:get_float("last_side_shown") + if i~=j then + if i>0 then hacky_swap_node(pos,"technic:hv_battery_box"..i) + elseif i==0 then hacky_swap_node(pos,"technic:hv_battery_box") end + meta:set_float("last_side_shown",i) + end + +--loading registered power tools + local inv = meta:get_inventory() + if inv:is_empty("src")==false then + local srcstack = inv:get_stack("src", 1) + local src_item=srcstack:to_table() + local src_meta=get_item_meta(src_item["metadata"]) + + local item_max_charge=nil + for i=1,registered_power_tools_count,1 do + if power_tools[i].tool_name==src_item["name"] then + src_meta=get_item_meta(src_item["metadata"]) + if src_meta==nil then + src_meta={} + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + else + if src_meta["technic_power_tool"]==nil then + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + end + end + item_max_charge=power_tools[i].max_charge + end + end + + if item_max_charge then + load1=src_meta["charge"] + load_step=16000 + if load10 then + if charge-load_step<0 then load_step=charge end + if load1+load_step>item_max_charge then load_step=item_max_charge-load1 end + load1=load1+load_step + charge=charge-load_step + set_RE_wear(src_item,load1,item_max_charge) + src_meta["charge"]=load1 + src_item["metadata"]=set_item_meta(src_meta) + inv:set_stack("src", 1, src_item) + end + meta:set_int("battery_charge",charge) + end + end + +-- dischargin registered power tools + if inv:is_empty("dst") == false then + srcstack = inv:get_stack("dst", 1) + src_item=srcstack:to_table() + local src_meta=get_item_meta(src_item["metadata"]) + local item_max_charge=nil + for i=1,registered_power_tools_count,1 do + if power_tools[i].tool_name==src_item["name"] then + src_meta=get_item_meta(src_item["metadata"]) + if src_meta==nil then + src_meta={} + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + else + if src_meta["technic_power_tool"]==nil then + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + end + end + item_max_charge=power_tools[i].max_charge + end + end + + if item_max_charge then + local load1=src_meta["charge"] + load_step=16000 + if load1>0 and chargemax_charge then load_step=max_charge-charge end + if load1-load_step<0 then load_step=load1 end + load1=load1-load_step + charge=charge+load_step + set_RE_wear(src_item,load1,item_max_charge) + src_meta["charge"]=load1 + src_item["metadata"]=set_item_meta(src_meta) + inv:set_stack("dst", 1, src_item) + end + end + end + + meta:set_int("battery_charge",charge) + + local load = math.floor((charge/1500000) * 100) + meta:set_string("formspec", + hv_battery_box_formspec.. + "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. + (load)..":technic_power_meter_fg.png]" + ) + + local pos1={} + + pos1.y=pos.y-1 + pos1.x=pos.x + pos1.z=pos.z + + + meta1 = minetest.env:get_meta(pos1) + if meta1:get_float("hv_cablelike")~=1 then return end + + local HV_nodes = {} + local PR_nodes = {} + local RE_nodes = {} + + HV_nodes[1]={} + HV_nodes[1].x=pos1.x + HV_nodes[1].y=pos1.y + HV_nodes[1].z=pos1.z + HV_nodes[1].visited=false + +table_index=1 + repeat + check_HV_node (PR_nodes,RE_nodes,HV_nodes,table_index) + table_index=table_index+1 + if HV_nodes[table_index]==nil then break end + until false + + +local pos1={} +i=1 + repeat + if PR_nodes[i]==nil then break end -- gettin power from all connected producers + pos1.x=PR_nodes[i].x + pos1.y=PR_nodes[i].y + pos1.z=PR_nodes[i].z + local meta1 = minetest.env:get_meta(pos1) + local internal_EU_buffer=meta1:get_float("internal_EU_buffer") + if charge0 then + charge=charge+charge_to_take + internal_EU_buffer=internal_EU_buffer-charge_to_take + meta1:set_float("internal_EU_buffer",internal_EU_buffer) + end + end + i=i+1 + until false + +if charge>max_charge then charge=max_charge end + +i=1 + repeat + if RE_nodes[i]==nil then break end + pos1.x=RE_nodes[i].x -- loading all conected machines buffers + pos1.y=RE_nodes[i].y + pos1.z=RE_nodes[i].z + local meta1 = minetest.env:get_meta(pos1) + local internal_EU_buffer=meta1:get_float("internal_EU_buffer") + local internal_EU_buffer_size=meta1:get_float("internal_EU_buffer_size") + + local charge_to_give=4000 + if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then + charge_to_give=internal_EU_buffer_size-internal_EU_buffer + end + if charge-charge_to_give<0 then charge_to_give=charge end + + internal_EU_buffer=internal_EU_buffer+charge_to_give + meta1:set_float("internal_EU_buffer",internal_EU_buffer) + charge=charge-charge_to_give; + + i=i+1 + until false + charge=math.floor(charge) + charge_string=tostring(charge) + meta:set_string("infotext", "HV Battery Box: \n"..charge_string.."/"..max_charge); + meta:set_int("battery_charge",charge) + +end +}) + +function add_new_HVcable_node (HV_nodes,pos1) +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 +HV_nodes[i].visited=false +return true +end + +function check_HV_node (PR_nodes,RE_nodes,HV_nodes,i) + local pos1={} + pos1.x=HV_nodes[i].x + pos1.y=HV_nodes[i].y + pos1.z=HV_nodes[i].z + HV_nodes[i].visited=true + new_node_added=false + + pos1.x=pos1.x+1 + check_HV_node_subp (PR_nodes,RE_nodes,HV_nodes,pos1) + pos1.x=pos1.x-2 + check_HV_node_subp (PR_nodes,RE_nodes,HV_nodes,pos1) + pos1.x=pos1.x+1 + + pos1.y=pos1.y+1 + check_HV_node_subp (PR_nodes,RE_nodes,HV_nodes,pos1) + pos1.y=pos1.y-2 + check_HV_node_subp (PR_nodes,RE_nodes,HV_nodes,pos1) + pos1.y=pos1.y+1 + + pos1.z=pos1.z+1 + check_HV_node_subp (PR_nodes,RE_nodes,HV_nodes,pos1) + pos1.z=pos1.z-2 + check_HV_node_subp (PR_nodes,RE_nodes,HV_nodes,pos1) + pos1.z=pos1.z+1 +return new_node_added +end + +function check_HV_node_subp (PR_nodes,RE_nodes,HV_nodes,pos1) +meta = minetest.env:get_meta(pos1) +if meta:get_float("HV_cablelike")==1 then new_node_added=add_new_HVcable_node(HV_nodes,pos1) end +for i in ipairs(HV_machines) do + if minetest.env:get_node(pos1).name == HV_machines[i].machine_name then + if HV_machines[i].machine_type == "PR" then + new_node_added=add_new_HVcable_node(PR_nodes,pos1) + end + if HV_machines[i].machine_type == "RE" then + new_node_added=add_new_HVcable_node(RE_nodes,pos1) + end + end +end +end + diff --git a/technic/init.lua b/technic/init.lua index ff904e2..eabf48e 100644 --- a/technic/init.lua +++ b/technic/init.lua @@ -41,6 +41,7 @@ dofile(modpath.."/forcefield.lua") --HV machines dofile(modpath.."/wires_hv.lua") +dofile(modpath.."/battery_box_hv.lua") --Tools if technic.config:getBool("enable_mining_drill") then dofile(modpath.."/mining_drill.lua") end From 630db84ad13682eadc0035c251febfa07353a969 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Sat, 25 May 2013 22:39:25 +0200 Subject: [PATCH 32/57] bugfix --- unified_inventory/api.lua | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/unified_inventory/api.lua b/unified_inventory/api.lua index ab55903..02c08e9 100644 --- a/unified_inventory/api.lua +++ b/unified_inventory/api.lua @@ -58,7 +58,7 @@ minetest.register_on_joinplayer(function(player) unified_inventory.alternate[player_name] = 1 unified_inventory.current_item[player_name] =nil unified_inventory.set_inventory_formspec(player,unified_inventory.get_formspec(player, unified_inventory.default)) - + --crafting guide inventories local inv = minetest.create_detached_inventory(player:get_player_name().."craftrecipe",{ allow_put = function(inv, listname, index, stack, player) @@ -75,8 +75,8 @@ local inv = minetest.create_detached_inventory(player:get_player_name().."craftr return 0 end, }) - inv:set_size("output", 1) - inv:set_size("build", 3*3) +inv:set_size("output", 1) +inv:set_size("build", 3*3) -- refill slot unified_inventory.refill = minetest.create_detached_inventory(player_name.."refill", { @@ -93,7 +93,6 @@ unified_inventory.refill = minetest.create_detached_inventory(player_name.."refi end, }) unified_inventory.refill:set_size("main", 1) -end) -- trash slot unified_inventory.trash = minetest.create_detached_inventory("trash", { @@ -111,24 +110,18 @@ unified_inventory.trash = minetest.create_detached_inventory("trash", { end, }) unified_inventory.trash:set_size("main", 1) +end) -- set_inventory_formspec unified_inventory.set_inventory_formspec = function(player,formspec) if player then - if minetest.setting_getbool("creative_mode") then - -- if creative mode is on then wait a bit - minetest.after(0.01,function() - player:set_inventory_formspec(formspec) - end) - else player:set_inventory_formspec(formspec) - end end end -- get_formspec unified_inventory.get_formspec = function(player,page) - if player==nil then return "" end + if player==nil then return "" end local player_name = player:get_player_name() unified_inventory.current_page[player_name]=page From 0d81a3f42a96378ab0fa4d34737ad99de19b2f66 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Sat, 25 May 2013 23:00:12 +0200 Subject: [PATCH 33/57] Bugfix --- item_drop/init.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/item_drop/init.lua b/item_drop/init.lua index db1f2a3..54b617f 100644 --- a/item_drop/init.lua +++ b/item_drop/init.lua @@ -4,6 +4,7 @@ time_pick = 3 if technic.config:getBool("enable_item_pickup") then minetest.register_globalstep(function(dtime) for _,player in ipairs(minetest.get_connected_players()) do + if player and player:get_hp() > 0 then local pos = player:getpos() pos.y = pos.y+0.5 local inv = player:get_inventory() @@ -26,6 +27,7 @@ if technic.config:getBool("enable_item_pickup") then end end end + end end end) end From 77254735e4a533bcce90e579f56fbae2c3c34359 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Wed, 29 May 2013 03:59:25 +0200 Subject: [PATCH 34/57] Make treetap work with moretrees rubber tree. Add moretrees as dependency --- technic/depends.txt | 1 + technic/tree_tap.lua | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/technic/depends.txt b/technic/depends.txt index 3859f8a..7d2e8c3 100644 --- a/technic/depends.txt +++ b/technic/depends.txt @@ -2,3 +2,4 @@ default moreores pipeworks mesecons +moretrees diff --git a/technic/tree_tap.lua b/technic/tree_tap.lua index 107faed..9d805d5 100644 --- a/technic/tree_tap.lua +++ b/technic/tree_tap.lua @@ -7,7 +7,8 @@ local pos=minetest.get_pointed_thing_position(pointed_thing,above) local node=minetest.env:get_node(pos) local node_name=node.name - if node_name == "farming_plus:rubber_tree_full" or node_name == "farming:rubber_tree_full" or node_name == "technic:rubber_tree_full" then + if node_name == "moretrees:rubber_tree_trunk" then + node.name = "moretrees:rubber_tree_trunk_empty" user:get_inventory():add_item("main",ItemStack("technic:raw_latex")) minetest.env:set_node(pos,node) local item=itemstack:to_table() @@ -47,3 +48,13 @@ description = "Rubber Fiber", inventory_image = "technic_rubber.png", }) + +minetest.register_abm({ + nodenames = {"moretrees:rubber_tree_trunk_empty"}, + interval = 60, + chance = 15, + action = function(pos, node) + node.name = "moretrees:rubber_tree_trunk" + minetest.env:set_node(pos, node) + end +}) From 7d890428f547758ffd907252b2effb1d743c02e4 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Thu, 30 May 2013 06:01:01 +0200 Subject: [PATCH 35/57] HV Battery Box textures added --- .../textures/technic_hv_battery_box_bottom.png | Bin 0 -> 653 bytes technic/textures/technic_hv_battery_box_side0.png | Bin 0 -> 777 bytes technic/textures/technic_hv_battery_box_top.png | Bin 0 -> 792 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 technic/textures/technic_hv_battery_box_bottom.png create mode 100644 technic/textures/technic_hv_battery_box_side0.png create mode 100644 technic/textures/technic_hv_battery_box_top.png diff --git a/technic/textures/technic_hv_battery_box_bottom.png b/technic/textures/technic_hv_battery_box_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..996b2d4cfdcd63908ee512b0f2165c090f861e7b GIT binary patch literal 653 zcmV;80&@L{P)(7T;J|G13}rY z@Tm0bALX;xpEoohhzV*+SA!`%6I7rIR1pK?~cCg+;Y-8Ps>%tTzdJjrt+Cgd69y9@8?Wz>6W zmn7eP`URy+a}9{PuoAw1^9$@oK4KXRI91TgNE$kdM@)YF>1Td>^E?KfYu zkBxWNNu2>Ibc3TxXDySe;pQAq2iG-;83aN6@h5Rj#0&yNp|j{Llv*|Dndt7=Z6IA- zbMoPt8wL1gu#_Sy*zTwdTXBid)#PI`GdONLw|&Rmd3ip_nq(FLx;f%2B_|7e+No-E zCOwq<-~aH{>o3{2XIzBswsZaaA2H)&8@ro|!bOD!%mh0&#&CY9Ul9ZzP+8Ppg$?8B zY7E|6H(!RloeW7z^+p=00000NkvXXu0mjfouVKV literal 0 HcmV?d00001 diff --git a/technic/textures/technic_hv_battery_box_side0.png b/technic/textures/technic_hv_battery_box_side0.png new file mode 100644 index 0000000000000000000000000000000000000000..fffd8eaa561b18485900a9899520329a116f0e4c GIT binary patch literal 777 zcmV+k1NQuhP)YDqQc_5Wv#5})F{UTbUB^#sEd62-fcd$QIF|u#N)#2& z+r%^(!`UTK*KxCJDOL137ZF~xi8eK88z=`A(H+XoA;o${Sr73P(Ad)kaOv-;QE?UO z$reR5LWWhpt^{SgG31@a9vf!?OBpxEyk{W*?$|P8?z}bG<$m)zMPmq{V$N=tc(AkJ z?i)8(0N`f08M(_nkO~GI%r1ENX3gGsliXz@Dm*?u2%Zhh(AArOg9s6Gwhs2GCmZC} zSe!Jd!Q(NlwFy^cd~`sF14zJ#;rmMPXVPOKN7D8Z_&=Rl%0%Qo;0OTwHc>`oLML)mREFvEZ!WMKGcXQ`tDcm ze*S};A~{9A{pl~hfBu4DxIkJ#MB}}o#DH02<}gKU0OuQ99N+x#JFQj5aYRHI`kuSr zUhvMNOQsMI?@((YR)cZ<1-5gu<}AeW2=YEGzUpMBD9)DaPlZeX0lS`S)bhApu| zTo!6htfw=rHmnsy8u#oleeZZ}xWrkDwHE6-OgA9DqxA!MU1@6|hRA7i4?t;!R9F0} z(TbOiwJ8dk+Ju}dB_&!cq zNFn$H}gLW WI#dbF@1UUo0000 Date: Mon, 3 Jun 2013 23:37:04 +0200 Subject: [PATCH 36/57] Added solar arrays for all voltage tiers. Added transformers for all voltage tiers. I changed the recipes for solar panels to make them less expensive. I also changed the output of the individual panel and made the arrays provie the real "oomph" :-) Solar panels and arrays are dependent on light level, time of day and height abive ground (0) for output and cheating with torches and stuff. Textures added. Fixed bugs in the hv battery box. It was not working at all. I don't understand the hv box top texture though??? I have a sense that all machines connected to the battery boxes are taking the same amount of juice from the box. A method of taking a little or a lot would be nice. --- technic/alloy_furnaces_commons.lua | 2 +- technic/battery_box_hv.lua | 6 +- technic/init.lua | 4 +- technic/items.lua | 30 ++++++ technic/solar_array_hv.lua | 93 +++++++++++++++++ technic/solar_array_lv.lua | 94 ++++++++++++++++++ technic/solar_array_mv.lua | 94 ++++++++++++++++++ technic/solar_panel.lua | 37 ++++--- .../technic_hv_solar_array_bottom.png | Bin 0 -> 574 bytes .../textures/technic_hv_solar_array_side.png | Bin 0 -> 709 bytes .../textures/technic_hv_solar_array_top.png | Bin 0 -> 777 bytes technic/textures/technic_hv_transformer.png | Bin 0 -> 1801 bytes .../technic_lv_solar_array_bottom.png | Bin 0 -> 579 bytes .../textures/technic_lv_solar_array_side.png | Bin 0 -> 465 bytes .../textures/technic_lv_solar_array_top.png | Bin 0 -> 743 bytes technic/textures/technic_lv_transformer.png | Bin 0 -> 1821 bytes .../technic_mv_solar_array_bottom.png | Bin 0 -> 574 bytes .../textures/technic_mv_solar_array_side.png | Bin 0 -> 628 bytes .../textures/technic_mv_solar_array_top.png | Bin 0 -> 728 bytes .../technic_hv_solar_array_bottom.png | Bin 0 -> 2019 bytes .../technic_hv_solar_array_side.png | Bin 0 -> 1772 bytes .../technicx32/technic_hv_solar_array_top.png | Bin 0 -> 2855 bytes .../technicx32/technic_hv_transformer.png | Bin 0 -> 1789 bytes .../technic_lv_solar_array_bottom.png | Bin 0 -> 2019 bytes .../technic_lv_solar_array_side.png | Bin 0 -> 1772 bytes .../technicx32/technic_lv_solar_array_top.png | Bin 0 -> 2728 bytes .../technicx32/technic_lv_transformer.png | Bin 0 -> 1809 bytes .../technic_mv_solar_array_bottom.png | Bin 0 -> 2019 bytes .../technic_mv_solar_array_side.png | Bin 0 -> 1772 bytes .../technicx32/technic_mv_solar_array_top.png | Bin 0 -> 2784 bytes 30 files changed, 343 insertions(+), 17 deletions(-) create mode 100644 technic/solar_array_hv.lua create mode 100644 technic/solar_array_lv.lua create mode 100644 technic/solar_array_mv.lua create mode 100644 technic/textures/technic_hv_solar_array_bottom.png create mode 100644 technic/textures/technic_hv_solar_array_side.png create mode 100644 technic/textures/technic_hv_solar_array_top.png create mode 100644 technic/textures/technic_hv_transformer.png create mode 100644 technic/textures/technic_lv_solar_array_bottom.png create mode 100644 technic/textures/technic_lv_solar_array_side.png create mode 100644 technic/textures/technic_lv_solar_array_top.png create mode 100644 technic/textures/technic_lv_transformer.png create mode 100644 technic/textures/technic_mv_solar_array_bottom.png create mode 100644 technic/textures/technic_mv_solar_array_side.png create mode 100644 technic/textures/technic_mv_solar_array_top.png create mode 100644 technic/textures/technicx32/technic_hv_solar_array_bottom.png create mode 100644 technic/textures/technicx32/technic_hv_solar_array_side.png create mode 100644 technic/textures/technicx32/technic_hv_solar_array_top.png create mode 100644 technic/textures/technicx32/technic_hv_transformer.png create mode 100644 technic/textures/technicx32/technic_lv_solar_array_bottom.png create mode 100644 technic/textures/technicx32/technic_lv_solar_array_side.png create mode 100644 technic/textures/technicx32/technic_lv_solar_array_top.png create mode 100644 technic/textures/technicx32/technic_lv_transformer.png create mode 100644 technic/textures/technicx32/technic_mv_solar_array_bottom.png create mode 100644 technic/textures/technicx32/technic_mv_solar_array_side.png create mode 100644 technic/textures/technicx32/technic_mv_solar_array_top.png diff --git a/technic/alloy_furnaces_commons.lua b/technic/alloy_furnaces_commons.lua index 559d002..9c9c42a 100644 --- a/technic/alloy_furnaces_commons.lua +++ b/technic/alloy_furnaces_commons.lua @@ -36,4 +36,4 @@ register_alloy_recipe ("default:steel_ingot",3, "technic:chromium_ingot",1, "tec 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:sand",2, "technic:coal_dust",2, "technic:silicon_wafer",1) -register_alloy_recipe ("technic:silicon_wafer",1, "technic:mithril_dust",1, "technic:doped_silicon_wafer",1) +register_alloy_recipe ("technic:silicon_wafer",1, "technic:gold_dust",1, "technic:doped_silicon_wafer",1) diff --git a/technic/battery_box_hv.lua b/technic/battery_box_hv.lua index 05166eb..e565d4c 100644 --- a/technic/battery_box_hv.lua +++ b/technic/battery_box_hv.lua @@ -13,7 +13,7 @@ minetest.register_craft({ output = 'technic:hv_battery_box 1', recipe = { {'technic:mv_battery_box', 'technic:mv_battery_box', 'mv_technic:battery_box'}, - {'technic:mv_battery_box', 'technic:transformer', 'mv_technic:battery_box'}, + {'technic:mv_battery_box', 'technic:hv_transformer', 'mv_technic:battery_box'}, {'', 'technic:hv_cable', ''}, } }) @@ -78,7 +78,7 @@ minetest.register_node("technic:hv_battery_box"..i, { drop="technic:hv_battery_box", on_construct = function(pos) local meta = minetest.env:get_meta(pos) - meta:set_string("infotext", "hv Battery box") + meta:set_string("infotext", "HV Battery box") meta:set_float("technic_hv_power_machine", 1) meta:set_string("formspec", battery_box_formspec) local inv = meta:get_inventory() @@ -342,7 +342,7 @@ end function check_HV_node_subp (PR_nodes,RE_nodes,HV_nodes,pos1) meta = minetest.env:get_meta(pos1) -if meta:get_float("HV_cablelike")==1 then new_node_added=add_new_HVcable_node(HV_nodes,pos1) end +if meta:get_float("hv_cablelike")==1 then new_node_added=add_new_HVcable_node(HV_nodes,pos1) end for i in ipairs(HV_machines) do if minetest.env:get_node(pos1).name == HV_machines[i].machine_name then if HV_machines[i].machine_type == "PR" then diff --git a/technic/init.lua b/technic/init.lua index eabf48e..3cc73be 100644 --- a/technic/init.lua +++ b/technic/init.lua @@ -20,6 +20,7 @@ dofile(modpath.."/battery_box.lua") dofile(modpath.."/alloy_furnaces_commons.lua") dofile(modpath.."/alloy_furnace.lua") dofile(modpath.."/solar_panel.lua") +dofile(modpath.."/solar_array_lv.lua") dofile(modpath.."/geothermal.lua") dofile(modpath.."/water_mill.lua") dofile(modpath.."/electric_furnace.lua") @@ -34,7 +35,7 @@ dofile(modpath.."/cnc_nodes.lua") --MV machines dofile(modpath.."/wires_mv.lua") dofile(modpath.."/battery_box_mv.lua") -dofile(modpath.."/solar_panel_mv.lua") +dofile(modpath.."/solar_array_mv.lua") dofile(modpath.."/electric_furnace_mv.lua") dofile(modpath.."/alloy_furnace_mv.lua") dofile(modpath.."/forcefield.lua") @@ -42,6 +43,7 @@ dofile(modpath.."/forcefield.lua") --HV machines dofile(modpath.."/wires_hv.lua") dofile(modpath.."/battery_box_hv.lua") +dofile(modpath.."/solar_array_hv.lua") --Tools if technic.config:getBool("enable_mining_drill") then dofile(modpath.."/mining_drill.lua") end diff --git a/technic/items.lua b/technic/items.lua index 7d18570..66c5c85 100644 --- a/technic/items.lua +++ b/technic/items.lua @@ -160,6 +160,21 @@ minetest.register_craft({ } }) +minetest.register_craftitem( "technic:lv_transformer", { + description = "Low Voltage Transformer", + inventory_image = "technic_lv_transformer.png", + on_place_on_ground = minetest.craftitem_place_item, +}) + +minetest.register_craft({ + output = 'technic:lv_transformer', + recipe = { + {'default:iron_lump', 'default:iron_lump', 'default:iron_lump'}, + {'technic:copper_coil', 'default:iron_lump', 'technic:copper_coil'}, + {'default:iron_lump', 'default:iron_lump', 'default:iron_lump'}, + } +}) + minetest.register_craftitem( "technic:mv_transformer", { description = "Medium Voltage Transformer", inventory_image = "technic_mv_transformer.png", @@ -175,6 +190,21 @@ minetest.register_craft({ } }) +minetest.register_craftitem( "technic:hv_transformer", { + description = "High Voltage Transformer", + inventory_image = "technic_hv_transformer.png", + on_place_on_ground = minetest.craftitem_place_item, +}) + +minetest.register_craft({ + output = 'technic:hv_transformer', + recipe = { + {'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot'}, + {'technic:copper_coil', 'technic:stainless_steel_ingot', 'technic:copper_coil'}, + {'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot'}, + } +}) + minetest.register_craftitem( "technic:control_logic_unit", { description = "Control Logic Unit", inventory_image = "technic_control_logic_unit.png", diff --git a/technic/solar_array_hv.lua b/technic/solar_array_hv.lua new file mode 100644 index 0000000..89f5d1b --- /dev/null +++ b/technic/solar_array_hv.lua @@ -0,0 +1,93 @@ +-- The high voltage solar array is an assembly of medium voltage arrays. +-- The assembly can deliver high voltage levels and is a 20% less efficient +-- compared to 5 individual medium voltage arrays due to losses in the transformer. +-- However high voltage is supplied. +-- Solar arrays are not able to store large amounts of energy. +minetest.register_node("technic:solar_array_hv", { + tiles = {"technic_hv_solar_array_top.png", "technic_hv_solar_array_bottom.png", "technic_hv_solar_array_side.png", + "technic_hv_solar_array_side.png", "technic_hv_solar_array_side.png", "technic_hv_solar_array_side.png"}, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), + description="HV Solar Array", + active = false, + technic_hv_power_machine=1, + internal_EU_buffer=0; + internal_EU_buffer_size=3000; + drawtype = "nodebox", + paramtype = "light", + is_ground_content = true, + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_float("technic_hv_power_machine", 1) + meta:set_float("internal_EU_buffer", 0) + meta:set_float("internal_EU_buffer_size", 3000) + + meta:set_string("infotext", "HV Solar Array") + meta:set_float("active", false) + end, +}) + +minetest.register_craft({ + output = 'technic:solar_array_hv 1', + recipe = { + {'technic:solar_array_mv', 'technic:solar_array_mv','technic:solar_array_mv'}, + {'technic:solar_array_mv', 'technic:hv_transformer','technic:solar_array_mv'}, + {'', 'technic:hv_cable',''}, + + } +}) + +minetest.register_abm( + {nodenames = {"technic:solar_array_hv"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + -- The action here is to make the solar array produce power + -- Power is dependent on the light level and the height above ground + -- 130m and above is optimal as it would be above cloud level. + -- Height gives 1/4 of the effect, light 3/4. Max. effect is 2880EU for the array. + -- There are many ways to cheat by using other light sources like lamps. + -- As there is no way to determine if light is sunlight that is just a shame. + -- To take care of some of it solar panels do not work outside daylight hours or if + -- built below -10m + local pos1={} + 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. + 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) + + else + meta:set_string("infotext", "Solar Array is inactive"); + meta:set_float("active",0) + end + end, +}) + +register_HV_machine ("technic:solar_array_hv","PR") diff --git a/technic/solar_array_lv.lua b/technic/solar_array_lv.lua new file mode 100644 index 0000000..f657814 --- /dev/null +++ b/technic/solar_array_lv.lua @@ -0,0 +1,94 @@ +-- The solar array is an assembly of panels into a powerful array +-- The assembly can deliver more energy than the individual panel because +-- of the transformer unit which converts the panel output variations into +-- a stable supply. +-- Solar arrays are not able to store large amounts of energy. +-- The LV arrays are used to make medium voltage arrays. +minetest.register_node("technic:solar_array_lv", { + tiles = {"technic_lv_solar_array_top.png", "technic_lv_solar_array_bottom.png", "technic_lv_solar_array_side.png", + "technic_lv_solar_array_side.png", "technic_lv_solar_array_side.png", "technic_lv_solar_array_side.png"}, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), + description="LV Solar Array", + active = false, + technic_power_machine=1, + internal_EU_buffer=0; + internal_EU_buffer_size=1000; + drawtype = "nodebox", + paramtype = "light", + is_ground_content = true, + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_float("technic_power_machine", 1) + meta:set_float("internal_EU_buffer", 0) + meta:set_float("internal_EU_buffer_size", 1000) + + meta:set_string("infotext", "LV Solar Array") + meta:set_float("active", false) + end, +}) + +minetest.register_craft({ + output = 'technic:solar_array_lv 1', + recipe = { + {'technic:solar_panel', 'technic:solar_panel', 'technic:solar_panel'}, + {'technic:solar_panel', 'technic:lv_transformer', 'technic:solar_panel'}, + {'default:steel_ingot', 'technic:lv_cable', 'default:steel_ingot'}, + + } +}) + +minetest.register_abm( + {nodenames = {"technic:solar_array_lv"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + -- The action here is to make the solar array produce power + -- Power is dependent on the light level and the height above ground + -- 130m and above is optimal as it would be above cloud level. + -- Height gives 1/4 of the effect, light 3/4. Max. effect is 160EU for the array. + -- There are many ways to cheat by using other light sources like lamps. + -- As there is no way to determine if light is sunlight that is just a shame. + -- To take care of some of it solar arrays do not work outside daylight hours or if + -- built below -10m + local pos1={} + 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. + 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) + + else + meta:set_string("infotext", "Solar Array is inactive"); + meta:set_float("active",0) + end + end, +}) + +register_LV_machine ("technic:solar_array_lv","PR") diff --git a/technic/solar_array_mv.lua b/technic/solar_array_mv.lua new file mode 100644 index 0000000..73fe85a --- /dev/null +++ b/technic/solar_array_mv.lua @@ -0,0 +1,94 @@ +-- The medium voltage solar array is an assembly of low voltage arrays. +-- The assembly can deliver medium voltage levels and is a 10% less efficient +-- compared to 5 individual low voltage arrays due to losses in the transformer. +-- However medium voltage is supplied. +-- Solar arrays are not able to store large amounts of energy. +-- The MV arrays are used to make high voltage arrays. +minetest.register_node("technic:solar_array_mv", { + tiles = {"technic_mv_solar_array_top.png", "technic_mv_solar_array_bottom.png", "technic_mv_solar_array_side.png", + "technic_mv_solar_array_side.png", "technic_mv_solar_array_side.png", "technic_mv_solar_array_side.png"}, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), + description="MV Solar Array", + active = false, + technic_mv_power_machine=1, + internal_EU_buffer=0; + internal_EU_buffer_size=1000; + drawtype = "nodebox", + paramtype = "light", + is_ground_content = true, + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_float("technic_mv_power_machine", 1) + meta:set_float("internal_EU_buffer", 0) + meta:set_float("internal_EU_buffer_size", 1000) + + meta:set_string("infotext", "MV Solar Array") + meta:set_float("active", false) + end, +}) + +minetest.register_craft({ + output = 'technic:solar_array_mv 1', + recipe = { + {'technic:solar_array_lv', 'technic:solar_array_lv','technic:solar_array_lv'}, + {'technic:solar_array_lv', 'technic:mv_transformer','technic:solar_array_lv'}, + {'', 'technic:mv_cable',''}, + + } +}) + +minetest.register_abm( + {nodenames = {"technic:solar_array_mv"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + -- The action here is to make the solar array produce power + -- Power is dependent on the light level and the height above ground + -- 130m and above is optimal as it would be above cloud level. + -- Height gives 1/4 of the effect, light 3/4. Max. effect is 720EU for the array. + -- There are many ways to cheat by using other light sources like lamps. + -- As there is no way to determine if light is sunlight that is just a shame. + -- To take care of some of it solar panels do not work outside daylight hours or if + -- built below -10m + local pos1={} + 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. + 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) + + else + meta:set_string("infotext", "Solar Array is inactive"); + meta:set_float("active",0) + end + end, +}) + +register_MV_machine ("technic:solar_array_mv","PR") diff --git a/technic/solar_panel.lua b/technic/solar_panel.lua index 93f2b63..5b53f5f 100644 --- a/technic/solar_panel.lua +++ b/technic/solar_panel.lua @@ -1,3 +1,6 @@ +-- Solar panels are the building blocks of LV solar arrays +-- They can however also be used separately but with reduced efficiency due to the missing transformer. +-- Individual panels are 20% less efficient than when the panels are combined into full arrays. minetest.register_node("technic:solar_panel", { tiles = {"technic_solar_panel_top.png", "technic_solar_panel_bottom.png", "technic_solar_panel_side.png", "technic_solar_panel_side.png", "technic_solar_panel_side.png", "technic_solar_panel_side.png"}, @@ -7,7 +10,7 @@ minetest.register_node("technic:solar_panel", { active = false, technic_power_machine=1, internal_EU_buffer=0; - internal_EU_buffer_size=1000; + internal_EU_buffer_size=160; drawtype = "nodebox", paramtype = "light", is_ground_content = true, @@ -23,7 +26,7 @@ minetest.register_node("technic:solar_panel", { local meta = minetest.env:get_meta(pos) meta:set_float("technic_power_machine", 1) meta:set_float("internal_EU_buffer", 0) - meta:set_float("internal_EU_buffer_size", 1000) + meta:set_float("internal_EU_buffer_size", 160) meta:set_string("infotext", "Solar Panel") meta:set_float("active", false) @@ -34,7 +37,7 @@ minetest.register_craft({ output = 'technic:solar_panel 1', recipe = { {'technic:doped_silicon_wafer', 'technic:doped_silicon_wafer','technic:doped_silicon_wafer'}, - {'technic:doped_silicon_wafer', 'moreores:copper_ingot','technic:doped_silicon_wafer'}, + {'technic:doped_silicon_wafer', 'technic:lv_cable', 'technic:doped_silicon_wafer'}, {'technic:doped_silicon_wafer', 'technic:doped_silicon_wafer','technic:doped_silicon_wafer'}, } @@ -42,29 +45,39 @@ minetest.register_craft({ minetest.register_abm( {nodenames = {"technic:solar_panel"}, - interval = 1, - chance = 1, + interval = 1, + chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - + -- The action here is to make the solar panel prodice power + -- Power is dependent on the light level and the height above ground + -- 130m and above is optimal as it would be above cloud level. + -- Height gives 1/4 of the effect, light 3/4. Max. effect is 26EU. + -- There are many ways to cheat by using other light sources like lamps. + -- As there is no way to determine if light is sunlight that is just a shame. + -- To take care of some of it solar panels do not work outside daylight hours or if + -- built below -10m local pos1={} 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 - if light >= 12 then - meta:set_string("infotext", "Solar Panel is active ") - meta:set_float("active",1) + -- turn on panel only during day time and if sufficient light + -- I know this is counter intuitive when cheating by using other light sources underground. + if light >= 12 and time_of_day>=0.24 and time_of_day<=0.76 and pos.y > -10 then local 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=40+(pos1.y/250*40) -- make solar energy depending on height + local charge_to_give=math.floor(light*(light*0.0867+pos1.y/130*0.4333)) if charge_to_give<0 then charge_to_give=0 end - if charge_to_give>160 then charge_to_give=160 end + if charge_to_give>26 then charge_to_give=26 end if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then - charge_to_give=internal_EU_buffer_size-internal_EU_buffer + charge_to_give=internal_EU_buffer_size-internal_EU_buffer end + meta:set_string("infotext", "Solar Panel 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) diff --git a/technic/textures/technic_hv_solar_array_bottom.png b/technic/textures/technic_hv_solar_array_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..596e79a37334030ce3ebe9790a26adeff94da6c9 GIT binary patch literal 574 zcmV-E0>S->P)pHNyHksIQMtuDhB45Ws)U! zRMZY;baV&z(!uXr>zS;rm?cCftj$1}Gq_5@j{_kP zlvu&n=Rs8hPs-=3!2)+d4GvF4Ob})E!3?P1jaCQWPeoA5nNYWr=LzyrKsWvAh(Mo$ zCuc?AZYTqEff_kyW^@F_`)F(ifrBWLjJ+1KcfuUqfghPUI&MO(4?7on-xv)&uM4;T zr6im4aC)mGhr@-G6Uw5L!rt(Dy>S(CQp^=yYcpfx3b9~efX-}9L97Pa7;aAnwKQrrvD>%ZDCC41f$3P-O;!easVhQBPC$MLCXZokQ37qhb z@ICqc*N+Q{`0SV%$Lk`#|CyiOec+#e|HMM#?b~R*aXh*25p-uSicjbHI58C`nDKa4gn(ti zU5L>*Ukz4cEoUvLZP3TywE`t)$`(-z8|UfdR6rN)Y?w}tZwE0aV!lypCz&vpl9G{g zW_UwTto6#G;~0n{F)(})G|*c^ms7T#(Hj;5S8LyW+9FWVZQrqAOn0Izwq&$=5e)iNg$VvF#}5iJ{Qkd=ejDnY+TpLaELK8hN6$- zKsDgrA;9oSj5}L4l0||l_uW|T9FK2IABZgGyogCrWMQh*F7yU#bguK@Y8{bDt(`U# zgn%sJe!tU)V`)bKeY5XKP%H?l6A8*zA{GN*j{|U^F={2{NUIk)25LPC5lmGOZ-fvL z9WWOiVGL(41xpFR*>a!{WejJ{!Br=FDd?C=8-fN%7I7aS%4nV8aJ?$^>Rh!G)DaQZ zGJ-5n&|Xj8?1l)mAz1vr)GVNM&Lj9p00080Nkl^Q-~ zm%Y8O-Pzrlc`10hhd%%QDKaK0ZmtdfdVTo(=NGmVJc@i-P$qzrr(fMpA}u+TR%%Uw zQJ{pXM!0`;;$3A6s#Y#X*N03+;pQ!obkQMDBrLeLxvo_Nai`Tu5?>XqxCw+q5Flce zendoH8gH#ba%VU!Yj=8lY$^lBkD;x5M1hu_7dfSH{*tqdk62( zxiAzaFL*Y|89-T>-+%j+31!Y+BMW7xTV0$prK@o|&$ZUddPETD=d|iY^zEyK(N-`M^!okN_4*$EO)OyzH@Z+3;pif zZ#WQ2JTO?4_`}OL5QMCm6en->>Uy1?Kl^$s&vTC;1@X@Dq#Xr9BC=vWhbp&=xojjL zB;|q-!sB+DPFAnZ z#(I3SzaxZV5AWUH`h0ltG0lqwdVIOFXU^WcSyr4JpmXC_e|#DT+uIMO<9|iaAim;B z6zuLDP(TgB(8`+;I^yyXAwGY*OK~1Y*LVNk@mOi)%ZmO7K`mtTbXr9g00000NkvXX Hu0mjfxUgI& literal 0 HcmV?d00001 diff --git a/technic/textures/technic_hv_transformer.png b/technic/textures/technic_hv_transformer.png new file mode 100644 index 0000000000000000000000000000000000000000..e1d4c98a05365c406a77d2bdaf9c662a8853325f GIT binary patch literal 1801 zcmV+k2ln`hP)geXWCAMNed+v1xskD#6V(B*c zX$r<-Pz1uV-V1w5vZb6r0CQseb9N_nYqt%&fd!pgVi(* zT(FXu`2TdW_J{xPthM&qd&B?LhJLVd69BiZU;pkJKm72+0NlD|+uXIg?qB`yYj@xE zle6L>X9^Au4zgy=8a8g-Hc;%Ix$E_~d}S0EY;B5G81623_t96MeEPyIcWxZ{uK?V- zY4azd&hD*2u{6)yK#li8{UlLyl16QUg|o^;p>3Y1>A}f~^z&=h+<5S;0c_f|>C4gV zz8^Qkyk;hlVpgX$HA=oZOmA12Mzu;5gd87vomuDfYh;U3oit;i=9gac)zz=QT>x`> zKviv$IWmt}6$GI~N~_kOR!vAV2y-z#-Ms`!EW>{}MBYwz6^f&WcJCN``u5w_Ukz~Q z`gQLNAd2(U!Wgmy>QjK_$Y_o7?1j{_fK)A&N(G>IsnB>Ie1AXD% z8*aII>(|z;mv>Zx4Lf#y*u=S?TM?|a_)M8nLB>zgqb+8HV3Rt>kG?`_c1%$0rL)|J zG@CTs6ensK(ZHotUO%a0&H9Ef&AslX#aB!F0N=ZFdv`G}qdCoZ?ZET&&Y6$vJC`vN z&~jLi!bF^-+Uf@M)<=Yn{<|XsFxSu zx-Wu`S@^7pkF11Ai*lhTGb8)hj{T23xA~_JeBgAy;Pk+yOP9&LgO8E-p0w4XRE#-s zXpoUT3+ew?DTJ$0RV-mQb)NbYczRi&%Mm*pTjk)R&l6W;n{6_ z8L1w}`a0p^D#7r@xOsI{V^RmPRRSROj=CDGI*cmDdkzdAz5jGCdnSOD%P;)8@xCh# z1B}4LM1^1c`YGnyG9UTIS9nj)Oy0lfea!4FasNGkX7Q3TaTpUc>Lh{1sp6-H3aSuf zDdHU@t-)VDvcLA08E7;b2Rp)GK%F8I&`~N-YSsDeGf(m2?+>u(vSswn?Wd!EiVM#9 z8&7RNOvgYUSA1*mNZR?B%rseL}-;{ z=uaFTK0st*mM?0uV8;1W{4mn=XbDsm<1%m=VuMpXQ7V<>Ew>>+XGcMtbE-N$DU2~R zBBg3lh=rCm$j1;QdAh^d%<4KwEH4we1jI}Os3#C`C|;rN8Ct!1_3^dzU7#YzjS z87dLtEmi|Wg+de|B$y}y8xc8~-a8T?&SAYnnKlM+B4pa;VFd8rCCgr_d5bef1y4u{ z2oA8JrIoaBJ_QXB^#p1Wny7#`hRlXIV+mY_S5U7+LC`+H_1_(w$aVI7vStdBh{0%z z2#A1p9_Jk{b2OVx!YDd*q9j3t2T~i5+7NFHieS`Ztqs}+xaGPp^6gDKADO#w@th<- z>)DzqfH8{x>jbmb5(FXMx#{e@@rPavajT9|k9bE0WMUXo^Jx13Ke`Km@sX3qZ`yL- z^0CCO@K_H9?>z>=3Wz!cMT}s)Lrj3EqN=EKWC~H1kV_g!(yF%&@K4=%$ByZ1`R@Hs z{Qb(oXhLV)ooEM04kxOi6|4!Ej0(*A(8sAnWl&Ee$dN=b=^K53FUnONA_(LXdaR9(Av z?SBSvCT+fF&+aK3T^m?Yyq8ElPDHaX5}g=-=(+LwHJ2pg&2{V6y}c5&qlflA$n{_N z?5e7j#S>0PaT#O@so2&;wRY{g)vG@BL8+h7{H*GZ?{5I$_C5Q5xZ%DBp1fi2qh)~Y r+qb`aPq}^j_MQ6PxpU|L#>4j?u}lFySv`Eh00000NkvXXu0mjfYgKPd literal 0 HcmV?d00001 diff --git a/technic/textures/technic_lv_solar_array_bottom.png b/technic/textures/technic_lv_solar_array_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..9e888e3011a8b619589b83266fa39877c56a9060 GIT binary patch literal 579 zcmV-J0=)f+P)< z02C1Ctpor7010qNS#tmY4yynF4yyr0}+8D022`y=qgePf{+lx7$K^g6m&H!B#>BZ zG0Tl@V%;G?AwofQZN%Ioh0AXj3>@dd^?K#gr!VA6s*3I&>ev{Q z5ddJQZa)0?al{qe-QDs2{l9$v{D9kdBXT$KWKFxL5W&kAFS)}+wBMLJuqY2-6LYG z1w3&J9v;5&_T4}H@$658>2AJXzf*N01}#ip7SaSpA~J~xzCGNqo3CH4qfa#mF27$m zk7KfM)(o&`LuQUOHX*Ra6(MpZ3T^w0GzoQiY=q%keR6t=3emOW3n*eQDcFIdJyB+( z=q}tQS3-++@1GgCimJlhv^^r@9c7z7PugR0*N!ew)kyQ5>paO!=%&u;`3dcoQh5(C RaP|NI002ovPDHLkV1mM@_{RVM literal 0 HcmV?d00001 diff --git a/technic/textures/technic_lv_solar_array_side.png b/technic/textures/technic_lv_solar_array_side.png new file mode 100644 index 0000000000000000000000000000000000000000..b22447ef68825d1731660a1c1b3c6c5af543bb5b GIT binary patch literal 465 zcmV;?0WSWDP)qLpk;0OPzs>xVu$@?{3L>$KR z4R{Ye(=>mHJzhzWiNVLYc#Eu#*g*g?oOP|FC-FzQLf|=ii1RJdynM?-8A_-N_aKdF zAqN7e-Svw&!-xo4e}0#jgL|A?-;?oBHcoej$6d4dtILs$D9;2iAlk23m%CTc5^$#k zz!|8Iw}wFpR6NZ>fhw--7FtS(Bl^IJns}NVq**))r~h~bbf&2) zG*Y*A7+?Me)P)StFOlm<`38f50YOv5D~SrI8Re;?6H~Vc7_(#c#X3mnhddK4BhLtt z(ShqgdBGWsB&N|?WD(d9q%&ihBodZq5QI+MBzEWqe@x>K{&dISA4~-800000NkvXX Hu0mjfYM9WK literal 0 HcmV?d00001 diff --git a/technic/textures/technic_lv_solar_array_top.png b/technic/textures/technic_lv_solar_array_top.png new file mode 100644 index 0000000000000000000000000000000000000000..cabd315d2f1fa54e79e918533b63d835c57e19fe GIT binary patch literal 743 zcmV?P)nkkrqXQe?dcj0F)7Qh=L{!H8mB81}R9S0Ye}~AO?eN0ugKP zuDyHTGsE}cCm-H1=K{3rTbtj0fBf-h_uHl8l%)b`5{~r!_qGOE95B^g5XVRk2?3)d zef-B?>@M1sne7<7ZkmyQ4gJW(2n}4gbNyNzWz^4y`Cy<;Iqdfc7$5;qDdzwVpfC|J zxVg7iw{moNSTz+@RZ-W=MJYSGd!{Y-UO|5i+!oLn$phs{6g+xzY$9putD@xjqHsiY zS$*~8edIpE&mcL_81$G^Pw{VOi%A@potlw1U1B_bqdiXmQtJu|L|ZZKA@6|vNIV8? z4KPUFZdUhv1^_FT3eg3oJ@iP-QccZ5Fb6O)*wW@tQ>nY5wnJ$Ku6Uob|1}ZFXStk`@nKvKFkp_-2w{_0c$gAt`1R z(kY`MN1Jjqo(Jy!J zyjm268U-Fyga@N6^nsZxmrH62vpG_R%)}_IQqVs;TWnli6X~|MCr3vI?7*q$#o{b~ zemtGelYFAhEs9UN&XC^9FWV^p+O+D_eto>}eMGax{KoFK55w7f8U}2*-!`8Mekb;W z$~V)Kd#9(%-O0_6DNg%@!hlAT002ovPDHLkV1kpSOBw(G literal 0 HcmV?d00001 diff --git a/technic/textures/technic_lv_transformer.png b/technic/textures/technic_lv_transformer.png new file mode 100644 index 0000000000000000000000000000000000000000..613b1962059f74b5fb04ffb0f857776724557560 GIT binary patch literal 1821 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 KMNUMnLSTZ1erHqw literal 0 HcmV?d00001 diff --git a/technic/textures/technicx32/technic_hv_solar_array_bottom.png b/technic/textures/technicx32/technic_hv_solar_array_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..94c82220d17121439939c1b88985aea891b76a69 GIT binary patch literal 2019 zcmV<92ORi`P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01m4F01m4Gj_kzz00007bV*G`2iyw* z7cUx+Q&eIA00(19L_t(o!*!QU%Ph%pg`bGXtm^LfevCfA#@1+~h5Q2y($)whfw9ql zHMT+4QcLR(*b-s}WEgqi`rf(k+g+6z5ne=f&q&4vwd(53$P*{dIVnH>#V?XfG7~Zp zRWcF;tTj}Xh(JW}IcdEg-$H~Vs*sQ*0)XH?QMLMS1|&d&2r-@GL;8B6WdvqMijd)` z7?=Qwh$5n>Dd|pMRuF**BAok5qKahT5iIM9hM{UiOuDX&eZ#Di5l9m<18be|Ndw4C zL zR>&x-ikKk?+6>8p$;=+@X_uA#cBAkC6@g6DjEF#0!3?CD5{SZWF{HOdOmS=N3uxNmIZgGuP5dh4-#7Mh$_}vaRQJjRk#`2JL7sq zLXB7(lIWCUtP>zz3UYK7b#=8QzNHWR&**O>c$@Jqht z&b=sA8bYx8w?8v+65gy%j1RhzfJtYiw1q0v~OSwv=W> zBr6wuPQsntuY^xBf))|Ud6ZCxORId)!s@|LIbfr`Ltjp@$5@5KjE zM3QYExI5d+OHG0qbL?1e*zC9u09u3-QLvGa83)vXSSuw{>Xd#c=F@5Apa1Pw%-gNlAHmpnNEq8*h)RQ&G_!`PG3Uh0;1HD*VUB@WE9OS< zAD?~B>3rtH^~yGO-hcRtS5Hs$-r2{bsjzPwPvyW>%0GM5 z8hu$25yqIfJ3dAcy0rtOK+Le-5VMkEReQLdSu2wfK~)*sc61%ir}YtTlK)%8vaZZI z@d*4*xNu~GHO1%rx?52m(nRElVI@F5Cv90C(aXmqMfl>~|L}(|zTnNbzr}a{`g{@dSAP{ylHrzU9^B!uyXOQGx&Z?>|;xQKj|HcDt4Mgdd`ogjYe$ zS|i-)r2g7|$TP=IZ@r3eFEu-e zWJka-?Ikw*PG1&que>-Xa||M)Hjg-3plC!8N6hvkDvf=hs$4&QUFvL^11~zOJ;TAMviEK4(SbBW%QU0QTFB{dzrQ8TQ+i z?RG=7E*Fu9#ZoRew(UW%drXTcLu>2G9cdr+ZAR3@)i?_(f*i7}+8z4J~Re!HRF>S`7OIM}kFt+72n*Y&9{%tK1= zYB_xz_r!sqjEIB%{h^?Rz=DshVp!|=9ApI6`=j`}nu(M*n-vlVTYZj)LW(N;UZW;j z^DJ5r=FCHsDp6IzuwQTZ9LLBFVhqHr((;_Rm(@2B!48ItD7!nEQR($|D@T(?h7cJj z4Uw{D_b5aX9GGK2+G2RzmGm&7C}XPm4_aUDc|h>+GMGau(;aJ#zAT97!#M7*&%xL> zeAK1G-Rm9!$K^FiPh!@l`i(;7zLOcuvD13ve*tr#O^<7`YHR=i002ovPDHLkV1i5_ B;l2O> literal 0 HcmV?d00001 diff --git a/technic/textures/technicx32/technic_hv_solar_array_side.png b/technic/textures/technicx32/technic_hv_solar_array_side.png new file mode 100644 index 0000000000000000000000000000000000000000..d39d3d81e462c2f4dfca86ec7563893195bca47b GIT binary patch literal 1772 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01m4F01m4Gj_kzz00007bV*G`2iyw* z7cVlU=KPod00wMHL_t(o!&R4CcH}q?L@z*)O1r!FGrO4C|2nGdlt=*c0ZOj+kMrn3 z5rIHNQ2z7Z|0S7ZCS)S2^;@7dLsf|k1i^h_*6ThH?uaS?nTZI1;A^3+)w>bw2S9{y z=l<)j7nTvU)<_XD9MuLQkcp}yswhf^W8*+XAfgr$0Ra(3GH?&ZYt+YEBYe^AV9t|f zos2+4$Ou~R#9G+T?gi0$v6+#XWCYq;A!CNSle?nl8K?px7$1Xhr@sanPKKgQIP3#o z3q+B~U2FhZ8xYm1wlzcqZH)wkMEB0gz>b6K{f!`np%k>*jEF#6wWHQBY7wDX+XW@k z1W{pK6TcRw`=h8JBG?!|(6>g+$%-H|QNXOz%<#3yOqw-X9|fx!^Sb`UB~hiBA==1r z=5-OPTBxmI_rui!*)7;R&SZRi;J<$%`Ln@-`M~FVNZ5KuL}+HH2uMAjnNM5i`;CgS z{GyrB%rK^=< zGim!d1L*yLOniBDeop|v`1~X@33qZ6)_Sj(duLr&ZEjZ??zCRKiA=`lCq!_5eW9&! zeSeb?WNWPR#A;R-nM$)_rmM*aaGTMOqn=e|T^A3TH}qnL_5P6W`1~y1xO0Ag z6KmCIM+CheXwwp&-J2W6H5Yvh)><^PpAn1z5v+I2jI|cld-WdBR%3d8e?2XT2y}03 z%?St^?px7n^lIdi*wy78zmI?Z*(B>oYqZ|!$3b|Yz0=2dM(;-N{rgvmU_?y^u&#^9 zd<3JGBT4mqenAeGo<1wvL&DUe$8G$=w)KqCklu7Je`|`&& zZ4CMth$^qY|0>9j18Mq`1EdPb2qJ<$27UC0oT|EKK3KCvOAy-VkXdGQ%PCn-)_Ui; zu3C$4^TM zqnEM)K8pj8kNJfA&;Q*95y3M__bONgU28s2kJrZ|JnOoC@*EJp9^KCj)_Icdynp{@ zty#hn`Pj1TiL&1DHCfvSZs+t>Vx+AZ83k{wS!y+BLAP1E=B!NT@d(rI7$D5|oAdi? zyQpBt@vrLdcGhGG@RK(!NmRGFm?08R(7d^E_x{O=R+}z?D)!$}YrSK~QAntAeSf27 zL^x|+%=eqTgKZ|JqR$A5DovH~@qxC+`20jwA4R-ncfQ~F?T#Yl8G9_(oVYu$zy1as zX^otdwNbqTX{>6g-9!o?*2F$OnRD{$o%gR_d-QgUc7M_kf1C~OEU?b=2`lIK7tI_je^?5n|Ol>ko^a=UMme1C9vk)xLfl zs3?+!&^*trz6-mfv+N*I>2~Z7C-3jCa<60)Q;^om2i8L7e8TC!LhBgBj$(Ekv@!7a zH|)uXsFZ9stIGxNXni6nq|}V32i8Z~Dv)zNNSTfjpWWYip4b>%?>D-G==t@v4^hJF z^Alh5i2#-n#6D-(7^oTV-@hT^M{cv^Gcw6JtB-RcD$F>GkiFNnJ$^O@>pYp)weMBi ztap5GzK&*p9LX{hpBL=ezZH@#$rU05tinrp5LCE~C6z075Xtwuev1@hb5`r3T6Zg~ zi3m+=G10}fy*t9W-tQ+wq*Ul=X2ecNL=aakeB{I#P0@SRy7VJor# O0000DK_@!=j)P0@X{Mf>g@q&D<-cWA6%WZ2EA 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 FV1k4YPv!ss literal 0 HcmV?d00001 diff --git a/technic/textures/technicx32/technic_hv_transformer.png b/technic/textures/technicx32/technic_hv_transformer.png new file mode 100644 index 0000000000000000000000000000000000000000..7794644fba52b375b9c2fea8f04dc1a3dccb3d2a GIT binary patch literal 1789 zcmV z)P~4y#U>{HpLX_s`2Vuk+Iy`9|5qJ)YV}$GR`&J1zs9?F?*`!Ub?Z8wTD^A3Kc8*e zviZ7r$kjIc`}^tb?d6->f6;XlwI3$d&W|vRqbP^b)`qOM;8(}qx^3^H4-NlU0Qy$< ze@0r{*XQ#2X`Zt#m)1n8=ShuWG>Mr#xk%^{pC5NeOPA9x_4Yn|^tu78S-b9Qs$=@I z$~lKajPIjH28qT8ncUJ$wOl6fe1?Y4(>9~i1-c;RlDg=-{M>~PEcwg31yJwYh`m7T z${2|iiE~91kVQo$4f#P{PS`0y3`yMMviZNrvK$9R`%To@cq7J z?+u{I6Ji~JNpY1j$~uP6jnLfIMLF|Gon~}&6q{DadkLMLQxHkz%-}Ipa&BH{M}9}| zV=LBweOaHpw-Bt~aF;~ki=q@olR{!R??>3uMOsK{@MPBqjYY_RZGLGK0ou3<=yv5{Q#@itZnfdawB<{GI;19Q#x+MwN2-;2!#u0 z@heq^2T#&H`(~IB5C193Wau@wN3|4DkCG-SNfg@@Bi{I>k2_3 zP{_bxPVU=Ia{3LrS_4XlU!*M=Ln4KH^E5Yq_;$|TFr7X7g~NY}Y0EcJX`F?b{6Qi= zB6TTR8Npcm=2poyHooxe^SfVL_59wCTod5-xjpjN6DM%ilGb91g^+WnPcr)JmyonX zI)4_!d-ro-_fhWrL^pFjIg93L-6TyNgrSn~w^R=tMn2TSoS?)X_WcpTFeWv`StOi<@&f>pFapoR zWhsdTn@?GSIDd-5k(>jH++6#_Pu}^MfrfbMJ%G2(@CIDsj%k&&Dy%qD_VcoO4K)lF#M*x&W%x z>d^+@>vF~+;?YoyDAp?cZvSsMeCQyz+|fgOM<)%PW8Bhpf)_Rq&@iKokAJ!csd;#w z25a%sgxCwn!hkT1!DiG2kY@G>zI+NST5HlYB@mDH<|4j!Bm=K=a_}I53hBAEM%Sd- zjM_nhN{woy@U0<3VU)&cjb}2n2w|}(*GxiyNez)0W1MpnKZR0?YTziV6hfiqs^mlP zk~}T`6xy1P63Q{OHDq3ZLGWyb336C#u?~_f8(6Yr$xvMY<vp8EN~}v5FTk4VSgB%xOca?YoC9qQxwJ+mO4s!f0SuRu0qY!EYG{|?BtWc2 zI}dR}6a)wfDhNOa1V$#_j(A|-ereXCZHAwvXp@q;I*Sp&2j=t~8MhjvloKpIDIgd? z`#h-dzal(XO38<$@EtBXE2yQy$h^XsZ7A72H)#vg57vwG`uFMVsro<@L;8#lgxqukD&JFl!a fZQAs|G5G!siW~h8)U-(*00000NkvXXu0mjfh`C(- literal 0 HcmV?d00001 diff --git a/technic/textures/technicx32/technic_lv_solar_array_bottom.png b/technic/textures/technicx32/technic_lv_solar_array_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..94c82220d17121439939c1b88985aea891b76a69 GIT binary patch literal 2019 zcmV<92ORi`P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01m4F01m4Gj_kzz00007bV*G`2iyw* z7cUx+Q&eIA00(19L_t(o!*!QU%Ph%pg`bGXtm^LfevCfA#@1+~h5Q2y($)whfw9ql zHMT+4QcLR(*b-s}WEgqi`rf(k+g+6z5ne=f&q&4vwd(53$P*{dIVnH>#V?XfG7~Zp zRWcF;tTj}Xh(JW}IcdEg-$H~Vs*sQ*0)XH?QMLMS1|&d&2r-@GL;8B6WdvqMijd)` z7?=Qwh$5n>Dd|pMRuF**BAok5qKahT5iIM9hM{UiOuDX&eZ#Di5l9m<18be|Ndw4C zL zR>&x-ikKk?+6>8p$;=+@X_uA#cBAkC6@g6DjEF#0!3?CD5{SZWF{HOdOmS=N3uxNmIZgGuP5dh4-#7Mh$_}vaRQJjRk#`2JL7sq zLXB7(lIWCUtP>zz3UYK7b#=8QzNHWR&**O>c$@Jqht z&b=sA8bYx8w?8v+65gy%j1RhzfJtYiw1q0v~OSwv=W> zBr6wuPQsntuY^xBf))|Ud6ZCxORId)!s@|LIbfr`Ltjp@$5@5KjE zM3QYExI5d+OHG0qbL?1e*zC9u09u3-QLvGa83)vXSSuw{>Xd#c=F@5Apa1Pw%-gNlAHmpnNEq8*h)RQ&G_!`PG3Uh0;1HD*VUB@WE9OS< zAD?~B>3rtH^~yGO-hcRtS5Hs$-r2{bsjzPwPvyW>%0GM5 z8hu$25yqIfJ3dAcy0rtOK+Le-5VMkEReQLdSu2wfK~)*sc61%ir}YtTlK)%8vaZZI z@d*4*xNu~GHO1%rx?52m(nRElVI@F5Cv90C(aXmqMfl>~|L}(|zTnNbzr}a{`g{@dSAP{ylHrzU9^B!uyXOQGx&Z?>|;xQKj|HcDt4Mgdd`ogjYe$ zS|i-)r2g7|$TP=IZ@r3eFEu-e zWJka-?Ikw*PG1&que>-Xa||M)Hjg-3plC!8N6hvkDvf=hs$4&QUFvL^11~zOJ;TAMviEK4(SbBW%QU0QTFB{dzrQ8TQ+i z?RG=7E*Fu9#ZoRew(UW%drXTcLu>2G9cdr+ZAR3@)i?_(f*i7}+8z4J~Re!HRF>S`7OIM}kFt+72n*Y&9{%tK1= zYB_xz_r!sqjEIB%{h^?Rz=DshVp!|=9ApI6`=j`}nu(M*n-vlVTYZj)LW(N;UZW;j z^DJ5r=FCHsDp6IzuwQTZ9LLBFVhqHr((;_Rm(@2B!48ItD7!nEQR($|D@T(?h7cJj z4Uw{D_b5aX9GGK2+G2RzmGm&7C}XPm4_aUDc|h>+GMGau(;aJ#zAT97!#M7*&%xL> zeAK1G-Rm9!$K^FiPh!@l`i(;7zLOcuvD13ve*tr#O^<7`YHR=i002ovPDHLkV1i5_ B;l2O> literal 0 HcmV?d00001 diff --git a/technic/textures/technicx32/technic_lv_solar_array_side.png b/technic/textures/technicx32/technic_lv_solar_array_side.png new file mode 100644 index 0000000000000000000000000000000000000000..d39d3d81e462c2f4dfca86ec7563893195bca47b GIT binary patch literal 1772 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01m4F01m4Gj_kzz00007bV*G`2iyw* z7cVlU=KPod00wMHL_t(o!&R4CcH}q?L@z*)O1r!FGrO4C|2nGdlt=*c0ZOj+kMrn3 z5rIHNQ2z7Z|0S7ZCS)S2^;@7dLsf|k1i^h_*6ThH?uaS?nTZI1;A^3+)w>bw2S9{y z=l<)j7nTvU)<_XD9MuLQkcp}yswhf^W8*+XAfgr$0Ra(3GH?&ZYt+YEBYe^AV9t|f zos2+4$Ou~R#9G+T?gi0$v6+#XWCYq;A!CNSle?nl8K?px7$1Xhr@sanPKKgQIP3#o z3q+B~U2FhZ8xYm1wlzcqZH)wkMEB0gz>b6K{f!`np%k>*jEF#6wWHQBY7wDX+XW@k z1W{pK6TcRw`=h8JBG?!|(6>g+$%-H|QNXOz%<#3yOqw-X9|fx!^Sb`UB~hiBA==1r z=5-OPTBxmI_rui!*)7;R&SZRi;J<$%`Ln@-`M~FVNZ5KuL}+HH2uMAjnNM5i`;CgS z{GyrB%rK^=< zGim!d1L*yLOniBDeop|v`1~X@33qZ6)_Sj(duLr&ZEjZ??zCRKiA=`lCq!_5eW9&! zeSeb?WNWPR#A;R-nM$)_rmM*aaGTMOqn=e|T^A3TH}qnL_5P6W`1~y1xO0Ag z6KmCIM+CheXwwp&-J2W6H5Yvh)><^PpAn1z5v+I2jI|cld-WdBR%3d8e?2XT2y}03 z%?St^?px7n^lIdi*wy78zmI?Z*(B>oYqZ|!$3b|Yz0=2dM(;-N{rgvmU_?y^u&#^9 zd<3JGBT4mqenAeGo<1wvL&DUe$8G$=w)KqCklu7Je`|`&& zZ4CMth$^qY|0>9j18Mq`1EdPb2qJ<$27UC0oT|EKK3KCvOAy-VkXdGQ%PCn-)_Ui; zu3C$4^TM zqnEM)K8pj8kNJfA&;Q*95y3M__bONgU28s2kJrZ|JnOoC@*EJp9^KCj)_Icdynp{@ zty#hn`Pj1TiL&1DHCfvSZs+t>Vx+AZ83k{wS!y+BLAP1E=B!NT@d(rI7$D5|oAdi? zyQpBt@vrLdcGhGG@RK(!NmRGFm?08R(7d^E_x{O=R+}z?D)!$}YrSK~QAntAeSf27 zL^x|+%=eqTgKZ|JqR$A5DovH~@qxC+`20jwA4R-ncfQ~F?T#Yl8G9_(oVYu$zy1as zX^otdwNbqTX{>6g-9!o?*2F$OnRD{$o%gR_d-QgUc7M_kf1C~OEU?b=2`lIK7tI_je^?5n|Ol>ko^a=UMme1C9vk)xLfl zs3?+!&^*trz6-mfv+N*I>2~Z7C-3jCa<60)Q;^om2i8L7e8TC!LhBgBj$(Ekv@!7a zH|)uXsFZ9stIGxNXni6nq|}V32i8Z~Dv)zNNSTfjpWWYip4b>%?>D-G==t@v4^hJF z^Alh5i2#-n#6D-(7^oTV-@hT^M{cv^Gcw6JtB-RcD$F>GkiFNnJ$^O@>pYp)weMBi ztap5GzK&*p9LX{hpBL=ezZH@#$rU05tinrp5LCE~C6z075Xtwuev1@hb5`r3T6Zg~ zi3m+=G10}fy*t9W-tQ+wq*Ul=X2ecNL=aakeB{I#P0@SRy7VJor# O0000Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01m4F01m4Gj_kzz00007bV*G`2iyw* z7cdFgw;Lh=017BcL_t(o!#$WucO1!eg})aOnUz(AnE){m%?8H?2~#B7c8|8yYM)~r zYhfMv*bDs#{|f&BFa0;P(aQG1N0x1|2a+PuBpW0+0w_#{p@z(i;dxQ$&Q+d_$h?{H zZoGSM%IE+1PfAJz??DwY22}+CYaPZIk|qQp#(;C#XdFl}BE|rqs)zsxF$9dYqkB{0 zYyyaoV&sP-D+(MbjV7az62{mOpcsrbfFL@0K-OrCfDlqlAOZr$SX2|i2O6y=)>$wH zjfpJF2);&)1qCsJ#)Qo>QV5t30wD%wWr?HB$l>>awf8=v`{E5-kJhO=2fROZgPo^` zbe;}byLgwK^`~^c+n`xD7}qg&zI)E@lkd5E?IX4xy`uAMhxz6La^%^4`kJGc+uU5f z!S>^IwjV#CAV*O^ap>se)srC`k28u!gBRzIdGhcTnH9EQ9wOmmUTlof9>2own|(GO zKg5~|#)?%Aj~?=7^C8F-x9`BllYO#$jH}nqv-#v}-o9H09pmoW39nx6fGRF;Grzh* zj0t0`MMSWspg1>8S#@dTEi`rTzK69L)+uV+^n4d5uf~sB~nt?yQs|2XiU(^W-$5k zkEHVH1d$x$TEGlqn$*=U-Y4qbThJawaRV5VW#cqj^JwTJ;&7QGFA5AI#2Bf4z)407 zFR%hIjxpni7&Hay;Stqwhgf&c@FQ6^M~tT=-v?7*Y)00cC59fV7L&~~=zR?cRe8wC z-nSqYF%FyM80RnmF3%_$Esjp^1X80> zNg?4}L8Cp7#(-)Cv{9`A1r2EOs4BjyFvb{Ch>XunF**BpAhWFAyo1d$8ig=6ImYG7 z7b)_a6wNgj7UyuequpL)e4^me+Aql)IdhkP&4r5#xNMTK$wg+)%`h>u%+&lBG+Han zEi6;CCulTV%wJd`g@C4rODW;<26J;ScyD3D2TII+a#q# zN)_-Hs}7S}W+#{Neuv;|G$srvbyea05KVzbaS>;yL0fi_pOH}1^z@mDD&_JYt zE5;e0TEv(74%Mp-=VGaMXpb?quQo=p_YdjWIcykvEj> zH^=ytAhmh>{1I6;&dCRtINq=6?DnXul74TK=WqXwSfA2f_!QU9iM7WWYf)hH#WQ-L zMcqH*PY=Flr_&*K6Lj|jo972q{UwgN6|Y}!;+h{b@CS5{0yazRpCoKH&(n>^bh~|w zQC_~-psXj@KX^%9?z6L1(%IU@WldghzUJcHt0O@I5Nnv8y-w-}jI_zKL@rYpDG^b8 zJYlcf&sZlzJ4!EHNI_C}!xNyaNg_IaZp8I8qA47)c>wtaWIL#8`n5 zz>rb|TC~P*p(!V58kIud5u+jM0OQ6HEfBTD`Viuf5KF*NmOG%9P&1X;xRK zu`IK`5sBp~fAfpa*n0N}O_87f;#ZtsTxVU-D*_~Kjg;Mk6C{xgixW`HZm13VlgQtG$lH_ zy9@@$3@cA(KjCASvhoZDUA8;>^!umyn9)7%qdGx(CPf>T@J+&^^lS2b7NgCPl1dv9L99jGW!f|IROJDh zo{}{xY?g!SnHZrYgnGD7RxDx!k{(eGb`cClpso+j^goUq@!*)OHON15j4hu5(iUHG}?u`Naz?E-kWud<(ILbBmT+pWh~#oGZ&S6pf6k-oV)F zT)n->wP(vHmX#Ys7F3t(}=mDs;SG0SO<(4;u)AAXo_f3P$k7c^Z_vz=Q2p?~}E%_g)MBuPNw`J2wGvYfsMyYrJdME&%p?=c}`KuD^Qqzn?v{^+)fE zhny;%K`50S^M4q zT0=k`xP)AN5W#SGTxp#-pL!OMs%3O^6rWB~2ok!wW+IZxv7;|xlH(V4cZQFC@5XEI zy?Skryr&lI+<4<>OM&~%w5-lhaTYjFBXhh$g<@!#7J^MC=|A=|<(YYcQU|Rqok+8Z zZw@d}PdQ`yT!x2+bY!x&@iU9>TDRzOnL5CeH?L}Yvwgu(P8+HIg&?o!%YWz0kDtdIopbrcKIPz_C+Nx*(9#?#rFoR1 z0!|b1CKl^b=7ot=iiKZ3zV*KSTefWZ#L0fa$%zG@UMbJ@uBYHVX&h57xkd z{IZYYmM>s%$J0Dt{1D4le2Pl3pRQ(;KVL4k~-pCmRRp-)j8O5|elX>Ey#{e{4v z-mwCoJb&p>7}!BELLr}{TFkTlmYb=}FZ25EpP}*mi^#ccEQ!YXCK^#>Pf@@^^cgYg@SJhO0PZ#&kY*);Ub?DD%jV4|C>uRU%u&yNrBRN4>)X4xy0N zQ9TjARG#0vd-v}8X)DlZG!9k5pj(|H5>P1@DaVui;px4+_`(6sx?m|Cv%9EtO>kEC zD?Glnk2$j=E?RL8BoJu^4pJ`R6M#S#isJCO-g%sNxXjUPHVLB$1QfyQi538OF*JfavCZMd(9E?2QwF%@+OP24O`Cr{ z`@@T7C586q>ZSKW2nhkH3b>5GXVh&0lQt)(4De4~fBOR` z#`0}H+wbQ)z?GNX&~sU5XXh!+-&fs!+eQF(+X0ZvnXf{`)_;Rc`zC?f;55Z{GaBvH1Q2DANRR830k)00000NkvXXu0mjfHQid9 literal 0 HcmV?d00001 diff --git a/technic/textures/technicx32/technic_mv_solar_array_bottom.png b/technic/textures/technicx32/technic_mv_solar_array_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..94c82220d17121439939c1b88985aea891b76a69 GIT binary patch literal 2019 zcmV<92ORi`P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01m4F01m4Gj_kzz00007bV*G`2iyw* z7cUx+Q&eIA00(19L_t(o!*!QU%Ph%pg`bGXtm^LfevCfA#@1+~h5Q2y($)whfw9ql zHMT+4QcLR(*b-s}WEgqi`rf(k+g+6z5ne=f&q&4vwd(53$P*{dIVnH>#V?XfG7~Zp zRWcF;tTj}Xh(JW}IcdEg-$H~Vs*sQ*0)XH?QMLMS1|&d&2r-@GL;8B6WdvqMijd)` z7?=Qwh$5n>Dd|pMRuF**BAok5qKahT5iIM9hM{UiOuDX&eZ#Di5l9m<18be|Ndw4C zL zR>&x-ikKk?+6>8p$;=+@X_uA#cBAkC6@g6DjEF#0!3?CD5{SZWF{HOdOmS=N3uxNmIZgGuP5dh4-#7Mh$_}vaRQJjRk#`2JL7sq zLXB7(lIWCUtP>zz3UYK7b#=8QzNHWR&**O>c$@Jqht z&b=sA8bYx8w?8v+65gy%j1RhzfJtYiw1q0v~OSwv=W> zBr6wuPQsntuY^xBf))|Ud6ZCxORId)!s@|LIbfr`Ltjp@$5@5KjE zM3QYExI5d+OHG0qbL?1e*zC9u09u3-QLvGa83)vXSSuw{>Xd#c=F@5Apa1Pw%-gNlAHmpnNEq8*h)RQ&G_!`PG3Uh0;1HD*VUB@WE9OS< zAD?~B>3rtH^~yGO-hcRtS5Hs$-r2{bsjzPwPvyW>%0GM5 z8hu$25yqIfJ3dAcy0rtOK+Le-5VMkEReQLdSu2wfK~)*sc61%ir}YtTlK)%8vaZZI z@d*4*xNu~GHO1%rx?52m(nRElVI@F5Cv90C(aXmqMfl>~|L}(|zTnNbzr}a{`g{@dSAP{ylHrzU9^B!uyXOQGx&Z?>|;xQKj|HcDt4Mgdd`ogjYe$ zS|i-)r2g7|$TP=IZ@r3eFEu-e zWJka-?Ikw*PG1&que>-Xa||M)Hjg-3plC!8N6hvkDvf=hs$4&QUFvL^11~zOJ;TAMviEK4(SbBW%QU0QTFB{dzrQ8TQ+i z?RG=7E*Fu9#ZoRew(UW%drXTcLu>2G9cdr+ZAR3@)i?_(f*i7}+8z4J~Re!HRF>S`7OIM}kFt+72n*Y&9{%tK1= zYB_xz_r!sqjEIB%{h^?Rz=DshVp!|=9ApI6`=j`}nu(M*n-vlVTYZj)LW(N;UZW;j z^DJ5r=FCHsDp6IzuwQTZ9LLBFVhqHr((;_Rm(@2B!48ItD7!nEQR($|D@T(?h7cJj z4Uw{D_b5aX9GGK2+G2RzmGm&7C}XPm4_aUDc|h>+GMGau(;aJ#zAT97!#M7*&%xL> zeAK1G-Rm9!$K^FiPh!@l`i(;7zLOcuvD13ve*tr#O^<7`YHR=i002ovPDHLkV1i5_ B;l2O> literal 0 HcmV?d00001 diff --git a/technic/textures/technicx32/technic_mv_solar_array_side.png b/technic/textures/technicx32/technic_mv_solar_array_side.png new file mode 100644 index 0000000000000000000000000000000000000000..d39d3d81e462c2f4dfca86ec7563893195bca47b GIT binary patch literal 1772 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 m9FEEt#4_Nl#Z%!D$NvNUq{J+VK9K$Z0000 Date: Mon, 3 Jun 2013 23:42:44 +0200 Subject: [PATCH 37/57] Removing ununsed textures. Added more safety to item_drop to get around a fatal server halt issue. --- item_drop/item_entity.lua | 2 +- technic/solar_panel_mv.lua | 78 ------------------ .../technic_mv_solar_panel_bottom.png | Bin 574 -> 0 bytes .../textures/technic_mv_solar_panel_side.png | Bin 628 -> 0 bytes .../textures/technic_mv_solar_panel_top.png | Bin 728 -> 0 bytes .../textures/technic_mv_solarpanel_bottom.png | Bin 574 -> 0 bytes .../textures/technic_mv_solarpanel_side.png | Bin 628 -> 0 bytes .../textures/technic_mv_solarpanel_top.png | Bin 728 -> 0 bytes .../technic_mv_solar_panel_bottom.png | Bin 2019 -> 0 bytes .../technic_mv_solar_panel_side.png | Bin 1772 -> 0 bytes .../technicx32/technic_mv_solar_panel_top.png | Bin 2728 -> 0 bytes 11 files changed, 1 insertion(+), 79 deletions(-) delete mode 100644 technic/solar_panel_mv.lua delete mode 100644 technic/textures/technic_mv_solar_panel_bottom.png delete mode 100644 technic/textures/technic_mv_solar_panel_side.png delete mode 100644 technic/textures/technic_mv_solar_panel_top.png delete mode 100644 technic/textures/technic_mv_solarpanel_bottom.png delete mode 100644 technic/textures/technic_mv_solarpanel_side.png delete mode 100644 technic/textures/technic_mv_solarpanel_top.png delete mode 100644 technic/textures/technicx32/technic_mv_solar_panel_bottom.png delete mode 100644 technic/textures/technicx32/technic_mv_solar_panel_side.png delete mode 100644 technic/textures/technicx32/technic_mv_solar_panel_top.png diff --git a/item_drop/item_entity.lua b/item_drop/item_entity.lua index 3d1a83b..5da8285 100644 --- a/item_drop/item_entity.lua +++ b/item_drop/item_entity.lua @@ -109,7 +109,7 @@ minetest.register_entity(":__builtin:item", { return end - if minetest.registered_nodes[name].liquidtype == "flowing" then + if minetest.registered_nodes[name] and minetest.registered_nodes[name].liquidtype == "flowing" then get_flowing_dir = function(self) local pos = self.object:getpos() local param2 = minetest.env:get_node(pos).param2 diff --git a/technic/solar_panel_mv.lua b/technic/solar_panel_mv.lua deleted file mode 100644 index 4deb42e..0000000 --- a/technic/solar_panel_mv.lua +++ /dev/null @@ -1,78 +0,0 @@ -minetest.register_node("technic:solar_panel_mv", { - tiles = {"technic_mv_solar_panel_top.png", "technic_mv_solar_panel_bottom.png", "technic_mv_solar_panel_side.png", - "technic_mv_solar_panel_side.png", "technic_mv_solar_panel_side.png", "technic_mv_solar_panel_side.png"}, - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - sounds = default.node_sound_wood_defaults(), - description="MV Solar Panel", - active = false, - technic_mv_power_machine=1, - internal_EU_buffer=0; - internal_EU_buffer_size=10000; - drawtype = "nodebox", - paramtype = "light", - is_ground_content = true, - node_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, - }, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, - }, - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_float("technic_mv_power_machine", 1) - meta:set_float("internal_EU_buffer", 0) - meta:set_float("internal_EU_buffer_size", 10000) - - meta:set_string("infotext", "MV Solar Panel") - meta:set_float("active", false) - end, -}) - -minetest.register_craft({ - output = 'technic:solar_panel_mv 1', - recipe = { - {'technic:solar_panel', 'technic:solar_panel','technic:solar_panel'}, - {'technic:solar_panel', 'technic:mv_transformer','technic:solar_panel'}, - {'', 'technic:mv_cable',''}, - - } -}) - -minetest.register_abm( - {nodenames = {"technic:solar_panel_mv"}, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - - local pos1={} - pos1.y=pos.y+1 - pos1.x=pos.x - pos1.z=pos.z - - local light = minetest.env:get_node_light(pos1, nil) - local meta = minetest.env:get_meta(pos) - if light == nil then light = 0 end - if light >= 14 then - meta:set_string("infotext", "Solar Panel is active ") - meta:set_float("active",1) - 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=300+(pos1.y/250*300) -- make solar energy depending on height - if charge_to_give<0 then charge_to_give=0 end - if charge_to_give>600 then charge_to_give=600 end - if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then - charge_to_give=internal_EU_buffer_size-internal_EU_buffer - end - internal_EU_buffer=internal_EU_buffer+charge_to_give - meta:set_float("internal_EU_buffer",internal_EU_buffer) - - else - meta:set_string("infotext", "Solar Panel is inactive"); - meta:set_float("active",0) - end - end, -}) - -register_MV_machine ("technic:solar_panel_mv","PR") diff --git a/technic/textures/technic_mv_solar_panel_bottom.png b/technic/textures/technic_mv_solar_panel_bottom.png deleted file mode 100644 index 596e79a37334030ce3ebe9790a26adeff94da6c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 574 zcmV-E0>S->P)pHNyHksIQMtuDhB45Ws)U! zRMZY;baV&z(!uXr>zS;rm?cCftj$1}Gq_5@j{_kP zlvu&n=Rs8hPs-=3!2)+d4GvF4Ob})E!3?P1jaCQWPeoA5nNYWr=LzyrKsWvAh(Mo$ zCuc?AZYTqEff_kyW^@F_`)F(ifrBWLjJ+1KcfuUqfghPUI&MO(4?7on-xv)&uM4;T zr6im4aC)mGhr@-G6Uw5L!rt(Dy>S(CQp^=yYcpfx3b9~efX-} z%dzA{5J1tJpHfNcX~r&WAlR}b0wY)u!44a60M8h`ey#dsC5u^eO*mKn`s3F`3b6(* z&h>fo=RberRapwz7gm%E`0dA^IgdggjlEXZ0?$-d!W=O2X0JQ{*I6MV`TBg&MzUA% zwH6~1Hv`!yp8WpPFCa=E4bhFr#pa7S2BW>X?_?o_6*I~91m@1it05R(g$SV(=l$6sJDEWyv_2Vg@|nh7EBjGUw}baP zsM`*j^moT~aecceb)(b=tqnF8Rw~=()LNO*5ftyEkqiO{QKT3%5>sRJj%KhQCv$Y% zjJx;mK0PrSdYmV2&WfN&a%@g-H^pIdq11x1*!P`Gcs!oC3biQaimsK+NL(QnER4Dz z%w?n)v69#4;JzDmKe+EVGoX~poQi&27pg|Y0D~EeQcjNQY+f)`o~M%$Tp!<9F%e1D zx+$BYNaCurA&d?=2lxBp?gNoUYlFTvFhf#!KA(&k_;weC8@dr@Rh9Uxq z1|?Dyk;o{CY~sW*#01~n-re5p?2nnp_rZ7He#ue>z=!+S9y~eu{^uW^>nM@V3aJ=? z?tJ=rmg<18?gFg=B_Ifh;^f(jSKc*U(&pK6%RQ+gbJ8NZ=qlB3+E^xau_=wwI_f+#D)uGp ze3A<%K!e|~K;het0u{d-te%@>ka*E~7S}(TJh^v7nmX&zIZsLkv7}h)oY)HpSO}y< z>7iz3b`DTrh%!b1LF@&f>}{nRVbXL9Y^k!)s|FaQgM24%+Ez&!sZhu9qF4|iHm1Hf zser{AHm>z#FdoNEX;*Kts;qEA5^V}ol@)499y!)J>S?>S$(5-5$3$17R@gL82cv%L zI?wK4dTnvO=Yx zHl5NMLjXc#3^FyJFZXsw&UNGQjkB{8l0tgt*UNc6+_@}@(RjE!9u>aOOS|{s?qHY= zRtbCCd4B%vkx~&Zmc`AntJ1?V_ym(cy>BxCwgi6_>V`P8y)$&f&T$iZD1n`yoW*n0000< KMNUMnLSTZ1erHqw diff --git a/technic/textures/technic_mv_solarpanel_bottom.png b/technic/textures/technic_mv_solarpanel_bottom.png deleted file mode 100644 index 596e79a37334030ce3ebe9790a26adeff94da6c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 574 zcmV-E0>S->P)pHNyHksIQMtuDhB45Ws)U! zRMZY;baV&z(!uXr>zS;rm?cCftj$1}Gq_5@j{_kP zlvu&n=Rs8hPs-=3!2)+d4GvF4Ob})E!3?P1jaCQWPeoA5nNYWr=LzyrKsWvAh(Mo$ zCuc?AZYTqEff_kyW^@F_`)F(ifrBWLjJ+1KcfuUqfghPUI&MO(4?7on-xv)&uM4;T zr6im4aC)mGhr@-G6Uw5L!rt(Dy>S(CQp^=yYcpfx3b9~efX-} z%dzA{5J1tJpHfNcX~r&WAlR}b0wY)u!44a60M8h`ey#dsC5u^eO*mKn`s3F`3b6(* z&h>fo=RberRapwz7gm%E`0dA^IgdggjlEXZ0?$-d!W=O2X0JQ{*I6MV`TBg&MzUA% zwH6~1Hv`!yp8WpPFCa=E4bhFr#pa7S2BW>X?_?o_6*I~91m@1it05R(g$SV(=l$6sJDEWyv_2Vg@|nh7EBjGUw}baP zsM`*j^moT~aecceb)(b=tqnF8Rw~=()LNO*5ftyEkqiO{QKT3%5>sRJj%KhQCv$Y% zjJx;mK0PrSdYmV2&WfN&a%@g-H^pIdq11x1*!P`Gcs!oC3biQaimsK+NL(QnER4Dz z%w?n)v69#4;JzDmKe+EVGoX~poQi&27pg|Y0D~EeQcjNQY+f)`o~M%$Tp!<9F%e1D zx+$BYNaCurA&d?=2lxBp?gNoUYlFTvFhf#!KA(&k_;weC8@dr@Rh9Uxq z1|?Dyk;o{CY~sW*#01~n-re5p?2nnp_rZ7He#ue>z=!+S9y~eu{^uW^>nM@V3aJ=? z?tJ=rmg<18?gFg=B_Ifh;^f(jSKc*U(&pK6%RQ+gbJ8NZ=qlB3+E^xau_=wwI_f+#D)uGp ze3A<%K!e|~K;het0u{d-te%@>ka*E~7S}(TJh^v7nmX&zIZsLkv7}h)oY)HpSO}y< z>7iz3b`DTrh%!b1LF@&f>}{nRVbXL9Y^k!)s|FaQgM24%+Ez&!sZhu9qF4|iHm1Hf zser{AHm>z#FdoNEX;*Kts;qEA5^V}ol@)499y!)J>S?>S$(5-5$3$17R@gL82cv%L zI?wK4dTnvO=Yx zHl5NMLjXc#3^FyJFZXsw&UNGQjkB{8l0tgt*UNc6+_@}@(RjE!9u>aOOS|{s?qHY= zRtbCCd4B%vkx~&Zmc`AntJ1?V_ym(cy>BxCwgi6_>V`P8y)$&f&T$iZD1n`yoW*n0000< KMNUMnLSTZ1erHqw diff --git a/technic/textures/technicx32/technic_mv_solar_panel_bottom.png b/technic/textures/technicx32/technic_mv_solar_panel_bottom.png deleted file mode 100644 index 94c82220d17121439939c1b88985aea891b76a69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2019 zcmV<92ORi`P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01m4F01m4Gj_kzz00007bV*G`2iyw* z7cUx+Q&eIA00(19L_t(o!*!QU%Ph%pg`bGXtm^LfevCfA#@1+~h5Q2y($)whfw9ql zHMT+4QcLR(*b-s}WEgqi`rf(k+g+6z5ne=f&q&4vwd(53$P*{dIVnH>#V?XfG7~Zp zRWcF;tTj}Xh(JW}IcdEg-$H~Vs*sQ*0)XH?QMLMS1|&d&2r-@GL;8B6WdvqMijd)` z7?=Qwh$5n>Dd|pMRuF**BAok5qKahT5iIM9hM{UiOuDX&eZ#Di5l9m<18be|Ndw4C zL zR>&x-ikKk?+6>8p$;=+@X_uA#cBAkC6@g6DjEF#0!3?CD5{SZWF{HOdOmS=N3uxNmIZgGuP5dh4-#7Mh$_}vaRQJjRk#`2JL7sq zLXB7(lIWCUtP>zz3UYK7b#=8QzNHWR&**O>c$@Jqht z&b=sA8bYx8w?8v+65gy%j1RhzfJtYiw1q0v~OSwv=W> zBr6wuPQsntuY^xBf))|Ud6ZCxORId)!s@|LIbfr`Ltjp@$5@5KjE zM3QYExI5d+OHG0qbL?1e*zC9u09u3-QLvGa83)vXSSuw{>Xd#c=F@5Apa1Pw%-gNlAHmpnNEq8*h)RQ&G_!`PG3Uh0;1HD*VUB@WE9OS< zAD?~B>3rtH^~yGO-hcRtS5Hs$-r2{bsjzPwPvyW>%0GM5 z8hu$25yqIfJ3dAcy0rtOK+Le-5VMkEReQLdSu2wfK~)*sc61%ir}YtTlK)%8vaZZI z@d*4*xNu~GHO1%rx?52m(nRElVI@F5Cv90C(aXmqMfl>~|L}(|zTnNbzr}a{`g{@dSAP{ylHrzU9^B!uyXOQGx&Z?>|;xQKj|HcDt4Mgdd`ogjYe$ zS|i-)r2g7|$TP=IZ@r3eFEu-e zWJka-?Ikw*PG1&que>-Xa||M)Hjg-3plC!8N6hvkDvf=hs$4&QUFvL^11~zOJ;TAMviEK4(SbBW%QU0QTFB{dzrQ8TQ+i z?RG=7E*Fu9#ZoRew(UW%drXTcLu>2G9cdr+ZAR3@)i?_(f*i7}+8z4J~Re!HRF>S`7OIM}kFt+72n*Y&9{%tK1= zYB_xz_r!sqjEIB%{h^?Rz=DshVp!|=9ApI6`=j`}nu(M*n-vlVTYZj)LW(N;UZW;j z^DJ5r=FCHsDp6IzuwQTZ9LLBFVhqHr((;_Rm(@2B!48ItD7!nEQR($|D@T(?h7cJj z4Uw{D_b5aX9GGK2+G2RzmGm&7C}XPm4_aUDc|h>+GMGau(;aJ#zAT97!#M7*&%xL> zeAK1G-Rm9!$K^FiPh!@l`i(;7zLOcuvD13ve*tr#O^<7`YHR=i002ovPDHLkV1i5_ B;l2O> diff --git a/technic/textures/technicx32/technic_mv_solar_panel_side.png b/technic/textures/technicx32/technic_mv_solar_panel_side.png deleted file mode 100644 index d39d3d81e462c2f4dfca86ec7563893195bca47b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1772 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 Date: Tue, 4 Jun 2013 00:05:07 +0200 Subject: [PATCH 38/57] Fix solr array recipes for hv and mv to match that of the lv array. --- technic/solar_array_hv.lua | 2 +- technic/solar_array_mv.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/technic/solar_array_hv.lua b/technic/solar_array_hv.lua index 89f5d1b..e159248 100644 --- a/technic/solar_array_hv.lua +++ b/technic/solar_array_hv.lua @@ -40,7 +40,7 @@ minetest.register_craft({ recipe = { {'technic:solar_array_mv', 'technic:solar_array_mv','technic:solar_array_mv'}, {'technic:solar_array_mv', 'technic:hv_transformer','technic:solar_array_mv'}, - {'', 'technic:hv_cable',''}, + {'default:steel_ingot', 'technic:hv_cable', 'default:steel_ingot'}, } }) diff --git a/technic/solar_array_mv.lua b/technic/solar_array_mv.lua index 73fe85a..de75301 100644 --- a/technic/solar_array_mv.lua +++ b/technic/solar_array_mv.lua @@ -41,7 +41,7 @@ minetest.register_craft({ recipe = { {'technic:solar_array_lv', 'technic:solar_array_lv','technic:solar_array_lv'}, {'technic:solar_array_lv', 'technic:mv_transformer','technic:solar_array_lv'}, - {'', 'technic:mv_cable',''}, + {'default:steel_ingot', 'technic:mv_cable', 'default:steel_ingot'}, } }) From 26c0bba1f2a31a1fc3f6148fc09fdc42d717ddf7 Mon Sep 17 00:00:00 2001 From: kpoppel Date: Tue, 4 Jun 2013 23:36:07 +0200 Subject: [PATCH 39/57] Added ingot grinding for the type which already have a <>_dust in place. The default bronze_ingot does not have a dust item. --- technic/grinder.lua | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/technic/grinder.lua b/technic/grinder.lua index b4dbd90..e89cb4c 100644 --- a/technic/grinder.lua +++ b/technic/grinder.lua @@ -22,14 +22,26 @@ 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 2") register_grinder_recipe("default:coal_lump","technic:coal_dust 2") register_grinder_recipe("default:copper_lump","technic:copper_dust 2") -register_grinder_recipe("moreores:tin_lump","technic:tin_dust 2") -register_grinder_recipe("moreores:silver_lump","technic:silver_dust 2") +register_grinder_recipe("default:copper_ingot","technic:copper_dust 2") register_grinder_recipe("default:gold_lump","technic:gold_dust 2") +register_grinder_recipe("default:gold_ingot","technic:gold_dust 2") +--register_grinder_recipe("default:bronze_ingot","technic:bronze_dust 2") -- Dust does not exist yet +--register_grinder_recipe("home_decor:brass_ingot","technic:brass_dust 2") -- needs check for the mod +register_grinder_recipe("moreores:tin_lump","technic:tin_dust 2") +register_grinder_recipe("moreores:tin_ingot","technic:tin_dust 2") +register_grinder_recipe("moreores:silver_lump","technic:silver_dust 2") +register_grinder_recipe("moreores:silver_ingot","technic:silver_dust 2") register_grinder_recipe("moreores:mithril_lump","technic:mithril_dust 2") +register_grinder_recipe("moreores:mithril_ingot","technic:mithril_dust 2") register_grinder_recipe("technic:chromium_lump","technic:chromium_dust 2") +register_grinder_recipe("technic:chromium_ingot","technic:chromium_dust 2") +register_grinder_recipe("technic:stainless_steel_ingot","stainless_steel_dust 2") +register_grinder_recipe("technic:brass_ingot","technic:brass_dust 2") register_grinder_recipe("technic:zinc_lump","technic:zinc_dust 2") +register_grinder_recipe("technic:zinc_ingot","technic:zinc_dust 2") 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") From e62a0fd0c1fc92125b168dc08ff33298d04860b5 Mon Sep 17 00:00:00 2001 From: kpoppel Date: Thu, 6 Jun 2013 22:46:40 +0200 Subject: [PATCH 40/57] Changed grinding of ingots to give 1 dust. This is to avoid duplication exploit. --- technic/grinder.lua | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/technic/grinder.lua b/technic/grinder.lua index e89cb4c..b676bed 100644 --- a/technic/grinder.lua +++ b/technic/grinder.lua @@ -22,26 +22,26 @@ 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 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 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 2") ---register_grinder_recipe("default:bronze_ingot","technic:bronze_dust 2") -- Dust does not exist yet ---register_grinder_recipe("home_decor:brass_ingot","technic:brass_dust 2") -- needs check for the mod +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("home_decor:brass_ingot","technic:brass_dust 1") -- needs check for the mod register_grinder_recipe("moreores:tin_lump","technic:tin_dust 2") -register_grinder_recipe("moreores:tin_ingot","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 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 2") -register_grinder_recipe("technic:chromium_lump","technic:chromium_dust 2") -register_grinder_recipe("technic:chromium_ingot","technic:chromium_dust 2") -register_grinder_recipe("technic:stainless_steel_ingot","stainless_steel_dust 2") -register_grinder_recipe("technic:brass_ingot","technic:brass_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("technic:zinc_lump","technic:zinc_dust 2") -register_grinder_recipe("technic:zinc_ingot","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") From 802db28dc397e5ceb9f543c8adbb4e451a65ec0e Mon Sep 17 00:00:00 2001 From: kpoppel Date: Thu, 6 Jun 2013 22:49:08 +0200 Subject: [PATCH 41/57] Whitespace cleanup --- technic/grinder.lua | 80 ++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/technic/grinder.lua b/technic/grinder.lua index b676bed..07baa05 100644 --- a/technic/grinder.lua +++ b/technic/grinder.lua @@ -21,36 +21,36 @@ 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: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: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("home_decor:brass_ingot","technic:brass_dust 1") -- needs check for the mod -register_grinder_recipe("moreores:tin_lump","technic:tin_dust 2") -register_grinder_recipe("moreores:tin_ingot","technic:tin_dust 1") +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_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("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") +register_grinder_recipe("technic:stainless_steel_ingot","stainless_steel_dust 1") +register_grinder_recipe("technic: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") minetest.register_craftitem( "technic:coal_dust", { description = "Coal Dust", @@ -68,7 +68,7 @@ minetest.register_craft({ type = "cooking", output = "default:steel_ingot", recipe = "technic:iron_dust", -}) +}) minetest.register_craftitem( "technic:copper_dust", { description = "Copper Dust", @@ -79,7 +79,7 @@ minetest.register_craft({ type = "cooking", output = "moreores:copper_ingot", recipe = "technic:copper_dust", -}) +}) minetest.register_craftitem( "technic:tin_dust", { description = "Tin Dust", @@ -90,7 +90,7 @@ minetest.register_craft({ type = "cooking", output = "moreores:tin_ingot", recipe = "technic:tin_dust", -}) +}) minetest.register_craftitem( "technic:silver_dust", { description = "Silver Dust", @@ -101,7 +101,7 @@ minetest.register_craft({ type = "cooking", output = "moreores:silver_ingot", recipe = "technic:silver_dust", -}) +}) minetest.register_craftitem( "technic:gold_dust", { description = "Gold Dust", @@ -112,7 +112,7 @@ minetest.register_craft({ type = "cooking", output = "moreores:gold_ingot", recipe = "technic:gold_dust", -}) +}) minetest.register_craftitem( "technic:mithril_dust", { description = "Mithril Dust", @@ -123,7 +123,7 @@ minetest.register_craft({ type = "cooking", output = "moreores:mithril_ingot", recipe = "technic:mithril_dust", -}) +}) minetest.register_craftitem( "technic:chromium_dust", { description = "Chromium Dust", @@ -134,7 +134,7 @@ minetest.register_craft({ type = "cooking", output = "technic:chromium_ingot", recipe = "technic:chromium_dust", -}) +}) minetest.register_craftitem( "technic:bronze_dust", { description = "Bronze Dust", @@ -145,7 +145,7 @@ minetest.register_craft({ type = "cooking", output = "moreores:bronze_ingot", recipe = "technic:bronze_dust", -}) +}) minetest.register_craftitem( "technic:brass_dust", { description = "Brass Dust", @@ -156,7 +156,7 @@ minetest.register_craft({ type = "cooking", output = "technic:brass_ingot", recipe = "technic:brass_dust", -}) +}) minetest.register_craftitem( "technic:stainless_steel_dust", { description = "Stainless Steel Dust", @@ -167,7 +167,7 @@ minetest.register_craft({ type = "cooking", output = "technic:stainless_steel_ingot", recipe = "technic:stainless_steel_dust", -}) +}) minetest.register_craftitem( "technic:zinc_dust", { description = "Zinc Dust", @@ -178,7 +178,7 @@ minetest.register_craft({ type = "cooking", output = "technic:zinc_ingot", recipe = "technic:zinc_dust", -}) +}) minetest.register_alias("grinder", "technic:grinder") minetest.register_craft({ @@ -193,7 +193,7 @@ minetest.register_craft({ minetest.register_craftitem("technic:grinder", { description = "Grinder", stack_max = 99, -}) +}) grinder_formspec = "invsize[8,9;]".. @@ -290,7 +290,7 @@ minetest.register_abm({ 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 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 @@ -299,7 +299,7 @@ minetest.register_abm({ 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)) + 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) @@ -307,7 +307,7 @@ minetest.register_abm({ 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 + if inv:is_empty("src") then meta:set_float("grinder_on",0) end else print("Grinder inventory full!") end @@ -316,10 +316,10 @@ minetest.register_abm({ end end if (meta:get_float("grinder_on")==0) then - local grinded=nil + local grinded=nil if not inv:is_empty("src") then grinded = get_grinded_item (inv:get_stack("src", 1)) - if grinded then + if grinded then meta:set_float("grinder_on",1) hacky_swap_node(pos,"technic:grinder_active") meta:set_string("infotext", "Grinder Active") @@ -328,13 +328,13 @@ minetest.register_abm({ meta:set_float("src_time", 0) return end - else + else hacky_swap_node(pos,"technic:grinder") meta:set_string("infotext", "Grinder Inactive") end end end -}) +}) function get_grinded_item (items) new_item =nil From a27b59dde52eec754db6930b420e1493e16980b8 Mon Sep 17 00:00:00 2001 From: kpoppel Date: Wed, 12 Jun 2013 22:08:23 +0200 Subject: [PATCH 42/57] Fix to the chainsaw. handle_node drops should no longer become nil. --- technic/chainsaw.lua | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/technic/chainsaw.lua b/technic/chainsaw.lua index c31d9a8..5b3b05b 100644 --- a/technic/chainsaw.lua +++ b/technic/chainsaw.lua @@ -138,6 +138,13 @@ if( minetest.get_modpath("growing_cactus") ~= nil ) then timber_nodenames["growing_cactus:branch_xx"] = true end +-- Support farming_plus if it is there +if( minetest.get_modpath("farming_plus") ~= nil ) then + if chainsaw_leaves == true then + timber_nodenames["farming_plus:cocoa_leaves"] = true + end +end + -- Table for saving what was sawed down local produced @@ -145,6 +152,9 @@ local produced chainsaw_dig_it = function(pos, player,current_charge) local remaining_charge=current_charge + -- Save the currently installed dropping mechanism so we can restore it. + local original_handle_node_drops = minetest.handle_node_drops + -- A bit of trickery here: use a different node drop callback -- and restore the original afterwards. minetest.handle_node_drops = chainsaw_handle_node_drops @@ -195,9 +205,6 @@ chainsaw_handle_node_drops = function(pos, drops, digger) end end --- Save the currently installed dropping mechanism so we can restore it. -local original_handle_node_drops = minetest.handle_node_drops - -- This function does all the hard work. Recursively we dig the node at hand -- if it is in the table and then search the surroundings for more stuff to dig. recursive_dig = function(pos, remaining_charge, player) From cfb5bd190c8188d0a0ffd43701864cb1de48bd5d Mon Sep 17 00:00:00 2001 From: kpoppel Date: Wed, 12 Jun 2013 23:30:37 +0200 Subject: [PATCH 43/57] Added the Mv and HV down converters. Doing that required some changes to the batteries in that they have new meta data aligned with the other machines. I also added a BA type machine in addition to the existing PR and RE types. This way it is easy to find he batteries on the network. --- technic/battery_box.lua | 669 +++++++++--------- technic/battery_box_hv.lua | 604 ++++++++-------- technic/battery_box_mv.lua | 617 ++++++++-------- technic/down_converter_hv.lua | 225 ++++++ technic/down_converter_mv.lua | 226 ++++++ technic/init.lua | 2 + technic/solar_array_mv.lua | 3 +- .../technic_hv_down_converter_bottom.png | Bin 0 -> 653 bytes .../technic_hv_down_converter_side.png | Bin 0 -> 609 bytes .../technic_hv_down_converter_top.png | Bin 0 -> 653 bytes .../technic_mv_down_converter_bottom.png | Bin 0 -> 738 bytes .../technic_mv_down_converter_side.png | Bin 0 -> 670 bytes .../technic_mv_down_converter_top.png | Bin 0 -> 738 bytes 13 files changed, 1371 insertions(+), 975 deletions(-) create mode 100644 technic/down_converter_hv.lua create mode 100644 technic/down_converter_mv.lua create mode 100644 technic/textures/technic_hv_down_converter_bottom.png create mode 100644 technic/textures/technic_hv_down_converter_side.png create mode 100644 technic/textures/technic_hv_down_converter_top.png create mode 100644 technic/textures/technic_mv_down_converter_bottom.png create mode 100644 technic/textures/technic_mv_down_converter_side.png create mode 100644 technic/textures/technic_mv_down_converter_top.png diff --git a/technic/battery_box.lua b/technic/battery_box.lua index 9c91821..5726053 100644 --- a/technic/battery_box.lua +++ b/technic/battery_box.lua @@ -1,408 +1,393 @@ -LV_machines = {} -registered_LV_machines_count=0 - -function register_LV_machine (string1,string2) -registered_LV_machines_count=registered_LV_machines_count+1 -LV_machines[registered_LV_machines_count]={} -LV_machines[registered_LV_machines_count].machine_name=string1 -LV_machines[registered_LV_machines_count].machine_type=string2 +-- 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 + 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', 'moreores:copper_ingot', 'default:wood'}, - {'default:wood', 'moreores:tin_ingot', 'default:wood'}, - {'default:wood', 'moreores:copper_ingot', 'default:wood'}, - } -}) + output = 'technic:battery 1', + recipe = { + {'default:wood', 'moreores:copper_ingot', 'default:wood'}, + {'default:wood', 'moreores:tin_ingot', 'default:wood'}, + {'default:wood', 'moreores:copper_ingot', 'default:wood'}, + } + }) 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'}, - } -}) + 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_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}}}}) + {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_craftitem("technic:battery_box", { - description = "Battery box", - stack_max = 99, -}) + description = "Battery box", + stack_max = 99, + }) 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;Battery box]".. + "label[3,0;Charge]".. + "label[5,0;Discharge]".. + "label[1,3;Power level]".. + "list[current_player;main;0,5;8,4;]" -minetest.register_node("technic:battery_box", { - description = "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(), - technic_power_machine=1, - last_side_shown=0, - drop="technic:battery_box", - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_string("infotext", "Battery box") - meta:set_float("technic_power_machine", 1) - meta:set_string("formspec", battery_box_formspec) - local inv = meta:get_inventory() - inv:set_size("src", 1) - inv:set_size("dst", 1) - battery_charge = 0 - max_charge = 60000 - last_side_shown=0 - 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: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 + return true + end, + }) for i=1,8,1 do -minetest.register_node("technic:battery_box"..i, { - description = "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"}, - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, - sounds = default.node_sound_wood_defaults(), - technic_power_machine=1, - last_side_shown=0, - drop="technic:battery_box", - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_string("infotext", "Battery box") - meta:set_float("technic_power_machine", 1) - meta:set_string("formspec", battery_box_formspec) - local inv = meta:get_inventory() - inv:set_size("src", 1) - inv:set_size("dst", 1) - battery_charge = 0 - max_charge = 60000 - last_side_shown=0 - 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: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"}, + 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", + 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 + return true + end, + }) end -LV_nodes_visited = {} - function get_RE_item_load (load1,max_load) -if load1==0 then load1=65535 end -local temp = 65536-load1 -temp= temp/65535*max_load -return math.floor(temp + 0.5) + if load1==0 then load1=65535 end + local temp = 65536-load1 + temp= temp/65535*max_load + return math.floor(temp + 0.5) end function set_RE_item_load (load1,max_load) -if load1 == 0 then return 65535 end -local temp=load1/max_load*65535 -temp=65536-temp -return math.floor(temp) + if load1 == 0 then return 65535 end + local temp=load1/max_load*65535 + temp=65536-temp + return math.floor(temp) end function set_RE_wear (item_stack,load1,max_load) -local temp=65536-math.floor(load1/max_load*65535) -item_stack["wear"]=tostring(temp) -return item_stack + local temp=65536-math.floor(load1/max_load*65535) + item_stack["wear"]=tostring(temp) + return item_stack end -minetest.register_abm({ - nodenames = {"technic:battery_box","technic:battery_box1","technic:battery_box2","technic:battery_box3","technic:battery_box4", - "technic:battery_box5","technic:battery_box6","technic:battery_box7","technic:battery_box8"}, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - local meta = minetest.env:get_meta(pos) - charge= meta:get_int("battery_charge") - max_charge= 60000 - local i=math.ceil((charge/max_charge)*8) - if i>8 then i=8 end - j=meta:get_float("last_side_shown") - if i~=j then - if i>0 then hacky_swap_node(pos,"technic:battery_box"..i) - elseif i==0 then hacky_swap_node(pos,"technic:battery_box") end - meta:set_float("last_side_shown",i) - end +minetest.register_abm( + {nodenames = {"technic:battery_box","technic:battery_box1","technic:battery_box2","technic:battery_box3","technic:battery_box4", + "technic:battery_box5","technic:battery_box6","technic:battery_box7","technic:battery_box8"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.env:get_meta(pos) + local max_charge = 60000 -- Set maximum charge for the device here + local charge = meta:get_int("internal_EU_buffer") ---loading registered power tools - local inv = meta:get_inventory() - if inv:is_empty("src")==false then - local srcstack = inv:get_stack("src", 1) - local src_item=srcstack:to_table() - local src_meta=get_item_meta(src_item["metadata"]) - - local item_max_charge=nil - for i=1,registered_power_tools_count,1 do - if power_tools[i].tool_name==src_item["name"] then - src_meta=get_item_meta(src_item["metadata"]) - if src_meta==nil then - src_meta={} - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - else - if src_meta["technic_power_tool"]==nil then - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - end - end - item_max_charge=power_tools[i].max_charge - end + -- Select node textures + local i=math.ceil((charge/max_charge)*8) + if i > 8 then i = 8 end + local j = meta:get_float("last_side_shown") + if i~=j then + if i>0 then hacky_swap_node(pos,"technic:battery_box"..i) + elseif i==0 then hacky_swap_node(pos,"technic:battery_box") end + meta:set_float("last_side_shown",i) end - if item_max_charge then - load1=src_meta["charge"] - load_step=1000 - if load10 then - if charge-load_step<0 then load_step=charge end - if load1+load_step>item_max_charge then load_step=item_max_charge-load1 end - load1=load1+load_step - charge=charge-load_step - set_RE_wear(src_item,load1,item_max_charge) - src_meta["charge"]=load1 - src_item["metadata"]=set_item_meta(src_meta) - inv:set_stack("src", 1, src_item) - end - meta:set_int("battery_charge",charge) - end - end - --- discharging registered power tools - if inv:is_empty("dst") == false then - srcstack = inv:get_stack("dst", 1) - src_item=srcstack:to_table() - local src_meta=get_item_meta(src_item["metadata"]) - local item_max_charge=nil - for i=1,registered_power_tools_count,1 do - if power_tools[i].tool_name==src_item["name"] then - src_meta=get_item_meta(src_item["metadata"]) - if src_meta==nil then - src_meta={} - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - else - if src_meta["technic_power_tool"]==nil then - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - end - end - item_max_charge=power_tools[i].max_charge - end - end - - if item_max_charge then - local load1=src_meta["charge"] - load_step=1000 - if load1>0 and chargemax_charge then load_step=max_charge-charge end - if load1-load_step<0 then load_step=load1 end - load1=load1-load_step - charge=charge+load_step - set_RE_wear(src_item,load1,item_max_charge) - src_meta["charge"]=load1 - src_item["metadata"]=set_item_meta(src_meta) - inv:set_stack("dst", 1, src_item) - end - end + --charge registered power tools + local inv = meta:get_inventory() + if inv:is_empty("src")==false then + local srcstack = inv:get_stack("src", 1) + local src_item=srcstack:to_table() + local src_meta=get_item_meta(src_item["metadata"]) + + local item_max_charge=nil + for i=1,registered_power_tools_count,1 do + if power_tools[i].tool_name==src_item["name"] then + src_meta=get_item_meta(src_item["metadata"]) + if src_meta==nil then + src_meta={} + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + else + if src_meta["technic_power_tool"]==nil then + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + end + end + -- Do the charging + local item_max_charge = power_tools[i].max_charge + local load1 = src_meta["charge"] + local load_step = 1000 -- how much to charge per tick + if load10 then + if charge-load_step<0 then load_step=charge end + if load1+load_step>item_max_charge then load_step=item_max_charge-load1 end + load1=load1+load_step + charge=charge-load_step + set_RE_wear(src_item,load1,item_max_charge) + src_meta["charge"]=load1 + src_item["metadata"]=set_item_meta(src_meta) + inv:set_stack("src", 1, src_item) + end + meta:set_int("internal_EU_buffer",charge) + break + end + end end - meta:set_int("battery_charge",charge) + -- discharging registered power tools + if inv:is_empty("dst") == false then + srcstack = inv:get_stack("dst", 1) + src_item=srcstack:to_table() + local src_meta=get_item_meta(src_item["metadata"]) + local item_max_charge=nil + for i=1,registered_power_tools_count,1 do + if power_tools[i].tool_name==src_item["name"] then + src_meta=get_item_meta(src_item["metadata"]) + if src_meta==nil then + src_meta={} + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + else + if src_meta["technic_power_tool"]==nil then + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + end + end + local item_max_charge = power_tools[i].max_charge + local load1 = src_meta["charge"] + local load_step = 4000 -- how much to discharge per tick + if load1>0 and chargemax_charge then load_step=max_charge-charge end + if load1-load_step<0 then load_step=load1 end + load1=load1-load_step + charge=charge+load_step + set_RE_wear(src_item,load1,item_max_charge) + src_meta["charge"]=load1 + src_item["metadata"]=set_item_meta(src_meta) + inv:set_stack("dst", 1, src_item) + end + meta:set_int("internal_EU_buffer",charge) + break + end + end + end - local load = math.floor(charge/60000 * 100) - meta:set_string("formspec", + local load = math.floor(charge/60000 * 100) + meta:set_string("formspec", battery_box_formspec.. - "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. - (load)..":technic_power_meter_fg.png]") + "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. + (load)..":technic_power_meter_fg.png]" + ) - local pos1={} + -- Next index the surrounding network the get the producers and receivers on the power grid + local pos1={} + pos1.y=pos.y-1 + pos1.x=pos.x + pos1.z=pos.z - pos1.y=pos.y-1 - pos1.x=pos.x - pos1.z=pos.z + meta1 = minetest.env:get_meta(pos1) + if meta1:get_float("cablelike")~=1 then return end + + local LV_nodes = {} + local PR_nodes = {} + local RE_nodes = {} + local BA_nodes = {} + + LV_nodes[1]={} + LV_nodes[1].x=pos1.x + LV_nodes[1].y=pos1.y + LV_nodes[1].z=pos1.z + LV_nodes[1].visited=false + + local table_index=1 + repeat + check_LV_node(PR_nodes,RE_nodes,BA_nodes,LV_nodes,table_index) + table_index=table_index+1 + if LV_nodes[table_index]==nil then break end + until false - meta1 = minetest.env:get_meta(pos1) - if meta1:get_float("cablelike")~=1 then return end + -- Get power from all connected producers + local pr_pos + for _,pr_pos in ipairs(PR_nodes) do + local meta1 = minetest.env:get_meta(pr_pos) + local internal_EU_buffer = meta1:get_float("internal_EU_buffer") + local charge_to_take = 200 + if charge0 then + charge=charge+charge_to_take + internal_EU_buffer=internal_EU_buffer-charge_to_take + meta1:set_float("internal_EU_buffer",internal_EU_buffer) + end + end + end - local LV_nodes = {} - local PR_nodes = {} - local RE_nodes = {} + if charge>max_charge then charge=max_charge end - LV_nodes[1]={} - LV_nodes[1].x=pos1.x - LV_nodes[1].y=pos1.y - LV_nodes[1].z=pos1.z - LV_nodes[1].visited=false + -- Provide power to all connected receivers + local re_pos + for _,re_pos in ipairs(RE_nodes) do + local meta1 = minetest.env:get_meta(re_pos) + local internal_EU_buffer = meta1:get_float("internal_EU_buffer") + local internal_EU_buffer_size = meta1:get_float("internal_EU_buffer_size") + local charge_to_give = math.min(200, charge/table.getn(RE_nodes)) + if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then + charge_to_give=internal_EU_buffer_size-internal_EU_buffer + end + if charge-charge_to_give<0 then charge_to_give=charge end + internal_EU_buffer=internal_EU_buffer+charge_to_give + meta1:set_float("internal_EU_buffer",internal_EU_buffer) + charge=charge-charge_to_give; + end + charge=math.floor(charge) + meta:set_string("infotext", "LV Battery box: "..charge.."/"..max_charge); + meta:set_int("internal_EU_buffer",charge) + end + }) -table_index=1 - repeat - check_LV_node (PR_nodes,RE_nodes,LV_nodes,table_index) - table_index=table_index+1 - if LV_nodes[table_index]==nil then break end - until false - - -local pos1={} -i=1 - repeat - if PR_nodes[i]==nil then break end -- getting power from all connected producers - pos1.x=PR_nodes[i].x - pos1.y=PR_nodes[i].y - pos1.z=PR_nodes[i].z - local meta1 = minetest.env:get_meta(pos1) - local internal_EU_buffer=meta1:get_float("internal_EU_buffer") - if charge0 then - charge=charge+charge_to_take - internal_EU_buffer=internal_EU_buffer-charge_to_take - meta1:set_float("internal_EU_buffer",internal_EU_buffer) - end - end - i=i+1 - until false - -if charge>max_charge then charge=max_charge end - -i=1 - repeat - if RE_nodes[i]==nil then break end - pos1.x=RE_nodes[i].x -- loading all conected machines buffers - pos1.y=RE_nodes[i].y - pos1.z=RE_nodes[i].z - local meta1 = minetest.env:get_meta(pos1) - local internal_EU_buffer=meta1:get_float("internal_EU_buffer") - local internal_EU_buffer_size=meta1:get_float("internal_EU_buffer_size") - - local charge_to_give=200 - if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then - charge_to_give=internal_EU_buffer_size-internal_EU_buffer - end - if charge-charge_to_give<0 then charge_to_give=charge end - - internal_EU_buffer=internal_EU_buffer+charge_to_give - meta1:set_float("internal_EU_buffer",internal_EU_buffer) - charge=charge-charge_to_give; - - i=i+1 - until false - charge=math.floor(charge) - charge_string=tostring(charge) - meta:set_string("infotext", "Battery box: "..charge_string.."/"..max_charge); - meta:set_int("battery_charge",charge) - +-- 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") +for i=1,8,1 do + register_LV_machine("technic:battery_box"..i,"BA") end -}) function add_new_cable_node (LV_nodes,pos1) - 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 - LV_nodes[i].visited=false - return true + 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 end -function check_LV_node (PR_nodes,RE_nodes,LV_nodes,i) - local pos1={} - pos1.x=LV_nodes[i].x - pos1.y=LV_nodes[i].y - pos1.z=LV_nodes[i].z - LV_nodes[i].visited=true - new_node_added=false +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,LV_nodes,pos1) - pos1.x=pos1.x-2 - check_LV_node_subp (PR_nodes,RE_nodes,LV_nodes,pos1) - pos1.x=pos1.x+1 + 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,LV_nodes,pos1) - pos1.y=pos1.y-2 - check_LV_node_subp (PR_nodes,RE_nodes,LV_nodes,pos1) - pos1.y=pos1.y+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,LV_nodes,pos1) - pos1.z=pos1.z-2 - check_LV_node_subp (PR_nodes,RE_nodes,LV_nodes,pos1) - pos1.z=pos1.z+1 -return new_node_added + 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,LV_nodes,pos1) -meta = minetest.env:get_meta(pos1) -if meta:get_float("cablelike")==1 then new_node_added=add_new_cable_node(LV_nodes,pos1) end -for i in ipairs(LV_machines) do - if minetest.env:get_node(pos1).name == LV_machines[i].machine_name then - if LV_machines[i].machine_type == "PR" then - new_node_added=add_new_cable_node(PR_nodes,pos1) - end - if LV_machines[i].machine_type == "RE" then - new_node_added=add_new_cable_node(RE_nodes,pos1) - end - end -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 diff --git a/technic/battery_box_hv.lua b/technic/battery_box_hv.lua index e565d4c..16aead9 100644 --- a/technic/battery_box_hv.lua +++ b/technic/battery_box_hv.lua @@ -1,357 +1,331 @@ -HV_machines = {} - -registered_HV_machines_count=0 - -function register_HV_machine (string1,string2) -registered_HV_machines_count=registered_HV_machines_count+1 -HV_machines[registered_HV_machines_count]={} -HV_machines[registered_HV_machines_count].machine_name=string1 -HV_machines[registered_HV_machines_count].machine_type=string2 +-- register MV machines here +technic.HV_machines = {} +local HV_machines = technic.HV_machines +function register_HV_machine(string1,string2) + technic.HV_machines[string1] = string2 end minetest.register_craft({ - output = 'technic:hv_battery_box 1', - recipe = { - {'technic:mv_battery_box', 'technic:mv_battery_box', 'mv_technic:battery_box'}, - {'technic:mv_battery_box', 'technic:hv_transformer', 'mv_technic:battery_box'}, - {'', 'technic:hv_cable', ''}, - } -}) + output = 'technic:hv_battery_box 1', + recipe = { + {'technic:mv_battery_box', 'technic:mv_battery_box', 'mv_technic:battery_box'}, + {'technic:mv_battery_box', 'technic:hv_transformer', 'mv_technic:battery_box'}, + {'', 'technic:hv_cable', ''}, + } + }) hv_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;HV Battery Box]".. - "label[3,0;Charge]".. - "label[5,0;Discharge]".. - "label[1,3;Power level]".. - "list[current_player;main;0,5;8,4;]" - -minetest.register_node("technic:hv_battery_box", { - description = "HV Battery Box", - tiles = {"technic_hv_battery_box_top.png", "technic_hv_battery_box_bottom.png", "technic_hv_battery_box_side0.png", - "technic_hv_battery_box_side0.png", "technic_hv_battery_box_side0.png", "technic_hv_battery_box_side0.png"}, - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - sounds = default.node_sound_wood_defaults(), - technic_mv_power_machine=1, - last_side_shown=0, - drop="technic:hv_battery_box", - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_string("infotext", "HV Battery Box") - meta:set_float("technic_hv_power_machine", 1) - meta:set_string("formspec", battery_box_formspec) - local inv = meta:get_inventory() - inv:set_size("src", 1) - inv:set_size("dst", 1) - battery_charge = 0 - max_charge = 1500000 - last_side_shown=0 - 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, -}) + "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;HV Battery Box]".. + "label[3,0;Charge]".. + "label[5,0;Discharge]".. + "label[1,3;Power level]".. + "list[current_player;main;0,5;8,4;]" +minetest.register_node( + "technic:hv_battery_box", { + description = "HV Battery Box", + tiles = {"technic_hv_battery_box_top.png", "technic_hv_battery_box_bottom.png", "technic_hv_battery_box_side0.png", + "technic_hv_battery_box_side0.png", "technic_hv_battery_box_side0.png", "technic_hv_battery_box_side0.png"}, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), + drop="technic:hv_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", "HV Battery Box") + meta:set_float("technic_hv_power_machine", 1) + meta:set_string("formspec", battery_box_formspec) + 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 + return true + end, + }) for i=1,8,1 do -minetest.register_node("technic:hv_battery_box"..i, { - description = "HV Battery Box", - tiles = {"technic_hv_battery_box_top.png", "technic_hv_battery_box_bottom.png", "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", - "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_hv_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(), - paramtype="light", - light_source=9, - technic_power_machine=1, - last_side_shown=0, - drop="technic:hv_battery_box", - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_string("infotext", "HV Battery box") - meta:set_float("technic_hv_power_machine", 1) - meta:set_string("formspec", battery_box_formspec) - local inv = meta:get_inventory() - inv:set_size("src", 1) - inv:set_size("dst", 1) - battery_charge = 0 - max_charge = 1500000 - last_side_shown=0 - 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:hv_battery_box"..i, { + description = "HV Battery Box", + tiles = {"technic_hv_battery_box_top.png", "technic_hv_battery_box_bottom.png", "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", + "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_hv_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(), + paramtype="light", + light_source=9, + drop="technic:hv_battery_box", + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + local inv = meta:get_inventory() + meta:set_string("infotext", "HV Battery box") + meta:set_float("technic_hv_power_machine", 1) + meta:set_string("formspec", battery_box_formspec) + 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("dst") then + return false + elseif not inv:is_empty("src") then + return false + end + return true + end, + }) end +minetest.register_abm( + {nodenames = {"technic:hv_battery_box","technic:hv_battery_box1","technic:hv_battery_box2","technic:hv_battery_box3","technic:hv_battery_box4", + "technic:hv_battery_box5","technic:hv_battery_box6","technic:hv_battery_box7","technic:hv_battery_box8" + }, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.env:get_meta(pos) + local max_charge = 1500000 + local charge = meta:get_int("internal_EU_buffer") -HV_nodes_visited = {} - - -minetest.register_abm({ - nodenames = {"technic:hv_battery_box","technic:hv_battery_box1","technic:hv_battery_box2","technic:hv_battery_box3","technic:hv_battery_box4", - "technic:hv_battery_box5","technic:hv_battery_box6","technic:hv_battery_box7","technic:hv_battery_box8" - }, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - local meta = minetest.env:get_meta(pos) - charge= meta:get_int("battery_charge") - max_charge= 1500000 - local i=math.ceil((charge/max_charge)*8) - if i>8 then i=8 end - j=meta:get_float("last_side_shown") - if i~=j then - if i>0 then hacky_swap_node(pos,"technic:hv_battery_box"..i) - elseif i==0 then hacky_swap_node(pos,"technic:hv_battery_box") end - meta:set_float("last_side_shown",i) - end - ---loading registered power tools - local inv = meta:get_inventory() - if inv:is_empty("src")==false then - local srcstack = inv:get_stack("src", 1) - local src_item=srcstack:to_table() - local src_meta=get_item_meta(src_item["metadata"]) - - local item_max_charge=nil - for i=1,registered_power_tools_count,1 do - if power_tools[i].tool_name==src_item["name"] then - src_meta=get_item_meta(src_item["metadata"]) - if src_meta==nil then - src_meta={} - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - else - if src_meta["technic_power_tool"]==nil then - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - end - end - item_max_charge=power_tools[i].max_charge - end - end - - if item_max_charge then - load1=src_meta["charge"] - load_step=16000 - if load10 then - if charge-load_step<0 then load_step=charge end - if load1+load_step>item_max_charge then load_step=item_max_charge-load1 end - load1=load1+load_step - charge=charge-load_step - set_RE_wear(src_item,load1,item_max_charge) - src_meta["charge"]=load1 - src_item["metadata"]=set_item_meta(src_meta) - inv:set_stack("src", 1, src_item) - end - meta:set_int("battery_charge",charge) - end - end - --- dischargin registered power tools - if inv:is_empty("dst") == false then - srcstack = inv:get_stack("dst", 1) - src_item=srcstack:to_table() - local src_meta=get_item_meta(src_item["metadata"]) - local item_max_charge=nil - for i=1,registered_power_tools_count,1 do - if power_tools[i].tool_name==src_item["name"] then - src_meta=get_item_meta(src_item["metadata"]) - if src_meta==nil then - src_meta={} - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - else - if src_meta["technic_power_tool"]==nil then - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - end - end - item_max_charge=power_tools[i].max_charge - end + -- Select node textures + local i = math.ceil((charge/max_charge)*8) + if i > 8 then i = 8 end + local j = meta:get_float("last_side_shown") + if i~=j then + if i>0 then hacky_swap_node(pos,"technic:hv_battery_box"..i) + elseif i==0 then hacky_swap_node(pos,"technic:hv_battery_box") end + meta:set_float("last_side_shown",i) end - if item_max_charge then - local load1=src_meta["charge"] - load_step=16000 - if load1>0 and chargemax_charge then load_step=max_charge-charge end - if load1-load_step<0 then load_step=load1 end - load1=load1-load_step - charge=charge+load_step - set_RE_wear(src_item,load1,item_max_charge) - src_meta["charge"]=load1 - src_item["metadata"]=set_item_meta(src_meta) - inv:set_stack("dst", 1, src_item) - end - end - end - - meta:set_int("battery_charge",charge) + --charge registered power tools + local inv = meta:get_inventory() + if inv:is_empty("src")==false then + local srcstack = inv:get_stack("src", 1) + local src_item=srcstack:to_table() + local src_meta=get_item_meta(src_item["metadata"]) - local load = math.floor((charge/1500000) * 100) - meta:set_string("formspec", + for i=1,registered_power_tools_count,1 do + if power_tools[i].tool_name==src_item["name"] then + src_meta=get_item_meta(src_item["metadata"]) + if src_meta==nil then + src_meta={} + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + else + if src_meta["technic_power_tool"]==nil then + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + end + end + -- Do the charging + local item_max_charge = power_tools[i].max_charge + local load1 = src_meta["charge"] + local load_step = 16000 -- how much to charge per tick + if load10 then + if charge-load_step<0 then load_step=charge end + if load1+load_step>item_max_charge then load_step=item_max_charge-load1 end + load1=load1+load_step + charge=charge-load_step + set_RE_wear(src_item,load1,item_max_charge) + src_meta["charge"]=load1 + src_item["metadata"]=set_item_meta(src_meta) + inv:set_stack("src", 1, src_item) + end + meta:set_int("internal_EU_buffer",charge) + break + end + end + end + + -- discharging registered power tools + if inv:is_empty("dst") == false then + srcstack = inv:get_stack("dst", 1) + src_item=srcstack:to_table() + local src_meta=get_item_meta(src_item["metadata"]) + local item_max_charge=nil + for i=1,registered_power_tools_count,1 do + if power_tools[i].tool_name==src_item["name"] then + src_meta=get_item_meta(src_item["metadata"]) + if src_meta==nil then + src_meta={} + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + else + if src_meta["technic_power_tool"]==nil then + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + end + end + local item_max_charge = power_tools[i].max_charge + local load1 = src_meta["charge"] + local load_step = 16000 -- how much to discharge per tick + if load1>0 and chargemax_charge then load_step=max_charge-charge end + if load1-load_step<0 then load_step=load1 end + load1=load1-load_step + charge=charge+load_step + set_RE_wear(src_item,load1,item_max_charge) + src_meta["charge"]=load1 + src_item["metadata"]=set_item_meta(src_meta) + inv:set_stack("dst", 1, src_item) + end + meta:set_int("internal_EU_buffer",charge) + break + end + end + end + + + local load = math.floor((charge/1500000) * 100) + meta:set_string("formspec", hv_battery_box_formspec.. - "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. - (load)..":technic_power_meter_fg.png]" - ) - - local pos1={} + "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. + (load)..":technic_power_meter_fg.png]" + ) - pos1.y=pos.y-1 - pos1.x=pos.x - pos1.z=pos.z + -- Next index the surrounding network the get the producers and receivers on the + local pos1={} + pos1.y=pos.y-1 + pos1.x=pos.x + pos1.z=pos.z - - meta1 = minetest.env:get_meta(pos1) - if meta1:get_float("hv_cablelike")~=1 then return end + meta1 = minetest.env:get_meta(pos1) + if meta1:get_float("hv_cablelike")~=1 then return end local HV_nodes = {} local PR_nodes = {} local RE_nodes = {} + local BA_nodes = {} HV_nodes[1]={} HV_nodes[1].x=pos1.x HV_nodes[1].y=pos1.y HV_nodes[1].z=pos1.z HV_nodes[1].visited=false - -table_index=1 - repeat - check_HV_node (PR_nodes,RE_nodes,HV_nodes,table_index) - table_index=table_index+1 - if HV_nodes[table_index]==nil then break end - until false + local table_index=1 + repeat + check_HV_node (PR_nodes,RE_nodes,BA_nodes,HV_nodes,table_index) + table_index=table_index+1 + if HV_nodes[table_index]==nil then break end + until false -local pos1={} -i=1 - repeat - if PR_nodes[i]==nil then break end -- gettin power from all connected producers - pos1.x=PR_nodes[i].x - pos1.y=PR_nodes[i].y - pos1.z=PR_nodes[i].z - local meta1 = minetest.env:get_meta(pos1) - local internal_EU_buffer=meta1:get_float("internal_EU_buffer") - if charge0 then - charge=charge+charge_to_take - internal_EU_buffer=internal_EU_buffer-charge_to_take - meta1:set_float("internal_EU_buffer",internal_EU_buffer) - end - end - i=i+1 - until false + -- Get power from all connected producers + local pr_pos + for _,pr_pos in ipairs(PR_nodes) do + local meta1 = minetest.env:get_meta(pr_pos) + local internal_EU_buffer = meta1:get_float("internal_EU_buffer") + local charge_to_take = 4000 + if charge0 then + charge=charge+charge_to_take + internal_EU_buffer=internal_EU_buffer-charge_to_take + meta1:set_float("internal_EU_buffer",internal_EU_buffer) + end + end + end -if charge>max_charge then charge=max_charge end + if charge>max_charge then charge=max_charge end -i=1 - repeat - if RE_nodes[i]==nil then break end - pos1.x=RE_nodes[i].x -- loading all conected machines buffers - pos1.y=RE_nodes[i].y - pos1.z=RE_nodes[i].z - local meta1 = minetest.env:get_meta(pos1) - local internal_EU_buffer=meta1:get_float("internal_EU_buffer") - local internal_EU_buffer_size=meta1:get_float("internal_EU_buffer_size") + -- Provide power to all connected receivers + local re_pos + for _,re_pos in ipairs(RE_nodes) do + local meta1 = minetest.env:get_meta(re_pos) + local internal_EU_buffer = meta1:get_float("internal_EU_buffer") + local internal_EU_buffer_size = meta1:get_float("internal_EU_buffer_size") + local charge_to_give = math.min(4000, charge/table.getn(RE_nodes)) + if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then + charge_to_give=internal_EU_buffer_size-internal_EU_buffer + end + if charge-charge_to_give<0 then charge_to_give=charge end - local charge_to_give=4000 - if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then - charge_to_give=internal_EU_buffer_size-internal_EU_buffer - end - if charge-charge_to_give<0 then charge_to_give=charge end - - internal_EU_buffer=internal_EU_buffer+charge_to_give - meta1:set_float("internal_EU_buffer",internal_EU_buffer) - charge=charge-charge_to_give; - - i=i+1 - until false - charge=math.floor(charge) - charge_string=tostring(charge) - meta:set_string("infotext", "HV Battery Box: \n"..charge_string.."/"..max_charge); - meta:set_int("battery_charge",charge) + internal_EU_buffer=internal_EU_buffer+charge_to_give + meta1:set_float("internal_EU_buffer",internal_EU_buffer) + charge=charge-charge_to_give; + end + charge=math.floor(charge) + meta:set_string("infotext", "MV Battery box: "..charge.."/"..max_charge); + meta:set_int("internal_EU_buffer",charge) + end + }) +-- 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") +for i=1,8,1 do + register_HV_machine("technic:hv_battery_box"..i,"BA") end -}) function add_new_HVcable_node (HV_nodes,pos1) -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 -HV_nodes[i].visited=false -return true + 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 end -function check_HV_node (PR_nodes,RE_nodes,HV_nodes,i) - local pos1={} - pos1.x=HV_nodes[i].x - pos1.y=HV_nodes[i].y - pos1.z=HV_nodes[i].z - HV_nodes[i].visited=true - new_node_added=false - - pos1.x=pos1.x+1 - check_HV_node_subp (PR_nodes,RE_nodes,HV_nodes,pos1) - pos1.x=pos1.x-2 - check_HV_node_subp (PR_nodes,RE_nodes,HV_nodes,pos1) - pos1.x=pos1.x+1 - - pos1.y=pos1.y+1 - check_HV_node_subp (PR_nodes,RE_nodes,HV_nodes,pos1) - pos1.y=pos1.y-2 - check_HV_node_subp (PR_nodes,RE_nodes,HV_nodes,pos1) - pos1.y=pos1.y+1 +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.z=pos1.z+1 - check_HV_node_subp (PR_nodes,RE_nodes,HV_nodes,pos1) - pos1.z=pos1.z-2 - check_HV_node_subp (PR_nodes,RE_nodes,HV_nodes,pos1) - pos1.z=pos1.z+1 -return new_node_added + 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,HV_nodes,pos1) -meta = minetest.env:get_meta(pos1) -if meta:get_float("hv_cablelike")==1 then new_node_added=add_new_HVcable_node(HV_nodes,pos1) end -for i in ipairs(HV_machines) do - if minetest.env:get_node(pos1).name == HV_machines[i].machine_name then - if HV_machines[i].machine_type == "PR" then - new_node_added=add_new_HVcable_node(PR_nodes,pos1) - end - if HV_machines[i].machine_type == "RE" then - new_node_added=add_new_HVcable_node(RE_nodes,pos1) - end - 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 -end - diff --git a/technic/battery_box_mv.lua b/technic/battery_box_mv.lua index 8fc6dc7..86c445c 100644 --- a/technic/battery_box_mv.lua +++ b/technic/battery_box_mv.lua @@ -1,355 +1,338 @@ -MV_machines = {} - -registered_MV_machines_count=0 - -function register_MV_machine (string1,string2) -registered_MV_machines_count=registered_MV_machines_count+1 -MV_machines[registered_MV_machines_count]={} -MV_machines[registered_MV_machines_count].machine_name=string1 -MV_machines[registered_MV_machines_count].machine_type=string2 +-- register MV machines here +technic.MV_machines = {} +--local MV_machines = {} +local MV_machines = technic.MV_machines +function register_MV_machine(string1,string2) + technic.MV_machines[string1] = string2 end -minetest.register_craft({ - output = 'technic:mv_battery_box 1', - recipe = { - {'technic:battery_box', 'technic:battery_box', 'technic:battery_box'}, - {'technic:battery_box', 'technic:mv_transformer', 'technic:battery_box'}, - {'', 'technic:mv_cable', ''}, - } -}) +minetest.register_craft( + { + output = 'technic:mv_battery_box 1', + recipe = { + {'technic:battery_box', 'technic:battery_box', 'technic:battery_box'}, + {'technic:battery_box', 'technic:mv_transformer', 'technic:battery_box'}, + {'', 'technic:mv_cable', ''}, + } + }) mv_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;MV_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;MV_Battery box]".. + "label[3,0;Charge]".. + "label[5,0;Discharge]".. + "label[1,3;Power level]".. + "list[current_player;main;0,5;8,4;]" -minetest.register_node("technic:mv_battery_box", { - description = "MV Battery Box", - tiles = {"technic_mv_battery_box_top.png", "technic_mv_battery_box_bottom.png", "technic_mv_battery_box_side0.png", - "technic_mv_battery_box_side0.png", "technic_mv_battery_box_side0.png", "technic_mv_battery_box_side0.png"}, - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - sounds = default.node_sound_wood_defaults(), - technic_mv_power_machine=1, - last_side_shown=0, - drop="technic:mv_battery_box", - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_string("infotext", "MV Battery box") - meta:set_float("technic_mv_power_machine", 1) - meta:set_string("formspec", battery_box_formspec) - local inv = meta:get_inventory() - inv:set_size("src", 1) - inv:set_size("dst", 1) - battery_charge = 0 - max_charge = 300000 - last_side_shown=0 - 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 +minetest.register_node( + "technic:mv_battery_box", { + description = "MV Battery Box", + tiles = {"technic_mv_battery_box_top.png", "technic_mv_battery_box_bottom.png", "technic_mv_battery_box_side0.png", + "technic_mv_battery_box_side0.png", "technic_mv_battery_box_side0.png", "technic_mv_battery_box_side0.png"}, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), + drop = "technic:mv_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", "MV Battery box") + meta:set_float("technic_mv_power_machine", 1) + meta:set_string("formspec", battery_box_formspec) + meta:set_float("internal_EU_buffer", 0) + meta:set_float("internal_EU_buffer_size", 300000) + 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 + return true end - return true - end, -}) + }) for i=1,8,1 do -minetest.register_node("technic:mv_battery_box"..i, { - description = "MV Battery Box", - tiles = {"technic_mv_battery_box_top.png", "technic_mv_battery_box_bottom.png", "technic_mv_battery_box_side0.png^technic_power_meter"..i..".png", - "technic_mv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_mv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_mv_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(), - technic_power_machine=1, - last_side_shown=0, - drop="technic:mv_battery_box", - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_string("infotext", "MV Battery box") - meta:set_float("technic_mv_power_machine", 1) - meta:set_string("formspec", battery_box_formspec) - local inv = meta:get_inventory() - inv:set_size("src", 1) - inv:set_size("dst", 1) - battery_charge = 0 - max_charge = 300000 - last_side_shown=0 - 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:mv_battery_box"..i, { + description = "MV Battery Box", + tiles = {"technic_mv_battery_box_top.png", "technic_mv_battery_box_bottom.png", "technic_mv_battery_box_side0.png^technic_power_meter"..i..".png", + "technic_mv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_mv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_mv_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:mv_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", "MV Battery box") + meta:set_float("technic_mv_power_machine", 1) + meta:set_string("formspec", battery_box_formspec) + meta:set_float("internal_EU_buffer", 0) + meta:set_float("internal_EU_buffer_size", 300000) + 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 + return true + end + }) end +minetest.register_abm( + {nodenames = {"technic:mv_battery_box","technic:mv_battery_box1","technic:mv_battery_box2","technic:mv_battery_box3","technic:mv_battery_box4", + "technic:mv_battery_box5","technic:mv_battery_box6","technic:mv_battery_box7","technic:mv_battery_box8" + }, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.env:get_meta(pos) + local max_charge = 300000 -- Set maximum charge for the device here + local charge = meta:get_int("internal_EU_buffer") -MV_nodes_visited = {} - - -minetest.register_abm({ - nodenames = {"technic:mv_battery_box","technic:mv_battery_box1","technic:mv_battery_box2","technic:mv_battery_box3","technic:mv_battery_box4", - "technic:mv_battery_box5","technic:mv_battery_box6","technic:mv_battery_box7","technic:mv_battery_box8" - }, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - local meta = minetest.env:get_meta(pos) - charge= meta:get_int("battery_charge") - max_charge= 300000 - local i=math.ceil((charge/max_charge)*8) - if i>8 then i=8 end - j=meta:get_float("last_side_shown") - if i~=j then - if i>0 then hacky_swap_node(pos,"technic:mv_battery_box"..i) - elseif i==0 then hacky_swap_node(pos,"technic:mv_battery_box") end - meta:set_float("last_side_shown",i) - end - ---loading registered power tools - local inv = meta:get_inventory() - if inv:is_empty("src")==false then - local srcstack = inv:get_stack("src", 1) - local src_item=srcstack:to_table() - local src_meta=get_item_meta(src_item["metadata"]) - - local item_max_charge=nil - for i=1,registered_power_tools_count,1 do - if power_tools[i].tool_name==src_item["name"] then - src_meta=get_item_meta(src_item["metadata"]) - if src_meta==nil then - src_meta={} - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - else - if src_meta["technic_power_tool"]==nil then - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - end - end - item_max_charge=power_tools[i].max_charge - end - end - - if item_max_charge then - load1=src_meta["charge"] - load_step=4000 - if load10 then - if charge-load_step<0 then load_step=charge end - if load1+load_step>item_max_charge then load_step=item_max_charge-load1 end - load1=load1+load_step - charge=charge-load_step - set_RE_wear(src_item,load1,item_max_charge) - src_meta["charge"]=load1 - src_item["metadata"]=set_item_meta(src_meta) - inv:set_stack("src", 1, src_item) - end - meta:set_int("battery_charge",charge) - end - end - --- dischargin registered power tools - if inv:is_empty("dst") == false then - srcstack = inv:get_stack("dst", 1) - src_item=srcstack:to_table() - local src_meta=get_item_meta(src_item["metadata"]) - local item_max_charge=nil - for i=1,registered_power_tools_count,1 do - if power_tools[i].tool_name==src_item["name"] then - src_meta=get_item_meta(src_item["metadata"]) - if src_meta==nil then - src_meta={} - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - else - if src_meta["technic_power_tool"]==nil then - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - end - end - item_max_charge=power_tools[i].max_charge - end + -- Select node textures + local i = math.ceil((charge/max_charge)*8) + if i > 8 then i = 8 end + local j = meta:get_float("last_side_shown") + if i~=j then + if i>0 then hacky_swap_node(pos,"technic:mv_battery_box"..i) + elseif i==0 then hacky_swap_node(pos,"technic:mv_battery_box") end + meta:set_float("last_side_shown",i) end - if item_max_charge then - local load1=src_meta["charge"] - load_step=4000 - if load1>0 and chargemax_charge then load_step=max_charge-charge end - if load1-load_step<0 then load_step=load1 end - load1=load1-load_step - charge=charge+load_step - set_RE_wear(src_item,load1,item_max_charge) - src_meta["charge"]=load1 - src_item["metadata"]=set_item_meta(src_meta) - inv:set_stack("dst", 1, src_item) - end - end - end - - meta:set_int("battery_charge",charge) + --charge registered power tools + local inv = meta:get_inventory() + if inv:is_empty("src")==false then + local srcstack = inv:get_stack("src", 1) + local src_item=srcstack:to_table() + local src_meta=get_item_meta(src_item["metadata"]) - local load = math.floor((charge/300000) * 100) - meta:set_string("formspec", + -- Power tools should really be made into a hash table to avoid linear search. But the list is short so okay... + for i=1,registered_power_tools_count,1 do + if power_tools[i].tool_name==src_item["name"] then + -- What is this code doing? Setting tool properties if not set already???? + src_meta=get_item_meta(src_item["metadata"]) + if src_meta==nil then + src_meta={} + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + else + if src_meta["technic_power_tool"]==nil then + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + end + end + -- Do the charging + local item_max_charge = power_tools[i].max_charge + local load1 = src_meta["charge"] + local load_step = 4000 -- how much to charge per tick + if load10 then + if charge-load_step<0 then load_step=charge end + if load1+load_step>item_max_charge then load_step=item_max_charge-load1 end + load1=load1+load_step + charge=charge-load_step + set_RE_wear(src_item,load1,item_max_charge) + src_meta["charge"] = load1 + src_item["metadata"] = set_item_meta(src_meta) + inv:set_stack("src", 1, src_item) + end + meta:set_int("internal_EU_buffer",charge) + break + end + end + end + + -- discharging registered power tools + if inv:is_empty("dst") == false then + srcstack = inv:get_stack("dst", 1) + src_item=srcstack:to_table() + local src_meta=get_item_meta(src_item["metadata"]) + local item_max_charge=nil + for i=1,registered_power_tools_count,1 do + if power_tools[i].tool_name==src_item["name"] then + src_meta=get_item_meta(src_item["metadata"]) + if src_meta==nil then + src_meta={} + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + else + if src_meta["technic_power_tool"]==nil then + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + end + end + local item_max_charge = power_tools[i].max_charge + local load1 = src_meta["charge"] + local load_step = 4000 -- how much to discharge per tick + if load1>0 and chargemax_charge then load_step=max_charge-charge end + if load1-load_step<0 then load_step=load1 end + load1=load1-load_step + charge=charge+load_step + set_RE_wear(src_item,load1,item_max_charge) + src_meta["charge"]=load1 + src_item["metadata"]=set_item_meta(src_meta) + inv:set_stack("dst", 1, src_item) + end + meta:set_int("internal_EU_buffer",charge) + break + end + end + end + + local load = math.floor((charge/300000) * 100) + meta:set_string("formspec", mv_battery_box_formspec.. - "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. - (load)..":technic_power_meter_fg.png]" - ) - - local pos1={} + "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. + (load)..":technic_power_meter_fg.png]" + ) - pos1.y=pos.y-1 - pos1.x=pos.x - pos1.z=pos.z + -- Next index the surrounding network the get the producers and receivers on the power grid + local pos1 = {} + pos1.y = pos.y-1 + pos1.x = pos.x + pos1.z = pos.z - - meta1 = minetest.env:get_meta(pos1) - if meta1:get_float("mv_cablelike")~=1 then return end + meta1 = minetest.env:get_meta(pos1) + if meta1:get_float("mv_cablelike")~=1 then return end local MV_nodes = {} local PR_nodes = {} local RE_nodes = {} + local BA_nodes = {} - MV_nodes[1]={} - MV_nodes[1].x=pos1.x - MV_nodes[1].y=pos1.y - MV_nodes[1].z=pos1.z - MV_nodes[1].visited=false - -table_index=1 - repeat - check_MV_node (PR_nodes,RE_nodes,MV_nodes,table_index) - table_index=table_index+1 - if MV_nodes[table_index]==nil then break end - until false + MV_nodes[1] = {} + MV_nodes[1].x = pos1.x + MV_nodes[1].y = pos1.y + MV_nodes[1].z = pos1.z + local table_index=1 + repeat + check_MV_node(PR_nodes,RE_nodes,BA_nodes,MV_nodes,table_index) + table_index=table_index+1 + if MV_nodes[table_index]==nil then break end + until false -local pos1={} -i=1 - repeat - if PR_nodes[i]==nil then break end -- gettin power from all connected producers - pos1.x=PR_nodes[i].x - pos1.y=PR_nodes[i].y - pos1.z=PR_nodes[i].z - local meta1 = minetest.env:get_meta(pos1) - local internal_EU_buffer=meta1:get_float("internal_EU_buffer") - if charge0 then - charge=charge+charge_to_take - internal_EU_buffer=internal_EU_buffer-charge_to_take - meta1:set_float("internal_EU_buffer",internal_EU_buffer) - end - end - i=i+1 - until false + -- Get power from all connected producers + local pr_pos + for _,pr_pos in ipairs(PR_nodes) do + local meta1 = minetest.env:get_meta(pr_pos) + local internal_EU_buffer = meta1:get_float("internal_EU_buffer") + local charge_to_take = 1000 + if charge0 then + charge=charge+charge_to_take + internal_EU_buffer=internal_EU_buffer-charge_to_take + meta1:set_float("internal_EU_buffer",internal_EU_buffer) + end + end + end -if charge>max_charge then charge=max_charge end + if charge>max_charge then charge=max_charge end -i=1 - repeat - if RE_nodes[i]==nil then break end - pos1.x=RE_nodes[i].x -- loading all conected machines buffers - pos1.y=RE_nodes[i].y - pos1.z=RE_nodes[i].z - local meta1 = minetest.env:get_meta(pos1) - local internal_EU_buffer=meta1:get_float("internal_EU_buffer") - local internal_EU_buffer_size=meta1:get_float("internal_EU_buffer_size") + -- Provide power to all connected receivers + local re_pos + for _,re_pos in ipairs(RE_nodes) do + local meta1 = minetest.env:get_meta(re_pos) + local internal_EU_buffer = meta1:get_float("internal_EU_buffer") + local internal_EU_buffer_size = meta1:get_float("internal_EU_buffer_size") + local charge_to_give = math.min(1000, charge/table.getn(RE_nodes)) + if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then + charge_to_give=internal_EU_buffer_size-internal_EU_buffer + end + if charge-charge_to_give<0 then charge_to_give=charge end - local charge_to_give=1000 - if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then - charge_to_give=internal_EU_buffer_size-internal_EU_buffer - end - if charge-charge_to_give<0 then charge_to_give=charge end - - internal_EU_buffer=internal_EU_buffer+charge_to_give - meta1:set_float("internal_EU_buffer",internal_EU_buffer) - charge=charge-charge_to_give; - - i=i+1 - until false - charge=math.floor(charge) - charge_string=tostring(charge) - meta:set_string("infotext", "Battery box: "..charge_string.."/"..max_charge); - meta:set_int("battery_charge",charge) + internal_EU_buffer=internal_EU_buffer+charge_to_give + meta1:set_float("internal_EU_buffer",internal_EU_buffer) + charge=charge-charge_to_give; + end + charge=math.floor(charge) + meta:set_string("infotext", "MV Battery box: "..charge.."/"..max_charge); + meta:set_int("internal_EU_buffer",charge) + end + }) +-- 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") +for i=1,8,1 do + register_MV_machine("technic:mv_battery_box"..i,"BA") end -}) function add_new_MVcable_node (MV_nodes,pos1) -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 -MV_nodes[i].visited=false -return true + 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,MV_nodes,i) - local pos1={} - pos1.x=MV_nodes[i].x - pos1.y=MV_nodes[i].y - pos1.z=MV_nodes[i].z - MV_nodes[i].visited=true - new_node_added=false - - pos1.x=pos1.x+1 - check_MV_node_subp (PR_nodes,RE_nodes,MV_nodes,pos1) - pos1.x=pos1.x-2 - check_MV_node_subp (PR_nodes,RE_nodes,MV_nodes,pos1) - pos1.x=pos1.x+1 - - pos1.y=pos1.y+1 - check_MV_node_subp (PR_nodes,RE_nodes,MV_nodes,pos1) - pos1.y=pos1.y-2 - check_MV_node_subp (PR_nodes,RE_nodes,MV_nodes,pos1) - pos1.y=pos1.y+1 +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.z=pos1.z+1 - check_MV_node_subp (PR_nodes,RE_nodes,MV_nodes,pos1) - pos1.z=pos1.z-2 - check_MV_node_subp (PR_nodes,RE_nodes,MV_nodes,pos1) - pos1.z=pos1.z+1 -return new_node_added + 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,MV_nodes,pos1) -meta = minetest.env:get_meta(pos1) -if meta:get_float("mv_cablelike")==1 then new_node_added=add_new_MVcable_node(MV_nodes,pos1) end -for i in ipairs(MV_machines) do - if minetest.env:get_node(pos1).name == MV_machines[i].machine_name then - if MV_machines[i].machine_type == "PR" then - new_node_added=add_new_MVcable_node(PR_nodes,pos1) - end - if MV_machines[i].machine_type == "RE" then - new_node_added=add_new_MVcable_node(RE_nodes,pos1) - end - 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 -end - diff --git a/technic/down_converter_hv.lua b/technic/down_converter_hv.lua new file mode 100644 index 0000000..0e2e16d --- /dev/null +++ b/technic/down_converter_hv.lua @@ -0,0 +1,225 @@ +-- The HV down converter will step down HV EUs to MV EUs +-- If we take the solar panel as calibration then the +-- 1 HVEU = 5 MVEU as we stack 5 MV arrays to get a HV array. +-- The downconverter does of course have a conversion loss. +-- This loses 30% of the power. +-- The converter does not store any energy by itself. +minetest.register_node("technic:down_converter_hv", { + description = "HV Down Converter", + tiles = {"technic_hv_down_converter_top.png", "technic_hv_down_converter_bottom.png", "technic_hv_down_converter_side.png", + "technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png"}, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), + drawtype = "nodebox", + paramtype = "light", + is_ground_content = true, + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_float("technic_hv_power_machine", 1) + meta:set_float("technic_mv_power_machine", 1) + meta:set_float("internal_EU_buffer",0) + meta:set_float("internal_EU_buffer_size",0) + meta:set_string("infotext", "HV Down Converter") + meta:set_float("active", false) + end, + }) + +minetest.register_craft({ + output = 'technic:down_converter_hv 1', + recipe = { + {'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot','technic:stainless_steel_ingot'}, + {'technic:hv_transformer', 'technic:hv_cable', 'technic:mv_transformer'}, + {'technic:hv_cable', 'technic:rubber', 'technic:mv_cable'}, + } +}) + +minetest.register_abm( + {nodenames = {"technic:down_converter_hv"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + -- HV->MV conversion factor + local hv_mv_factor = 5 + -- The maximun charge a single converter can handle. Let's set this to + -- what 5 HV solar arrays can produce - 30% loss (2880*5*0.7) + local max_charge = 10080*hv_mv_factor + + local meta = minetest.env:get_meta(pos) + local meta1 = nil + local pos1 = {} + local available_charge = 0 -- counted in MV units + local used_charge = 0 -- counted in MV units + + -- Index all HV nodes connected to the network + -- HV cable comes in through the bottom + pos1.y = pos.y-1 + pos1.x = pos.x + pos1.z = pos.z + meta1 = minetest.env:get_meta(pos1) + if meta1:get_float("hv_cablelike")~=1 then return end + + local HV_nodes = {} -- HV type + local HV_PR_nodes = {} -- HV type + local HV_BA_nodes = {} -- HV type + + HV_nodes[1] = {} + HV_nodes[1].x = pos1.x + HV_nodes[1].y = pos1.y + HV_nodes[1].z = pos1.z + + local table_index = 1 + repeat + check_HV_node(HV_PR_nodes,nil,HV_BA_nodes,HV_nodes,table_index) + table_index = table_index + 1 + if HV_nodes[table_index] == nil then break end + until false + + --print("HV_nodes: PR="..table.getn(HV_PR_nodes).." BA="..table.getn(HV_BA_nodes)) + + -- Index all MV nodes connected to the network + -- MV cable comes out of the top + pos1.y = pos.y+1 + pos1.x = pos.x + pos1.z = pos.z + meta1 = minetest.env:get_meta(pos1) + if meta1:get_float("mv_cablelike")~=1 then return end + + local MV_nodes = {} -- MV type + local MV_RE_nodes = {} -- MV type + local MV_BA_nodes = {} -- MV type + + MV_nodes[1] = {} + MV_nodes[1].x = pos1.x + MV_nodes[1].y = pos1.y + MV_nodes[1].z = pos1.z + + table_index = 1 + repeat + check_MV_node(nil,MV_RE_nodes,MV_BA_nodes,MV_nodes,table_index) + table_index = table_index + 1 + if MV_nodes[table_index] == nil then break end + until false + + --print("MV_nodes: RE="..table.getn(MV_RE_nodes).." BA="..table.getn(MV_BA_nodes)) + + -- First get available power from all the attached HV suppliers + -- Get the supplier internal EU buffer and read the EUs from it + -- No update yet! + local pos1 +-- FIXME: Until further leave the producers out of it and just let the batteries be the hub +-- for _,pos1 in ipairs(HV_PR_nodes) do +-- meta1 = minetest.env:get_meta(pos1) +-- local internal_EU_buffer = meta1:get_float("internal_EU_buffer") +-- available_charge = available_charge + meta1:get_float("internal_EU_buffer") * hv_mv_factor +-- -- Limit conversion capacity +-- if available_charge > max_charge then +-- available_charge = max_charge +-- break +-- end +-- end +-- --print("Available_charge PR:"..available_charge) + + for _,pos1 in ipairs(HV_BA_nodes) do + meta1 = minetest.env:get_meta(pos1) + local internal_EU_buffer = meta1:get_float("internal_EU_buffer") + available_charge = available_charge + meta1:get_float("internal_EU_buffer") * hv_mv_factor + -- Limit conversion capacity + if available_charge > max_charge then + available_charge = max_charge + break + end + end + --print("Available_charge PR+BA:"..available_charge) + + -- Calculate total number of receivers: + local MV_receivers = table.getn(MV_RE_nodes)+table.getn(MV_BA_nodes) + + -- Next supply power to all connected MV machines + -- Get the power receiver internal EU buffer and give EUs to it + -- Note: for now leave out RE type machines until producers distribute power themselves even without a battery +-- for _,pos1 in ipairs(MV_RE_nodes) do +-- local meta1 = minetest.env:get_meta(pos1) +-- local internal_EU_buffer = meta1:get_float("internal_EU_buffer") +-- local internal_EU_buffer_size = meta1:get_float("internal_EU_buffer_size") +-- local charge_to_give = math.min(4000, available_charge/MV_receivers) -- power rating limit on the MV wire +-- -- How much can this unit take? +-- if internal_EU_buffer+charge_to_give > internal_EU_buffer_size then +-- charge_to_give=internal_EU_buffer_size-internal_EU_buffer +-- end +-- -- If we are emptying the supply take the remainder +-- if available_charge internal_EU_buffer_size then + charge_to_give=internal_EU_buffer_size-internal_EU_buffer + end + --print("charge_to_give2:"..charge_to_give) + -- If we are emptying the supply take the remainder + if available_charge 0 then + internal_EU_buffer = internal_EU_buffer-charge_to_take + meta1:set_float("internal_EU_buffer",internal_EU_buffer) + end + end + + if used_charge>0 then + meta:set_string("infotext", "HV Down Converter is active (HV:"..available_charge.."/MV:"..used_charge..")"); + meta:set_float("active",1) -- used for setting textures someday maybe + else + meta:set_string("infotext", "HV Down Converter is inactive (HV:"..available_charge.."/MV:"..used_charge..")"); + meta:set_float("active",0) -- used for setting textures someday maybe + return + end + end, +}) + +-- This machine does not store energy it receives energy from the HV side and outputs it on the MV side +register_HV_machine ("technic:down_converter_hv","RE") +register_MV_machine ("technic:down_converter_hv","PR") diff --git a/technic/down_converter_mv.lua b/technic/down_converter_mv.lua new file mode 100644 index 0000000..1d26630 --- /dev/null +++ b/technic/down_converter_mv.lua @@ -0,0 +1,226 @@ +-- The MV down converter will step down MV EUs to LV EUs +-- If we take the solar panel as calibration then the +-- 1 MVEU = 5 LVEU as we stack 5 LV arrays to get an MV array. +-- The downconverter does of course have a conversion loss. +-- This loses 30% of the power. +-- The converter does not store any energy by itself. +minetest.register_node( + "technic:down_converter_mv", { + description = "MV Down Converter", + tiles = {"technic_mv_down_converter_top.png", "technic_mv_down_converter_bottom.png", "technic_mv_down_converter_side.png", + "technic_mv_down_converter_side.png", "technic_mv_down_converter_side.png", "technic_mv_down_converter_side.png"}, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), + drawtype = "nodebox", + paramtype = "light", + is_ground_content = true, + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_float("technic_mv_power_machine", 1) + meta:set_float("technic_power_machine", 1) + meta:set_float("internal_EU_buffer",0) + meta:set_float("internal_EU_buffer_size",0) + meta:set_string("infotext", "MV Down Converter") + meta:set_float("active", false) + end, + }) + +minetest.register_craft({ + output = 'technic:down_converter_mv 1', + recipe = { + {'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot','technic:stainless_steel_ingot'}, + {'technic:mv_transformer', 'technic:mv_cable', 'technic:lv_transformer'}, + {'technic:mv_cable', 'technic:rubber', 'technic:lv_cable'}, + } +}) + +minetest.register_abm( + {nodenames = {"technic:down_converter_mv"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + -- MV->LV conversion factor + local mv_lv_factor = 5 + -- The maximun charge a single converter can handle. Let's set this to + -- what 5 MV solar arrays can produce - 30% loss (720*5*0.7) + local max_charge = 2520*mv_lv_factor + + local meta = minetest.env:get_meta(pos) + local meta1 = nil + local pos1 = {} + local available_charge = 0 -- counted in LV units + local used_charge = 0 -- counted in LV units + + -- Index all MV nodes connected to the network + -- MV cable comes in through the bottom + pos1.y = pos.y-1 + pos1.x = pos.x + pos1.z = pos.z + meta1 = minetest.env:get_meta(pos1) + if meta1:get_float("mv_cablelike")~=1 then return end + + local MV_nodes = {} -- MV type + local MV_PR_nodes = {} -- MV type + local MV_BA_nodes = {} -- MV type + + MV_nodes[1] = {} + MV_nodes[1].x = pos1.x + MV_nodes[1].y = pos1.y + MV_nodes[1].z = pos1.z + + local table_index = 1 + repeat + check_MV_node(MV_PR_nodes,nil,MV_BA_nodes,MV_nodes,table_index) + table_index = table_index + 1 + if MV_nodes[table_index] == nil then break end + until false + + --print("MV_nodes: PR="..table.getn(MV_PR_nodes).." BA="..table.getn(MV_BA_nodes)) + + -- Index all LV nodes connected to the network + -- LV cable comes out of the top + pos1.y = pos.y+1 + pos1.x = pos.x + pos1.z = pos.z + meta1 = minetest.env:get_meta(pos1) + if meta1:get_float("cablelike")~=1 then return end + + local LV_nodes = {} -- LV type + local LV_RE_nodes = {} -- LV type + local LV_BA_nodes = {} -- LV type + + LV_nodes[1] = {} + LV_nodes[1].x = pos1.x + LV_nodes[1].y = pos1.y + LV_nodes[1].z = pos1.z + + table_index = 1 + repeat + check_LV_node(nil,LV_RE_nodes,LV_BA_nodes,LV_nodes,table_index) + table_index = table_index + 1 + if LV_nodes[table_index] == nil then break end + until false + + --print("LV_nodes: RE="..table.getn(LV_RE_nodes).." BA="..table.getn(LV_BA_nodes)) + + -- First get available power from all the attached MV suppliers + -- Get the supplier internal EU buffer and read the EUs from it + -- No update yet! + local pos1 +-- FIXME: Until further leave the producers out of it and just let the batteries be the hub +-- for _,pos1 in ipairs(MV_PR_nodes) do +-- meta1 = minetest.env:get_meta(pos1) +-- local internal_EU_buffer = meta1:get_float("internal_EU_buffer") +-- available_charge = available_charge + meta1:get_float("internal_EU_buffer") * mv_lv_factor +-- -- Limit conversion capacity +-- if available_charge > max_charge then +-- available_charge = max_charge +-- break +-- end +-- end +-- print("Available_charge PR:"..available_charge) + + for _,pos1 in ipairs(MV_BA_nodes) do + meta1 = minetest.env:get_meta(pos1) + local internal_EU_buffer = meta1:get_float("internal_EU_buffer") + available_charge = available_charge + meta1:get_float("internal_EU_buffer") * mv_lv_factor + -- Limit conversion capacity + if available_charge > max_charge then + available_charge = max_charge + break + end + end + --print("Available_charge PR+BA:"..available_charge) + + -- Calculate total number of receivers: + local LV_receivers = table.getn(LV_RE_nodes)+table.getn(LV_BA_nodes) + + -- Next supply power to all connected LV machines + -- Get the power receiver internal EU buffer and give EUs to it + -- Note: for now leave out RE type machines until producers distribute power themselves even without a battery +-- for _,pos1 in ipairs(LV_RE_nodes) do +-- local meta1 = minetest.env:get_meta(pos1) +-- local internal_EU_buffer = meta1:get_float("internal_EU_buffer") +-- local internal_EU_buffer_size = meta1:get_float("internal_EU_buffer_size") +-- local charge_to_give = math.min(1000, available_charge/LV_receivers) -- power rating limit on the LV wire +-- -- How much can this unit take? +-- if internal_EU_buffer+charge_to_give > internal_EU_buffer_size then +-- charge_to_give=internal_EU_buffer_size-internal_EU_buffer +-- end +-- -- If we are emptying the supply take the remainder +-- if available_charge internal_EU_buffer_size then + charge_to_give=internal_EU_buffer_size-internal_EU_buffer + end + --print("charge_to_give2:"..charge_to_give) + -- If we are emptying the supply take the remainder + if available_charge 0 then + internal_EU_buffer = internal_EU_buffer-charge_to_take + meta1:set_float("internal_EU_buffer",internal_EU_buffer) + end + end + + if used_charge>0 then + meta:set_string("infotext", "MV Down Converter is active (MV:"..available_charge.."/LV:"..used_charge..")"); + meta:set_float("active",1) -- used for setting textures someday maybe + else + meta:set_string("infotext", "MV Down Converter is inactive (MV:"..available_charge.."/LV:"..used_charge..")"); + meta:set_float("active",0) -- used for setting textures someday maybe + return + end + end, +}) + +-- This machine does not store energy it receives energy from the MV side and outputs it on the LV side +register_MV_machine ("technic:down_converter_mv","RE") +register_LV_machine ("technic:down_converter_mv","PR") diff --git a/technic/init.lua b/technic/init.lua index 3cc73be..2248295 100644 --- a/technic/init.lua +++ b/technic/init.lua @@ -36,6 +36,7 @@ dofile(modpath.."/cnc_nodes.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.."/electric_furnace_mv.lua") dofile(modpath.."/alloy_furnace_mv.lua") dofile(modpath.."/forcefield.lua") @@ -44,6 +45,7 @@ dofile(modpath.."/forcefield.lua") 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 diff --git a/technic/solar_array_mv.lua b/technic/solar_array_mv.lua index de75301..abcc027 100644 --- a/technic/solar_array_mv.lua +++ b/technic/solar_array_mv.lua @@ -83,7 +83,8 @@ minetest.register_abm( 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. else meta:set_string("infotext", "Solar Array is inactive"); meta:set_float("active",0) diff --git a/technic/textures/technic_hv_down_converter_bottom.png b/technic/textures/technic_hv_down_converter_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..996b2d4cfdcd63908ee512b0f2165c090f861e7b GIT binary patch literal 653 zcmV;80&@L{P)(7T;J|G13}rY z@Tm0bALX;xpEoohhzV*+SA!`%6I7rIR1pK?~cCg+;Y-8Ps>%tTzdJjrt+Cgd69y9@8?Wz>6W zmn7eP`URy+a}9{PuoAw1^9$@oK4KXRI91TgNE$kdM@)YF>1Td>^E?KfYu zkBxWNNu2>Ibc3TxXDySe;pQAq2iG-;83aN6@h5Rj#0&yNp|j{Llv*|Dndt7=Z6IA- zbMoPt8wL1gu#_Sy*zTwdTXBid)#PI`GdONLw|&Rmd3ip_nq(FLx;f%2B_|7e+No-E zCOwq<-~aH{>o3{2XIzBswsZaaA2H)&8@ro|!bOD!%mh0&#&CY9Ul9ZzP+8Ppg$?8B zY7E|6H(!RloeW7z^+p=00000NkvXXu0mjfouVKV literal 0 HcmV?d00001 diff --git a/technic/textures/technic_hv_down_converter_side.png b/technic/textures/technic_hv_down_converter_side.png new file mode 100644 index 0000000000000000000000000000000000000000..ab904f1c14f4d6c5c1e001499032a330684b44ef GIT binary patch literal 609 zcmV-n0-pVeP)sj50q#je zK~y-)b(249R6!KQfA`*b@8u6<30ub{iU^8==~oQc=2KXRU%=9Upr1ml{RCDP%9a*Z zHWr38LaGoph3@WqbFalD>zc5)nK>}`%*;9G%FSoPfB*zBK}`t{FeTayD&P*PhzgM% z1fq4MG7`m;f+28gW^@-Qi+CIT|gnAc!fp zR-s}FPLbhC<1*PYw#^!?44-wR@F+qFJUQE=+fWWq4>&%1a7}|ZKi)%QPT)%d)_XC0^z0g5V-9d9!}??6`eBW7h)i0njm6fZG|Hlt0#)~b~RsV)Q& zASzgsP^pZFKtu=+^0Zw^kaPK-)(J_5sF28xtv9#_pZZ^~<)GIeGC3c?Iqa`P@9vO? zqcb7`?;I5s0#K8S=6`-)#g|q_o5{cD#YWGLbdGG)3!hi{zX;OLQ?xR&2O2pbg2?{g z&CBV#`T|su+ECLnOnBh)j{6@@@OGEiTT4OOx(w0*hacbJ?QJ6eK~tGpx%K=}h?PlOWI>Z#Y$cHwGJZ*_C5EcFcr*Zx28Y`Dj00000NkvXXu0mjfvhV^= literal 0 HcmV?d00001 diff --git a/technic/textures/technic_hv_down_converter_top.png b/technic/textures/technic_hv_down_converter_top.png new file mode 100644 index 0000000000000000000000000000000000000000..996b2d4cfdcd63908ee512b0f2165c090f861e7b GIT binary patch literal 653 zcmV;80&@L{P)(7T;J|G13}rY z@Tm0bALX;xpEoohhzV*+SA!`%6I7rIR1pK?~cCg+;Y-8Ps>%tTzdJjrt+Cgd69y9@8?Wz>6W zmn7eP`URy+a}9{PuoAw1^9$@oK4KXRI91TgNE$kdM@)YF>1Td>^E?KfYu zkBxWNNu2>Ibc3TxXDySe;pQAq2iG-;83aN6@h5Rj#0&yNp|j{Llv*|Dndt7=Z6IA- zbMoPt8wL1gu#_Sy*zTwdTXBid)#PI`GdONLw|&Rmd3ip_nq(FLx;f%2B_|7e+No-E zCOwq<-~aH{>o3{2XIzBswsZaaA2H)&8@ro|!bOD!%mh0&#&CY9Ul9ZzP+8Ppg$?8B zY7E|6H(!RloeW7z^+p=00000NkvXXu0mjfouVKV literal 0 HcmV?d00001 diff --git a/technic/textures/technic_mv_down_converter_bottom.png b/technic/textures/technic_mv_down_converter_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..a61066045e69a3957d960ab08593e28ea0cfa2e6 GIT binary patch literal 738 zcmV<80v-K{P)$3&$UJfsbMn4>gb>)ajTj@P6fP+-3;^iG=bL$^l!7g#AR>qe&RTNLl$@F7nG_@YzLQeo-!ES<#z5~#&SMfc7}@s&5n)?5UOxRpEhob;a7hWJ6z`s%ZkR=c-WtO& z;Jrsae}>*DXW?rZqiHCVQun*$oJlERwbr!W>9z9d<%MAwD7BE{h#W$#m3f}1EwipG zz4x13T2pJq*7M{jg>f9wNH^$ti zmV$MTx7SxYJuXTmt%71ymb=4rw?hcpePk$6WE>Iof&(^rr6zRbNeg%Nay&R^ZgbF`}?6ROO#TyZ3{p-ozm^~@ZO`8 zqG=i;DXFcc+wEelrK&1=y&kG8ON=ojTJvu>#2CZj(GeHt=K!p4Y;bXY&icj%Ur$eQ z&e6$pLI~7#jd*!*5E88^#$!G_{Xu_oo8hlBmbDz~Z*KGIV?`&=8C+f>opX$ef~u+j zZY1|Nx36Q%=jn9Hv@DTQB83nDWLb7^;zG+E7-R6>=IW32s+_a3b^!FyByOrE2)#yN+{a~_h4W0Eu_iXtYH36YdYtu?DFD>&!q zb~-FZx=%@x(8+Uz5IkO6n_;f&n&3T2lAyJwzPfs_fDnSVZ3!V@ttHQMl#~)50-I0$%6$ZlL;Y&nYpB-ZCg~^G*r%!Wf`A#f6ke|gVi~aN81cXXE1^%&t?>!zaPxH zt!pGgkY*W?QrCuAV7z@_;OzDLxTYc28kMFgbzNhvW%%p+9sajH08o}Aq9`IwQ>6Ev zUbjme$2VSHcHr#}7Brl5h~1r?5JeGLnqr;9d(Vr*!+Sr|my;7h2;|04)ip{f#Qxr1 zaPuV=ML`_LG;>2)YtdTcy{By&gp`C3&{|Uz1xb?dAC&eb&XJI~l>h($07*qoM6N<$ Ef(NcA%m4rY literal 0 HcmV?d00001 diff --git a/technic/textures/technic_mv_down_converter_top.png b/technic/textures/technic_mv_down_converter_top.png new file mode 100644 index 0000000000000000000000000000000000000000..a61066045e69a3957d960ab08593e28ea0cfa2e6 GIT binary patch literal 738 zcmV<80v-K{P)$3&$UJfsbMn4>gb>)ajTj@P6fP+-3;^iG=bL$^l!7g#AR>qe&RTNLl$@F7nG_@YzLQeo-!ES<#z5~#&SMfc7}@s&5n)?5UOxRpEhob;a7hWJ6z`s%ZkR=c-WtO& z;Jrsae}>*DXW?rZqiHCVQun*$oJlERwbr!W>9z9d<%MAwD7BE{h#W$#m3f}1EwipG zz4x13T2pJq*7M{jg>f9wNH^$ti zmV$MTx7SxYJuXTmt%71ymb=4rw?hc Date: Wed, 19 Jun 2013 00:24:37 +0200 Subject: [PATCH 44/57] Added case study of radiated power through inductive coils. --- technic/init.lua | 4 + technic/lighting.lua | 594 ++++++++++++++++++ technic/power_radiator.lua | 308 +++++++++ ...c_homedecor_glowlight_cube_white_sides.png | Bin 0 -> 255 bytes ...cor_glowlight_cube_white_sides_ceiling.png | Bin 0 -> 258 bytes ...hnic_homedecor_glowlight_cube_white_tb.png | Bin 0 -> 261 bytes ..._homedecor_glowlight_cube_yellow_sides.png | Bin 0 -> 350 bytes ...or_glowlight_cube_yellow_sides_ceiling.png | Bin 0 -> 353 bytes ...nic_homedecor_glowlight_cube_yellow_tb.png | Bin 0 -> 352 bytes ..._homedecor_glowlight_thick_white_sides.png | Bin 0 -> 264 bytes ...decor_glowlight_thick_white_wall_sides.png | Bin 0 -> 265 bytes ...homedecor_glowlight_thick_yellow_sides.png | Bin 0 -> 475 bytes ...ecor_glowlight_thick_yellow_wall_sides.png | Bin 0 -> 478 bytes ...c_homedecor_glowlight_thin_white_sides.png | Bin 0 -> 225 bytes ...edecor_glowlight_thin_white_wall_sides.png | Bin 0 -> 232 bytes ..._homedecor_glowlight_thin_yellow_sides.png | Bin 0 -> 335 bytes ...decor_glowlight_thin_yellow_wall_sides.png | Bin 0 -> 355 bytes .../technic_homedecor_glowlight_white_tb.png | Bin 0 -> 330 bytes .../technic_homedecor_glowlight_yellow_tb.png | Bin 0 -> 633 bytes 19 files changed, 906 insertions(+) create mode 100644 technic/lighting.lua create mode 100644 technic/power_radiator.lua create mode 100644 technic/textures/technic_homedecor_glowlight_cube_white_sides.png create mode 100644 technic/textures/technic_homedecor_glowlight_cube_white_sides_ceiling.png create mode 100644 technic/textures/technic_homedecor_glowlight_cube_white_tb.png create mode 100644 technic/textures/technic_homedecor_glowlight_cube_yellow_sides.png create mode 100644 technic/textures/technic_homedecor_glowlight_cube_yellow_sides_ceiling.png create mode 100644 technic/textures/technic_homedecor_glowlight_cube_yellow_tb.png create mode 100644 technic/textures/technic_homedecor_glowlight_thick_white_sides.png create mode 100644 technic/textures/technic_homedecor_glowlight_thick_white_wall_sides.png create mode 100644 technic/textures/technic_homedecor_glowlight_thick_yellow_sides.png create mode 100644 technic/textures/technic_homedecor_glowlight_thick_yellow_wall_sides.png create mode 100644 technic/textures/technic_homedecor_glowlight_thin_white_sides.png create mode 100644 technic/textures/technic_homedecor_glowlight_thin_white_wall_sides.png create mode 100644 technic/textures/technic_homedecor_glowlight_thin_yellow_sides.png create mode 100644 technic/textures/technic_homedecor_glowlight_thin_yellow_wall_sides.png create mode 100644 technic/textures/technic_homedecor_glowlight_white_tb.png create mode 100644 technic/textures/technic_homedecor_glowlight_yellow_tb.png diff --git a/technic/init.lua b/technic/init.lua index 2248295..6dd7eac 100644 --- a/technic/init.lua +++ b/technic/init.lua @@ -40,6 +40,10 @@ dofile(modpath.."/down_converter_mv.lua") dofile(modpath.."/electric_furnace_mv.lua") dofile(modpath.."/alloy_furnace_mv.lua") dofile(modpath.."/forcefield.lua") +-- These two are a concept study: Supplying 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") diff --git a/technic/lighting.lua b/technic/lighting.lua new file mode 100644 index 0000000..5aab4c3 --- /dev/null +++ b/technic/lighting.lua @@ -0,0 +1,594 @@ +-- NOTE: The code is takes directly from VanessaE's homedecor mod. +-- I just made it the lights into indictive appliances for this mod. + +-- This file supplies electric powered glowlights + +-- Boilerplate to support localized strings if intllib mod is installed. +local S +if (minetest.get_modpath("intllib")) then + dofile(minetest.get_modpath("intllib").."/intllib.lua") + S = intllib.Getter(minetest.get_current_modname()) +else + S = function ( s ) return s end +end + +function technic_homedecor_node_is_owned(pos, placer) + local ownername = false + if type(IsPlayerNodeOwner) == "function" then -- node_ownership mod + if HasOwner(pos, placer) then -- returns true if the node is owned + if not IsPlayerNodeOwner(pos, placer:get_player_name()) then + if type(getLastOwner) == "function" then -- ...is an old version + ownername = getLastOwner(pos) + elseif type(GetNodeOwnerName) == "function" then -- ...is a recent version + ownername = GetNodeOwnerName(pos) + else + ownername = S("someone") + end + end + end + + elseif type(isprotect)=="function" then -- glomie's protection mod + if not isprotect(5, pos, placer) then + ownername = S("someone") + end + elseif type(protector)=="table" and type(protector.can_dig)=="function" then -- Zeg9's protection mod + if not protector.can_dig(5, pos, placer) then + ownername = S("someone") + end + end + + if ownername ~= false then + minetest.chat_send_player( placer:get_player_name(), S("Sorry, %s owns that spot."):format(ownername) ) + return true + else + return false + end +end + +local dirs1 = { 20, 23, 22, 21 } +local dirs2 = { 9, 18, 7, 12 } + +function technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) + if not technic_homedecor_node_is_owned(pointed_thing.under, placer) + and not technic_homedecor_node_is_owned(pointed_thing.above, placer) then + local node = minetest.env:get_node(pointed_thing.under) + if not minetest.registered_nodes[node.name] or not minetest.registered_nodes[node.name].on_rightclick then + + local above = pointed_thing.above + local under = pointed_thing.under + local pitch = placer:get_look_pitch() + local pname = minetest.env:get_node(under).name + local node = minetest.env:get_node(above) + local fdir = minetest.dir_to_facedir(placer:get_look_dir()) + local wield_name = itemstack:get_name() + + if not minetest.registered_nodes[pname] + or not minetest.registered_nodes[pname].on_rightclick then + + local iswall = (above.x ~= under.x) or (above.z ~= under.z) + local isceiling = (above.x == under.x) and (above.z == under.z) and (pitch > 0) + local pos1 = above + + if minetest.registered_nodes[pname]["buildable_to"] then + pos1 = under + iswall = false + end + + if not minetest.registered_nodes[minetest.env:get_node(pos1).name]["buildable_to"] then return end + + if iswall then + minetest.env:add_node(pos1, {name = wield_name, param2 = dirs2[fdir+1] }) -- place wall variant + elseif isceiling then + minetest.env:add_node(pos1, {name = wield_name, param2 = 20 }) -- place upside down variant + else + minetest.env:add_node(pos1, {name = wield_name, param2 = 0 }) -- place right side up + end + + if not homedecor_expect_infinite_stacks then + itemstack:take_item() + return itemstack + end + end + else + minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) + end + end +end + +-- Yellow -- Half node +minetest.register_node('technic:homedecor_glowlight_half_yellow', { + description = S("Yellow Glowlight (thick)"), + drawtype = "nodebox", + tiles = { + 'technic_homedecor_glowlight_yellow_tb.png', + 'technic_homedecor_glowlight_yellow_tb.png', + 'technic_homedecor_glowlight_thick_yellow_sides.png', + 'technic_homedecor_glowlight_thick_yellow_sides.png', + 'technic_homedecor_glowlight_thick_yellow_sides.png', + 'technic_homedecor_glowlight_thick_yellow_sides.png' + }, + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } + }, + node_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } + }, + + sunlight_propagates = false, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + sounds = default.node_sound_wood_defaults(), + + groups = { snappy = 3 }, + on_place = function(itemstack, placer, pointed_thing) + technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) + return itemstack + end, + on_construct = function(pos) + print("Hello") + technic_inductive_on_construct(pos, 100, "Yellow Glowlight (thick)") + print("Hello2") + end, + on_punch = function(pos, node, puncher) + print("Punch") + technic_inductive_on_punch_off(pos, 100, "technic:homedecor_glowlight_half_yellow_active") + print("Punch2") + end +}) + +minetest.register_node('technic:homedecor_glowlight_half_yellow_active', { + description = S("Yellow Glowlight (thick)"), + drawtype = "nodebox", + tiles = { + 'technic_homedecor_glowlight_yellow_tb.png', + 'technic_homedecor_glowlight_yellow_tb.png', + 'technic_homedecor_glowlight_thick_yellow_sides.png', + 'technic_homedecor_glowlight_thick_yellow_sides.png', + 'technic_homedecor_glowlight_thick_yellow_sides.png', + 'technic_homedecor_glowlight_thick_yellow_sides.png' + }, + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } + }, + node_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } + }, + + sunlight_propagates = false, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + light_source = LIGHT_MAX, + sounds = default.node_sound_wood_defaults(), + + groups = { snappy = 3, not_in_creative_inventory=1}, + drop="technic:homedecor_glowlight_half_yellow", + on_place = function(itemstack, placer, pointed_thing) + technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) + return itemstack + end, + on_construct = function(pos) + technic_inductive_on_construct(pos, 100, "Yellow Glowlight (thick)") + end, + on_punch = function(pos, node, puncher) + technic_inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_half_yellow") + end +}) + +-- Yellow -- Quarter node +minetest.register_node('technic:homedecor_glowlight_quarter_yellow', { + description = S("Yellow Glowlight (thin)"), + drawtype = "nodebox", + tiles = { + 'technic_homedecor_glowlight_yellow_tb.png', + 'technic_homedecor_glowlight_yellow_tb.png', + 'technic_homedecor_glowlight_thin_yellow_sides.png', + 'technic_homedecor_glowlight_thin_yellow_sides.png', + 'technic_homedecor_glowlight_thin_yellow_sides.png', + 'technic_homedecor_glowlight_thin_yellow_sides.png' + }, + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 } + }, + node_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 } + }, + + sunlight_propagates = false, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + sounds = default.node_sound_wood_defaults(), + + groups = { snappy = 3 }, + on_place = function(itemstack, placer, pointed_thing) + technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) + return itemstack + end, + on_construct = function(pos) + technic_inductive_on_construct(pos, 100, "Yellow Glowlight (thin)") + end, + on_punch = function(pos, node, puncher) + technic_inductive_on_punch_off(pos, 100, "technic:homedecor_glowlight_quarter_yellow_active") + end +}) + +minetest.register_node('technic:homedecor_glowlight_quarter_yellow_active', { + description = S("Yellow Glowlight (thin)"), + drawtype = "nodebox", + tiles = { + 'technic_homedecor_glowlight_yellow_tb.png', + 'technic_homedecor_glowlight_yellow_tb.png', + 'technic_homedecor_glowlight_thin_yellow_sides.png', + 'technic_homedecor_glowlight_thin_yellow_sides.png', + 'technic_homedecor_glowlight_thin_yellow_sides.png', + 'technic_homedecor_glowlight_thin_yellow_sides.png' + }, + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 } + }, + node_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 } + }, + + sunlight_propagates = false, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + light_source = LIGHT_MAX-1, + sounds = default.node_sound_wood_defaults(), + + groups = { snappy = 3, not_in_creative_inventory=1}, + drop="technic:homedecor_glowlight_quarter_yellow", + on_place = function(itemstack, placer, pointed_thing) + technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) + return itemstack + end, + on_construct = function(pos) + technic_inductive_on_construct(pos, 100, "Yellow Glowlight (thin)") + end, + on_punch = function(pos, node, puncher) + technic_inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_quarter_yellow") + end +}) + + +-- White -- half node +minetest.register_node('technic:homedecor_glowlight_half_white', { + description = S("White Glowlight (thick)"), + drawtype = "nodebox", + tiles = { + 'technic_homedecor_glowlight_white_tb.png', + 'technic_homedecor_glowlight_white_tb.png', + 'technic_homedecor_glowlight_thick_white_sides.png', + 'technic_homedecor_glowlight_thick_white_sides.png', + 'technic_homedecor_glowlight_thick_white_sides.png', + 'technic_homedecor_glowlight_thick_white_sides.png' + }, + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } + }, + node_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } + }, + + sunlight_propagates = false, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + sounds = default.node_sound_wood_defaults(), + + groups = { snappy = 3 }, + on_place = function(itemstack, placer, pointed_thing) + technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) + return itemstack + end, + on_construct = function(pos) + technic_inductive_on_construct(pos, 100, "White Glowlight (thick)") + end, + on_punch = function(pos, node, puncher) + technic_inductive_on_punch_off(pos, 100, "technic:homedecor_glowlight_half_white_active") + end +}) + +minetest.register_node('technic:homedecor_glowlight_half_white_active', { + description = S("White Glowlight (thick)"), + drawtype = "nodebox", + tiles = { + 'technic_homedecor_glowlight_white_tb.png', + 'technic_homedecor_glowlight_white_tb.png', + 'technic_homedecor_glowlight_thick_white_sides.png', + 'technic_homedecor_glowlight_thick_white_sides.png', + 'technic_homedecor_glowlight_thick_white_sides.png', + 'technic_homedecor_glowlight_thick_white_sides.png' + }, + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } + }, + node_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } + }, + + sunlight_propagates = false, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + light_source = LIGHT_MAX, + sounds = default.node_sound_wood_defaults(), + + groups = { snappy = 3, not_in_creative_inventory=1}, + drop="technic:homedecor_glowlight_half_white", + on_place = function(itemstack, placer, pointed_thing) + technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) + return itemstack + end, + on_construct = function(pos) + technic_inductive_on_construct(pos, 100, "White Glowlight (thick)") + end, + on_punch = function(pos, node, puncher) + technic_inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_half_white") + end +}) + +-- White -- Quarter node +minetest.register_node('technic:homedecor_glowlight_quarter_white', { + description = S("White Glowlight (thin)"), + drawtype = "nodebox", + tiles = { + 'technic_homedecor_glowlight_white_tb.png', + 'technic_homedecor_glowlight_white_tb.png', + 'technic_homedecor_glowlight_thin_white_sides.png', + 'technic_homedecor_glowlight_thin_white_sides.png', + 'technic_homedecor_glowlight_thin_white_sides.png', + 'technic_homedecor_glowlight_thin_white_sides.png' + }, + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 } + }, + node_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 } + }, + + sunlight_propagates = false, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + sounds = default.node_sound_wood_defaults(), + + groups = { snappy = 3 }, + on_place = function(itemstack, placer, pointed_thing) + technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) + return itemstack + end, + on_construct = function(pos) + technic_inductive_on_construct(pos, 100, "White Glowlight (thin)") + end, + on_punch = function(pos, node, puncher) + technic_inductive_on_punch_off(pos, 100, "technic:homedecor_glowlight_quarter_white_active") + end +}) + +minetest.register_node('technic:homedecor_glowlight_quarter_white_active', { + description = S("White Glowlight (thin)"), + drawtype = "nodebox", + tiles = { + 'technic_homedecor_glowlight_white_tb.png', + 'technic_homedecor_glowlight_white_tb.png', + 'technic_homedecor_glowlight_thin_white_sides.png', + 'technic_homedecor_glowlight_thin_white_sides.png', + 'technic_homedecor_glowlight_thin_white_sides.png', + 'technic_homedecor_glowlight_thin_white_sides.png' + }, + selection_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 } + }, + node_box = { + type = "fixed", + fixed = { -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 } + }, + + sunlight_propagates = false, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + light_source = LIGHT_MAX-1, + sounds = default.node_sound_wood_defaults(), + + groups = { snappy = 3, not_in_creative_inventory=1}, + drop="technic:homedecor_glowlight_quarter_white", + on_place = function(itemstack, placer, pointed_thing) + technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) + return itemstack + end, + on_construct = function(pos) + technic_inductive_on_construct(pos, 100, "White Glowlight (thin)") + end, + on_punch = function(pos, node, puncher) + technic_inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_quarter_white") + end +}) + +-- Glowlight "cubes" - yellow +minetest.register_node('technic:homedecor_glowlight_small_cube_yellow', { + description = S("Yellow Glowlight (small cube)"), + drawtype = "nodebox", + tiles = { + 'technic_homedecor_glowlight_cube_yellow_tb.png', + 'technic_homedecor_glowlight_cube_yellow_tb.png', + 'technic_homedecor_glowlight_cube_yellow_sides.png', + 'technic_homedecor_glowlight_cube_yellow_sides.png', + 'technic_homedecor_glowlight_cube_yellow_sides.png', + 'technic_homedecor_glowlight_cube_yellow_sides.png' + }, + selection_box = { + type = "fixed", + fixed = { -0.25, -0.5, -0.25, 0.25, 0, 0.25 } + }, + node_box = { + type = "fixed", + fixed = { -0.25, -0.5, -0.25, 0.25, 0, 0.25 } + }, + + sunlight_propagates = false, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + sounds = default.node_sound_wood_defaults(), + + groups = { snappy = 3 }, + on_place = function(itemstack, placer, pointed_thing) + technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) + return itemstack + end, + on_construct = function(pos) + technic_inductive_on_construct(pos, 50, "Yellow Glowlight (small cube)") + end, + on_punch = function(pos, node, puncher) + technic_inductive_on_punch_off(pos, 50, "technic:homedecor_glowlight_small_cube_yellow_active") + end +}) + +minetest.register_node('technic:homedecor_glowlight_small_cube_yellow_active', { + description = S("Yellow Glowlight (small cube)"), + drawtype = "nodebox", + tiles = { + 'technic_homedecor_glowlight_cube_yellow_tb.png', + 'technic_homedecor_glowlight_cube_yellow_tb.png', + 'technic_homedecor_glowlight_cube_yellow_sides.png', + 'technic_homedecor_glowlight_cube_yellow_sides.png', + 'technic_homedecor_glowlight_cube_yellow_sides.png', + 'technic_homedecor_glowlight_cube_yellow_sides.png' + }, + selection_box = { + type = "fixed", + fixed = { -0.25, -0.5, -0.25, 0.25, 0, 0.25 } + }, + node_box = { + type = "fixed", + fixed = { -0.25, -0.5, -0.25, 0.25, 0, 0.25 } + }, + + sunlight_propagates = false, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + light_source = LIGHT_MAX-1, + sounds = default.node_sound_wood_defaults(), + + groups = { snappy = 3, not_in_creative_inventory=1}, + drop="technic:homedecor_glowlight_cube_yellow", + on_place = function(itemstack, placer, pointed_thing) + technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) + return itemstack + end, + on_construct = function(pos) + technic_inductive_on_construct(pos, 50, "Yellow Glowlight (small cube)") + end, + on_punch = function(pos, node, puncher) + technic_inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_small_cube_yellow") + end +}) + +-- Glowlight "cubes" - white +minetest.register_node('technic:homedecor_glowlight_small_cube_white', { + description = S("White Glowlight (small cube)"), + drawtype = "nodebox", + tiles = { + 'technic_homedecor_glowlight_cube_white_tb.png', + 'technic_homedecor_glowlight_cube_white_tb.png', + 'technic_homedecor_glowlight_cube_white_sides.png', + 'technic_homedecor_glowlight_cube_white_sides.png', + 'technic_homedecor_glowlight_cube_white_sides.png', + 'technic_homedecor_glowlight_cube_white_sides.png' + }, + selection_box = { + type = "fixed", + fixed = { -0.25, -0.5, -0.25, 0.25, 0, 0.25 } + }, + node_box = { + type = "fixed", + fixed = { -0.25, -0.5, -0.25, 0.25, 0, 0.25 } + }, + + sunlight_propagates = false, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + sounds = default.node_sound_wood_defaults(), + + groups = { snappy = 3 }, + on_place = function(itemstack, placer, pointed_thing) + technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) + return itemstack + end, + on_construct = function(pos) + technic_inductive_on_construct(pos, 50, "White Glowlight (small cube)") + end, + on_punch = function(pos, node, puncher) + technic_inductive_on_punch_off(pos, 50, "technic:homedecor_glowlight_small_cube_white_active") + end +}) + +minetest.register_node('technic:homedecor_glowlight_small_cube_white_active', { + description = S("White Glowlight (small cube)"), + drawtype = "nodebox", + tiles = { + 'technic_homedecor_glowlight_cube_white_tb.png', + 'technic_homedecor_glowlight_cube_white_tb.png', + 'technic_homedecor_glowlight_cube_white_sides.png', + 'technic_homedecor_glowlight_cube_white_sides.png', + 'technic_homedecor_glowlight_cube_white_sides.png', + 'technic_homedecor_glowlight_cube_white_sides.png' + }, + selection_box = { + type = "fixed", + fixed = { -0.25, -0.5, -0.25, 0.25, 0, 0.25 } + }, + node_box = { + type = "fixed", + fixed = { -0.25, -0.5, -0.25, 0.25, 0, 0.25 } + }, + + sunlight_propagates = false, + paramtype = "light", + paramtype2 = "facedir", + walkable = true, + light_source = LIGHT_MAX-1, + sounds = default.node_sound_wood_defaults(), + + groups = { snappy = 3, not_in_creative_inventory=1}, + drop="technic:homedecor_glowlight_cube_white", + on_place = function(itemstack, placer, pointed_thing) + technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) + return itemstack + end, + on_construct = function(pos) + technic_inductive_on_construct(pos, 50, "White Glowlight (small cube)") + end, + on_punch = function(pos, node, puncher) + technic_inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_small_cube_white") + end +}) + +register_inductive_machine("technic:homedecor_glowlight_half_yellow") +register_inductive_machine("technic:homedecor_glowlight_half_white") +register_inductive_machine("technic:homedecor_glowlight_quarter_yellow") +register_inductive_machine("technic:homedecor_glowlight_quarter_white") +register_inductive_machine("technic:homedecor_glowlight_small_cube_yellow") +register_inductive_machine("technic:homedecor_glowlight_small_cube_white") diff --git a/technic/power_radiator.lua b/technic/power_radiator.lua new file mode 100644 index 0000000..3383d18 --- /dev/null +++ b/technic/power_radiator.lua @@ -0,0 +1,308 @@ +-- The power radiator fuctions like an inductive charger +-- only better in the game setting. +-- The purpose is to allow small appliances to receive power +-- without the overhead of the wiring needed for larger machines. +-- +-- The power radiator will consume power corresponding to the +-- sum(power rating of the attached appliances)/0.6 +-- Using inductive power transfer is very inefficient so this is +-- set to the factor 0.6. + +-- API for inductive powered nodes: +-- Use the functions below to set the corresponding callbacks +-- Also two nodes are needed: The inactive and the active one. The active must be called _active . + +-- Register a new appliance using this function +technic_inductive_nodes = {} +registered_inductive_count=0 + +register_inductive_machine = function(name) + registered_inductive_count=registered_inductive_count+1 + technic_inductive_nodes[registered_inductive_count]=name + registered_inductive_count=registered_inductive_count+1 + technic_inductive_nodes[registered_inductive_count]=name.."_active" + end + + +-- Appliances: +-- has_supply: pos of supply node if the appliance has a power radiator near with sufficient power for the demand else "" +-- EU_demand: The power demand of the device. +-- EU_charge: Actual use. set to EU_demand if active==1 +-- active: set to 1 if the device is on +technic_inductive_on_construct = function(pos, eu_demand, infotext) + local meta = minetest.env:get_meta(pos) + meta:set_string("infotext", infotext) + meta:set_int("technic_inductive_power_machine", 1) + meta:set_int("EU_demand",eu_demand) -- The power demand of this appliance + meta:set_int("EU_charge",0) -- The actual power draw of this appliance + meta:set_string("has_supply","") -- Register whether we are powered or not. For use with several radiators. + meta:set_int("active", 0) -- If the appliance can be turned on and off by using it use this. + end + +technic_inductive_on_punch_off = function(pos, eu_charge, swapnode) + local meta = minetest.env:get_meta(pos) + if meta:get_string("has_supply") ~= "" then + hacky_swap_node(pos, swapnode) + meta:set_int("active", 1) + meta:set_int("EU_charge",eu_charge) + --print("-----------") + --print("Turn on:") + --print("EUcha:"..meta:get_int("EU_charge")) + --print("has_supply:"..meta:get_string("has_supply")) + --print("<----------->") + end + end + +technic_inductive_on_punch_on = function(pos, eu_charge, swapnode) + local meta = minetest.env:get_meta(pos) + hacky_swap_node(pos, swapnode) + meta:set_int("active", 0) + meta:set_int("EU_charge",eu_charge) + --print("-----------") + --print("Turn off:") + --print("EUcha:"..meta:get_int("EU_charge")) + --print("has_supply:"..meta:get_string("has_supply")) + --print("<---------->") + end + +--minetest.register_node( +-- "technic:test_induc", { +-- description = "Test radiator node", +-- drawtype = "nodebox", +-- tiles = { +-- 'homedecor_glowlight_yellow_tb.png', +-- 'homedecor_glowlight_yellow_tb.png', +-- 'homedecor_glowlight_thick_yellow_sides.png', +-- 'homedecor_glowlight_thick_yellow_sides.png', +-- 'homedecor_glowlight_thick_yellow_sides.png', +-- 'homedecor_glowlight_thick_yellow_sides.png' +-- }, +-- +---- tiles = {"technic_hv_down_converter_top.png", "technic_hv_down_converter_top.png", "technic_hv_down_converter_top.png", +---- "technic_hv_down_converter_top.png", "technic_hv_down_converter_top.png", "technic_hv_down_converter_top.png"}, +-- selection_box = { +-- type = "fixed", +-- fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } +-- }, +-- node_box = { +-- type = "fixed", +-- fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } +-- }, +-- sunlight_propagates = false, +-- paramtype = "light", +-- paramtype2 = "facedir", +-- walkable = true, +-- groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, +-- on_place = function(itemstack, placer, pointed_thing) +-- homedecor_rotate_and_place(itemstack, placer, pointed_thing) +-- return itemstack +-- end, +-- on_construct = function(pos) +-- local meta = minetest.env:get_meta(pos) +-- meta:set_string("infotext", "Power Radiator Appliance") +-- meta:set_int("technic_inductive_power_machine", 1) +-- meta:set_int("EU_demand",200) -- The power demand of this appliance +-- meta:set_int("EU_charge",0) -- The actual power draw of this appliance +-- meta:set_string("has_supply","") -- Register whether we are powered or not. For use with several radiators. +-- meta:set_int("active", 0) -- If the appliance can be turned on and off by using it use this. +-- end, +-- on_punch = function(pos,node,puncher) +-- local meta = minetest.env:get_meta(pos) +-- if meta:get_string("has_supply") ~= "" then +-- hacky_swap_node(pos, "technic:test_induc_active") +-- meta:set_int("active", 1) +-- meta:set_int("EU_charge",200) +-- print("-----------") +-- print("Turn on:") +-- print("EUcha:"..meta:get_int("EU_charge")) +-- print("<----------->") +-- end +-- end, +-- }) +-- +--minetest.register_node( +-- "technic:test_induc_active", { +-- description = "Test radiator node", +-- drawtype = "nodebox", +-- tiles = { +-- 'homedecor_glowlight_yellow_tb.png', +-- 'homedecor_glowlight_yellow_tb.png', +-- 'homedecor_glowlight_thick_yellow_sides.png', +-- 'homedecor_glowlight_thick_yellow_sides.png', +-- 'homedecor_glowlight_thick_yellow_sides.png', +-- 'homedecor_glowlight_thick_yellow_sides.png' +-- }, +-- +---- tiles = {"technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png", +---- "technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png"}, +-- selection_box = { +-- type = "fixed", +-- fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } +-- }, +-- node_box = { +-- type = "fixed", +-- fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } +-- }, +-- sunlight_propagates = false, +-- paramtype = "light", +-- paramtype2 = "facedir", +-- walkable = true, +-- light_source=14, +-- groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, +-- drop="technic:test_induc", +-- on_place = function(itemstack, placer, pointed_thing) +-- homedecor_rotate_and_place(itemstack, placer, pointed_thing) +-- return itemstack +-- end, +-- on_construct = function(pos) +-- local meta = minetest.env:get_meta(pos) +-- meta:set_string("infotext", "Power Radiator Appliance Active") +-- meta:set_int("technic_inductive_power_machine", 1) +-- meta:set_int("EU_demand",200) -- The power demand of this appliance +-- meta:set_int("EU_charge",0) -- The actual power draw of this appliance +-- meta:set_string("has_supply","") -- Register whether we are powered or not. For use with several radiators. +-- end, +-- on_punch = function(pos,node,puncher) +-- local meta = minetest.env:get_meta(pos) +-- hacky_swap_node(pos, "technic:test_induc") +-- meta:set_int("active", 0) +-- meta:set_int("EU_charge",0) +-- print("-----------") +-- print("Turn off:") +-- print("EUcha:"..meta:get_int("EU_charge")) +-- print("<---------->") +-- end, +-- }) + +local shutdown_inductive_appliances = function(pos) + -- The supply radius + local rad = 4 + -- If the radiator is removed. turn off all appliances in region + -- If another radiator is near it will turn on the appliances again + local positions = minetest.env:find_nodes_in_area({x=pos.x-rad,y=pos.y-rad,z=pos.z-rad},{x=pos.x+rad,y=pos.y+rad,z=pos.z+rad}, technic_inductive_nodes) + for _,pos1 in ipairs(positions) do + local meta1 = minetest.env:get_meta(pos1) + -- If the appliance is belonging to this node + if meta1:get_string("has_supply") == pos.x..pos.y..pos.z then + local nodename = minetest.env:get_node(pos1).name + -- Swap the node and make sure it is off and unpowered + if string.sub(nodename, -7) == "_active" then + hacky_swap_node(pos1, string.sub(nodename, 1, -8)) + meta1:set_int("active", 0) + meta1:set_int("EU_charge", 0) + end + meta1:set_string("has_supply", "") + end + end + end + + +minetest.register_node( + "technic:power_radiator", { + description = "Power Radiator", + tiles = {"technic_hv_down_converter_top.png", "technic_hv_down_converter_bottom.png", "technic_hv_down_converter_side.png", + "technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png"}, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), + drawtype = "nodebox", + paramtype = "light", + is_ground_content = true, + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_int("technic_mv_power_machine", 1) -- MV machine + meta:set_int("internal_EU_buffer",0) -- internal buffer value + meta:set_int("internal_EU_buffer_size",1000) -- Size of buffer + meta:set_int("connected_EU_demand",0) -- Potential demand of connected appliances + meta:set_string("infotext", "Power Radiator") +-- meta:set_int("active", 0) + end, + on_dig = function(pos, node, digger) + shutdown_inductive_appliances(pos) + return minetest.node_dig(pos, node, digger) + end, + }) + +minetest.register_craft( + { + output = 'technic:power_radiator 1', + recipe = { + {'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot'}, + {'technic:copper_coil', 'technic:mv_transformer', 'technic:copper_coil'}, + {'technic:rubber', 'technic:mv_cable', 'technic:rubber'}, + } + }) + +minetest.register_abm( + {nodenames = {"technic:power_radiator"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.env:get_meta(pos) + local my_supply = meta:get_int("internal_EU_buffer") + -- The maximum EU sourcing a single radiator can provide. + local max_charge = 1000 -- == the max EU demand of the radiator + local connected_EU_demand = meta:get_int("connected_EU_demand") + --print("--------------------") + --print("My Supply:"..my_supply) + --print("Connected Demand:"..connected_EU_demand) + if my_supply > 0 then + -- Efficiency factor + local eff_factor = 0.6 + -- The supply radius + local rad = 4 + + local meta1 = nil + local pos1 = {} + local used_charge = 0 + + -- Index all nodes within supply range + local positions = minetest.env:find_nodes_in_area({x=pos.x-rad,y=pos.y-rad,z=pos.z-rad},{x=pos.x+rad,y=pos.y+rad,z=pos.z+rad}, technic_inductive_nodes) + for _,pos1 in ipairs(positions) do + local meta1 = minetest.env:get_meta(pos1) + -- If not supplied see if this node can handle it. + if meta1:get_string("has_supply") == "" then + -- if demand surpasses the capacity of this node, don't bother adding it. + local eu_demand = meta1:get_int("EU_demand")/eff_factor + if connected_EU_demand+eu_demand <= max_charge and connected_EU_demand+eu_demand <= my_supply then + -- We can power the appliance. Register, and spend power if it is on. + connected_EU_demand = connected_EU_demand+eu_demand + + meta1:set_string("has_supply", pos.x..pos.y..pos.z) + used_charge = math.floor(used_charge+meta1:get_int("EU_charge")/eff_factor) + end + elseif meta1:get_string("has_supply") == pos.x..pos.y..pos.z then + -- The appliance has power from this node. Spend power if it is on. + used_charge = math.floor(used_charge+meta1:get_int("EU_charge")/eff_factor) + end + end + --If demand surpasses actual supply turn off everything - we are out of power + if used_charge>my_supply then + meta:set_string("infotext", "Power Radiator is overloaded ("..math.floor(used_charge/my_supply*100).."% of available power)"); +-- meta:set_int("active",1) -- used for setting textures someday maybe + shutdown_inductive_appliances(pos) + connected_EU_demand = 0 + else + meta:set_string("infotext", "Power Radiator is powered ("..math.floor(used_charge/my_supply*100).."% of available power)"); + meta:set_int("internal_EU_buffer",my_supply-used_charge) +-- meta:set_int("active",1) -- used for setting textures someday maybe + end + else + meta:set_string("infotext", "Power Radiator is unpowered"); +-- meta:set_int("active",0) -- used for setting textures someday maybe + end + + -- Save state + meta:set_int("connected_EU_demand",connected_EU_demand) + return + end, + }) + +register_MV_machine ("technic:power_radiator","RE") diff --git a/technic/textures/technic_homedecor_glowlight_cube_white_sides.png b/technic/textures/technic_homedecor_glowlight_cube_white_sides.png new file mode 100644 index 0000000000000000000000000000000000000000..91219991028f94ba74323ebb05d8710435c61b57 GIT binary patch literal 255 zcmVEPht>gwv^ z;^N=m-`w2X;o;%+_4VxR?C0m_>+9?2=;-6)ch#|Ns9JrAZ3_ z002`-L_t&-)5XZi4S+BV0KstQ4!L8S{_8}1EJOqBYc=BfBz}a$J48AIgD0Jm?I(k) zFxIUg1C_DJ2>A_CL{%A@R&yLvXE101Qf&;uP|m&W&)+H~8BAmCU$+1N002ovPDHLk FV1g4Gg>C=< literal 0 HcmV?d00001 diff --git a/technic/textures/technic_homedecor_glowlight_cube_white_sides_ceiling.png b/technic/textures/technic_homedecor_glowlight_cube_white_sides_ceiling.png new file mode 100644 index 0000000000000000000000000000000000000000..c8006eb3dfc4d1756662c6f5a12df55289769d91 GIT binary patch literal 258 zcmV+d0sa1oP)qi`T6fqqu>FMd* z+}z>e;o{=r-{0T$_4VW9ch#|NsA~3tis; z0034=L_t&-)5XZg5r8lZL{XESbCN~>b%HM%I^Z96b{@Omj#yGcW#(sdV$A?@D1x%| zunHXsstAnth6D)$-@Y)~xp%0Jz!sUaMo(ZYj^X@8@a-pf0JQHJOdpq@oB#j-07*qo IM6N<$f*&f0EC2ui literal 0 HcmV?d00001 diff --git a/technic/textures/technic_homedecor_glowlight_cube_white_tb.png b/technic/textures/technic_homedecor_glowlight_cube_white_tb.png new file mode 100644 index 0000000000000000000000000000000000000000..b2e355ac966f8747d7ca08408022fb3fbb048be4 GIT binary patch literal 261 zcmV+g0s8)lP)gwv|=H~hN`Stbn^78WS?d{>=;osli*wd^<>lr7|No&i z&Km##09HvvK~xyirOr1JfG`Y1QIn%{lq~LlO*)yOgkQd5XT|kOe1tQvM34@KTr{Gw zi6PA~h!KgQ;Ltg*>H~svUN!(Ndmo~0qhz9*DllwIsg+>=bN$&33>_M8dFQQ$00000 LNkvXXu0mjf2VIJd literal 0 HcmV?d00001 diff --git a/technic/textures/technic_homedecor_glowlight_cube_yellow_sides.png b/technic/textures/technic_homedecor_glowlight_cube_yellow_sides.png new file mode 100644 index 0000000000000000000000000000000000000000..b79be077dcbbb3802cf80af6546b1bf1c5ddcbcc GIT binary patch literal 350 zcmWlT&nv@m0ER!zq-~;>$Yt$dO|ga&xooo^rWtKB5@X1k)Rq+&2UZKs+DTipw2P%M zBg(;nT8<8W99)#t@<*u0*WrDip40p8Pq-b8igtw%qR}~G^+;^~PlHTqeRq>rLS4u_ zW)|Wqt^5tjB|n>R`E2kB8Hhs(Do}uXc!31uVGC|y4YF_u`>+ftn1nP$U;{Rx2suc? zJXjzGD_{pNbV3-`AqeBJ10INi4+dZrW?&Iq-~bI6;1NDx4t8M{hM){w{~U*<+X1K5 z>}z{nDw|{~nZ6Jy>Q2rtLZa2!*Ych5y}u-sr+dA*Sn}xSLGBvNexy_#Z(p@fx~g5( zl^>1PXbt}U;aJdiw|yhjn#;mL{jACSoOM|J0d=KbSd2ZV)hX??v?QE1x3y$hi2nhb CSHr~s literal 0 HcmV?d00001 diff --git a/technic/textures/technic_homedecor_glowlight_cube_yellow_sides_ceiling.png b/technic/textures/technic_homedecor_glowlight_cube_yellow_sides_ceiling.png new file mode 100644 index 0000000000000000000000000000000000000000..a9d397af3597c0c4608dc95fee0ba0162c4c41a6 GIT binary patch literal 353 zcmWlTO(=r_0EWM9ChaFHX-mq1WCv@?!BW~cvsulIZ8iU9+M1N1=HkF=SZF1paaf6z z`fLYn%E3x*F1WZT7iZs&H8x1Jdva`%r)c+`|i;K@Qg87FJ;qVsHXSumtlEfFMY433=Fs z73cvM977T^kcCZ%fCEBch6R{|aY(@$%zzi%Fbtz$fflI3J8Z)gOhPXdfeWcrmTyNq zPBCbDjTQx^InpOiHzXPjrwZrJxAjMB)tIa5u~p{`I4!8x3^`Pv`>UY$Mox)&QiEJm#!}2F~MlBRkg{6XxCMy+xQ^M1kZraDLH1- Ee*{#+1ONa4 literal 0 HcmV?d00001 diff --git a/technic/textures/technic_homedecor_glowlight_cube_yellow_tb.png b/technic/textures/technic_homedecor_glowlight_cube_yellow_tb.png new file mode 100644 index 0000000000000000000000000000000000000000..daf03ab4f16e74e9b1390deb4bcabc5df7be9680 GIT binary patch literal 352 zcmWlTPbh-{0L4F>mA;vg1GzZRaIlh+lG;CJH8Zm%n!j5_%AzLaz#@H_R;y*S!!DR) zk(8AK<)AohLsC)>#Ldw`{d^AZ{d$Mjdy>;()reK1AP5>;m&GNs^j}3v+3Op%eKHCs zjon5;IEko#$5e7YblTk=@CsXyhHFT|1>|83c3=+{;0!ik1Y#gT5PDz*#=r#uNI)Dy zumm$O4udcan-GCHm<2z0zzTM#hIyEPDKJ4N=)nzr&;YG)1<&Axbr^y+I7Tk?A8F;= zqc)4tU3u?2HYkhzVrpCZ7H?CZm#VvP=4Wx$?|D;%6ycATgf1T_@C9`(HRh7u^W_66 zQ>HwPE4+q*=-Ok}J6x_$?$%z_>G#v>itJNM%=M6MPF{cA2!i>&Db=2f=HxBG*5R2$@9^;O?(XjG?d|gN^4Qqe;Nal#@$uo|;nvpH^YioL z+9>nP%wS~004AJL_t&-(`}F24umiWL{Y1~?ZQy` z|8G^)-Du-U`oJU|4rCo<>w`0>6+o@O08v$k{Q*Z1Rirs08euf=6LU(5xsj+*Xk5zI zDTSNNG)_4$A7{yV8Uuwc@s9hSK&C?fR_`!8_8z9dWfpO%-`wAh>(~JLi4OxEXNUCw O0000+9ig0Nd@6|iz97Ncwb*H`iTz%X7vbi P00000NkvXXu0mjf!h3q@ literal 0 HcmV?d00001 diff --git a/technic/textures/technic_homedecor_glowlight_thick_yellow_sides.png b/technic/textures/technic_homedecor_glowlight_thick_yellow_sides.png new file mode 100644 index 0000000000000000000000000000000000000000..769b05485f2f3451b3d2be5b0c91d98d0ad1a7b8 GIT binary patch literal 475 zcmWlUO-Pdg0EWM2Q<+W&ru|s+2U|lcv6=lT?Tc@G4%e7&H2fLNih>9P^Wf}I%si~9 zwRW*fLN&t#%}~RPR4_%8jBf`e31lfn(V;GOFrU5-@B8o^pODKb>vel{f*|Pa)l!{G z!~dlwsc$}%=~l7*vUpY$grRWSX0ulHNteT8gM4@dPay^m;0|;_4;+PDh(H>gh7ef6 z1V^9@ERY4&kOQ}%1dhQDI1JfP1TwsYN~i)4jKB~K!z*xu4)#JS>;^69p&R<37%E@@ z_CpFdL4;9AhfJj|?IqJ_u)@k8DyL|Qeq*)`>~rbFph5@2L;@GK!F@Oc`(X?U zVJk==!xZQsAFNOhNnnIz5YX9ESKq3%%sH%*Yu933|7M!SX*kgr?=j7V)Pw!4pI5#o z+9L6{1&fK0=hbjq!)sw4k>fvqUkZ7R`YY82|R9)XT`ZitMZf`D1wL zy?xN{Yxb;#zd45;?V~H{U+=xS7_-G1&WKoKeD89w<#DuZoA5_h@0Jvuwj`O8O`q0v zv%ft4#nvufK~wy%xyW%vpYr`eUhJqb1LnTk~k+V6)b{5UzSL k-{o^hAKtj|x2dFKW>qy>oYV2e+b%0n!ci$($1IJ$e+a@3 z;#Y&zeIvwP?(I%twysp3(QC-_U|N&Xq1t;p*2|XU{V6??<~C7^xqo-#t*nRscURs0 Zr5_i`d$(qDi3`vM22WQ%mvv4FO#mz!YAXN$ literal 0 HcmV?d00001 diff --git a/technic/textures/technic_homedecor_glowlight_thin_white_wall_sides.png b/technic/textures/technic_homedecor_glowlight_thin_white_wall_sides.png new file mode 100644 index 0000000000000000000000000000000000000000..0fd3b1efd18315d4654ef1fc5e24527fb8acc179 GIT binary patch literal 232 zcmVP)+9?P|Nm>MLyrIe09{E$K~xyimCwlvz%U3!Q8SoHjp_gYY^5m)6k4du zvygW|WsKv#AsQi~+mJXw;Isj#K_grs>puZrSqUp+pD_kDV9PoTHQqRduh3xc4ucA4xF^Zu75lU}3C?URr(Z0t4) z!trX(?_j3nzFwQd3>s*K4yc1RsD}pFfLhSP5`>@_^pFoKD1l9=f@R2oMJR*-%s~X& zp#}Cp2m4@vFl@sLEWkV*z&cdI8u)>NJ?D-TGj25*9Yx8jge85htib=+5W1hV#O1kO zWH*=HUf-S9nOgOvqVAwwyp6pCX2r&f^Dje-&F>g1`rc5#D)frT_=rn9ZH`UUOvj(y zol`R(M?Yua$W7xHF__lTJQ3j{p`ZlYUSj{~q IvE4QM2j6nEJOBUy literal 0 HcmV?d00001 diff --git a/technic/textures/technic_homedecor_glowlight_thin_yellow_wall_sides.png b/technic/textures/technic_homedecor_glowlight_thin_yellow_wall_sides.png new file mode 100644 index 0000000000000000000000000000000000000000..4b28a27c75e7ab0ee122049ad01dc496c0c1fa9a GIT binary patch literal 355 zcmWlTODMwu0EhqbY=*TV@1-o1v9*+Ew%MA+%wyyrO(~BY+?0#Pnm6M>BE=HFoOu& zPzk%Bg;Lmrb(n`q@WDPTLLT_R3*;L+!cxqf-C}a3g{%v^J=;;A%0 zeRc%TMbGITmpc`!rp{8?P1{>+*4Bk$z5nbkCog}@Jg90|n^fpVyWFduT)$|z?b}yI z3{PZ!+`PtBJ%_K4tG^F7l2%63efL9G@)+lgQ~U7V?C)3hg>;&bm^@P76-s?{>3f2K blgoiG^@}<;P-c*~OJRcD+Gsg2yT|?jWr4R* literal 0 HcmV?d00001 diff --git a/technic/textures/technic_homedecor_glowlight_white_tb.png b/technic/textures/technic_homedecor_glowlight_white_tb.png new file mode 100644 index 0000000000000000000000000000000000000000..fdc8a4d6df99063ce7d00f49a02ea5bc9e39a4fb GIT binary patch literal 330 zcmV-Q0k!^#P)gwwI`}^$d?C0m_?d|RI^78BJ>-F{Z>FMe5@$v8P@ALEXS*l(D0001? zNkl7AR}|b z?U9nh#u+CeXwowo6t4JDxO6IHDlQLa+!lz{<4Osd6534p>+x&KSJUs7ntPvHbiIzB c9_Iu68+zyz14K|_C;$Ke07*qoM6N<$f@>M8jQ{`u literal 0 HcmV?d00001 diff --git a/technic/textures/technic_homedecor_glowlight_yellow_tb.png b/technic/textures/technic_homedecor_glowlight_yellow_tb.png new file mode 100644 index 0000000000000000000000000000000000000000..ffd9c58ab5eac048725d87c8a01f39f2590cfa70 GIT binary patch literal 633 zcmWlVYb?|O0KorAFV5&WB9FG((Xy4*YOBrJ9bF!Arw^69zA&VRp|~w+bs0i)40F^< zo%5D!=V~4aS4!==EYpWdyV7d$1v~54_2KvXegBoj#zeTeY2Pzm{PAI`yLxB~Ct8Qg+V}M!yQnA9{S-fXu$y8E8)sg$3(kaDv9^B?09X>8xGwP`tHo4VsTr3zS?=i ze5J=!-7*#8U-m@Xpx36BkkrL}26;h{f9OM<&rx6Vsm93!AHQ9aL&mxJwv69V8qJ7Q zuo<;SK8t1zZj)0or;z$4mC3uuzajm5r04jOI>!>QRo`*C>WOH`cX@QTDzHXlJNdTH zP?WoQW9w3^d5<->&?aPyW@PON#^9Oitn!?{GPPpihG}ei=d`Om`arQ&f2oi+6AkvY z=B}i;QeEv_RD|6$k#6=2AL<{_W}c`iODPZ^RCWH$h_fhrFFJ(<1sspe{A275{ Date: Tue, 2 Jul 2013 00:03:36 +0200 Subject: [PATCH 45/57] Changed power distribution method and streamlined the various existing machines. An electrical network now requires a switching station to work. This statin is the one resolving the network collecting power and distributing it again. Added up/down converter. It is kind of finished. It can be updated with a slot for an upgrade but so far it works without by resolving the types of wires above and below the box. Tool and machine registering changed to use a table with key+value instead of the iterative method it used to have. The power radiator changed to be able to send up to 3000MV EUs in a radius of 6. This update will most likely require existing networks to be dug up and placed again. Also the switching station must be added. --- technic/alloy_furnace.lua | 509 ++++++++++---------- technic/alloy_furnace_mv.lua | 641 +++++++++++++++++--------- technic/alloy_furnaces_commons.lua | 97 ++-- technic/battery_box.lua | 461 +++++++----------- technic/battery_box_hv.lua | 405 ++++++---------- technic/battery_box_mv.lua | 399 ++++++---------- technic/cans.lua | 16 +- technic/chainsaw.lua | 4 +- technic/cnc.lua | 407 ++++++++-------- technic/electric_furnace.lua | 310 ++++++------- technic/electric_furnace_mv.lua | 551 +++++++++++----------- technic/flashlight.lua | 4 +- technic/forcefield.lua | 15 +- technic/generator.lua | 222 +++++---- technic/geothermal.lua | 228 ++++----- technic/grinder.lua | 596 ++++++++++++------------ technic/grinder_gloopores.lua | 10 +- technic/init.lua | 66 +-- technic/lighting.lua | 66 ++- technic/mining_drill.lua | 28 +- technic/mining_laser_mk1.lua | 8 +- technic/music_player.lua | 246 +++++----- technic/power_radiator.lua | 211 +++------ technic/register_machine_and_tool.lua | 70 +++ technic/solar_array_hv.lua | 63 +-- technic/solar_array_lv.lua | 78 ++-- technic/solar_array_mv.lua | 76 ++- technic/solar_panel.lua | 26 +- technic/sonic_screwdriver.lua | 4 +- technic/supply_converter.lua | 223 +++++++++ technic/switching_station.lua | 352 ++++++++++++++ technic/tool_workshop.lua | 182 ++++---- technic/water_mill.lua | 187 ++++---- 33 files changed, 3589 insertions(+), 3172 deletions(-) create mode 100644 technic/register_machine_and_tool.lua create mode 100644 technic/supply_converter.lua create mode 100644 technic/switching_station.lua diff --git a/technic/alloy_furnace.lua b/technic/alloy_furnace.lua index 149688e..d36b93c 100644 --- a/technic/alloy_furnace.lua +++ b/technic/alloy_furnace.lua @@ -1,12 +1,14 @@ +-- LV Alloy furnace minetest.register_craft({ output = 'technic:coal_alloy_furnace', recipe = { {'default:brick', 'default:brick', 'default:brick'}, - {'default:brick', '', 'default:brick'}, + {'default:brick', '', 'default:brick'}, {'default:brick', 'default:brick', 'default:brick'}, } }) +-- FIXME: kpoppel: I'd like to introduce an induction heating element here... minetest.register_craft({ output = 'technic:alloy_furnace', recipe = { @@ -16,193 +18,178 @@ minetest.register_craft({ } }) --- LV alloy furnace +local alloy_furnace_formspec = + "invsize[8,9;]".. + "list[current_name;src;3,1;1,1;]".. + "list[current_name;src2;3,2;1,1;]".. + "list[current_name;dst;5,1;2,2;]".. + "list[current_player;main;0,5;8,4;]".. + "label[0,0;Electric Alloy Furnace]" -alloy_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;src2;3,2;1,1;]".. - "list[current_name;dst;5,1;2,2;]".. - "list[current_player;main;0,5;8,4;]".. - "label[0,0;Electric Alloy Furnace]".. - "label[1,3;Power level]" - -minetest.register_node("technic:alloy_furnace", { - description = "Electric alloy furnace", - tiles = {"technic_alloy_furnace_top.png", "technic_machine_bottom.png", "technic_alloy_furnace_side.png", - "technic_alloy_furnace_side.png", "technic_alloy_furnace_side.png", "technic_alloy_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", alloy_furnace_formspec) - meta:set_string("infotext", "Electric Alloy furnace") - local inv = meta:get_inventory() - inv:set_size("src", 1) - inv:set_size("src2", 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) - meta:set_float("tube_time", 0) - 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 end - if not inv:is_empty("src") then - return false end - if not inv:is_empty("src2") then - return false end - return true - end, +minetest.register_node( + "technic:alloy_furnace", + { + description = "Electric alloy furnace", + tiles = {"technic_alloy_furnace_top.png", "technic_machine_bottom.png", "technic_alloy_furnace_side.png", + "technic_alloy_furnace_side.png", "technic_alloy_furnace_side.png", "technic_alloy_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 Alloy furnace") + meta:set_float("technic_power_machine", 1) + meta:set_string("formspec", alloy_furnace_formspec) + local inv = meta:get_inventory() + inv:set_size("src", 1) + inv:set_size("src2", 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("src2") 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:alloy_furnace_active", { - description = "Alloy Furnace", - tiles = {"technic_alloy_furnace_top.png", "technic_machine_bottom.png", "technic_alloy_furnace_side.png", - "technic_alloy_furnace_side.png", "technic_alloy_furnace_side.png", "technic_alloy_furnace_front_active.png"}, - paramtype2 = "facedir", - light_source = 8, - drop = "technic:alloy_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, - 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:alloy_furnace_active", + { + description = "Alloy Furnace", + tiles = {"technic_alloy_furnace_top.png", "technic_machine_bottom.png", "technic_alloy_furnace_side.png", + "technic_alloy_furnace_side.png", "technic_alloy_furnace_side.png", "technic_alloy_furnace_front_active.png"}, + paramtype2 = "facedir", + light_source = 8, + drop = "technic:alloy_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("src2") 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:alloy_furnace","technic:alloy_furnace_active"}, - interval = 1, - chance = 1, - - action = function(pos, node, active_object_count, active_object_count_wider) +minetest.register_abm( + { nodenames = {"technic:alloy_furnace","technic:alloy_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") - local load = math.floor(internal_EU_buffer/2000 * 100) - meta:set_string("formspec", - "invsize[8,9;]".. - "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. - (load)..":technic_power_meter_fg.png]".. - "list[current_name;src;3,1;1,1;]".. - "list[current_name;src2;3,2;1,1;]".. - "list[current_name;dst;5,1;2,2;]".. - "list[current_player;main;0,5;8,4;]".. - "label[0,0;Electric Alloy Furnace]".. - "label[1,3;Power level]") + -- Machine information + local machine_name = "Electric Alloy Furnace" + local machine_node = "technic:alloy_furnace" + local machine_state_demand = { 50, 600 } - local inv = meta:get_inventory() + -- 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) + meta:set_int("tube_time", 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 = 1 + local recipe = nil + local result = nil - local furnace_is_cookin = meta:get_int("furnace_is_cookin") + -- Get what to cook if anything + local srcstack = inv:get_stack("src", 1) + local src2stack = inv:get_stack("src2", 1) + local src_item1 = nil + local src_item2 = nil + if srcstack and src2stack then + src_item1 = srcstack:to_table() + src_item2 = src2stack:to_table() + empty = 0 + end + + if src_item1 and src_item2 then + recipe = technic.get_alloy_recipe(src_item1,src_item2) + end + if recipe then + result = { name=recipe.dst_name, count=recipe.dst_count} + end - local srclist = inv:get_list("src") - local srclist2 = inv:get_list("src2") + if recipe then + print("recipe "..recipe.dst_name.." : result "..result.name.." : empty "..empty.." : src_item1 "..src_item1.name.." : src_item2 "..src_item2.name) + end - srcstack = inv:get_stack("src", 1) - if srcstack then src_item1=srcstack:to_table() end - srcstack = inv:get_stack("src2", 1) - if srcstack then src_item2=srcstack:to_table() end - dst_index=nil + if state == 1 then + hacky_swap_node(pos, machine_node) + meta:set_string("infotext", machine_name.." Idle") + + if empty == 0 and recipe and inv:room_for_item("dst", result) then + meta:set_string("infotext", machine_name.." Active") + meta:set_string("src_time", 0) + next_state = 2 + end - if src_item1 and src_item2 then - dst_index=get_cook_result(src_item1,src_item2) - end + elseif state == 2 then + hacky_swap_node(pos, machine_node.."_active") + meta:set_int("src_time", meta:get_int("src_time") + 1) + if meta:get_int("src_time") == 4 then -- 4 ticks per output + meta:set_string("src_time", 0) + -- check if there's room for output in "dst" list and that we have the materials + if recipe and inv:room_for_item("dst", result) then + -- Take stuff from "src" list + srcstack:take_item(recipe.src1_count) + inv:set_stack("src", 1, srcstack) + src2stack:take_item(recipe.src2_count) + inv:set_stack("src2", 1, src2stack) + -- Put result in "dst" list + inv:add_item("dst",result) + else + next_state = 1 + 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:alloy_furnace","RE") +technic.register_LV_machine ("technic:alloy_furnace_active","RE") - 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") + 1) - if dst_index and meta:get_float("src_time") >= 4 then - -- check if there's room for output in "dst" list - dst_stack={} - dst_stack["name"]=alloy_recipes[dst_index].dst_name - dst_stack["count"]=alloy_recipes[dst_index].dst_count - if inv:room_for_item("dst",dst_stack) then - -- Put result in "dst" list - inv:add_item("dst",dst_stack) - -- take stuff from "src" list - for i=1,alloy_recipes[dst_index].src1_count,1 do - srcstack = inv:get_stack("src", 1) - srcstack:take_item() - inv:set_stack("src", 1, srcstack) - end - for i=1,alloy_recipes[dst_index].src2_count,1 do - srcstack = inv:get_stack("src2", 1) - srcstack:take_item() - inv:set_stack("src2", 1, srcstack) - end - - - else - print("Furnace inventory full!") - end - meta:set_string("src_time", 0) - end - end - end - - if dst_index and meta:get_int("furnace_is_cookin")==0 then - hacky_swap_node(pos,"technic:alloy_furnace_active") - meta:set_string("infotext","Electric Alloy Furnace active") - meta:set_int("furnace_is_cookin",1) - meta:set_string("src_time", 0) - return - end - - if meta:get_int("furnace_is_cookin")==0 or dst_index==nil then - hacky_swap_node(pos,"technic:alloy_furnace") - meta:set_string("infotext","Electric Alloy Furnace inactive") - meta:set_int("furnace_is_cookin",0) - meta:set_string("src_time", 0) - end - -end, -}) - -function get_cook_result(src_item1, src_item2) -local counter=registered_recipes_count-1 -for i=1, counter,1 do -if alloy_recipes[i].src1_name==src_item1["name"] and - alloy_recipes[i].src2_name==src_item2["name"] and - alloy_recipes[i].src1_count<=src_item1["count"] and - alloy_recipes[i].src2_count<=src_item2["count"] - then return i end -end -return nil -end - -register_LV_machine ("technic:alloy_furnace","RE") -register_LV_machine ("technic:alloy_furnace_active","RE") - ---coal driven alloy furnace: - +-------------------------------------------------- +-- coal driven alloy furnace. This uses no EUs: +-------------------------------------------------- coal_alloy_furnace_formspec = "size[8,9]".. "label[0,0;Alloy Furnace]".. @@ -212,7 +199,7 @@ coal_alloy_furnace_formspec = "list[current_name;src2;3,1;1,1;]".. "list[current_name;dst;5,1;2,2;]".. "list[current_player;main;0,5;8,4;]" - + minetest.register_node("technic:coal_alloy_furnace", { description = "Alloy Furnace", tiles = {"technic_coal_alloy_furnace_top.png", "technic_coal_alloy_furnace_bottom.png", "technic_coal_alloy_furnace_side.png", @@ -230,9 +217,6 @@ minetest.register_node("technic:coal_alloy_furnace", { inv:set_size("src", 1) inv:set_size("src2", 1) inv:set_size("dst", 4) - local furnace_is_cookin = 0 - local dst_index = nil - end, can_dig = function(pos,player) local meta = minetest.env:get_meta(pos); @@ -268,10 +252,10 @@ minetest.register_abm({ nodenames = {"technic:coal_alloy_furnace","technic:coal_alloy_furnace_active"}, interval = 1, chance = 1, - + action = function(pos, node, active_object_count, active_object_count_wider) local meta = minetest.env:get_meta(pos) - for i, name in ipairs({ + for i, name in pairs({ "fuel_totaltime", "fuel_time", "src_totaltime", @@ -282,108 +266,101 @@ minetest.register_abm({ end end - local inv = meta:get_inventory() + local inv = meta:get_inventory() + local recipe = nil + -- Get what to cook if anything + local srcstack = inv:get_stack("src", 1) + if srcstack then src_item1=srcstack:to_table() end + + local src2stack = inv:get_stack("src2", 1) + if src2stack then src_item2=src2stack:to_table() end + + if src_item1 and src_item2 then + recipe = technic.get_alloy_recipe(src_item1,src_item2) + end + + local was_active = false + + if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then + was_active = true + meta:set_float("fuel_time", meta:get_float("fuel_time") + 1) + meta:set_float("src_time", meta:get_float("src_time") + 1) + if recipe and meta:get_float("src_time") == 6 then + -- check if there's room for output in "dst" list + local dst_stack = { name=recipe.dst_name, count=recipe.dst_count} + if inv:room_for_item("dst",dst_stack) then + -- Take stuff from "src" list + srcstack:take_item(recipe.src1_count) + inv:set_stack("src", 1, srcstack) + src2stack:take_item(recipe.src2_count) + inv:set_stack("src2", 1, src2stack) + -- Put result in "dst" list + inv:add_item("dst",dst_stack) + else + print("Furnace inventory full!") -- Silly code... + end + meta:set_string("src_time", 0) + end + end + + if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then + local percent = math.floor(meta:get_float("fuel_time") / + meta:get_float("fuel_totaltime") * 100) + meta:set_string("infotext","Furnace active: "..percent.."%") + hacky_swap_node(pos,"technic:coal_alloy_furnace_active") + meta:set_string("formspec", + "size[8,9]".. + "label[0,0;Electric Alloy Furnace]".. + "image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:".. + (100-percent)..":default_furnace_fire_fg.png]".. + "list[current_name;fuel;2,3;1,1;]".. + "list[current_name;src;2,1;1,1;]".. + "list[current_name;src2;3,1;1,1;]".. + "list[current_name;dst;5,1;2,2;]".. + "list[current_player;main;0,5;8,4;]") + return + end + + -- FIXME: Make this look more like the electrical version. + -- This code refetches the recipe to see if it can be done again after the iteration srcstack = inv:get_stack("src", 1) if srcstack then src_item1=srcstack:to_table() end srcstack = inv:get_stack("src2", 1) if srcstack then src_item2=srcstack:to_table() end - dst_index=nil - - if src_item1 and src_item2 then - dst_index=get_cook_result(src_item1,src_item2) - end - - local was_active = false - - if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then - was_active = true - meta:set_float("fuel_time", meta:get_float("fuel_time") + 1) - meta:set_float("src_time", meta:get_float("src_time") + 1) - if dst_index and meta:get_float("src_time") >= 5 then - -- check if there's room for output in "dst" list - dst_stack={} - dst_stack["name"]=alloy_recipes[dst_index].dst_name - dst_stack["count"]=alloy_recipes[dst_index].dst_count - if inv:room_for_item("dst",dst_stack) then - -- Put result in "dst" list - inv:add_item("dst", dst_stack) - -- take stuff from "src" list - for i=1,alloy_recipes[dst_index].src1_count,1 do - srcstack = inv:get_stack("src", 1) - srcstack:take_item() - inv:set_stack("src", 1, srcstack) - end - for i=1,alloy_recipes[dst_index].src2_count,1 do - srcstack = inv:get_stack("src2", 1) - srcstack:take_item() - inv:set_stack("src2", 1, srcstack) - end - else - print("Furnace inventory full!") - end - meta:set_string("src_time", 0) - end - end - - if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then - local percent = math.floor(meta:get_float("fuel_time") / - meta:get_float("fuel_totaltime") * 100) - meta:set_string("infotext","Furnace active: "..percent.."%") - hacky_swap_node(pos,"technic:coal_alloy_furnace_active") - meta:set_string("formspec", - "size[8,9]".. - "label[0,0;Electric Alloy Furnace]".. - "image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:".. - (100-percent)..":default_furnace_fire_fg.png]".. - "list[current_name;fuel;2,3;1,1;]".. - "list[current_name;src;2,1;1,1;]".. - "list[current_name;src2;3,1;1,1;]".. - "list[current_name;dst;5,1;2,2;]".. - "list[current_player;main;0,5;8,4;]") - return + if src_item1 and src_item2 then + recipe = technic.get_alloy_recipe(src_item1,src_item2) end + if recipe==nil then + if was_active then + meta:set_string("infotext","Furnace is empty") + hacky_swap_node(pos,"technic:coal_alloy_furnace") + meta:set_string("formspec", coal_alloy_furnace_formspec) + end + return + end + + -- Next take a hard look at the fuel situation local fuel = nil local fuellist = inv:get_list("fuel") - - srcstack = inv:get_stack("src", 1) - if srcstack then src_item1=srcstack:to_table() end - srcstack = inv:get_stack("src2", 1) - if srcstack then src_item2=srcstack:to_table() end - dst_index=nil - if src_item1 and src_item2 then - dst_index=get_cook_result(src_item1,src_item2) - end - - if fuellist then - fuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) + fuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) end if fuel.time <= 0 then - meta:set_string("infotext","Furnace out of fuel") - hacky_swap_node(pos,"technic:coal_alloy_furnace") - meta:set_string("formspec", coal_alloy_furnace_formspec) - return - end - - if dst_index==nil then - if was_active then - meta:set_string("infotext","Furnace is empty") - hacky_swap_node(pos,"technic:coal_alloy_furnace") - meta:set_string("formspec", coal_alloy_furnace_formspec) - end - return + meta:set_string("infotext","Furnace out of fuel") + hacky_swap_node(pos,"technic:coal_alloy_furnace") + meta:set_string("formspec", coal_alloy_furnace_formspec) + return end meta:set_string("fuel_totaltime", fuel.time) meta:set_string("fuel_time", 0) - + local stack = inv:get_stack("fuel", 1) stack:take_item() inv:set_stack("fuel", 1, stack) - -end, -}) + end, + }) diff --git a/technic/alloy_furnace_mv.lua b/technic/alloy_furnace_mv.lua index 1d78f6e..cadcb67 100644 --- a/technic/alloy_furnace_mv.lua +++ b/technic/alloy_furnace_mv.lua @@ -9,262 +9,451 @@ minetest.register_craft({ } }) -MV_alloy_furnace_formspec = +local mv_alloy_furnace_formspec = "invsize[8,10;]".. "label[0,0;MV Alloy Furnace]".. - "image[1,1;1,2;technic_power_meter_bg.png]".. - "label[1,2.8;Power level]".. - "list[current_name;src;3,1;1,2;]".. + "list[current_name;src;3,1;1,2;]".. "list[current_name;dst;5,1;2,2;]".. "list[current_player;main;0,6;8,4;]".. "list[current_name;upgrade1;1,4;1,1;]".. "list[current_name;upgrade2;2,4;1,1;]".. "label[1,5;Upgrade Slots]" -minetest.register_node("technic:mv_alloy_furnace", { - description = "MV Alloy Furnace", - tiles = {"technic_mv_alloy_furnace_top.png", "technic_mv_alloy_furnace_bottom.png", "technic_mv_alloy_furnace_side_tube.png", - "technic_mv_alloy_furnace_side_tube.png", "technic_mv_alloy_furnace_side.png", "technic_mv_alloy_furnace_front.png"}, - paramtype2 = "facedir", - groups = {cracky=2, tubedevice=1,tubedevice_receiver=1}, - tube={insert_object=function(pos,node,stack,direction) - local meta=minetest.env:get_meta(pos) - local inv=meta:get_inventory() - return inv:add_item("src",stack) - end, - can_insert=function(pos,node,stack,direction) +minetest.register_node( + "technic:mv_alloy_furnace", + {description = "MV Alloy Furnace", + tiles = {"technic_mv_alloy_furnace_top.png", "technic_mv_alloy_furnace_bottom.png", "technic_mv_alloy_furnace_side_tube.png", + "technic_mv_alloy_furnace_side_tube.png", "technic_mv_alloy_furnace_side.png", "technic_mv_alloy_furnace_front.png"}, + paramtype2 = "facedir", + groups = {cracky=2, tubedevice=1,tubedevice_receiver=1}, + tube={insert_object=function(pos,node,stack,direction) + local meta=minetest.env:get_meta(pos) + local inv=meta:get_inventory() + return inv:add_item("src",stack) + end, + can_insert=function(pos,node,stack,direction) local meta=minetest.env:get_meta(pos) local inv=meta:get_inventory() return inv:room_for_item("src",stack) - end, - }, - 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", mv_alloy_furnace_formspec) - meta:set_string("infotext", "MV Electric Alloy furnace") - local inv = meta:get_inventory() - inv:set_size("src", 2) - inv:set_size("dst", 4) - inv:set_size("upgrade1", 1) - inv:set_size("upgrade2", 1) - 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) - - 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 end - if not inv:is_empty("src") then - return false end - if not inv:is_empty("upgrade1") then - return false end - if not inv:is_empty("upgrade2") then - return false end - return true - end, + end, + }, + 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", "MV Alloy furnace") + meta:set_float("technic_mv_power_machine", 1) + meta:set_int("tube_time", 0) + meta:set_string("formspec", mv_alloy_furnace_formspec) + local inv = meta:get_inventory() + inv:set_size("src", 2) + inv:set_size("dst", 4) + inv:set_size("upgrade1", 1) + inv:set_size("upgrade2", 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") or not inv:is_empty("upgrade1") or not inv:is_empty("upgrade2") 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:mv_alloy_furnace_active", { - description = "MV Alloy Furnace", - tiles = {"technic_mv_alloy_furnace_top.png", "technic_mv_alloy_furnace_bottom.png", "technic_mv_alloy_furnace_side_tube.png", - "technic_mv_alloy_furnace_side_tube.png", "technic_mv_alloy_furnace_side.png", "technic_mv_alloy_furnace_front_active.png"}, - paramtype2 = "facedir", - light_source = 8, - drop = "technic:mv_alloy_furnace", - groups = {cracky=2, tubedevice=1,tubedevice_receiver=1,not_in_creative_inventory=1}, - tube={insert_object=function(pos,node,stack,direction) - local meta=minetest.env:get_meta(pos) - local inv=meta:get_inventory() - return inv:add_item("src",stack) - end, - can_insert=function(pos,node,stack,direction) +minetest.register_node( + "technic:mv_alloy_furnace_active", + {description = "MV Alloy Furnace", + tiles = {"technic_mv_alloy_furnace_top.png", "technic_mv_alloy_furnace_bottom.png", "technic_mv_alloy_furnace_side_tube.png", + "technic_mv_alloy_furnace_side_tube.png", "technic_mv_alloy_furnace_side.png", "technic_mv_alloy_furnace_front_active.png"}, + paramtype2 = "facedir", + light_source = 8, + drop = "technic:mv_alloy_furnace", + groups = {cracky=2, tubedevice=1,tubedevice_receiver=1,not_in_creative_inventory=1}, + tube={insert_object=function(pos,node,stack,direction) + local meta=minetest.env:get_meta(pos) + local inv=meta:get_inventory() + return inv:add_item("src",stack) + end, + can_insert=function(pos,node,stack,direction) local meta=minetest.env:get_meta(pos) local inv=meta:get_inventory() return inv:room_for_item("src",stack) - end, - }, - legacy_facedir_simple = true, - sounds = default.node_sound_stone_defaults(), - internal_EU_buffer=0; - interal_EU_buffer_size=2000; - technic_power_machine=1, - 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 end - if not inv:is_empty("src") then - return false end - if not inv:is_empty("upgrade1") then - return false end - if not inv:is_empty("upgrade2") then - return false end - return true - end, + end, + }, + 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") or not inv:is_empty("upgrade1") or not inv:is_empty("upgrade2") 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, + -- These three makes sure upgrades are not moved in or out while the furnace is active. + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if listname == "src" or listname == "dst" then + return 99 + else + return 0 -- Disallow the move + end + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if listname == "src" or listname == "dst" then + return 99 + else + return 0 -- Disallow the move + end + end, + allow_metadata_inventory_move = function(pos, from_list, to_list, to_list, to_index, count, player) + return 0 + end, }) -minetest.register_abm({ - nodenames = {"technic:mv_alloy_furnace","technic:mv_alloy_furnace_active"}, - interval = 1, - chance = 1, +local send_cooked_items = function(pos,x_velocity,z_velocity) + -- Send items on their way in the pipe system. + local meta=minetest.env:get_meta(pos) + local inv = meta:get_inventory() + local i=0 + for _,stack in ipairs(inv:get_list("dst")) do + i=i+1 + if stack then + local item0=stack:to_table() + if item0 then + item0["count"]="1" + local item1=tube_item({x=pos.x,y=pos.y,z=pos.z},item0) + item1:get_luaentity().start_pos = {x=pos.x,y=pos.y,z=pos.z} + item1:setvelocity({x=x_velocity, y=0, z=z_velocity}) + item1:setacceleration({x=0, y=0, z=0}) + stack:take_item(1); + inv:set_stack("dst", i, stack) + return + end + end + end + end - action = function(pos, node, active_object_count, active_object_count_wider) - local pos1={} - pos1.x=pos.x - pos1.y=pos.y - pos1.z=pos.z - local x_velocity=0 - local z_velocity=0 +local smelt_item = function(pos) + local meta=minetest.env:get_meta(pos) + local inv = meta:get_inventory() + meta:set_int("src_time", meta:get_int("src_time") + 3) -- Cooking time 3x faster + local result = minetest.get_craft_result({method = "cooking", width = 1, items = inv:get_list("src")}) + dst_stack={} + dst_stack["name"]=alloy_recipes[dst_index].dst_name + dst_stack["count"]=alloy_recipes[dst_index].dst_count - -- output is on the left side of the furnace - if node.param2==3 then pos1.z=pos1.z-1 z_velocity =-1 end - if node.param2==2 then pos1.x=pos1.x-1 x_velocity =-1 end - if node.param2==1 then pos1.z=pos1.z+1 z_velocity = 1 end - if node.param2==0 then pos1.x=pos1.x+1 x_velocity = 1 end + if result and result.item and meta:get_int("src_time") >= result.time then + meta:set_int("src_time", 0) + -- check if there's room for output in "dst" list + 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.item) + return 1 + else + return 0 -- done + end + end + return 0 -- done + end - local output_tube_connected = false - local meta=minetest.env:get_meta(pos1) - if meta:get_int("tubelike")==1 then output_tube_connected=true end - meta = minetest.env:get_meta(pos) - local inv = meta:get_inventory() - local upg_item1 - local upg_item1_name="" - local upg_item2 - local upg_item2_name="" - local srcstack = inv:get_stack("upgrade1", 1) - if srcstack then upg_item1=srcstack:to_table() end - srcstack = inv:get_stack("upgrade2", 1) - if srcstack then upg_item2=srcstack:to_table() end - if upg_item1 then upg_item1_name=upg_item1.name end - if upg_item2 then upg_item2_name=upg_item2.name end +minetest.register_abm( + {nodenames = {"technic:mv_alloy_furnace","technic:mv_alloy_furnace_active"}, + interval = 1, + chance = 1, - local speed=0 - if upg_item1_name=="technic:control_logic_unit" then speed=speed+1 end - if upg_item2_name=="technic:control_logic_unit" then speed=speed+1 end - tube_time=meta:get_float("tube_time") - tube_time=tube_time+speed - if tube_time>3 then - tube_time=0 - if output_tube_connected then send_cooked_alloys(pos,x_velocity,z_velocity) end - end - meta:set_float("tube_time", tube_time) + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.env:get_meta(pos) + local eu_input = meta:get_int("MV_EU_input") + local state = meta:get_int("state") + local next_state = state - local extra_buffer_size = 0 - if upg_item1_name=="technic:battery" then extra_buffer_size =extra_buffer_size + 10000 end - if upg_item2_name=="technic:battery" then extra_buffer_size =extra_buffer_size + 10000 end - local internal_EU_buffer_size=2000+extra_buffer_size - meta:set_float("internal_EU_buffer_size",internal_EU_buffer_size) - - internal_EU_buffer=meta:get_float("internal_EU_buffer") - if internal_EU_buffer > internal_EU_buffer_size then internal_EU_buffer = internal_EU_buffer_size end - local meta = minetest.env:get_meta(pos) - local load = math.floor(internal_EU_buffer/internal_EU_buffer_size * 100) - meta:set_string("formspec", - MV_alloy_furnace_formspec.. - "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. - (load)..":technic_power_meter_fg.png]") - - local inv = meta:get_inventory() - - local furnace_is_cookin = meta:get_int("furnace_is_cookin") - - local srclist = inv:get_list("src") - local srclist2 = inv:get_list("src2") + -- Machine information + local machine_name = "MV Alloy Furnace" + local machine_node = "technic:mv_alloy_furnace" + local machine_state_demand = { 50, 2000, 1500, 1000 } - srcstack = inv:get_stack("src", 1) - if srcstack then src_item1=srcstack:to_table() end - srcstack = inv:get_stack("src", 2) - if srcstack then src_item2=srcstack:to_table() end - dst_index=nil + -- 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("MV_EU_demand", machine_state_demand[1]) + meta:set_int("MV_EU_input", 0) + return + end + + -- Power off automatically if no longer connected to a switching station + technic.switching_station_timeout_count(pos, "MV") + + -- Execute always logic + -- CODE HERE -- - if src_item1 and src_item2 then - dst_index=get_cook_result(src_item1,src_item2) - end + -- 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 meta=minetest.env:get_meta(pos) + + -- Get the names of the upgrades + local meta=minetest.env:get_meta(pos) + local inv = meta:get_inventory() + local upg_item1 + local upg_item1_name="" + local upg_item2 + local upg_item2_name="" + local srcstack = inv:get_stack("upgrade1", 1) + if srcstack then upg_item1=srcstack:to_table() end + srcstack = inv:get_stack("upgrade2", 1) + if srcstack then upg_item2=srcstack:to_table() end + if upg_item1 then upg_item1_name=upg_item1.name end + if upg_item2 then upg_item2_name=upg_item2.name end + + -- Save some power by installing battery upgrades. Fully upgraded makes this + -- furnace use the same amount of power as the LV version + local EU_saving_upgrade = 0 + if upg_item1_name=="technic:battery" then EU_saving_upgrade = EU_saving_upgrade + 1 end + if upg_item2_name=="technic:battery" then EU_saving_upgrade = EU_saving_upgrade + 1 end + + -- Tube loading speed can be upgraded using control logic units + local tube_speed_upgrade = 0 + if upg_item1_name=="technic:control_logic_unit" then tube_speed_upgrade = tube_speed_upgrade + 1 end + if upg_item2_name=="technic:control_logic_unit" then tube_speed_upgrade = tube_speed_upgrade + 1 end + + -- Handle pipeworks (consumes tube_speed_upgrade) + local pos1={x=pos.x, y=pos.y, z=pos.z} + local x_velocity=0 + local z_velocity=0 + + -- Output is on the left side of the furnace + if node.param2==3 then pos1.z=pos1.z-1 z_velocity =-1 end + if node.param2==2 then pos1.x=pos1.x-1 x_velocity =-1 end + if node.param2==1 then pos1.z=pos1.z+1 z_velocity = 1 end + if node.param2==0 then pos1.x=pos1.x+1 x_velocity = 1 end + + local output_tube_connected = false + local meta1 = minetest.env:get_meta(pos1) + if meta1:get_int("tubelike") == 1 then + output_tube_connected=true + end + tube_time = meta:get_int("tube_time") + tube_time = tube_time + tube_speed_upgrade + if tube_time > 3 then + tube_time = 0 + if output_tube_connected then + send_cooked_items(pos,x_velocity,z_velocity) + end + end + meta:set_int("tube_time", tube_time) + -- The machine shuts down if we have nothing to smelt and no tube is connected + -- or if we have nothing to send with a tube connected. + if (not output_tube_connected and inv:is_empty("src")) + or ( output_tube_connected and inv:is_empty("dst")) then + next_state = 1 + end + ---------------------- + local empty = 1 + local recipe = nil + local result = nil - 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") + 1) - if dst_index and meta:get_float("src_time") >= 4 then - -- check if there's room for output in "dst" list - dst_stack={} - dst_stack["name"]=alloy_recipes[dst_index].dst_name - dst_stack["count"]=alloy_recipes[dst_index].dst_count - if inv:room_for_item("dst",dst_stack) then - -- Put result in "dst" list - inv:add_item("dst",dst_stack) - -- take stuff from "src" list - for i=1,alloy_recipes[dst_index].src1_count,1 do - srcstack = inv:get_stack("src", 1) - srcstack:take_item() - inv:set_stack("src", 1, srcstack) - end - for i=1,alloy_recipes[dst_index].src2_count,1 do - srcstack = inv:get_stack("src", 2) - srcstack:take_item() - inv:set_stack("src", 2, srcstack) - end - - else - print("Furnace inventory full!") - end - meta:set_string("src_time", 0) - end - end + -- Get what to cook if anything + local srcstack = inv:get_stack("src", 1) + local src2stack = inv:get_stack("src", 2) + local src_item1 = nil + local src_item2 = nil + if srcstack and src2stack then + src_item1 = srcstack:to_table() + src_item2 = src2stack:to_table() + empty = 0 + end + + if src_item1 and src_item2 then + recipe = technic.get_alloy_recipe(src_item1,src_item2) + end + if recipe then + result = { name=recipe.dst_name, count=recipe.dst_count} + end + + if state == 1 then + hacky_swap_node(pos, machine_node) + meta:set_string("infotext", machine_name.." Idle") + + local meta=minetest.env:get_meta(pos) + local inv = meta:get_inventory() + if not inv:is_empty("src") then + if empty == 0 and recipe and inv:room_for_item("dst", result) then + meta:set_string("infotext", machine_name.." Active") + meta:set_int("src_time", 0) + next_state = 2+EU_saving_upgrade -- Next state is decided by the battery upgrade (state 2= 0 batteries, state 3 = 1 battery, 4 = 2 batteries) + end + end + + elseif state == 2 or state == 3 or state == 4 then + hacky_swap_node(pos, machine_node.."_active") + meta:set_int("src_time", meta:get_int("src_time") + 1) + if meta:get_int("src_time") == 4 then -- 4 ticks per output + meta:set_string("src_time", 0) + -- check if there's room for output in "dst" list and that we have the materials + if recipe and inv:room_for_item("dst", result) then + -- Take stuff from "src" list + srcstack:take_item(recipe.src1_count) + inv:set_stack("src", 1, srcstack) + src2stack:take_item(recipe.src2_count) + inv:set_stack("src2", 1, src2stack) + -- Put result in "dst" list + inv:add_item("dst",result) + else + next_state = 1 + end + end + end + end + -- Change state? + if next_state ~= state then + meta:set_int("MV_EU_demand", machine_state_demand[next_state]) + meta:set_int("state", next_state) end - if dst_index and meta:get_int("furnace_is_cookin")==0 then - hacky_swap_node(pos,"technic:mv_alloy_furnace_active") - meta:set_string("infotext","MV Alloy Furnace active") - meta:set_int("furnace_is_cookin",1) - meta:set_string("src_time", 0) - return - end - if meta:get_int("furnace_is_cookin")==0 or dst_index==nil then - hacky_swap_node(pos,"technic:mv_alloy_furnace") - meta:set_string("infotext","MV Alloy Furnace inactive") - meta:set_int("furnace_is_cookin",0) - meta:set_string("src_time", 0) - end -end, -}) + ------------------------------------ -function send_cooked_alloys (pos,x_velocity,z_velocity) - local meta=minetest.env:get_meta(pos) - local inv = meta:get_inventory() - local i=0 - for _,stack in ipairs(inv:get_list("dst")) do - i=i+1 - if stack then - local item0=stack:to_table() - if item0 then - item0["count"]="1" - local item1=tube_item({x=pos.x,y=pos.y,z=pos.z},item0) - item1:get_luaentity().start_pos = {x=pos.x,y=pos.y,z=pos.z} - item1:setvelocity({x=x_velocity, y=0, z=z_velocity}) - item1:setacceleration({x=0, y=0, z=0}) - stack:take_item(1); - inv:set_stack("dst", i, stack) - return - end - end - end -end +-- local pos1={} +-- pos1.x=pos.x +-- pos1.y=pos.y +-- pos1.z=pos.z +-- local x_velocity=0 +-- local z_velocity=0 +-- +-- -- output is on the left side of the furnace +-- if node.param2==3 then pos1.z=pos1.z-1 z_velocity =-1 end +-- if node.param2==2 then pos1.x=pos1.x-1 x_velocity =-1 end +-- if node.param2==1 then pos1.z=pos1.z+1 z_velocity = 1 end +-- if node.param2==0 then pos1.x=pos1.x+1 x_velocity = 1 end +-- +-- local output_tube_connected = false +-- local meta=minetest.env:get_meta(pos1) +-- if meta:get_int("tubelike")==1 then output_tube_connected=true end +-- meta = minetest.env:get_meta(pos) +-- local inv = meta:get_inventory() +-- local upg_item1 +-- local upg_item1_name="" +-- local upg_item2 +-- local upg_item2_name="" +-- local srcstack = inv:get_stack("upgrade1", 1) +-- if srcstack then upg_item1=srcstack:to_table() end +-- srcstack = inv:get_stack("upgrade2", 1) +-- if srcstack then upg_item2=srcstack:to_table() end +-- if upg_item1 then upg_item1_name=upg_item1.name end +-- if upg_item2 then upg_item2_name=upg_item2.name end +-- +-- local speed=0 +-- if upg_item1_name=="technic:control_logic_unit" then speed=speed+1 end +-- if upg_item2_name=="technic:control_logic_unit" then speed=speed+1 end +-- tube_time=meta:get_float("tube_time") +-- tube_time=tube_time+speed +-- if tube_time>3 then +-- tube_time=0 +-- if output_tube_connected then send_cooked_items(pos,x_velocity,z_velocity) end +-- end +-- meta:set_float("tube_time", tube_time) +-- +-- local extra_buffer_size = 0 +-- if upg_item1_name=="technic:battery" then extra_buffer_size =extra_buffer_size + 10000 end +-- if upg_item2_name=="technic:battery" then extra_buffer_size =extra_buffer_size + 10000 end +-- local internal_EU_buffer_size=2000+extra_buffer_size +-- meta:set_float("internal_EU_buffer_size",internal_EU_buffer_size) +-- +-- internal_EU_buffer=meta:get_float("internal_EU_buffer") +-- if internal_EU_buffer > internal_EU_buffer_size then internal_EU_buffer = internal_EU_buffer_size end +-- local meta = minetest.env:get_meta(pos) +-- local load = math.floor(internal_EU_buffer/internal_EU_buffer_size * 100) +-- meta:set_string("formspec", +-- MV_alloy_furnace_formspec.. +-- "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. +-- (load)..":technic_power_meter_fg.png]") +-- +-- local inv = meta:get_inventory() +-- +-- local furnace_is_cookin = meta:get_int("furnace_is_cookin") +-- +-- local srclist = inv:get_list("src") +-- local srclist2 = inv:get_list("src2") +-- +-- srcstack = inv:get_stack("src", 1) +-- if srcstack then src_item1=srcstack:to_table() end +-- srcstack = inv:get_stack("src", 2) +-- if srcstack then src_item2=srcstack:to_table() end +-- dst_index=nil +-- +-- if src_item1 and src_item2 then +-- dst_index=get_cook_result(src_item1,src_item2) +-- 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") + 1) +-- if dst_index and meta:get_float("src_time") >= 4 then +-- -- check if there's room for output in "dst" list +-- dst_stack={} +-- dst_stack["name"]=alloy_recipes[dst_index].dst_name +-- dst_stack["count"]=alloy_recipes[dst_index].dst_count +-- if inv:room_for_item("dst",dst_stack) then +-- -- Put result in "dst" list +-- inv:add_item("dst",dst_stack) +-- -- take stuff from "src" list +-- for i=1,alloy_recipes[dst_index].src1_count,1 do +-- srcstack = inv:get_stack("src", 1) +-- srcstack:take_item() +-- inv:set_stack("src", 1, srcstack) +-- end +-- for i=1,alloy_recipes[dst_index].src2_count,1 do +-- srcstack = inv:get_stack("src", 2) +-- srcstack:take_item() +-- inv:set_stack("src", 2, srcstack) +-- end +-- +-- else +-- print("Furnace inventory full!") +-- end +-- meta:set_string("src_time", 0) +-- end +-- end +-- end +-- +-- if dst_index and meta:get_int("furnace_is_cookin")==0 then +-- hacky_swap_node(pos,"technic:mv_alloy_furnace_active") +-- meta:set_string("infotext","MV Alloy Furnace active") +-- meta:set_int("furnace_is_cookin",1) +-- meta:set_string("src_time", 0) +-- return +-- end +-- +-- if meta:get_int("furnace_is_cookin")==0 or dst_index==nil then +-- hacky_swap_node(pos,"technic:mv_alloy_furnace") +-- meta:set_string("infotext","MV Alloy Furnace inactive") +-- meta:set_int("furnace_is_cookin",0) +-- meta:set_string("src_time", 0) +-- end +-- + end, + }) -register_MV_machine ("technic:mv_alloy_furnace","RE") -register_MV_machine ("technic:mv_alloy_furnace_active","RE") +technic.register_MV_machine ("technic:mv_alloy_furnace","RE") +technic.register_MV_machine ("technic:mv_alloy_furnace_active","RE") diff --git a/technic/alloy_furnaces_commons.lua b/technic/alloy_furnaces_commons.lua index 9c9c42a..5a6e65b 100644 --- a/technic/alloy_furnaces_commons.lua +++ b/technic/alloy_furnaces_commons.lua @@ -1,32 +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, + }) + end end register_alloy_recipe ("technic:copper_dust",3, "technic:tin_dust",1, "technic:bronze_dust",4) diff --git a/technic/battery_box.lua b/technic/battery_box.lua index 5726053..1f0740d 100644 --- a/technic/battery_box.lua +++ b/technic/battery_box.lua @@ -1,23 +1,8 @@ --- 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) +-- 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 1', @@ -28,29 +13,32 @@ minetest.register_craft({ } }) -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_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_craftitem("technic:battery_box", { - description = "Battery box", - stack_max = 99, - }) +-------------------------------------------- +-- The Battery box +-------------------------------------------- +minetest.register_craftitem( + "technic:battery_box", + { + description = "Battery box", + stack_max = 99, + }) +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'}, + } + }) - -battery_box_formspec = +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;]".. @@ -71,28 +59,28 @@ minetest.register_node( 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) + 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) - 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 - return true - end, + 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, }) @@ -105,51 +93,101 @@ for i=1,8,1 do 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", - 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 - return true - end, + 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 -function get_RE_item_load (load1,max_load) - if load1==0 then load1=65535 end - local temp = 65536-load1 - temp= temp/65535*max_load - return math.floor(temp + 0.5) -end +local power_tools = technic.LV_power_tools -function set_RE_item_load (load1,max_load) - if load1 == 0 then return 65535 end - local temp=load1/max_load*65535 - temp=65536-temp - return math.floor(temp) -end +local charge_LV_tools = function(meta, charge) + --charge registered power tools + local inv = meta:get_inventory() + if inv:is_empty("src")==false then + local srcstack = inv:get_stack("src", 1) + local src_item=srcstack:to_table() + local src_meta=get_item_meta(src_item["metadata"]) + + local toolname = src_item["name"] + if power_tools[toolname] ~= nil then + -- Set meta data for the tool if it didn't do it itself :-( + src_meta=get_item_meta(src_item["metadata"]) + if src_meta==nil then + src_meta={} + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + else + if src_meta["technic_power_tool"]==nil then + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + end + end + -- Do the charging + local item_max_charge = power_tools[toolname] + local load = src_meta["charge"] + local load_step = 1000 -- how much to charge per tick + if load0 then + if charge-load_step<0 then load_step=charge end + if load+load_step>item_max_charge then load_step=item_max_charge-load end + load=load+load_step + charge=charge-load_step + technic.set_RE_wear(src_item,load,item_max_charge) + src_meta["charge"] = load + src_item["metadata"] = set_item_meta(src_meta) + inv:set_stack("src", 1, src_item) + end + end + end + return charge -- return the remaining charge in the battery + end -function set_RE_wear (item_stack,load1,max_load) - local temp=65536-math.floor(load1/max_load*65535) - item_stack["wear"]=tostring(temp) - return item_stack -end +local discharge_LV_tools = function(meta, charge, max_charge) + -- discharging registered power tools + local inv = meta:get_inventory() + if inv:is_empty("dst") == false then + srcstack = inv:get_stack("dst", 1) + src_item=srcstack:to_table() + local src_meta=get_item_meta(src_item["metadata"]) + local toolname = src_item["name"] + if power_tools[toolname] ~= nil then + -- Set meta data for the tool if it didn't do it itself :-( + src_meta=get_item_meta(src_item["metadata"]) + if src_meta==nil then + src_meta={} + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + else + if src_meta["technic_power_tool"]==nil then + src_meta["technic_power_tool"]=true + src_meta["charge"]=0 + end + end + -- Do the discharging + local item_max_charge = power_tools[toolname] + local load = src_meta["charge"] + local load_step = 4000 -- how much to discharge per tick + if load>0 and chargemax_charge then load_step=max_charge-charge end + if load-load_step<0 then load_step=load end + load=load-load_step + charge=charge+load_step + technic.set_RE_wear(src_item,load,item_max_charge) + src_meta["charge"]=load + src_item["metadata"]=set_item_meta(src_meta) + inv:set_stack("dst", 1, src_item) + end + end + end + return charge -- return the remaining charge in the battery + end minetest.register_abm( {nodenames = {"technic:battery_box","technic:battery_box1","technic:battery_box2","technic:battery_box3","technic:battery_box4", @@ -157,12 +195,39 @@ minetest.register_abm( interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local meta = minetest.env:get_meta(pos) - local max_charge = 60000 -- Set maximum charge for the device here - local charge = meta:get_int("internal_EU_buffer") + local meta = minetest.env:get_meta(pos) + local max_charge = 60000 -- Set maximum charge for the device here + local max_charge_rate = 1000 -- Set maximum rate of charging + local max_discharge_rate = 2000 -- Set maximum rate of discharging + local eu_input = meta:get_int("LV_EU_input") + local current_charge = meta:get_int("internal_EU_charge") -- Battery charge right now + + -- Power off automatically if no longer connected to a switching station + technic.switching_station_timeout_count(pos, "LV") + + -- Charge/discharge the battery with the input EUs + if eu_input >=0 then + current_charge = math.min(current_charge+eu_input, max_charge) + else + current_charge = math.max(current_charge+eu_input, 0) + end + + -- Charging/discharging tools here + current_charge = charge_LV_tools(meta, current_charge) + current_charge = discharge_LV_tools(meta, current_charge, max_charge) + + -- Set a demand (we allow batteries to charge on less than the demand though) + meta:set_int("LV_EU_demand", math.min(max_charge_rate, max_charge-current_charge)) + --print("BA:"..max_charge_rate.."|"..max_charge-current_charge.."|"..math.min(max_charge_rate, max_charge-current_charge)) + + -- Set how much we can supply + meta:set_int("LV_EU_supply", math.min(max_discharge_rate, current_charge)) + + meta:set_int("internal_EU_charge", current_charge) + --dprint("BA: input:"..eu_input.." supply="..meta:get_int("LV_EU_supply").." demand="..meta:get_int("LV_EU_demand").." current:"..current_charge) -- Select node textures - local i=math.ceil((charge/max_charge)*8) + local i=math.ceil((current_charge/max_charge)*8) if i > 8 then i = 8 end local j = meta:get_float("last_side_shown") if i~=j then @@ -170,224 +235,26 @@ minetest.register_abm( elseif i==0 then hacky_swap_node(pos,"technic:battery_box") end meta:set_float("last_side_shown",i) end - - --charge registered power tools - local inv = meta:get_inventory() - if inv:is_empty("src")==false then - local srcstack = inv:get_stack("src", 1) - local src_item=srcstack:to_table() - local src_meta=get_item_meta(src_item["metadata"]) - - local item_max_charge=nil - for i=1,registered_power_tools_count,1 do - if power_tools[i].tool_name==src_item["name"] then - src_meta=get_item_meta(src_item["metadata"]) - if src_meta==nil then - src_meta={} - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - else - if src_meta["technic_power_tool"]==nil then - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - end - end - -- Do the charging - local item_max_charge = power_tools[i].max_charge - local load1 = src_meta["charge"] - local load_step = 1000 -- how much to charge per tick - if load10 then - if charge-load_step<0 then load_step=charge end - if load1+load_step>item_max_charge then load_step=item_max_charge-load1 end - load1=load1+load_step - charge=charge-load_step - set_RE_wear(src_item,load1,item_max_charge) - src_meta["charge"]=load1 - src_item["metadata"]=set_item_meta(src_meta) - inv:set_stack("src", 1, src_item) - end - meta:set_int("internal_EU_buffer",charge) - break - end - end - end - - -- discharging registered power tools - if inv:is_empty("dst") == false then - srcstack = inv:get_stack("dst", 1) - src_item=srcstack:to_table() - local src_meta=get_item_meta(src_item["metadata"]) - local item_max_charge=nil - for i=1,registered_power_tools_count,1 do - if power_tools[i].tool_name==src_item["name"] then - src_meta=get_item_meta(src_item["metadata"]) - if src_meta==nil then - src_meta={} - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - else - if src_meta["technic_power_tool"]==nil then - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - end - end - local item_max_charge = power_tools[i].max_charge - local load1 = src_meta["charge"] - local load_step = 4000 -- how much to discharge per tick - if load1>0 and chargemax_charge then load_step=max_charge-charge end - if load1-load_step<0 then load_step=load1 end - load1=load1-load_step - charge=charge+load_step - set_RE_wear(src_item,load1,item_max_charge) - src_meta["charge"]=load1 - src_item["metadata"]=set_item_meta(src_meta) - inv:set_stack("dst", 1, src_item) - end - meta:set_int("internal_EU_buffer",charge) - break - end - end - end - local load = math.floor(charge/60000 * 100) + local load = math.floor(current_charge/max_charge * 100) meta:set_string("formspec", battery_box_formspec.. "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. (load)..":technic_power_meter_fg.png]" ) - -- Next index the surrounding network the get the producers and receivers on the power grid - local pos1={} - pos1.y=pos.y-1 - pos1.x=pos.x - pos1.z=pos.z - - meta1 = minetest.env:get_meta(pos1) - if meta1:get_float("cablelike")~=1 then return end - - local LV_nodes = {} - local PR_nodes = {} - local RE_nodes = {} - local BA_nodes = {} - - LV_nodes[1]={} - LV_nodes[1].x=pos1.x - LV_nodes[1].y=pos1.y - LV_nodes[1].z=pos1.z - LV_nodes[1].visited=false - - local table_index=1 - repeat - check_LV_node(PR_nodes,RE_nodes,BA_nodes,LV_nodes,table_index) - table_index=table_index+1 - if LV_nodes[table_index]==nil then break end - until false - - - -- Get power from all connected producers - local pr_pos - for _,pr_pos in ipairs(PR_nodes) do - local meta1 = minetest.env:get_meta(pr_pos) - local internal_EU_buffer = meta1:get_float("internal_EU_buffer") - local charge_to_take = 200 - if charge0 then - charge=charge+charge_to_take - internal_EU_buffer=internal_EU_buffer-charge_to_take - meta1:set_float("internal_EU_buffer",internal_EU_buffer) - end - end + if eu_input == 0 then + meta:set_string("infotext", "LV Battery box: "..current_charge.."/"..max_charge.." (idle)") + else + meta:set_string("infotext", "LV Battery box: "..current_charge.."/"..max_charge) end - if charge>max_charge then charge=max_charge end - - -- Provide power to all connected receivers - local re_pos - for _,re_pos in ipairs(RE_nodes) do - local meta1 = minetest.env:get_meta(re_pos) - local internal_EU_buffer = meta1:get_float("internal_EU_buffer") - local internal_EU_buffer_size = meta1:get_float("internal_EU_buffer_size") - local charge_to_give = math.min(200, charge/table.getn(RE_nodes)) - if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then - charge_to_give=internal_EU_buffer_size-internal_EU_buffer - end - if charge-charge_to_give<0 then charge_to_give=charge end - - internal_EU_buffer=internal_EU_buffer+charge_to_give - meta1:set_float("internal_EU_buffer",internal_EU_buffer) - charge=charge-charge_to_give; - end - charge=math.floor(charge) - meta:set_string("infotext", "LV Battery box: "..charge.."/"..max_charge); - meta:set_int("internal_EU_buffer",charge) end }) -- 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 -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 + technic.register_LV_machine("technic:battery_box"..i,"BA") end diff --git a/technic/battery_box_hv.lua b/technic/battery_box_hv.lua index 16aead9..8cd0e2f 100644 --- a/technic/battery_box_hv.lua +++ b/technic/battery_box_hv.lua @@ -1,10 +1,4 @@ --- register MV machines here -technic.HV_machines = {} -local HV_machines = technic.HV_machines -function register_HV_machine(string1,string2) - technic.HV_machines[string1] = string2 -end - +-- HV battery box minetest.register_craft({ output = 'technic:hv_battery_box 1', recipe = { @@ -14,7 +8,7 @@ minetest.register_craft({ } }) -hv_battery_box_formspec = +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;]".. @@ -35,74 +29,176 @@ minetest.register_node( sounds = default.node_sound_wood_defaults(), drop="technic:hv_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", "HV Battery Box") meta:set_float("technic_hv_power_machine", 1) meta:set_string("formspec", battery_box_formspec) + meta:set_int("HV_EU_demand", 0) -- How much can this node charge + meta:set_int("HV_EU_supply", 0) -- How much can this node discharge + meta:set_int("HV_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) - 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 + 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 - return true end, }) for i=1,8,1 do minetest.register_node( - "technic:hv_battery_box"..i, { - description = "HV Battery Box", - tiles = {"technic_hv_battery_box_top.png", "technic_hv_battery_box_bottom.png", "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", - "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_hv_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(), - paramtype="light", - light_source=9, - drop="technic:hv_battery_box", - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - local inv = meta:get_inventory() - meta:set_string("infotext", "HV Battery box") - meta:set_float("technic_hv_power_machine", 1) - meta:set_string("formspec", battery_box_formspec) - 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("dst") then - return false - elseif not inv:is_empty("src") then - return false - end - return true - end, - }) + "technic:hv_battery_box"..i, + {description = "HV Battery Box", + tiles = {"technic_hv_battery_box_top.png", "technic_hv_battery_box_bottom.png", "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", + "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_hv_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(), + paramtype="light", + light_source=9, + drop="technic:hv_battery_box", + 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 +local power_tools = technic.HV_power_tools + +local charge_HV_tools = function(meta, charge) + --charge registered power tools + local inv = meta:get_inventory() + if inv:is_empty("src")==false then + local srcstack = inv:get_stack("src", 1) + local src_item=srcstack:to_table() + local src_meta=get_item_meta(src_item["metadata"]) + + local toolname = src_item["name"] + if power_tools[toolname] ~= nil then + -- Set meta data for the tool if it didn't do it itself :-( + src_meta=get_item_meta(src_item["metadata"]) + if src_meta==nil then + src_meta={} + src_meta["technic_hv_power_tool"]=true + src_meta["charge"]=0 + else + if src_meta["technic_hv_power_tool"]==nil then + src_meta["technic_hv_power_tool"]=true + src_meta["charge"]=0 + end + end + -- Do the charging + local item_max_charge = power_tools[toolname] + local load = src_meta["charge"] + local load_step = 1000 -- how much to charge per tick + if load0 then + if charge-load_step<0 then load_step=charge end + if load+load_step>item_max_charge then load_step=item_max_charge-load end + load=load+load_step + charge=charge-load_step + technic.set_RE_wear(src_item,load,item_max_charge) + src_meta["charge"] = load + src_item["metadata"] = set_item_meta(src_meta) + inv:set_stack("src", 1, src_item) + end + end + end + return charge -- return the remaining charge in the battery + end + +local discharge_HV_tools = function(meta, charge, max_charge) + -- discharging registered power tools + local inv = meta:get_inventory() + if inv:is_empty("dst") == false then + srcstack = inv:get_stack("dst", 1) + src_item=srcstack:to_table() + local src_meta=get_item_meta(src_item["metadata"]) + local toolname = src_item["name"] + if power_tools[toolname] ~= nil then + -- Set meta data for the tool if it didn't do it itself :-( + src_meta=get_item_meta(src_item["metadata"]) + if src_meta==nil then + src_meta={} + src_meta["technic_hv_power_tool"]=true + src_meta["charge"]=0 + else + if src_meta["technic_hv_power_tool"]==nil then + src_meta["technic_hv_power_tool"]=true + src_meta["charge"]=0 + end + end + -- Do the discharging + local item_max_charge = power_tools[toolname] + local load = src_meta["charge"] + local load_step = 4000 -- how much to discharge per tick + if load>0 and chargemax_charge then load_step=max_charge-charge end + if load-load_step<0 then load_step=load end + load=load-load_step + charge=charge+load_step + technic.set_RE_wear(src_item,load,item_max_charge) + src_meta["charge"]=load + src_item["metadata"]=set_item_meta(src_meta) + inv:set_stack("dst", 1, src_item) + end + end + end + return charge -- return the remaining charge in the battery + end + minetest.register_abm( {nodenames = {"technic:hv_battery_box","technic:hv_battery_box1","technic:hv_battery_box2","technic:hv_battery_box3","technic:hv_battery_box4", "technic:hv_battery_box5","technic:hv_battery_box6","technic:hv_battery_box7","technic:hv_battery_box8" }, interval = 1, - chance = 1, + chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local meta = minetest.env:get_meta(pos) - local max_charge = 1500000 - local charge = meta:get_int("internal_EU_buffer") + local meta = minetest.env:get_meta(pos) + local max_charge = 1500000 -- Set maximum charge for the device here + local max_charge_rate = 3000 -- Set maximum rate of charging + local max_discharge_rate = 5000 -- Set maximum rate of discharging (16000) + local eu_input = meta:get_int("HV_EU_input") + local current_charge = meta:get_int("internal_EU_charge") -- Battery charge right now + + -- Power off automatically if no longer connected to a switching station + technic.switching_station_timeout_count(pos, "HV") + + -- Charge/discharge the battery with the input EUs + if eu_input >=0 then + current_charge = math.min(current_charge+eu_input, max_charge) + else + current_charge = math.max(current_charge+eu_input, 0) + end + + -- Charging/discharging tools here + current_charge = charge_HV_tools(meta, current_charge) + current_charge = discharge_HV_tools(meta, current_charge, max_charge) + + -- Set a demand (we allow batteries to charge on less than the demand though) + meta:set_int("HV_EU_demand", math.min(max_charge_rate, max_charge-current_charge)) + + -- Set how much we can supply + meta:set_int("HV_EU_supply", math.min(max_discharge_rate, current_charge)) + + meta:set_int("internal_EU_charge", current_charge) + --dprint("BA: input:"..eu_input.." supply="..meta:get_int("HV_EU_supply").." demand="..meta:get_int("HV_EU_demand").." current:"..current_charge) -- Select node textures - local i = math.ceil((charge/max_charge)*8) + local i=math.ceil((current_charge/max_charge)*8) if i > 8 then i = 8 end local j = meta:get_float("last_side_shown") if i~=j then @@ -111,221 +207,24 @@ minetest.register_abm( meta:set_float("last_side_shown",i) end - --charge registered power tools - local inv = meta:get_inventory() - if inv:is_empty("src")==false then - local srcstack = inv:get_stack("src", 1) - local src_item=srcstack:to_table() - local src_meta=get_item_meta(src_item["metadata"]) - - for i=1,registered_power_tools_count,1 do - if power_tools[i].tool_name==src_item["name"] then - src_meta=get_item_meta(src_item["metadata"]) - if src_meta==nil then - src_meta={} - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - else - if src_meta["technic_power_tool"]==nil then - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - end - end - -- Do the charging - local item_max_charge = power_tools[i].max_charge - local load1 = src_meta["charge"] - local load_step = 16000 -- how much to charge per tick - if load10 then - if charge-load_step<0 then load_step=charge end - if load1+load_step>item_max_charge then load_step=item_max_charge-load1 end - load1=load1+load_step - charge=charge-load_step - set_RE_wear(src_item,load1,item_max_charge) - src_meta["charge"]=load1 - src_item["metadata"]=set_item_meta(src_meta) - inv:set_stack("src", 1, src_item) - end - meta:set_int("internal_EU_buffer",charge) - break - end - end - end - - -- discharging registered power tools - if inv:is_empty("dst") == false then - srcstack = inv:get_stack("dst", 1) - src_item=srcstack:to_table() - local src_meta=get_item_meta(src_item["metadata"]) - local item_max_charge=nil - for i=1,registered_power_tools_count,1 do - if power_tools[i].tool_name==src_item["name"] then - src_meta=get_item_meta(src_item["metadata"]) - if src_meta==nil then - src_meta={} - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - else - if src_meta["technic_power_tool"]==nil then - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - end - end - local item_max_charge = power_tools[i].max_charge - local load1 = src_meta["charge"] - local load_step = 16000 -- how much to discharge per tick - if load1>0 and chargemax_charge then load_step=max_charge-charge end - if load1-load_step<0 then load_step=load1 end - load1=load1-load_step - charge=charge+load_step - set_RE_wear(src_item,load1,item_max_charge) - src_meta["charge"]=load1 - src_item["metadata"]=set_item_meta(src_meta) - inv:set_stack("dst", 1, src_item) - end - meta:set_int("internal_EU_buffer",charge) - break - end - end - end - - - local load = math.floor((charge/1500000) * 100) + local load = math.floor(current_charge/max_charge * 100) meta:set_string("formspec", - hv_battery_box_formspec.. + battery_box_formspec.. "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. (load)..":technic_power_meter_fg.png]" ) - -- Next index the surrounding network the get the producers and receivers on the - local pos1={} - pos1.y=pos.y-1 - pos1.x=pos.x - pos1.z=pos.z - - meta1 = minetest.env:get_meta(pos1) - if meta1:get_float("hv_cablelike")~=1 then return end - - local HV_nodes = {} - local PR_nodes = {} - local RE_nodes = {} - local BA_nodes = {} - - HV_nodes[1]={} - HV_nodes[1].x=pos1.x - HV_nodes[1].y=pos1.y - HV_nodes[1].z=pos1.z - HV_nodes[1].visited=false - - local table_index=1 - repeat - check_HV_node (PR_nodes,RE_nodes,BA_nodes,HV_nodes,table_index) - table_index=table_index+1 - if HV_nodes[table_index]==nil then break end - until false - - -- Get power from all connected producers - local pr_pos - for _,pr_pos in ipairs(PR_nodes) do - local meta1 = minetest.env:get_meta(pr_pos) - local internal_EU_buffer = meta1:get_float("internal_EU_buffer") - local charge_to_take = 4000 - if charge0 then - charge=charge+charge_to_take - internal_EU_buffer=internal_EU_buffer-charge_to_take - meta1:set_float("internal_EU_buffer",internal_EU_buffer) - end - end + if eu_input == 0 then + meta:set_string("infotext", "HV Battery box: "..current_charge.."/"..max_charge.." (idle)") + else + meta:set_string("infotext", "HV Battery box: "..current_charge.."/"..max_charge) end - - if charge>max_charge then charge=max_charge end - - -- Provide power to all connected receivers - local re_pos - for _,re_pos in ipairs(RE_nodes) do - local meta1 = minetest.env:get_meta(re_pos) - local internal_EU_buffer = meta1:get_float("internal_EU_buffer") - local internal_EU_buffer_size = meta1:get_float("internal_EU_buffer_size") - local charge_to_give = math.min(4000, charge/table.getn(RE_nodes)) - if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then - charge_to_give=internal_EU_buffer_size-internal_EU_buffer - end - if charge-charge_to_give<0 then charge_to_give=charge end - - internal_EU_buffer=internal_EU_buffer+charge_to_give - meta1:set_float("internal_EU_buffer",internal_EU_buffer) - charge=charge-charge_to_give; - end - charge=math.floor(charge) - meta:set_string("infotext", "MV Battery box: "..charge.."/"..max_charge); - meta:set_int("internal_EU_buffer",charge) end }) -- 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 -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 + technic.register_HV_machine("technic:hv_battery_box"..i,"BA") end diff --git a/technic/battery_box_mv.lua b/technic/battery_box_mv.lua index 86c445c..dfedc05 100644 --- a/technic/battery_box_mv.lua +++ b/technic/battery_box_mv.lua @@ -1,11 +1,4 @@ --- register MV machines here -technic.MV_machines = {} ---local MV_machines = {} -local MV_machines = technic.MV_machines -function register_MV_machine(string1,string2) - technic.MV_machines[string1] = string2 -end - +-- MV Battery box minetest.register_craft( { output = 'technic:mv_battery_box 1', @@ -16,7 +9,7 @@ minetest.register_craft( } }) -mv_battery_box_formspec = +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;]".. @@ -43,73 +36,172 @@ minetest.register_node( meta:set_string("infotext", "MV Battery box") meta:set_float("technic_mv_power_machine", 1) meta:set_string("formspec", battery_box_formspec) - meta:set_float("internal_EU_buffer", 0) - meta:set_float("internal_EU_buffer_size", 300000) + meta:set_int("MV_EU_demand", 0) -- How much can this node charge + meta:set_int("MV_EU_supply", 0) -- How much can this node discharge + meta:set_int("MV_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) - 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 + 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 - return true - end + end, }) for i=1,8,1 do minetest.register_node( - "technic:mv_battery_box"..i, { + "technic:mv_battery_box"..i, + { description = "MV Battery Box", tiles = {"technic_mv_battery_box_top.png", "technic_mv_battery_box_bottom.png", "technic_mv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_mv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_mv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_mv_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:mv_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", "MV Battery box") - meta:set_float("technic_mv_power_machine", 1) - meta:set_string("formspec", battery_box_formspec) - meta:set_float("internal_EU_buffer", 0) - meta:set_float("internal_EU_buffer_size", 300000) - 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 + 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 - return true - end + end, }) end +local power_tools = technic.MV_power_tools + +local charge_MV_tools = function(meta, charge) + --charge registered power tools + local inv = meta:get_inventory() + if inv:is_empty("src")==false then + local srcstack = inv:get_stack("src", 1) + local src_item=srcstack:to_table() + local src_meta=get_item_meta(src_item["metadata"]) + + local toolname = src_item["name"] + if power_tools[toolname] ~= nil then + -- Set meta data for the tool if it didn't do it itself :-( + src_meta=get_item_meta(src_item["metadata"]) + if src_meta==nil then + src_meta={} + src_meta["technic_mv_power_tool"]=true + src_meta["charge"]=0 + else + if src_meta["technic_mv_power_tool"]==nil then + src_meta["technic_mv_power_tool"]=true + src_meta["charge"]=0 + end + end + -- Do the charging + local item_max_charge = power_tools[toolname] + local load = src_meta["charge"] + local load_step = 1000 -- how much to charge per tick + if load0 then + if charge-load_step<0 then load_step=charge end + if load+load_step>item_max_charge then load_step=item_max_charge-load end + load=load+load_step + charge=charge-load_step + technic.set_RE_wear(src_item,load,item_max_charge) + src_meta["charge"] = load + src_item["metadata"] = set_item_meta(src_meta) + inv:set_stack("src", 1, src_item) + end + end + end + return charge -- return the remaining charge in the battery + end + +local discharge_MV_tools = function(meta, charge, max_charge) + -- discharging registered power tools + local inv = meta:get_inventory() + if inv:is_empty("dst") == false then + srcstack = inv:get_stack("dst", 1) + src_item=srcstack:to_table() + local src_meta=get_item_meta(src_item["metadata"]) + local toolname = src_item["name"] + if power_tools[toolname] ~= nil then + -- Set meta data for the tool if it didn't do it itself :-( + src_meta=get_item_meta(src_item["metadata"]) + if src_meta==nil then + src_meta={} + src_meta["technic_mv_power_tool"]=true + src_meta["charge"]=0 + else + if src_meta["technic_mv_power_tool"]==nil then + src_meta["technic_mv_power_tool"]=true + src_meta["charge"]=0 + end + end + -- Do the discharging + local item_max_charge = power_tools[toolname] + local load = src_meta["charge"] + local load_step = 4000 -- how much to discharge per tick + if load>0 and chargemax_charge then load_step=max_charge-charge end + if load-load_step<0 then load_step=load end + load=load-load_step + charge=charge+load_step + technic.set_RE_wear(src_item,load,item_max_charge) + src_meta["charge"]=load + src_item["metadata"]=set_item_meta(src_meta) + inv:set_stack("dst", 1, src_item) + end + end + end + return charge -- return the remaining charge in the battery + end + minetest.register_abm( - {nodenames = {"technic:mv_battery_box","technic:mv_battery_box1","technic:mv_battery_box2","technic:mv_battery_box3","technic:mv_battery_box4", - "technic:mv_battery_box5","technic:mv_battery_box6","technic:mv_battery_box7","technic:mv_battery_box8" - }, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - local meta = minetest.env:get_meta(pos) - local max_charge = 300000 -- Set maximum charge for the device here - local charge = meta:get_int("internal_EU_buffer") + { + nodenames = {"technic:mv_battery_box","technic:mv_battery_box1","technic:mv_battery_box2","technic:mv_battery_box3","technic:mv_battery_box4", + "technic:mv_battery_box5","technic:mv_battery_box6","technic:mv_battery_box7","technic:mv_battery_box8" + }, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.env:get_meta(pos) + local max_charge = 300000 -- Set maximum charge for the device here + local max_charge_rate = 2000 -- Set maximum rate of charging (4000) + local max_discharge_rate = 3000 -- Set maximum rate of discharging + local eu_input = meta:get_int("MV_EU_input") + local current_charge = meta:get_int("internal_EU_charge") -- Battery charge right now + + -- Power off automatically if no longer connected to a switching station + technic.switching_station_timeout_count(pos, "MV") + + -- Charge/discharge the battery with the input EUs + if eu_input >=0 then + current_charge = math.min(current_charge+eu_input, max_charge) + else + current_charge = math.max(current_charge+eu_input, 0) + end + + -- Charging/discharging tools here + current_charge = charge_MV_tools(meta, current_charge) + current_charge = discharge_MV_tools(meta, current_charge, max_charge) + + -- Set a demand (we allow batteries to charge on less than the demand though) + meta:set_int("MV_EU_demand", math.min(max_charge_rate, max_charge-current_charge)) + + -- Set how much we can supply + meta:set_int("MV_EU_supply", math.min(max_discharge_rate, current_charge)) + + meta:set_int("internal_EU_charge", current_charge) + --dprint("BA: input:"..eu_input.." supply="..meta:get_int("MV_EU_supply").." demand="..meta:get_int("MV_EU_demand").." current:"..current_charge) -- Select node textures - local i = math.ceil((charge/max_charge)*8) + local i=math.ceil((current_charge/max_charge)*8) if i > 8 then i = 8 end local j = meta:get_float("last_side_shown") if i~=j then @@ -118,221 +210,24 @@ minetest.register_abm( meta:set_float("last_side_shown",i) end - --charge registered power tools - local inv = meta:get_inventory() - if inv:is_empty("src")==false then - local srcstack = inv:get_stack("src", 1) - local src_item=srcstack:to_table() - local src_meta=get_item_meta(src_item["metadata"]) - - -- Power tools should really be made into a hash table to avoid linear search. But the list is short so okay... - for i=1,registered_power_tools_count,1 do - if power_tools[i].tool_name==src_item["name"] then - -- What is this code doing? Setting tool properties if not set already???? - src_meta=get_item_meta(src_item["metadata"]) - if src_meta==nil then - src_meta={} - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - else - if src_meta["technic_power_tool"]==nil then - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - end - end - -- Do the charging - local item_max_charge = power_tools[i].max_charge - local load1 = src_meta["charge"] - local load_step = 4000 -- how much to charge per tick - if load10 then - if charge-load_step<0 then load_step=charge end - if load1+load_step>item_max_charge then load_step=item_max_charge-load1 end - load1=load1+load_step - charge=charge-load_step - set_RE_wear(src_item,load1,item_max_charge) - src_meta["charge"] = load1 - src_item["metadata"] = set_item_meta(src_meta) - inv:set_stack("src", 1, src_item) - end - meta:set_int("internal_EU_buffer",charge) - break - end - end - end - - -- discharging registered power tools - if inv:is_empty("dst") == false then - srcstack = inv:get_stack("dst", 1) - src_item=srcstack:to_table() - local src_meta=get_item_meta(src_item["metadata"]) - local item_max_charge=nil - for i=1,registered_power_tools_count,1 do - if power_tools[i].tool_name==src_item["name"] then - src_meta=get_item_meta(src_item["metadata"]) - if src_meta==nil then - src_meta={} - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - else - if src_meta["technic_power_tool"]==nil then - src_meta["technic_power_tool"]=true - src_meta["charge"]=0 - end - end - local item_max_charge = power_tools[i].max_charge - local load1 = src_meta["charge"] - local load_step = 4000 -- how much to discharge per tick - if load1>0 and chargemax_charge then load_step=max_charge-charge end - if load1-load_step<0 then load_step=load1 end - load1=load1-load_step - charge=charge+load_step - set_RE_wear(src_item,load1,item_max_charge) - src_meta["charge"]=load1 - src_item["metadata"]=set_item_meta(src_meta) - inv:set_stack("dst", 1, src_item) - end - meta:set_int("internal_EU_buffer",charge) - break - end - end - end - - local load = math.floor((charge/300000) * 100) + local load = math.floor(current_charge/max_charge * 100) meta:set_string("formspec", - mv_battery_box_formspec.. + battery_box_formspec.. "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. (load)..":technic_power_meter_fg.png]" ) - -- Next index the surrounding network the get the producers and receivers on the power grid - local pos1 = {} - pos1.y = pos.y-1 - pos1.x = pos.x - pos1.z = pos.z - - meta1 = minetest.env:get_meta(pos1) - if meta1:get_float("mv_cablelike")~=1 then return end - - local MV_nodes = {} - local PR_nodes = {} - local RE_nodes = {} - local BA_nodes = {} - - MV_nodes[1] = {} - MV_nodes[1].x = pos1.x - MV_nodes[1].y = pos1.y - MV_nodes[1].z = pos1.z - - local table_index=1 - repeat - check_MV_node(PR_nodes,RE_nodes,BA_nodes,MV_nodes,table_index) - table_index=table_index+1 - if MV_nodes[table_index]==nil then break end - until false - - -- Get power from all connected producers - local pr_pos - for _,pr_pos in ipairs(PR_nodes) do - local meta1 = minetest.env:get_meta(pr_pos) - local internal_EU_buffer = meta1:get_float("internal_EU_buffer") - local charge_to_take = 1000 - if charge0 then - charge=charge+charge_to_take - internal_EU_buffer=internal_EU_buffer-charge_to_take - meta1:set_float("internal_EU_buffer",internal_EU_buffer) - end - end + if eu_input == 0 then + meta:set_string("infotext", "MV Battery box: "..current_charge.."/"..max_charge.." (idle)") + else + meta:set_string("infotext", "MV Battery box: "..current_charge.."/"..max_charge) end - - if charge>max_charge then charge=max_charge end - - -- Provide power to all connected receivers - local re_pos - for _,re_pos in ipairs(RE_nodes) do - local meta1 = minetest.env:get_meta(re_pos) - local internal_EU_buffer = meta1:get_float("internal_EU_buffer") - local internal_EU_buffer_size = meta1:get_float("internal_EU_buffer_size") - local charge_to_give = math.min(1000, charge/table.getn(RE_nodes)) - if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then - charge_to_give=internal_EU_buffer_size-internal_EU_buffer - end - if charge-charge_to_give<0 then charge_to_give=charge end - - internal_EU_buffer=internal_EU_buffer+charge_to_give - meta1:set_float("internal_EU_buffer",internal_EU_buffer) - charge=charge-charge_to_give; - end - charge=math.floor(charge) - meta:set_string("infotext", "MV Battery box: "..charge.."/"..max_charge); - meta:set_int("internal_EU_buffer",charge) end - }) + }) -- 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") -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 + technic.register_MV_machine("technic:mv_battery_box"..i,"BA") end diff --git a/technic/cans.lua b/technic/cans.lua index 78ff413..6a98ce9 100644 --- a/technic/cans.lua +++ b/technic/cans.lua @@ -1,5 +1,5 @@ -water_can_max_load = 16 -lava_can_max_load = 8 +local water_can_max_load = 16 +local lava_can_max_load = 8 minetest.register_craft({ output = 'technic:water_can 1', @@ -42,7 +42,7 @@ minetest.register_tool("technic:water_can", { minetest.env:add_node(pointed_thing.under, {name="air"}) load=load+1; item["metadata"]=tostring(load) - set_RE_wear(item,load,water_can_max_load) + technic.set_RE_wear(item,load,water_can_max_load) itemstack:replace(item) end return itemstack @@ -54,7 +54,7 @@ minetest.register_tool("technic:water_can", { minetest.env:add_node(pointed_thing.under, {name="default:water_source"}) load=load-1; item["metadata"]=tostring(load) - set_RE_wear(item,load,water_can_max_load) + technic.set_RE_wear(item,load,water_can_max_load) itemstack:replace(item) return itemstack end @@ -64,7 +64,7 @@ minetest.register_tool("technic:water_can", { minetest.env:add_node(pointed_thing.above, {name="default:water_source"}) load=load-1; item["metadata"]=tostring(load) - set_RE_wear(item,load,water_can_max_load) + technic.set_RE_wear(item,load,water_can_max_load) itemstack:replace(item) return itemstack end @@ -90,7 +90,7 @@ minetest.register_tool("technic:lava_can", { minetest.env:add_node(pointed_thing.under, {name="air"}) load=load+1; item["metadata"]=tostring(load) - set_RE_wear(item,load,lava_can_max_load) + technic.set_RE_wear(item,load,lava_can_max_load) itemstack:replace(item) end return itemstack @@ -102,7 +102,7 @@ minetest.register_tool("technic:lava_can", { minetest.env:add_node(pointed_thing.under, {name="default:lava_source"}) load=load-1; item["metadata"]=tostring(load) - set_RE_wear(item,load,lava_can_max_load) + technic.set_RE_wear(item,load,lava_can_max_load) itemstack:replace(item) return itemstack end @@ -112,7 +112,7 @@ minetest.register_tool("technic:lava_can", { minetest.env:add_node(pointed_thing.above, {name="default:lava_source"}) load=load-1; item["metadata"]=tostring(load) - set_RE_wear(item,load,lava_can_max_load) + technic.set_RE_wear(item,load,lava_can_max_load) itemstack:replace(item) return itemstack end diff --git a/technic/chainsaw.lua b/technic/chainsaw.lua index 5b3b05b..5c5de4c 100644 --- a/technic/chainsaw.lua +++ b/technic/chainsaw.lua @@ -3,7 +3,7 @@ local chainsaw_max_charge = 30000 -- 30000 - Maximum charge of the saw local chainsaw_charge_per_node = 12 -- 12 - Gives 2500 nodes on a single charge (about 50 complete normal trees) local chainsaw_leaves = true -- true - Cut down entire trees, leaves and all -register_power_tool ("technic:chainsaw",chainsaw_max_charge) +technic.register_LV_power_tool ("technic:chainsaw",chainsaw_max_charge) minetest.register_tool("technic:chainsaw", { description = "Chainsaw", @@ -20,7 +20,7 @@ minetest.register_tool("technic:chainsaw", { if charge < chainsaw_charge_per_node then return end -- only cut if charged charge=chainsaw_dig_it(minetest.get_pointed_thing_position(pointed_thing, above),user,charge) - set_RE_wear(item,charge,chainsaw_max_charge) + technic.set_RE_wear(item,charge,chainsaw_max_charge) meta["charge"]=charge item["metadata"]=set_item_meta(meta) itemstack:replace(item) diff --git a/technic/cnc.lua b/technic/cnc.lua index 4976502..ad3dc67 100644 --- a/technic/cnc.lua +++ b/technic/cnc.lua @@ -1,8 +1,8 @@ --- Technic CNC v1.0 by kpo +-- Technic CNC v1.0 by kpoppel -- Based on the NonCubic Blocks MOD v1.4 by yves_de_beck -- Idea: --- Somehw have a tabbed/paged panel if the number of shapes should expand +-- Somehow have a tabbed/paged panel if the number of shapes should expand -- 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. @@ -32,24 +32,6 @@ local twosize_products = { element_edge = 2, } ---cnc_recipes ={} ---registered_cnc_recipes_count=1 --- ---function register_cnc_recipe (string1,string2) --- cnc_recipes[registered_cnc_recipes_count]={} --- cnc_recipes[registered_cnc_recipes_count].src_name=string1 --- cnc_recipes[registered_cnc_recipes_count].dst_name=string2 --- registered_cnc_recipes_count=registered_cnc_recipes_count+1 --- if unified_inventory then --- unified_inventory.register_craft({ --- type = "cnc milling", --- output = string2, --- items = {string1}, --- width = 0, --- }) --- end ---end - local cnc_formspec = "invsize[9,11;]".. "label[1,0;Choose Milling Program:]".. @@ -88,215 +70,212 @@ local cnc_formspec = "list[current_player;main;0,7;8,4;]" - -local cnc_power_formspec= - "label[0,3;Power]".. - "image[0,1;1,2;technic_power_meter_bg.png]" - local size = 1; -- The form handler is declared here because we need it in both the inactive and active modes -- in order to be able to change programs wile it is running. local form_handler = function(pos, formname, fields, sender) - -- REGISTER MILLING PROGRAMS AND OUTPUTS: - ------------------------------------------ - -- Program for half/full size - if fields["full"] then - size = 1 - return - end - - if fields["half"] then - size = 2 - return - end - - -- Resolve the node name and the number of items to make - local meta = minetest.env:get_meta(pos) - local inv = meta:get_inventory() - local inputstack = inv:get_stack("src", 1) - local inputname = inputstack:get_name() - local multiplier = 0 - for k, _ in pairs(fields) do - -- Set a multipier for the half/full size capable blocks - if twosize_products[k] ~= nil then - multiplier = size*twosize_products[k] - else - multiplier = onesize_products[k] - end - - if onesize_products[k] ~= nil or twosize_products[k] ~= nil then - meta:set_float( "cnc_multiplier", multiplier) - meta:set_string("cnc_user", sender:get_player_name()) - end - - if onesize_products[k] ~= nil or (twosize_products[k] ~= nil and size==2) then - meta:set_string("cnc_product", inputname .. "_technic_cnc_" .. k) - print(inputname .. "_technic_cnc_" .. k) - break - end - - if twosize_products[k] ~= nil and size==1 then - meta:set_string("cnc_product", inputname .. "_technic_cnc_" .. k .. "_double") - print(inputname .. "_technic_cnc_" .. k .. "_double") - break - end - end - return - end -- callback function + -- REGISTER MILLING PROGRAMS AND OUTPUTS: + ------------------------------------------ + -- Program for half/full size + if fields["full"] then + size = 1 + return + end + + if fields["half"] then + size = 2 + return + end + + -- Resolve the node name and the number of items to make + local meta = minetest.env:get_meta(pos) + local inv = meta:get_inventory() + local inputstack = inv:get_stack("src", 1) + local inputname = inputstack:get_name() + local multiplier = 0 + for k, _ in pairs(fields) do + -- Set a multipier for the half/full size capable blocks + if twosize_products[k] ~= nil then + multiplier = size*twosize_products[k] + else + multiplier = onesize_products[k] + end + + if onesize_products[k] ~= nil or twosize_products[k] ~= nil then + meta:set_float( "cnc_multiplier", multiplier) + meta:set_string("cnc_user", sender:get_player_name()) + end + + if onesize_products[k] ~= nil or (twosize_products[k] ~= nil and size==2) then + meta:set_string("cnc_product", inputname .. "_technic_cnc_" .. k) + --print(inputname .. "_technic_cnc_" .. k) + break + end + + if twosize_products[k] ~= nil and size==1 then + meta:set_string("cnc_product", inputname .. "_technic_cnc_" .. k .. "_double") + --print(inputname .. "_technic_cnc_" .. k .. "_double") + break + end + end + return + end -- callback function -- The actual block inactive state -minetest.register_node("technic:cnc", { - description = "CNC Milling Machine", - tiles = {"technic_cnc_top.png", "technic_cnc_bottom.png", "technic_cnc_side.png", - "technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front.png"}, - drawtype = "nodebox", - paramtype = "light", - paramtype2 = "facedir", - node_box = { - type = "fixed", - fixed = { - {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - - }, - }, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - groups = {cracky=2}, - legacy_facedir_simple = true, - technic_power_machine=1, - internal_EU_buffer=0; - internal_EU_buffer_size=5000; - cnc_time = 0; - src_time = 0; -- fixme - - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_string("infotext", "CNC Machine Inactive") - 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", cnc_formspec..cnc_power_formspec) - meta:set_float("cnc_time", 0) - - 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(), "CNC machine cannot be removed because it is not empty"); - return false - end - return true - end, - - on_receive_fields = form_handler, - }) +minetest.register_node( + "technic:cnc", + { + description = "CNC Milling Machine", + tiles = {"technic_cnc_top.png", "technic_cnc_bottom.png", "technic_cnc_side.png", + "technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front.png"}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + + }, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + groups = {cracky=2}, + legacy_facedir_simple = true, + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_string("infotext", "CNC Machine") + meta:set_float("technic_power_machine", 1) + meta:set_string("formspec", cnc_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, + on_receive_fields = form_handler, + }) -- Active state block minetest.register_node("technic:cnc_active", { - description = "CNC Machine", - tiles = {"technic_cnc_top_active.png", "technic_cnc_bottom.png", "technic_cnc_side.png", - "technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front_active.png"}, - paramtype2 = "facedir", - groups = {cracky=2,not_in_creative_inventory=1}, - legacy_facedir_simple = true, - 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(), "CNC machine cannot be removed because it is not empty"); - return false - end - return true - end, - on_receive_fields = form_handler, -}) + description = "CNC Machine", + tiles = {"technic_cnc_top_active.png", "technic_cnc_bottom.png", "technic_cnc_side.png", + "technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front_active.png"}, + paramtype2 = "facedir", + groups = {cracky=2,not_in_creative_inventory=1}, + legacy_facedir_simple = true, + 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(), "CNC machine cannot be removed because it is not empty"); + return false + end + return true + end, + on_receive_fields = form_handler, + }) -- 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 diff --git a/technic/electric_furnace.lua b/technic/electric_furnace.lua index e9d3236..4f2f11c 100644 --- a/technic/electric_furnace.lua +++ b/technic/electric_furnace.lua @@ -1,173 +1,159 @@ -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;Electric Furnace]".. - "label[1,3;Power level]" - -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(), - 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 = "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", "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", - "invsize[8,9;]".. - "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. - (load)..":technic_power_meter_fg.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;Electric Furnace]".. - "label[1,3;Power level]") + -- 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 - - 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") +technic.register_LV_machine ("technic:electric_furnace","RE") +technic.register_LV_machine ("technic:electric_furnace_active","RE") diff --git a/technic/electric_furnace_mv.lua b/technic/electric_furnace_mv.lua index fd90b14..7f205b5 100644 --- a/technic/electric_furnace_mv.lua +++ b/technic/electric_furnace_mv.lua @@ -1,279 +1,304 @@ -minetest.register_craft({ - output = 'technic:mv_electric_furnace', - recipe = { - {'technic:stainless_steel_ingot', 'technic:electric_furnace', 'technic:stainless_steel_ingot'}, - {'pipeworks:tube_000000', 'technic:mv_transformer', 'pipeworks:tube_000000'}, - {'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'}, - } -}) +-- MV Electric Furnace +-- This is a faster version of the stone furnace which runs on EUs +-- In addition to this it can be upgraded with microcontrollers and batteries +-- This new version uses the batteries to lower the power consumption of the machine +-- Also in addition this furnace can be attached to the pipe system from the pipeworks mod. +-- FIXME: kpoppel I'd like to introduce an induction heating element here also +minetest.register_craft( + {output = 'technic:mv_electric_furnace', + recipe = { + {'technic:stainless_steel_ingot', 'technic:electric_furnace', 'technic:stainless_steel_ingot'}, + {'pipeworks:tube_000000', 'technic:mv_transformer', 'pipeworks:tube_000000'}, + {'technic:stainless_steel_ingot', 'technic:mv_cable', 'technic:stainless_steel_ingot'}, + } + }) -mv_electric_furnace_formspec = - "invsize[8,10;]".. - "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,6;8,4;]".. - "label[0,0;MV Electric Furnace]".. - "label[1,2.8;Power level]".. - "list[current_name;upgrade1;1,4;1,1;]".. - "list[current_name;upgrade2;2,4;1,1;]".. - "label[1,5;Upgrade Slots]" +local mv_electric_furnace_formspec = + "invsize[8,10;]".. + "list[current_name;src;3,1;1,1;]".. + "list[current_name;dst;5,1;2,2;]".. + "list[current_player;main;0,6;8,4;]".. + "label[0,0;MV Electric Furnace]".. + "list[current_name;upgrade1;1,4;1,1;]".. + "list[current_name;upgrade2;2,4;1,1;]".. + "label[1,5;Upgrade Slots]" -minetest.register_node("technic:mv_electric_furnace", { - description = "MV Electric furnace", - tiles = {"technic_mv_electric_furnace_top.png", "technic_mv_electric_furnace_bottom.png", "technic_mv_electric_furnace_side_tube.png", - "technic_mv_electric_furnace_side_tube.png", "technic_mv_electric_furnace_side.png", "technic_mv_electric_furnace_front.png"}, - paramtype2 = "facedir", - groups = {cracky=2, tubedevice=1,tubedevice_receiver=1,}, - tube={insert_object=function(pos,node,stack,direction) - local meta=minetest.env:get_meta(pos) - local inv=meta:get_inventory() - return inv:add_item("src",stack) - end, - can_insert=function(pos,node,stack,direction) +minetest.register_node( + "technic:mv_electric_furnace", + {description = "MV Electric furnace", + tiles = {"technic_mv_electric_furnace_top.png", "technic_mv_electric_furnace_bottom.png", "technic_mv_electric_furnace_side_tube.png", + "technic_mv_electric_furnace_side_tube.png", "technic_mv_electric_furnace_side.png", "technic_mv_electric_furnace_front.png"}, + paramtype2 = "facedir", + groups = {cracky=2, tubedevice=1,tubedevice_receiver=1,}, + tube={insert_object=function(pos,node,stack,direction) + local meta=minetest.env:get_meta(pos) + local inv=meta:get_inventory() + return inv:add_item("src",stack) + end, + can_insert=function(pos,node,stack,direction) local meta=minetest.env:get_meta(pos) local inv=meta:get_inventory() return inv:room_for_item("src",stack) - end, - }, - 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_mv_power_machine", 1) - meta:set_string("formspec", mv_electric_furnace_formspec) - meta:set_string("infotext", "Electric furnace") - local inv = meta:get_inventory() - inv:set_size("src", 1) - inv:set_size("dst", 4) - inv:set_size("upgrade1", 1) - inv:set_size("upgrade2", 1) - 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) - meta:set_float("tube_time", 0) - 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 - elseif not inv:is_empty("upgrade1") then - return false - elseif not inv:is_empty("upgrade2") then - return false - end - return true - end, -}) + end, + }, + 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", "MV Electric furnace") + meta:set_float("technic_mv_power_machine", 1) + meta:set_int("tube_time", 0) + meta:set_string("formspec", mv_electric_furnace_formspec) + local inv = meta:get_inventory() + inv:set_size("src", 1) + inv:set_size("dst", 4) + inv:set_size("upgrade1", 1) + inv:set_size("upgrade2", 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") or not inv:is_empty("upgrade1") or not inv:is_empty("upgrade2") 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:mv_electric_furnace_active", { - description = "MV Electric Furnace", - tiles = {"technic_mv_electric_furnace_top.png", "technic_mv_electric_furnace_bottom.png", "technic_mv_electric_furnace_side_tube.png", - "technic_mv_electric_furnace_side_tube.png", "technic_mv_electric_furnace_side.png", "technic_mv_electric_furnace_front_active.png"}, - paramtype2 = "facedir", - light_source = 8, - drop = "technic:mv_electric_furnace", - groups = {cracky=2, tubedevice=1,tubedevice_receiver=1,not_in_creative_inventory=1}, - tube={insert_object=function(pos,node,stack,direction) - local meta=minetest.env:get_meta(pos) - local inv=meta:get_inventory() - return inv:add_item("src",stack) - end, - can_insert=function(pos,node,stack,direction) +minetest.register_node( + "technic:mv_electric_furnace_active", + {description = "MV Electric Furnace", + tiles = {"technic_mv_electric_furnace_top.png", "technic_mv_electric_furnace_bottom.png", "technic_mv_electric_furnace_side_tube.png", + "technic_mv_electric_furnace_side_tube.png", "technic_mv_electric_furnace_side.png", "technic_mv_electric_furnace_front_active.png"}, + paramtype2 = "facedir", + light_source = 8, + drop = "technic:mv_electric_furnace", + groups = {cracky=2, tubedevice=1,tubedevice_receiver=1,not_in_creative_inventory=1}, + tube={insert_object=function(pos,node,stack,direction) + local meta=minetest.env:get_meta(pos) + local inv=meta:get_inventory() + return inv:add_item("src",stack) + end, + can_insert=function(pos,node,stack,direction) local meta=minetest.env:get_meta(pos) local inv=meta:get_inventory() return inv:room_for_item("src",stack) - end, - }, - 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_mv_power_machine", 1) - meta:set_string("formspec", mv_electric_furnace_formspec) - meta:set_string("infotext", "Electric furnace"); - local inv = meta:get_inventory() - inv:set_size("src", 1) - inv:set_size("dst", 4) - inv:set_size("upgrade1", 1) - inv:set_size("upgrade2", 1) - 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 - elseif not inv:is_empty("upgrade1") then - return false - elseif not inv:is_empty("upgrade2") then - return false - end - return true - end, -}) + end, + }, + 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") or not inv:is_empty("upgrade1") or not inv:is_empty("upgrade2") 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, + -- These three makes sure upgrades are not moved in or out while the furnace is active. + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if listname == "src" or listname == "dst" then + return 99 + else + return 0 -- Disallow the move + end + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if listname == "src" or listname == "dst" then + return 99 + else + return 0 -- Disallow the move + end + end, + allow_metadata_inventory_move = function(pos, from_list, to_list, to_list, to_index, count, player) + return 0 + end, + }) -minetest.register_abm({ - nodenames = {"technic:mv_electric_furnace","technic:mv_electric_furnace_active"}, - interval = 1, - chance = 1, - - action = function(pos, node, active_object_count, active_object_count_wider) - - local pos1={} - pos1.x=pos.x - pos1.y=pos.y - pos1.z=pos.z - local x_velocity=0 - local z_velocity=0 - - -- output is on the left side of the furnace - if node.param2==3 then pos1.z=pos1.z-1 z_velocity =-1 end - if node.param2==2 then pos1.x=pos1.x-1 x_velocity =-1 end - if node.param2==1 then pos1.z=pos1.z+1 z_velocity = 1 end - if node.param2==0 then pos1.x=pos1.x+1 x_velocity = 1 end - - local output_tube_connected = false - local meta=minetest.env:get_meta(pos1) - if meta:get_int("tubelike")==1 then output_tube_connected=true end - meta = minetest.env:get_meta(pos) - local inv = meta:get_inventory() - local upg_item1 - local upg_item1_name="" - local upg_item2 - local upg_item2_name="" - local srcstack = inv:get_stack("upgrade1", 1) - if srcstack then upg_item1=srcstack:to_table() end - srcstack = inv:get_stack("upgrade2", 1) - if srcstack then upg_item2=srcstack:to_table() end - if upg_item1 then upg_item1_name=upg_item1.name end - if upg_item2 then upg_item2_name=upg_item2.name end - - local speed=0 - if upg_item1_name=="technic:control_logic_unit" then speed=speed+1 end - if upg_item2_name=="technic:control_logic_unit" then speed=speed+1 end - tube_time=meta:get_float("tube_time") - tube_time=tube_time+speed - if tube_time>3 then - tube_time=0 - if output_tube_connected then send_cooked_items(pos,x_velocity,z_velocity) end - end - meta:set_float("tube_time", tube_time) - - local extra_buffer_size = 0 - if upg_item1_name=="technic:battery" then extra_buffer_size =extra_buffer_size + 10000 end - if upg_item2_name=="technic:battery" then extra_buffer_size =extra_buffer_size + 10000 end - local internal_EU_buffer_size=2000+extra_buffer_size - meta:set_float("internal_EU_buffer_size",internal_EU_buffer_size) - - internal_EU_buffer=meta:get_float("internal_EU_buffer") - if internal_EU_buffer > internal_EU_buffer_size then internal_EU_buffer = internal_EU_buffer_size end - local load = math.floor(internal_EU_buffer/(internal_EU_buffer_size) * 100) - meta:set_string("formspec", - "invsize[8,10;]".. - "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. - (load)..":technic_power_meter_fg.png]".. - "list[current_name;src;3,1;1,1;]".. - "list[current_name;dst;5,1;2,2;]".. - "list[current_player;main;0,6;8,4;]".. - "label[0,0;MV Electric Furnace]".. - "label[1,2.8;Power level]".. - "list[current_name;upgrade1;1,4;1,1;]".. - "list[current_name;upgrade2;2,4;1,1;]".. - "label[1,5;Upgrade Slots]") - - local furnace_is_cookin = meta:get_float("furnace_is_cookin") - - - local srclist = inv:get_list("src") - local cooked=nil - - 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!") +local send_cooked_items = function(pos,x_velocity,z_velocity) + -- Send items on their way in the pipe system. + local meta=minetest.env:get_meta(pos) + local inv = meta:get_inventory() + local i=0 + for _,stack in ipairs(inv:get_list("dst")) do + i=i+1 + if stack then + local item0=stack:to_table() + if item0 then + item0["count"]="1" + local item1=tube_item({x=pos.x,y=pos.y,z=pos.z},item0) + item1:get_luaentity().start_pos = {x=pos.x,y=pos.y,z=pos.z} + item1:setvelocity({x=x_velocity, y=0, z=z_velocity}) + item1:setacceleration({x=0, y=0, z=0}) + stack:take_item(1); + inv:set_stack("dst", i, stack) + return end - meta:set_string("src_time", 0) - end - end + end + end + end + +local smelt_item = function(pos) + local meta=minetest.env:get_meta(pos) + local inv = meta:get_inventory() + meta:set_int("src_time", meta:get_int("src_time") + 3) -- Cooking time 3x faster + 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 + meta:set_int("src_time", 0) + -- check if there's room for output in "dst" list + 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.item) + return 1 + else + return 0 -- done + end + end + return 0 -- done + end + +minetest.register_abm( + {nodenames = {"technic:mv_electric_furnace","technic:mv_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("MV_EU_input") + local state = meta:get_int("state") + local next_state = state + + -- Machine information + local machine_name = "MV Electric Furnace" + local machine_node = "technic:mv_electric_furnace" + local machine_state_demand = { 50, 2000, 1500, 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("MV_EU_demand", machine_state_demand[1]) + meta:set_int("MV_EU_input", 0) + return end - - - - if srclist then - cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) - if cooked.time>0 then - hacky_swap_node(pos,"technic:mv_electric_furnace_active") - meta:set_string("infotext","Furnace active") - meta:set_string("furnace_is_cookin",1) - meta:set_string("src_time", 0) - return - end - + + -- Power off automatically if no longer connected to a switching station + technic.switching_station_timeout_count(pos, "MV") + + -- Execute always logic + -- CODE HERE -- + + -- 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 meta=minetest.env:get_meta(pos) + + -- Get the names of the upgrades + local meta=minetest.env:get_meta(pos) + local inv = meta:get_inventory() + local upg_item1 + local upg_item1_name="" + local upg_item2 + local upg_item2_name="" + local srcstack = inv:get_stack("upgrade1", 1) + if srcstack then upg_item1=srcstack:to_table() end + srcstack = inv:get_stack("upgrade2", 1) + if srcstack then upg_item2=srcstack:to_table() end + if upg_item1 then upg_item1_name=upg_item1.name end + if upg_item2 then upg_item2_name=upg_item2.name end + + -- Save some power by installing battery upgrades. Fully upgraded makes this + -- furnace use the same amount of power as the LV version + local EU_saving_upgrade = 0 + if upg_item1_name=="technic:battery" then EU_saving_upgrade = EU_saving_upgrade + 1 end + if upg_item2_name=="technic:battery" then EU_saving_upgrade = EU_saving_upgrade + 1 end + + -- Tube loading speed can be upgraded using control logic units + local tube_speed_upgrade = 0 + if upg_item1_name=="technic:control_logic_unit" then tube_speed_upgrade = tube_speed_upgrade + 1 end + if upg_item2_name=="technic:control_logic_unit" then tube_speed_upgrade = tube_speed_upgrade + 1 end + + -- Handle pipeworks (consumes tube_speed_upgrade) + local pos1={x=pos.x, y=pos.y, z=pos.z} + local x_velocity=0 + local z_velocity=0 + + -- Output is on the left side of the furnace + if node.param2==3 then pos1.z=pos1.z-1 z_velocity =-1 end + if node.param2==2 then pos1.x=pos1.x-1 x_velocity =-1 end + if node.param2==1 then pos1.z=pos1.z+1 z_velocity = 1 end + if node.param2==0 then pos1.x=pos1.x+1 x_velocity = 1 end + + local output_tube_connected = false + local meta1 = minetest.env:get_meta(pos1) + if meta1:get_int("tubelike") == 1 then + output_tube_connected=true + end + tube_time = meta:get_int("tube_time") + tube_time = tube_time + tube_speed_upgrade + if tube_time > 3 then + tube_time = 0 + if output_tube_connected then + send_cooked_items(pos,x_velocity,z_velocity) + end + end + meta:set_int("tube_time", tube_time) + + -- The machine shuts down if we have nothing to smelt and no tube is connected + -- or if we have nothing to send with a tube connected. + if (not output_tube_connected and inv:is_empty("src")) + or ( output_tube_connected and inv:is_empty("dst")) then + next_state = 1 end - - hacky_swap_node(pos,"technic:mv_electric_furnace") - meta:set_string("infotext","Furnace inactive") - meta:set_string("furnace_is_cookin",0) - meta:set_string("src_time", 0) - -end, -}) - -function send_cooked_items (pos,x_velocity,z_velocity) - local meta=minetest.env:get_meta(pos) - local inv = meta:get_inventory() - local i=0 - for _,stack in ipairs(inv:get_list("dst")) do - i=i+1 - if stack then - local item0=stack:to_table() - if item0 then - item0["count"]="1" - local item1=tube_item({x=pos.x,y=pos.y,z=pos.z},item0) - item1:get_luaentity().start_pos = {x=pos.x,y=pos.y,z=pos.z} - item1:setvelocity({x=x_velocity, y=0, z=z_velocity}) - item1:setacceleration({x=0, y=0, z=0}) - stack:take_item(1); - inv:set_stack("dst", i, stack) - return - end - end + ---------------------- + + if state == 1 then + hacky_swap_node(pos, machine_node) + meta:set_string("infotext", machine_name.." Idle") + + local meta=minetest.env:get_meta(pos) + local inv = meta:get_inventory() + if not inv:is_empty("src") then + local result = minetest.get_craft_result({method = "cooking", width = 1, items = inv:get_list("src")}) + if result then + meta:set_string("infotext", machine_name.." Active") + meta:set_int("src_time", 0) + next_state = 2+EU_saving_upgrade -- Next state is decided by the battery upgrade (state 2= 0 batteries, state 3 = 1 battery, 4 = 2 batteries) + end + else + meta:set_string("infotext", "Electric Furnace Idle") + end + + elseif state == 2 or state == 3 or state == 4 then + hacky_swap_node(pos, machine_node.."_active") + meta:set_string("infotext", machine_name.." Active") + result = smelt_item(pos, data) + if result == 0 then + next_state = 1 + end end -end + end + -- Change state? + if next_state ~= state then + meta:set_int("MV_EU_demand", machine_state_demand[next_state]) + meta:set_int("state", next_state) + end + end, + }) -register_MV_machine ("technic:mv_electric_furnace","RE") -register_MV_machine ("technic:mv_electric_furnace_active","RE") +technic.register_MV_machine ("technic:mv_electric_furnace","RE") +technic.register_MV_machine ("technic:mv_electric_furnace_active","RE") diff --git a/technic/flashlight.lua b/technic/flashlight.lua index f6e4dc2..dd36c31 100644 --- a/technic/flashlight.lua +++ b/technic/flashlight.lua @@ -1,7 +1,7 @@ -- original code comes from walkin_light mod by Echo http://minetest.net/forum/viewtopic.php?id=2621 -flashlight_max_charge=30000 -register_power_tool ("technic:flashlight",flashlight_max_charge) +local flashlight_max_charge=30000 +technic.register_LV_power_tool ("technic:flashlight",flashlight_max_charge) minetest.register_tool("technic:flashlight", { description = "Flashlight", diff --git a/technic/forcefield.lua b/technic/forcefield.lua index dbcae01..8af98f4 100644 --- a/technic/forcefield.lua +++ b/technic/forcefield.lua @@ -66,7 +66,7 @@ local function remove_forcefield(p, range) end end -forcefield_receive_fields = function(pos, formname, fields, sender) +local forcefield_receive_fields = function(pos, formname, fields, sender) local meta = minetest.env:get_meta(pos) local range = meta:get_int("range") if fields.add then range = range + 1 end @@ -88,7 +88,7 @@ forcefield_receive_fields = function(pos, formname, fields, sender) end end -function get_forcefield_formspec(range, load) +local get_forcefield_formspec = function(range, load) if not load then load = 0 end return "invsize[8,9;]".. "label[0,0;Forcefield emitter]".. @@ -103,7 +103,7 @@ function get_forcefield_formspec(range, load) "list[current_player;main;0,5;8,4;]" end -local function forcefield_check(pos) +local forcefield_check = function(pos) local meta = minetest.env:get_meta(pos) local node = minetest.env:get_node(pos) local internal_EU_buffer=meta:get_float("internal_EU_buffer") @@ -145,7 +145,6 @@ minetest.register_node("technic:forcefield_emitter_off", { tiles = {"technic_forcefield_emitter_off.png"}, is_ground_content = true, groups = {cracky = 1}, - technic_power_machine=1, on_timer = forcefield_check, on_receive_fields = forcefield_receive_fields, on_construct = function(pos) @@ -206,9 +205,5 @@ minetest.register_node("technic:forcefield", { }, }) -register_MV_machine ("technic:forcefield_emitter_on","RE") -register_MV_machine ("technic:forcefield_emitter_off","RE") - - - - +technic.register_MV_machine("technic:forcefield_emitter_on","RE") +technic.register_MV_machine("technic:forcefield_emitter_off","RE") diff --git a/technic/generator.lua b/technic/generator.lua index ae899a6..48f3b03 100644 --- a/technic/generator.lua +++ b/technic/generator.lua @@ -1,3 +1,7 @@ +-- Th coal driven EU generator. +-- A simple device to get started on the electric machines. +-- Inefficient and expensive in coal (200EU 16 ticks) +-- Also only allows for LV machinery to run. minetest.register_alias("generator", "technic:generator") minetest.register_alias("generator", "technic:generator_active") @@ -15,7 +19,7 @@ minetest.register_craftitem("technic:generator", { stack_max = 99, }) -generator_formspec = +local generator_formspec = "invsize[8,9;]".. "image[0,0;5,5;technic_generator_menu.png]".. "image[1,1;1,2;technic_power_meter_bg.png]".. @@ -26,124 +30,118 @@ generator_formspec = "list[current_player;main;0,5;8,4;]" -minetest.register_node("technic:generator", { - description = "Coal Driven Generator", - tiles = {"technic_generator_top.png", "technic_machine_bottom.png", "technic_generator_side.png", - "technic_generator_side.png", "technic_generator_side.png", "technic_generator_front.png"}, - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - legacy_facedir_simple = true, - sounds = default.node_sound_wood_defaults(), - technic_power_machine=1, - internal_EU_buffer=0; - internal_EU_buffer_size=5000; - burn_time=0; - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_string("infotext", "Generator") - 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", generator_formspec) - meta:set_float("burn_time", 0) - - local inv = meta:get_inventory() - inv:set_size("src", 1) - +minetest.register_node( + "technic:generator", + { + description = "Coal Driven Generator", + tiles = {"technic_generator_top.png", "technic_machine_bottom.png", "technic_generator_side.png", + "technic_generator_side.png", "technic_generator_side.png", "technic_generator_front.png"}, + paramtype2 = "facedir", + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + legacy_facedir_simple = true, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_string("infotext", "Coal Electric Generator") + meta:set_float("technic_power_machine", 1) + meta:set_int("LV_EU_supply", 0) + meta:set_int("LV_EU_from_fuel", 1) -- Signal to the switching station that this device burns some sort of fuel and needs special handling + meta:set_int("burn_time", 0) + meta:set_string("formspec", generator_formspec) + local inv = meta:get_inventory() + inv:set_size("src", 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") then - return false - end - return true + can_dig = function(pos,player) + local meta = minetest.env:get_meta(pos); + local inv = meta:get_inventory() + if not inv:is_empty("src") 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:generator_active", { - description = "Coal Driven Generator", - tiles = {"technic_generator_top.png", "technic_machine_bottom.png", "technic_generator_side.png", - "technic_generator_side.png", "technic_generator_side.png", "technic_generator_front_active.png"}, - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, - legacy_facedir_simple = true, - sounds = default.node_sound_wood_defaults(), - drop="technic:generator", - technic_power_machine=1, - internal_EU_buffer=0; - internal_EU_buffer_size=0; - burn_time=0; - 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 - return true +minetest.register_node( + "technic:generator_active", + { + description = "Coal Driven Generator", + tiles = {"technic_generator_top.png", "technic_machine_bottom.png", "technic_generator_side.png", + "technic_generator_side.png", "technic_generator_side.png", "technic_generator_front_active.png"}, + paramtype2 = "facedir", + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, + legacy_facedir_simple = true, + sounds = default.node_sound_wood_defaults(), + drop="technic:generator", + can_dig = function(pos,player) + local meta = minetest.env:get_meta(pos); + local inv = meta:get_inventory() + if not inv:is_empty("src") 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:generator","technic:generator_active"}, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) +minetest.register_abm( + { + nodenames = {"technic:generator","technic:generator_active"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.env:get_meta(pos) + local burn_time= meta:get_int("burn_time") - local meta = minetest.env:get_meta(pos) - local burn_time= meta:get_float("burn_time") - local charge= meta:get_float("internal_EU_buffer") - local max_charge= meta:get_float("internal_EU_buffer_size") - local burn_charge=200 + -- If more to burn and the energy produced was used: produce some more + if burn_time>0 then + if meta:get_int("LV_EU_supply") == 0 then + -- We did not use the power + meta:set_int("LV_EU_supply", 200) -- Give 200EUs + else + burn_time = burn_time - 1 + meta:set_int("burn_time",burn_time) + end + end - if burn_time>0 then - if charge+burn_charge>max_charge then - burn_charge=max_charge-charge - end - if burn_charge>0 then - burn_time=burn_time-1 - meta:set_float("burn_time",burn_time) - charge=charge+burn_charge - meta:set_float("internal_EU_buffer",charge) - end - - end - if burn_time==0 then - local inv = meta:get_inventory() - if inv:is_empty("src")==false then - local srcstack = inv:get_stack("src", 1) - src_item=srcstack:to_table() - if src_item["name"]== "default:coal_lump" then - srcstack:take_item() - inv:set_stack("src", 1, srcstack) - burn_time=16 - meta:set_float("burn_time",burn_time) - hacky_swap_node (pos,"technic:generator_active") - end - end - end + -- Burn another piece of coal + if burn_time==0 then + local inv = meta:get_inventory() + if inv:is_empty("src") == false then + local srcstack = inv:get_stack("src", 1) + src_item=srcstack:to_table() + if src_item["name"] == "default:coal_lump" then + srcstack:take_item() + inv:set_stack("src", 1, srcstack) + burn_time=16 + meta:set_int("burn_time",burn_time) + hacky_swap_node (pos,"technic:generator_active") + meta:set_int("LV_EU_supply", 200) -- Give 200EUs + end + end + end - local load = math.floor((charge/max_charge)*100) - local percent = math.floor((burn_time/16)*100) - meta:set_string("formspec", - "invsize[8,9;]".. - "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. - (load)..":technic_power_meter_fg.png]".. - "label[0,0;Generator]".. - "label[1,3;Power level]".. - "list[current_name;src;3,1;1,1;]".. - "image[4,1;1,1;default_furnace_fire_bg.png^[lowpart:".. - (percent)..":default_furnace_fire_fg.png]".. - "list[current_player;main;0,5;8,4;]" - ) + local load = 8 -- math.floor((charge/max_charge)*100) + local percent = math.floor((burn_time/16)*100) + meta:set_string("formspec", + "invsize[8,9;]".. + "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. + (load)..":technic_power_meter_fg.png]".. + "label[0,0;Generator]".. + "label[1,3;Power level]".. + "list[current_name;src;3,1;1,1;]".. + "image[4,1;1,1;default_furnace_fire_bg.png^[lowpart:".. + (percent)..":default_furnace_fire_fg.png]".. + "list[current_player;main;0,5;8,4;]" + ) - if burn_time==0 then - hacky_swap_node (pos,"technic:generator") - end + if burn_time==0 then + hacky_swap_node (pos,"technic:generator") + end + end + }) - end -}) - -register_LV_machine ("technic:generator","PR") -register_LV_machine ("technic:generator_active","PR") +technic.register_LV_machine ("technic:generator","PR") +technic.register_LV_machine ("technic:generator_active","PR") diff --git a/technic/geothermal.lua b/technic/geothermal.lua index dccabf4..5ba7a23 100644 --- a/technic/geothermal.lua +++ b/technic/geothermal.lua @@ -1,3 +1,7 @@ +-- A geothermal EU generator +-- Using hot lava and water this device can create energy from steam +-- The machine is only producing LV EUs and can thus not drive more advanced equipment +-- The output is a little more than the coal burning generator (max 300EUs) minetest.register_alias("geothermal", "technic:geothermal") minetest.register_craft({ @@ -14,7 +18,7 @@ minetest.register_craftitem("technic:geothermal", { stack_max = 99, }) -geothermal_formspec = +local geothermal_formspec = "invsize[8,4;]".. "image[1,1;1,2;technic_power_meter_bg.png]".. "label[0,0;Geothermal Generator]".. @@ -22,117 +26,131 @@ geothermal_formspec = "list[current_player;main;0,5;8,4;]" -minetest.register_node("technic:geothermal", { - description = "Geothermal Generator", - tiles = {"technic_geothermal_top.png", "technic_machine_bottom.png", "technic_geothermal_side.png", - "technic_geothermal_side.png", "technic_geothermal_side.png", "technic_geothermal_side.png"}, - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - legacy_facedir_simple = true, - sounds = default.node_sound_wood_defaults(), - technic_power_machine=1, - internal_EU_buffer=0; - internal_EU_buffer_size=5000; - burn_time=0; - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_string("infotext", "Geothermal Generator") - meta:set_float("technic_power_machine", 1) - meta:set_float("internal_EU_buffer", 0) - meta:set_float("internal_EU_buffer_size", 2000) - meta:set_string("formspec", geothermal_formspec) - end, +minetest.register_node( + "technic:geothermal", + { + description = "Geothermal Generator", + tiles = {"technic_geothermal_top.png", "technic_machine_bottom.png", "technic_geothermal_side.png", + "technic_geothermal_side.png", "technic_geothermal_side.png", "technic_geothermal_side.png"}, + paramtype2 = "facedir", + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + 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", "Geothermal Generator") + meta:set_float("technic_power_machine", 1) + meta:set_int("LV_EU_supply", 0) + meta:set_string("formspec", geothermal_formspec) + end, + }) -}) +minetest.register_node( + "technic:geothermal_active", + { + description = "Geothermal Generator", + tiles = {"technic_geothermal_top_active.png", "technic_machine_bottom.png", "technic_geothermal_side.png", + "technic_geothermal_side.png", "technic_geothermal_side.png", "technic_geothermal_side.png"}, + paramtype2 = "facedir", + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, + legacy_facedir_simple = true, + sounds = default.node_sound_wood_defaults(), + drop="technic:geothermal", + }) -minetest.register_node("technic:geothermal_active", { - description = "Geothermal Generator", - tiles = {"technic_geothermal_top_active.png", "technic_machine_bottom.png", "technic_geothermal_side.png", - "technic_geothermal_side.png", "technic_geothermal_side.png", "technic_geothermal_side.png"}, - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, - legacy_facedir_simple = true, - sounds = default.node_sound_wood_defaults(), - drop="technic:geothermal", - technic_power_machine=1, - internal_EU_buffer=0; - internal_EU_buffer_size=0; -}) +local check_node_around = function(pos) + local node=minetest.env:get_node(pos) + if node.name=="default:water_source" or node.name=="default:water_flowing" then return 1 end + if node.name=="default:lava_source" or node.name=="default:lava_flowing" then return 2 end + return 0 + end -minetest.register_abm({ - nodenames = {"technic:geothermal","technic:geothermal_active"}, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) +minetest.register_abm( + { + nodenames = {"technic:geothermal","technic:geothermal_active"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.env:get_meta(pos) + local water_nodes = 0 + local lava_nodes = 0 + local production_level = 0 + local eu_supply = 0 - 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 water_nodes = 0 - local lava_nodes = 0 - local production_level=0 - local load_step=0 + -- Correct positioning is water on one side and lava on the other. + -- The two cannot be adjacent because the lava the turns into obsidian or rock. + -- To get to 100% production stack the water and lava one extra block down as well: + -- WGL (W=Water, L=Lava, G=the generator, |=an LV cable) + -- W|L + pos.x=pos.x+1 + local check=check_node_around(pos) + if check==1 then water_nodes=water_nodes+1 end + if check==2 then lava_nodes=lava_nodes+1 end + pos.y=pos.y-1 + local check=check_node_around(pos) + if check==1 then water_nodes=water_nodes+1 end + if check==2 then lava_nodes=lava_nodes+1 end - pos.x=pos.x+1 - local check=check_node_around (pos) - if check==1 then water_nodes=water_nodes+1 end - if check==2 then lava_nodes=lava_nodes+1 end - pos.x=pos.x-2 - check=check_node_around (pos) - if check==1 then water_nodes=water_nodes+1 end - if check==2 then lava_nodes=lava_nodes+1 end - pos.x=pos.x+1 - pos.z=pos.z+1 - check=check_node_around (pos) - if check==1 then water_nodes=water_nodes+1 end - if check==2 then lava_nodes=lava_nodes+1 end - pos.z=pos.z-2 - check=check_node_around (pos) - if check==1 then water_nodes=water_nodes+1 end - if check==2 then lava_nodes=lava_nodes+1 end - pos.z=pos.z+1 + pos.x=pos.x-2 + check=check_node_around(pos) + if check==1 then water_nodes=water_nodes+1 end + if check==2 then lava_nodes=lava_nodes+1 end + pos.y=pos.y+1 + check=check_node_around(pos) + if check==1 then water_nodes=water_nodes+1 end + if check==2 then lava_nodes=lava_nodes+1 end + + pos.x=pos.x+1 + pos.z=pos.z+1 + check=check_node_around(pos) + if check==1 then water_nodes=water_nodes+1 end + if check==2 then lava_nodes=lava_nodes+1 end + pos.y=pos.y-1 + check=check_node_around(pos) + if check==1 then water_nodes=water_nodes+1 end + if check==2 then lava_nodes=lava_nodes+1 end + + pos.z=pos.z-2 + check=check_node_around(pos) + if check==1 then water_nodes=water_nodes+1 end + if check==2 then lava_nodes=lava_nodes+1 end + pos.y=pos.y+1 + check=check_node_around(pos) + if check==1 then water_nodes=water_nodes+1 end + if check==2 then lava_nodes=lava_nodes+1 end + + -- Back to (0,0,0) + pos.z=pos.z+1 - if water_nodes==1 and lava_nodes==1 then production_level=50 load_step=30 end - if water_nodes==2 and lava_nodes==1 then production_level=75 load_step=45 end - if water_nodes==1 and lava_nodes==2 then production_level=75 load_step=45 end - if water_nodes==2 and lava_nodes==2 then production_level=100 load_step=60 end - if water_nodes==3 and lava_nodes==1 then production_level=25 load_step=15 end - if water_nodes==1 and lava_nodes==3 then production_level=25 load_step=15 end + if water_nodes==1 and lava_nodes==1 then production_level = 25; eu_supply = 50 end + if water_nodes==2 and lava_nodes==1 then production_level = 50; eu_supply = 100 end + if water_nodes==1 and lava_nodes==2 then production_level = 75; eu_supply = 200 end + if water_nodes==2 and lava_nodes==2 then production_level = 100; eu_supply = 300 end - if production_level>0 then - if charge+load_step>max_charge then - load_step=max_charge-charge - end - if load_step>0 then - charge=charge+load_step - meta:set_float("internal_EU_buffer",charge) - end - end + if production_level>0 then + meta:set_int("LV_EU_supply", eu_supply) + end - local load = math.floor((charge/max_charge)*100) - meta:set_string("formspec", - "invsize[8,4;]".. - "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. - (load)..":technic_power_meter_fg.png]".. - "label[0,0;Geothermal Generator]".. - "label[1,3;Power level]".. - "label[4,0;Production at "..tostring(production_level).."%]" - ) + local load = 1 -- math.floor((charge/max_charge)*100) + meta:set_string("formspec", + "invsize[8,4;]".. + "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. + (load)..":technic_power_meter_fg.png]".. + "label[0,0;Geothermal Generator]".. + "label[1,3;Power level]".. + "label[4,0;Production at "..tostring(production_level).."%]" + ) - if production_level>0 and minetest.env:get_node(pos).name=="technic:geothermal" then - hacky_swap_node (pos,"technic:geothermal_active") - return - end - if production_level==0 then hacky_swap_node (pos,"technic:geothermal") end -end -}) + if production_level>0 and minetest.env:get_node(pos).name=="technic:geothermal" then + hacky_swap_node (pos,"technic:geothermal_active") + return + end + if production_level==0 then + hacky_swap_node (pos,"technic:geothermal") + meta:set_int("LV_EU_supply", 0) + end + end + }) -function check_node_around (pos) -local node=minetest.env:get_node(pos) -if node.name=="default:water_source" or node.name=="default:water_flowing" then return 1 end -if node.name=="default:lava_source" or node.name=="default:lava_flowing" then return 2 end -return 0 -end - -register_LV_machine ("technic:geothermal","PR") -register_LV_machine ("technic:geothermal_active","PR") +technic.register_LV_machine ("technic:geothermal","PR") +technic.register_LV_machine ("technic:geothermal_active","PR") diff --git a/technic/grinder.lua b/technic/grinder.lua index 07baa05..8b41184 100644 --- a/technic/grinder.lua +++ b/technic/grinder.lua @@ -1,352 +1,360 @@ -grinder_recipes ={} +technic.grinder_recipes ={} -registered_grinder_recipes_count=1 +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 -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 +-- 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 -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("home_decor:brass_ingot","technic:brass_dust 1") -- needs check for the mod -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("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.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") +technic.register_grinder_recipe("technic:coal_dust","dye:black 2") +technic.register_grinder_recipe("default:cactus","dye:green 2") +technic.register_grinder_recipe("default:dry_shrub","dye:brown 2") +technic.register_grinder_recipe("flowers:flower_geranium","dye:blue 2") +technic.register_grinder_recipe("flowers:flower_dandelion_white","dye:white 2") +technic.register_grinder_recipe("flowers:flower_dandelion_yellow","dye:yellow 2") +technic.register_grinder_recipe("flowers:flower_tulip","dye:orange 2") +technic.register_grinder_recipe("flowers:flower_rose","dye:red 2") +technic.register_grinder_recipe("flowers:flower_viola","dye:violet 2") 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 = "moreores: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 = "moreores:gold_ingot", - recipe = "technic:gold_dust", -}) + type = "cooking", + output = "moreores: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 = "moreores:bronze_ingot", - recipe = "technic:bronze_dust", -}) + type = "cooking", + output = "moreores: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', 'moreores: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, -}) + description = "Grinder", + stack_max = 99, + }) -grinder_formspec = - "invsize[8,9;]".. - "image[1,1;1,2;technic_power_meter_bg.png]".. - "label[0,0;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;]" +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(), - 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) +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) + -- 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 -minetest.register_abm({ - nodenames = {"technic:grinder","technic:grinder_active"}, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) + -- 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") - 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 + if state == 1 then + hacky_swap_node(pos, machine_node) + meta:set_string("infotext", machine_name.." Idle") - local load = math.floor((charge/max_charge)*100) - meta:set_string("formspec", - "invsize[8,9;]".. - "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. - (load)..":technic_power_meter_fg.png]".. - "label[0,0;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;]" - ) + 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 - local inv = meta:get_inventory() - local srclist = inv:get_list("src") - if inv:is_empty("src") then meta:set_float("grinder_on",0) end + elseif state == 2 then + hacky_swap_node(pos, machine_node.."_active") + meta:set_string("infotext", machine_name.." Active") - 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 -}) + 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)) -function get_grinded_item (items) -new_item =nil -src_item=items:to_table() -item_name=src_item["name"] + 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 + }) -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") +technic.register_LV_machine ("technic:grinder","RE") +technic.register_LV_machine ("technic:grinder_active","RE") diff --git a/technic/grinder_gloopores.lua b/technic/grinder_gloopores.lua index 0c58c98..6f603b3 100644 --- a/technic/grinder_gloopores.lua +++ b/technic/grinder_gloopores.lua @@ -1,8 +1,8 @@ -register_grinder_recipe("gloopores:alatro_lump","technic:alatro_dust 2") -register_grinder_recipe("gloopores:kalite_lump","technic:kalite_dust 2") -register_grinder_recipe("gloopores:arol_lump","technic:arol_dust 2") -register_grinder_recipe("gloopores:talinite_lump","technic:talinite_dust 2") -register_grinder_recipe("gloopores:akalin_lump","technic:akalin_dust 2") +technic.register_grinder_recipe("gloopores:alatro_lump","technic:alatro_dust 2") +technic.register_grinder_recipe("gloopores:kalite_lump","technic:kalite_dust 2") +technic.register_grinder_recipe("gloopores:arol_lump","technic:arol_dust 2") +technic.register_grinder_recipe("gloopores:talinite_lump","technic:talinite_dust 2") +technic.register_grinder_recipe("gloopores:akalin_lump","technic:akalin_dust 2")   minetest.register_craftitem("technic:alatro_dust", {         description = "Alatro Dust", diff --git a/technic/init.lua b/technic/init.lua index 6dd7eac..abe0439 100644 --- a/technic/init.lua +++ b/technic/init.lua @@ -4,7 +4,13 @@ technic = {} -modpath=minetest.get_modpath("technic") +technic.dprint = function(string) + if technic.DBG == 1 then + print(string) + end + end + +local modpath=minetest.get_modpath("technic") --Read technic config file dofile(modpath.."/config.lua") @@ -14,19 +20,26 @@ dofile(modpath.."/helpers.lua") --items dofile(modpath.."/items.lua") +-- Register functions +dofile(modpath.."/register_machine_and_tool.lua") +dofile(modpath.."/alloy_furnaces_commons.lua") -- Idea: Let the LV, MV, HV version of the furnace support different alloys + +-- Switching station LV,MV,HV +dofile(modpath.."/switching_station.lua") +dofile(modpath.."/supply_converter.lua") + --LV machines dofile(modpath.."/wires.lua") dofile(modpath.."/battery_box.lua") -dofile(modpath.."/alloy_furnaces_commons.lua") dofile(modpath.."/alloy_furnace.lua") dofile(modpath.."/solar_panel.lua") dofile(modpath.."/solar_array_lv.lua") dofile(modpath.."/geothermal.lua") dofile(modpath.."/water_mill.lua") +dofile(modpath.."/generator.lua") dofile(modpath.."/electric_furnace.lua") dofile(modpath.."/tool_workshop.lua") dofile(modpath.."/music_player.lua") -dofile(modpath.."/generator.lua") dofile(modpath.."/grinder.lua") dofile(modpath.."/cnc.lua") dofile(modpath.."/cnc_api.lua") @@ -36,20 +49,18 @@ dofile(modpath.."/cnc_nodes.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.."/electric_furnace_mv.lua") dofile(modpath.."/alloy_furnace_mv.lua") -dofile(modpath.."/forcefield.lua") --- These two are a concept study: Supplying appliances with inductive coupled power: --- lighting and associated textures is taken directly from VanessaE's homedecor and made electric. +--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 +-- +----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 @@ -59,8 +70,8 @@ dofile(modpath.."/cans.lua") dofile(modpath.."/chainsaw.lua") dofile(modpath.."/tree_tap.lua") dofile(modpath.."/sonic_screwdriver.lua") - --- mesecons and tubes related +-- +---- mesecons and tubes related dofile(modpath.."/injector.lua") dofile(modpath.."/node_breaker.lua") dofile(modpath.."/deployer.lua") @@ -68,24 +79,23 @@ dofile(modpath.."/constructor.lua") dofile(modpath.."/frames.lua") function has_locked_chest_privilege(meta, player) - if player:get_player_name() ~= meta:get_string("owner") then - return false - end - return true + if player:get_player_name() ~= meta:get_string("owner") then + return false + end + return true end +-- Swap nodes out. Return the node name. function hacky_swap_node(pos,name) - local node = minetest.env:get_node(pos) - local meta = minetest.env:get_meta(pos) - local meta0 = meta:to_table() - if node.name == name then - return nil - end - node.name = name - local meta0 = meta:to_table() - minetest.env:set_node(pos,node) - meta = minetest.env:get_meta(pos) - meta:from_table(meta0) - return 1 + local node = minetest.env:get_node(pos) + if node.name ~= name then + local meta = minetest.env:get_meta(pos) + local meta0 = meta:to_table() + node.name = name + minetest.env:set_node(pos,node) + meta = minetest.env:get_meta(pos) + meta:from_table(meta0) + end + return node.name end diff --git a/technic/lighting.lua b/technic/lighting.lua index 5aab4c3..1d4b45f 100644 --- a/technic/lighting.lua +++ b/technic/lighting.lua @@ -48,7 +48,7 @@ end local dirs1 = { 20, 23, 22, 21 } local dirs2 = { 9, 18, 7, 12 } -function technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) +local technic_homedecor_rotate_and_place = function(itemstack, placer, pointed_thing) if not technic_homedecor_node_is_owned(pointed_thing.under, placer) and not technic_homedecor_node_is_owned(pointed_thing.above, placer) then local node = minetest.env:get_node(pointed_thing.under) @@ -128,14 +128,10 @@ minetest.register_node('technic:homedecor_glowlight_half_yellow', { return itemstack end, on_construct = function(pos) - print("Hello") - technic_inductive_on_construct(pos, 100, "Yellow Glowlight (thick)") - print("Hello2") + technic.inductive_on_construct(pos, 100, "Yellow Glowlight (thick)") end, on_punch = function(pos, node, puncher) - print("Punch") - technic_inductive_on_punch_off(pos, 100, "technic:homedecor_glowlight_half_yellow_active") - print("Punch2") + technic.inductive_on_punch_off(pos, 100, "technic:homedecor_glowlight_half_yellow_active") end }) @@ -173,10 +169,10 @@ minetest.register_node('technic:homedecor_glowlight_half_yellow_active', { return itemstack end, on_construct = function(pos) - technic_inductive_on_construct(pos, 100, "Yellow Glowlight (thick)") + technic.inductive_on_construct(pos, 100, "Yellow Glowlight (thick)") end, on_punch = function(pos, node, puncher) - technic_inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_half_yellow") + technic.inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_half_yellow") end }) @@ -213,10 +209,10 @@ minetest.register_node('technic:homedecor_glowlight_quarter_yellow', { return itemstack end, on_construct = function(pos) - technic_inductive_on_construct(pos, 100, "Yellow Glowlight (thin)") + technic.inductive_on_construct(pos, 100, "Yellow Glowlight (thin)") end, on_punch = function(pos, node, puncher) - technic_inductive_on_punch_off(pos, 100, "technic:homedecor_glowlight_quarter_yellow_active") + technic.inductive_on_punch_off(pos, 100, "technic:homedecor_glowlight_quarter_yellow_active") end }) @@ -254,10 +250,10 @@ minetest.register_node('technic:homedecor_glowlight_quarter_yellow_active', { return itemstack end, on_construct = function(pos) - technic_inductive_on_construct(pos, 100, "Yellow Glowlight (thin)") + technic.inductive_on_construct(pos, 100, "Yellow Glowlight (thin)") end, on_punch = function(pos, node, puncher) - technic_inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_quarter_yellow") + technic.inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_quarter_yellow") end }) @@ -295,10 +291,10 @@ minetest.register_node('technic:homedecor_glowlight_half_white', { return itemstack end, on_construct = function(pos) - technic_inductive_on_construct(pos, 100, "White Glowlight (thick)") + technic.inductive_on_construct(pos, 100, "White Glowlight (thick)") end, on_punch = function(pos, node, puncher) - technic_inductive_on_punch_off(pos, 100, "technic:homedecor_glowlight_half_white_active") + technic.inductive_on_punch_off(pos, 100, "technic:homedecor_glowlight_half_white_active") end }) @@ -336,10 +332,10 @@ minetest.register_node('technic:homedecor_glowlight_half_white_active', { return itemstack end, on_construct = function(pos) - technic_inductive_on_construct(pos, 100, "White Glowlight (thick)") + technic.inductive_on_construct(pos, 100, "White Glowlight (thick)") end, on_punch = function(pos, node, puncher) - technic_inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_half_white") + technic.inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_half_white") end }) @@ -376,10 +372,10 @@ minetest.register_node('technic:homedecor_glowlight_quarter_white', { return itemstack end, on_construct = function(pos) - technic_inductive_on_construct(pos, 100, "White Glowlight (thin)") + technic.inductive_on_construct(pos, 100, "White Glowlight (thin)") end, on_punch = function(pos, node, puncher) - technic_inductive_on_punch_off(pos, 100, "technic:homedecor_glowlight_quarter_white_active") + technic.inductive_on_punch_off(pos, 100, "technic:homedecor_glowlight_quarter_white_active") end }) @@ -417,10 +413,10 @@ minetest.register_node('technic:homedecor_glowlight_quarter_white_active', { return itemstack end, on_construct = function(pos) - technic_inductive_on_construct(pos, 100, "White Glowlight (thin)") + technic.inductive_on_construct(pos, 100, "White Glowlight (thin)") end, on_punch = function(pos, node, puncher) - technic_inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_quarter_white") + technic.inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_quarter_white") end }) @@ -457,10 +453,10 @@ minetest.register_node('technic:homedecor_glowlight_small_cube_yellow', { return itemstack end, on_construct = function(pos) - technic_inductive_on_construct(pos, 50, "Yellow Glowlight (small cube)") + technic.inductive_on_construct(pos, 50, "Yellow Glowlight (small cube)") end, on_punch = function(pos, node, puncher) - technic_inductive_on_punch_off(pos, 50, "technic:homedecor_glowlight_small_cube_yellow_active") + technic.inductive_on_punch_off(pos, 50, "technic:homedecor_glowlight_small_cube_yellow_active") end }) @@ -498,10 +494,10 @@ minetest.register_node('technic:homedecor_glowlight_small_cube_yellow_active', { return itemstack end, on_construct = function(pos) - technic_inductive_on_construct(pos, 50, "Yellow Glowlight (small cube)") + technic.inductive_on_construct(pos, 50, "Yellow Glowlight (small cube)") end, on_punch = function(pos, node, puncher) - technic_inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_small_cube_yellow") + technic.inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_small_cube_yellow") end }) @@ -538,10 +534,10 @@ minetest.register_node('technic:homedecor_glowlight_small_cube_white', { return itemstack end, on_construct = function(pos) - technic_inductive_on_construct(pos, 50, "White Glowlight (small cube)") + technic.inductive_on_construct(pos, 50, "White Glowlight (small cube)") end, on_punch = function(pos, node, puncher) - technic_inductive_on_punch_off(pos, 50, "technic:homedecor_glowlight_small_cube_white_active") + technic.inductive_on_punch_off(pos, 50, "technic:homedecor_glowlight_small_cube_white_active") end }) @@ -579,16 +575,16 @@ minetest.register_node('technic:homedecor_glowlight_small_cube_white_active', { return itemstack end, on_construct = function(pos) - technic_inductive_on_construct(pos, 50, "White Glowlight (small cube)") + technic.inductive_on_construct(pos, 50, "White Glowlight (small cube)") end, on_punch = function(pos, node, puncher) - technic_inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_small_cube_white") + technic.inductive_on_punch_on(pos, 0, "technic:homedecor_glowlight_small_cube_white") end }) -register_inductive_machine("technic:homedecor_glowlight_half_yellow") -register_inductive_machine("technic:homedecor_glowlight_half_white") -register_inductive_machine("technic:homedecor_glowlight_quarter_yellow") -register_inductive_machine("technic:homedecor_glowlight_quarter_white") -register_inductive_machine("technic:homedecor_glowlight_small_cube_yellow") -register_inductive_machine("technic:homedecor_glowlight_small_cube_white") +technic.register_inductive_machine("technic:homedecor_glowlight_half_yellow") +technic.register_inductive_machine("technic:homedecor_glowlight_half_white") +technic.register_inductive_machine("technic:homedecor_glowlight_quarter_yellow") +technic.register_inductive_machine("technic:homedecor_glowlight_quarter_white") +technic.register_inductive_machine("technic:homedecor_glowlight_small_cube_yellow") +technic.register_inductive_machine("technic:homedecor_glowlight_small_cube_white") diff --git a/technic/mining_drill.lua b/technic/mining_drill.lua index 33a8e5a..4a50f2f 100644 --- a/technic/mining_drill.lua +++ b/technic/mining_drill.lua @@ -1,9 +1,9 @@ -mining_drill_max_charge=60000 -mining_drill_mk2_max_charge=240000 -mining_drill_mk3_max_charge=960000 -mining_drill_power_usage=200 -mining_drill_mk2_power_usage=600 -mining_drill_mk3_power_usage=1800 +local mining_drill_max_charge=60000 +local mining_drill_mk2_max_charge=240000 +local mining_drill_mk3_max_charge=960000 +local mining_drill_power_usage=200 +local mining_drill_mk2_power_usage=600 +local mining_drill_mk3_power_usage=1800 minetest.register_craft({ output = 'technic:mining_drill', @@ -210,7 +210,7 @@ function drill_dig_it4 (pos,player) drill_dig_it0 (pos,player) end -register_power_tool ("technic:mining_drill",mining_drill_max_charge) +technic.register_MV_power_tool ("technic:mining_drill",mining_drill_max_charge) minetest.register_tool("technic:mining_drill", { description = "Mining Drill Mk1", inventory_image = "technic_mining_drill.png", @@ -227,7 +227,7 @@ minetest.register_tool("technic:mining_drill", { charge =charge-mining_drill_power_usage; meta["charge"]=charge item["metadata"]=set_item_meta(meta) - set_RE_wear(item,charge,mining_drill_max_charge) + technic.set_RE_wear(item,charge,mining_drill_max_charge) itemstack:replace(item) end return itemstack @@ -243,10 +243,10 @@ minetest.register_tool("technic:mining_drill_mk2", { return itemstack end, }) -register_power_tool ("technic:mining_drill_mk2",mining_drill_mk2_max_charge) +technic.register_HV_power_tool ("technic:mining_drill_mk2",mining_drill_mk2_max_charge) for i=1,4,1 do -register_power_tool ("technic:mining_drill_mk2_"..i,mining_drill_mk2_max_charge) +technic.register_HV_power_tool ("technic:mining_drill_mk2_"..i,mining_drill_mk2_max_charge) minetest.register_tool("technic:mining_drill_mk2_"..i, { description = "Mining Drill Mk2 in Mode "..i, inventory_image = "technic_mining_drill_mk2.png^technic_tool_mode"..i..".png", @@ -267,10 +267,10 @@ minetest.register_tool("technic:mining_drill_mk3", { return itemstack end, }) -register_power_tool ("technic:mining_drill_mk3",mining_drill_mk3_max_charge) +technic.register_HV_power_tool ("technic:mining_drill_mk3",mining_drill_mk3_max_charge) for i=1,5,1 do -register_power_tool ("technic:mining_drill_mk3_"..i,mining_drill_mk3_max_charge) +technic.register_HV_power_tool ("technic:mining_drill_mk3_"..i,mining_drill_mk3_max_charge) minetest.register_tool("technic:mining_drill_mk3_"..i, { description = "Mining Drill Mk3 in Mode "..i, inventory_image = "technic_mining_drill_mk3.png^technic_tool_mode"..i..".png", @@ -299,7 +299,7 @@ function mining_drill_mk2_handler (itemstack,user,pointed_thing) if charge<0 then charge=0 end meta["charge"]=charge item["metadata"]=set_item_meta(meta) - set_RE_wear(item,charge,mining_drill_mk2_max_charge) + technic.set_RE_wear(item,charge,mining_drill_mk2_max_charge) itemstack:replace(item) end return itemstack @@ -321,7 +321,7 @@ function mining_drill_mk3_handler (itemstack,user,pointed_thing) if charge<0 then charge=0 end meta["charge"]=charge item["metadata"]=set_item_meta(meta) - set_RE_wear(item,charge,mining_drill_mk3_max_charge) + technic.set_RE_wear(item,charge,mining_drill_mk3_max_charge) itemstack:replace(item) end return itemstack diff --git a/technic/mining_laser_mk1.lua b/technic/mining_laser_mk1.lua index 5bafb6c..4dc76f8 100644 --- a/technic/mining_laser_mk1.lua +++ b/technic/mining_laser_mk1.lua @@ -1,5 +1,5 @@ -laser_mk1_max_charge=40000 -register_power_tool ("technic:laser_mk1",laser_mk1_max_charge) +local laser_mk1_max_charge=40000 +technic.register_LV_power_tool ("technic:laser_mk1",laser_mk1_max_charge) local laser_shoot = function(itemstack, player, pointed_thing) local laser_straight_mode=0 @@ -62,8 +62,8 @@ minetest.register_tool("technic:laser_mk1", { charge=meta["charge"] if charge-400>0 then laser_shoot(item, user, pointed_thing) - charge =charge-400; - set_RE_wear(item,charge,laser_mk1_max_charge) + charge = charge-400; + technic.set_RE_wear(item,charge,laser_mk1_max_charge) meta["charge"]=charge item["metadata"]=set_item_meta(meta) itemstack:replace(item) diff --git a/technic/music_player.lua b/technic/music_player.lua index 81b9a65..e0520ff 100644 --- a/technic/music_player.lua +++ b/technic/music_player.lua @@ -1,3 +1,5 @@ +-- LV Music player. +-- The playe can play music. But it is high ampage! minetest.register_alias("music_player", "technic:music_player") minetest.register_craft({ output = 'technic:music_player', @@ -11,112 +13,144 @@ minetest.register_craft({ minetest.register_craftitem("technic:music_player", { description = "Music Player", stack_max = 99, -}) - -music_player_formspec = - "invsize[8,9;]".. - "image[1,1;1,2;technic_power_meter_bg.png]".. - "label[0,0;Music Player]".. - "label[1,3;Power level]".. - "button[5,2;1,1;track1;1]".. - "button[6,2;1,1;track2;2]" - - -minetest.register_node("technic:music_player", { - description = "Music Player", - tiles = {"technic_music_player_top.png", "technic_machine_bottom.png", "technic_music_player_side.png", - "technic_music_player_side.png", "technic_music_player_side.png", "technic_music_player_side.png"}, - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - sounds = default.node_sound_wood_defaults(), - technic_power_machine=1, - internal_EU_buffer=0, - internal_EU_buffer_size=5000, - music_player_on=0, - music_playing =0, - music_handle = 0, - music_player_current_track =1, - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_string("infotext", "Music Player") - meta:set_float("technic_power_machine", 1) - meta:set_float("internal_EU_buffer", 1) - meta:set_float("internal_EU_buffer_size", 5000) - meta:set_string("formspec", music_player_formspec) - meta:set_float("music_player_on", 0) - meta:set_float("music_player_current_track", 1) - end, - - on_receive_fields = function(pos, formanme, fields, sender) - - local meta = minetest.env:get_meta(pos) - player_on=meta:get_float("music_player_on") - music_handle=meta:get_float("music_handle") - music_player_current_track=meta:get_float("music_player_current_track") - if fields.track1 then music_player_current_track=1 end - if fields.track2 then music_player_current_track=2 end - if fields.track3 then music_player_current_track=3 end - if fields.track4 then music_player_current_track=4 end - if fields.track5 then music_player_current_track=5 end - if fields.track6 then music_player_current_track=6 end - if fields.track7 then music_player_current_track=7 end - if fields.track8 then music_player_current_track=8 end - if fields.track9 then music_player_current_track=9 end - meta:set_float("music_player_current_track",music_player_current_track) - if fields.play and player_on==1 then - if music_handle then minetest.sound_stop(music_handle) end - music_handle=minetest.sound_play("technic_track"..music_player_current_track, {pos = pos, gain = 1.0,loop = true, max_hear_distance = 72,}) - meta:set_float("music_playing",1) - end - if fields.stop then - meta:set_float("music_playing",0) - if music_handle then minetest.sound_stop(music_handle) end - end - meta:set_float("music_handle",music_handle) - end, }) -minetest.register_abm({ - nodenames = {"technic:music_player"}, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - local meta = minetest.env:get_meta(pos) - local charge= meta:get_float("internal_EU_buffer") - local max_charge= meta:get_float("internal_EU_buffer_size") - player_on=meta:get_float("music_player_on") - music_player_current_track=meta:get_float("music_player_current_track") - local play_cost=80 - - if charge>play_cost then - if meta:get_float("music_playing")==1 then charge=charge-play_cost end - meta:set_float("internal_EU_buffer",charge) - meta:set_float("music_player_on",1) - else - meta:set_float("music_playing",0) - meta:set_float("music_player_on",0) - if music_handle then minetest.sound_stop(music_handle) end - end - local load = math.floor((charge/max_charge)*100) - meta:set_string("formspec", - "invsize[8,9;]".. - "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. - (load)..":technic_power_meter_fg.png]".. - "label[0,0;Music Player]".. - "label[1,3;Power level]".. - "button[4,1;1,1;track1;1]".. - "button[5,1;1,1;track2;2]".. - "button[6,1;1,1;track3;3]".. - "button[4,2;1,1;track4;4]".. - "button[5,2;1,1;track5;5]".. - "button[6,2;1,1;track6;6]".. - "button[4,3;1,1;track7;7]".. - "button[5,3;1,1;track8;8]".. - "button[6,3;1,1;track9;9]".. - "button[4,4;1,2;play;Play]".. - "button[6,4;1,2;stop;Stop]".. - "label[4,0;Current track "..tostring(music_player_current_track).."]" - ) - end -}) +local music_player_formspec = + "invsize[8,9;]".. + "label[0,0;Music Player]".. + "button[4,1;1,1;track1;1]".. + "button[5,1;1,1;track2;2]".. + "button[6,1;1,1;track3;3]".. + "button[4,2;1,1;track4;4]".. + "button[5,2;1,1;track5;5]".. + "button[6,2;1,1;track6;6]".. + "button[4,3;1,1;track7;7]".. + "button[5,3;1,1;track8;8]".. + "button[6,3;1,1;track9;9]".. + "button[4,4;1,2;play;Play]".. + "button[6,4;1,2;stop;Stop]".. + "label[4,0;Current track --]" -register_LV_machine ("technic:music_player","RE") +minetest.register_node( + "technic:music_player", + { + description = "Music Player", + tiles = {"technic_music_player_top.png", "technic_machine_bottom.png", "technic_music_player_side.png", + "technic_music_player_side.png", "technic_music_player_side.png", "technic_music_player_side.png"}, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_string("infotext", "Music Player") + meta:set_float("technic_power_machine", 1) + meta:set_int("active", 0) -- Is the device on? + meta:set_int("music_player_current_track", 1) + meta:set_string("formspec", music_player_formspec) + end, + on_receive_fields = function(pos, formanme, fields, sender) + local meta = minetest.env:get_meta(pos) + music_handle = meta:get_int("music_handle") + music_player_current_track = meta:get_int("music_player_current_track") + if fields.track1 then music_player_current_track = 1 end + if fields.track2 then music_player_current_track = 2 end + if fields.track3 then music_player_current_track = 3 end + if fields.track4 then music_player_current_track = 4 end + if fields.track5 then music_player_current_track = 5 end + if fields.track6 then music_player_current_track = 6 end + if fields.track7 then music_player_current_track = 7 end + if fields.track8 then music_player_current_track = 8 end + if fields.track9 then music_player_current_track = 9 end + meta:set_int("music_player_current_track",music_player_current_track) + if fields.play and meta:get_int("active") == 0 then + if music_handle then minetest.sound_stop(music_handle) end + music_handle = minetest.sound_play("technic_track"..music_player_current_track, {pos = pos, gain = 1.0,loop = true, max_hear_distance = 72,}) + meta:set_int("active",1) + end + if fields.stop then + meta:set_int("active",0) + if music_handle then minetest.sound_stop(music_handle) end + end + meta:set_int("music_handle",music_handle) + end, + }) + +minetest.register_abm( + { nodenames = {"technic:music_player"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.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 = "Music Player" + local machine_node = "technic:music_player" + local machine_state_demand = { 10, 150 } + + local music_handle = meta:get_int("music_handle") + + -- 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) -- if someday two nodes for this + meta:set_string("infotext", machine_name.." Unpowered") + next_state = 1 + elseif eu_input == machine_state_demand[state] then + -- Powered - do the state specific actions + if state == 1 then + -- hacky_swap_node(pos, machine_node) -- if someday two nodes for this + meta:set_string("infotext", machine_name.." Idle") + + if meta:get_int("active") == 1 then + next_state = 2 + end + + elseif state == 2 then + -- hacky_swap_node(pos, machine_node.."_active") -- if someday two nodes for this + meta:set_string("infotext", machine_name.." Active") + + music_player_current_track=meta:get_int("music_player_current_track") + meta:set_string("formspec", + "invsize[8,9;]".. + "label[0,0;Music Player]".. + "button[4,1;1,1;track1;1]".. + "button[5,1;1,1;track2;2]".. + "button[6,1;1,1;track3;3]".. + "button[4,2;1,1;track4;4]".. + "button[5,2;1,1;track5;5]".. + "button[6,2;1,1;track6;6]".. + "button[4,3;1,1;track7;7]".. + "button[5,3;1,1;track8;8]".. + "button[6,3;1,1;track9;9]".. + "button[4,4;1,2;play;Play]".. + "button[6,4;1,2;stop;Stop]".. + "label[4,0;Current track "..tostring(music_player_current_track).."]" + ) + if meta:get_int("active") == 0 then + if music_handle then minetest.sound_stop(music_handle) end + next_state = 1 + 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:music_player","RE") diff --git a/technic/power_radiator.lua b/technic/power_radiator.lua index 3383d18..383bf87 100644 --- a/technic/power_radiator.lua +++ b/technic/power_radiator.lua @@ -8,38 +8,34 @@ -- Using inductive power transfer is very inefficient so this is -- set to the factor 0.6. +------------------------------------------------------------------ -- API for inductive powered nodes: -- Use the functions below to set the corresponding callbacks -- Also two nodes are needed: The inactive and the active one. The active must be called _active . - +------------------------------------------------------------------ -- Register a new appliance using this function -technic_inductive_nodes = {} -registered_inductive_count=0 - -register_inductive_machine = function(name) - registered_inductive_count=registered_inductive_count+1 - technic_inductive_nodes[registered_inductive_count]=name - registered_inductive_count=registered_inductive_count+1 - technic_inductive_nodes[registered_inductive_count]=name.."_active" - end - +technic.inductive_nodes = {} +technic.register_inductive_machine = function(name) + table.insert(technic.inductive_nodes, name) + table.insert(technic.inductive_nodes, name.."_active") + end -- Appliances: -- has_supply: pos of supply node if the appliance has a power radiator near with sufficient power for the demand else "" -- EU_demand: The power demand of the device. -- EU_charge: Actual use. set to EU_demand if active==1 -- active: set to 1 if the device is on -technic_inductive_on_construct = function(pos, eu_demand, infotext) +technic.inductive_on_construct = function(pos, eu_demand, infotext) local meta = minetest.env:get_meta(pos) meta:set_string("infotext", infotext) meta:set_int("technic_inductive_power_machine", 1) - meta:set_int("EU_demand",eu_demand) -- The power demand of this appliance + meta:set_int("MV_EU_demand",eu_demand) -- The power demand of this appliance meta:set_int("EU_charge",0) -- The actual power draw of this appliance meta:set_string("has_supply","") -- Register whether we are powered or not. For use with several radiators. meta:set_int("active", 0) -- If the appliance can be turned on and off by using it use this. end -technic_inductive_on_punch_off = function(pos, eu_charge, swapnode) +technic.inductive_on_punch_off = function(pos, eu_charge, swapnode) local meta = minetest.env:get_meta(pos) if meta:get_string("has_supply") ~= "" then hacky_swap_node(pos, swapnode) @@ -53,7 +49,7 @@ technic_inductive_on_punch_off = function(pos, eu_charge, swapnode) end end -technic_inductive_on_punch_on = function(pos, eu_charge, swapnode) +technic.inductive_on_punch_on = function(pos, eu_charge, swapnode) local meta = minetest.env:get_meta(pos) hacky_swap_node(pos, swapnode) meta:set_int("active", 0) @@ -65,121 +61,12 @@ technic_inductive_on_punch_on = function(pos, eu_charge, swapnode) --print("<---------->") end ---minetest.register_node( --- "technic:test_induc", { --- description = "Test radiator node", --- drawtype = "nodebox", --- tiles = { --- 'homedecor_glowlight_yellow_tb.png', --- 'homedecor_glowlight_yellow_tb.png', --- 'homedecor_glowlight_thick_yellow_sides.png', --- 'homedecor_glowlight_thick_yellow_sides.png', --- 'homedecor_glowlight_thick_yellow_sides.png', --- 'homedecor_glowlight_thick_yellow_sides.png' --- }, --- ----- tiles = {"technic_hv_down_converter_top.png", "technic_hv_down_converter_top.png", "technic_hv_down_converter_top.png", ----- "technic_hv_down_converter_top.png", "technic_hv_down_converter_top.png", "technic_hv_down_converter_top.png"}, --- selection_box = { --- type = "fixed", --- fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } --- }, --- node_box = { --- type = "fixed", --- fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } --- }, --- sunlight_propagates = false, --- paramtype = "light", --- paramtype2 = "facedir", --- walkable = true, --- groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, --- on_place = function(itemstack, placer, pointed_thing) --- homedecor_rotate_and_place(itemstack, placer, pointed_thing) --- return itemstack --- end, --- on_construct = function(pos) --- local meta = minetest.env:get_meta(pos) --- meta:set_string("infotext", "Power Radiator Appliance") --- meta:set_int("technic_inductive_power_machine", 1) --- meta:set_int("EU_demand",200) -- The power demand of this appliance --- meta:set_int("EU_charge",0) -- The actual power draw of this appliance --- meta:set_string("has_supply","") -- Register whether we are powered or not. For use with several radiators. --- meta:set_int("active", 0) -- If the appliance can be turned on and off by using it use this. --- end, --- on_punch = function(pos,node,puncher) --- local meta = minetest.env:get_meta(pos) --- if meta:get_string("has_supply") ~= "" then --- hacky_swap_node(pos, "technic:test_induc_active") --- meta:set_int("active", 1) --- meta:set_int("EU_charge",200) --- print("-----------") --- print("Turn on:") --- print("EUcha:"..meta:get_int("EU_charge")) --- print("<----------->") --- end --- end, --- }) --- ---minetest.register_node( --- "technic:test_induc_active", { --- description = "Test radiator node", --- drawtype = "nodebox", --- tiles = { --- 'homedecor_glowlight_yellow_tb.png', --- 'homedecor_glowlight_yellow_tb.png', --- 'homedecor_glowlight_thick_yellow_sides.png', --- 'homedecor_glowlight_thick_yellow_sides.png', --- 'homedecor_glowlight_thick_yellow_sides.png', --- 'homedecor_glowlight_thick_yellow_sides.png' --- }, --- ----- tiles = {"technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png", ----- "technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png"}, --- selection_box = { --- type = "fixed", --- fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } --- }, --- node_box = { --- type = "fixed", --- fixed = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 } --- }, --- sunlight_propagates = false, --- paramtype = "light", --- paramtype2 = "facedir", --- walkable = true, --- light_source=14, --- groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, --- drop="technic:test_induc", --- on_place = function(itemstack, placer, pointed_thing) --- homedecor_rotate_and_place(itemstack, placer, pointed_thing) --- return itemstack --- end, --- on_construct = function(pos) --- local meta = minetest.env:get_meta(pos) --- meta:set_string("infotext", "Power Radiator Appliance Active") --- meta:set_int("technic_inductive_power_machine", 1) --- meta:set_int("EU_demand",200) -- The power demand of this appliance --- meta:set_int("EU_charge",0) -- The actual power draw of this appliance --- meta:set_string("has_supply","") -- Register whether we are powered or not. For use with several radiators. --- end, --- on_punch = function(pos,node,puncher) --- local meta = minetest.env:get_meta(pos) --- hacky_swap_node(pos, "technic:test_induc") --- meta:set_int("active", 0) --- meta:set_int("EU_charge",0) --- print("-----------") --- print("Turn off:") --- print("EUcha:"..meta:get_int("EU_charge")) --- print("<---------->") --- end, --- }) - local shutdown_inductive_appliances = function(pos) -- The supply radius local rad = 4 -- If the radiator is removed. turn off all appliances in region -- If another radiator is near it will turn on the appliances again - local positions = minetest.env:find_nodes_in_area({x=pos.x-rad,y=pos.y-rad,z=pos.z-rad},{x=pos.x+rad,y=pos.y+rad,z=pos.z+rad}, technic_inductive_nodes) + local positions = minetest.env:find_nodes_in_area({x=pos.x-rad,y=pos.y-rad,z=pos.z-rad},{x=pos.x+rad,y=pos.y+rad,z=pos.z+rad}, technic.inductive_nodes) for _,pos1 in ipairs(positions) do local meta1 = minetest.env:get_meta(pos1) -- If the appliance is belonging to this node @@ -218,8 +105,7 @@ minetest.register_node( on_construct = function(pos) local meta = minetest.env:get_meta(pos) meta:set_int("technic_mv_power_machine", 1) -- MV machine - meta:set_int("internal_EU_buffer",0) -- internal buffer value - meta:set_int("internal_EU_buffer_size",1000) -- Size of buffer + meta:set_int("MV_EU_demand",1) -- Demand on the primary side when idle meta:set_int("connected_EU_demand",0) -- Potential demand of connected appliances meta:set_string("infotext", "Power Radiator") -- meta:set_int("active", 0) @@ -246,34 +132,45 @@ minetest.register_abm( chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) local meta = minetest.env:get_meta(pos) - local my_supply = meta:get_int("internal_EU_buffer") - -- The maximum EU sourcing a single radiator can provide. - local max_charge = 1000 -- == the max EU demand of the radiator - local connected_EU_demand = meta:get_int("connected_EU_demand") - --print("--------------------") - --print("My Supply:"..my_supply) - --print("Connected Demand:"..connected_EU_demand) - if my_supply > 0 then + local eu_input = meta:get_int("MV_EU_input") + local eu_demand = meta:get_int("MV_EU_demand") + + -- Power off automatically if no longer connected to a switching station + technic.switching_station_timeout_count(pos, "MV") + + if eu_input == 0 then + -- No power + meta:set_string("infotext", "Power Radiator is unpowered"); +-- meta:set_int("active",1) -- used for setting textures someday maybe + shutdown_inductive_appliances(pos) + connected_EU_demand = 0 + elseif eu_input == eu_demand then + -- Powered and ready + + -- The maximum EU sourcing a single radiator can provide. + local max_charge = 3000 -- == the max EU demand of the radiator + local connected_EU_demand = meta:get_int("connected_EU_demand") + -- Efficiency factor local eff_factor = 0.6 -- The supply radius - local rad = 4 + local rad = 6 local meta1 = nil local pos1 = {} local used_charge = 0 -- Index all nodes within supply range - local positions = minetest.env:find_nodes_in_area({x=pos.x-rad,y=pos.y-rad,z=pos.z-rad},{x=pos.x+rad,y=pos.y+rad,z=pos.z+rad}, technic_inductive_nodes) + local positions = minetest.env:find_nodes_in_area({x=pos.x-rad,y=pos.y-rad,z=pos.z-rad},{x=pos.x+rad,y=pos.y+rad,z=pos.z+rad}, technic.inductive_nodes) for _,pos1 in ipairs(positions) do local meta1 = minetest.env:get_meta(pos1) -- If not supplied see if this node can handle it. if meta1:get_string("has_supply") == "" then -- if demand surpasses the capacity of this node, don't bother adding it. - local eu_demand = meta1:get_int("EU_demand")/eff_factor - if connected_EU_demand+eu_demand <= max_charge and connected_EU_demand+eu_demand <= my_supply then + local app_eu_demand = meta1:get_int("EU_demand")/eff_factor + if connected_EU_demand + app_eu_demand <= max_charge then -- We can power the appliance. Register, and spend power if it is on. - connected_EU_demand = connected_EU_demand+eu_demand + connected_EU_demand = connected_EU_demand + app_eu_demand meta1:set_string("has_supply", pos.x..pos.y..pos.z) used_charge = math.floor(used_charge+meta1:get_int("EU_charge")/eff_factor) @@ -281,28 +178,28 @@ minetest.register_abm( elseif meta1:get_string("has_supply") == pos.x..pos.y..pos.z then -- The appliance has power from this node. Spend power if it is on. used_charge = math.floor(used_charge+meta1:get_int("EU_charge")/eff_factor) + print("My Lamp ("..pos.x..","..pos.y..","..pos.z..") Used:"..used_charge) + end + meta:set_string("infotext", "Power Radiator is powered ("..math.floor(used_charge/max_charge*100).."% of maximum power)"); + if used_charge == 0 then + meta:set_int("MV_EU_demand", 1) -- Still idle + else + meta:set_int("MV_EU_demand", used_charge) end - end - --If demand surpasses actual supply turn off everything - we are out of power - if used_charge>my_supply then - meta:set_string("infotext", "Power Radiator is overloaded ("..math.floor(used_charge/my_supply*100).."% of available power)"); --- meta:set_int("active",1) -- used for setting textures someday maybe - shutdown_inductive_appliances(pos) - connected_EU_demand = 0 - else - meta:set_string("infotext", "Power Radiator is powered ("..math.floor(used_charge/my_supply*100).."% of available power)"); - meta:set_int("internal_EU_buffer",my_supply-used_charge) -- meta:set_int("active",1) -- used for setting textures someday maybe end + -- Save state + meta:set_int("connected_EU_demand",connected_EU_demand) else - meta:set_string("infotext", "Power Radiator is unpowered"); --- meta:set_int("active",0) -- used for setting textures someday maybe + -- This is the case where input ~= demand. Overloaded or underpowered! +-- --If demand surpasses actual supply turn off everything - we are out of power +-- if used_charge>eu_input then +-- meta:set_string("infotext", "Power Radiator is overloaded ("..math.floor(used_charge/eu_input*100).."% of available power)"); +---- meta:set_int("active",1) -- used for setting textures someday maybe +-- shutdown_inductive_appliances(pos) +-- connected_EU_demand = 0 end - - -- Save state - meta:set_int("connected_EU_demand",connected_EU_demand) - return end, }) -register_MV_machine ("technic:power_radiator","RE") +technic.register_MV_machine ("technic:power_radiator","RE") diff --git a/technic/register_machine_and_tool.lua b/technic/register_machine_and_tool.lua new file mode 100644 index 0000000..2178224 --- /dev/null +++ b/technic/register_machine_and_tool.lua @@ -0,0 +1,70 @@ +-- This file includes the functions and data structures for registering machines and tools for LV, MV, HV types. +-- We use the technioc namespace for these functions and data to avoid eventual conflict. + +-- register LV machines here +technic.LV_machines = {} +technic.LV_power_tools = {} +technic.register_LV_machine = function(nodename,type) + technic.LV_machines[nodename] = type + end + +technic.unregister_LV_machine = function(nodename,type) + technic.LV_machines[nodename] = nil + end + +technic.register_LV_power_tool = function(craftitem,max_charge) + technic.LV_power_tools[craftitem] = max_charge + end + +-- register MV machines here +technic.MV_machines = {} +technic.MV_power_tools = {} +technic.register_MV_machine = function(nodename,type) + technic.MV_machines[nodename] = type + end + +technic.unregister_MV_machine = function(nodename) + technic.MV_machines[nodename] = nil + end + +technic.register_MV_power_tool = function(craftitem,max_charge) + technic.MV_power_tools[craftitem] = max_charge + end + +-- register HV machines here +technic.HV_machines = {} +technic.HV_power_tools = {} +technic.register_HV_machine = function(nodename,type) + technic.HV_machines[nodename] = type + end + +technic.unregister_HV_machine = function(nodename) + technic.HV_machines[nodename] = nil + end + +technic.register_HV_power_tool = function(craftitem,max_charge) + technic.HV_power_tools[craftitem] = max_charge + end + + +-- Utility functions. Not sure exactly what they do.. water.lua uses the two first. +function technic.get_RE_item_load (load1,max_load) + if load1==0 then load1=65535 end + local temp = 65536-load1 + temp= temp/65535*max_load + return math.floor(temp + 0.5) +end + +function technic.set_RE_item_load (load1,max_load) + if load1 == 0 then return 65535 end + local temp=load1/max_load*65535 + temp=65536-temp + return math.floor(temp) +end + +-- Wear down a tool depending on the remaining charge. +function technic.set_RE_wear (item_stack,load,max_load) + local temp=65536-math.floor(load/max_load*65535) + item_stack["wear"]=tostring(temp) + return item_stack +end diff --git a/technic/solar_array_hv.lua b/technic/solar_array_hv.lua index e159248..a2fb516 100644 --- a/technic/solar_array_hv.lua +++ b/technic/solar_array_hv.lua @@ -10,9 +10,6 @@ minetest.register_node("technic:solar_array_hv", { sounds = default.node_sound_wood_defaults(), description="HV Solar Array", active = false, - technic_hv_power_machine=1, - internal_EU_buffer=0; - internal_EU_buffer_size=3000; drawtype = "nodebox", paramtype = "light", is_ground_content = true, @@ -27,29 +24,25 @@ minetest.register_node("technic:solar_array_hv", { on_construct = function(pos) local meta = minetest.env:get_meta(pos) meta:set_float("technic_hv_power_machine", 1) - meta:set_float("internal_EU_buffer", 0) - meta:set_float("internal_EU_buffer_size", 3000) - + meta:set_int("HV_EU_supply", 0) meta:set_string("infotext", "HV Solar Array") - meta:set_float("active", false) end, }) -minetest.register_craft({ - output = 'technic:solar_array_hv 1', - recipe = { - {'technic:solar_array_mv', 'technic:solar_array_mv','technic:solar_array_mv'}, - {'technic:solar_array_mv', 'technic:hv_transformer','technic:solar_array_mv'}, - {'default:steel_ingot', 'technic:hv_cable', 'default:steel_ingot'}, - - } -}) +minetest.register_craft( + {output = 'technic:solar_array_hv 1', + recipe = { + {'technic:solar_array_mv', 'technic:solar_array_mv','technic:solar_array_mv'}, + {'technic:solar_array_mv', 'technic:hv_transformer','technic:solar_array_mv'}, + {'default:steel_ingot', 'technic:hv_cable', 'default:steel_ingot'}, + } + }) minetest.register_abm( - {nodenames = {"technic:solar_array_hv"}, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) + {nodenames = {"technic:solar_array_hv"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) -- The action here is to make the solar array produce power -- Power is dependent on the light level and the height above ground -- 130m and above is optimal as it would be above cloud level. @@ -62,7 +55,7 @@ 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) @@ -70,24 +63,16 @@ minetest.register_abm( -- 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, + }) -register_HV_machine ("technic:solar_array_hv","PR") +technic.register_HV_machine ("technic:solar_array_hv","PR") diff --git a/technic/solar_array_lv.lua b/technic/solar_array_lv.lua index f657814..ecc55d9 100644 --- a/technic/solar_array_lv.lua +++ b/technic/solar_array_lv.lua @@ -10,10 +10,6 @@ minetest.register_node("technic:solar_array_lv", { groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, sounds = default.node_sound_wood_defaults(), description="LV Solar Array", - active = false, - technic_power_machine=1, - internal_EU_buffer=0; - internal_EU_buffer_size=1000; drawtype = "nodebox", paramtype = "light", is_ground_content = true, @@ -27,68 +23,56 @@ minetest.register_node("technic:solar_array_lv", { }, on_construct = function(pos) local meta = minetest.env:get_meta(pos) - meta:set_float("technic_power_machine", 1) - meta:set_float("internal_EU_buffer", 0) - meta:set_float("internal_EU_buffer_size", 1000) - + meta:set_int("technic_power_machine", 1) + meta:set_int("LV_EU_supply", 0) meta:set_string("infotext", "LV Solar Array") - meta:set_float("active", false) end, }) -minetest.register_craft({ - output = 'technic:solar_array_lv 1', - recipe = { - {'technic:solar_panel', 'technic:solar_panel', 'technic:solar_panel'}, - {'technic:solar_panel', 'technic:lv_transformer', 'technic:solar_panel'}, - {'default:steel_ingot', 'technic:lv_cable', 'default:steel_ingot'}, - - } -}) +minetest.register_craft( + {output = 'technic:solar_array_lv 1', + recipe = { + {'technic:solar_panel', 'technic:solar_panel', 'technic:solar_panel'}, + {'technic:solar_panel', 'technic:lv_transformer', 'technic:solar_panel'}, + {'default:steel_ingot', 'technic:lv_cable', 'default:steel_ingot'}, + } + }) minetest.register_abm( - {nodenames = {"technic:solar_array_lv"}, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) + {nodenames = {"technic:solar_array_lv"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) -- The action here is to make the solar array produce power -- Power is dependent on the light level and the height above ground -- 130m and above is optimal as it would be above cloud level. - -- Height gives 1/4 of the effect, light 3/4. Max. effect is 160EU for the array. - -- There are many ways to cheat by using other light sources like lamps. - -- As there is no way to determine if light is sunlight that is just a shame. - -- To take care of some of it solar arrays do not work outside daylight hours or if - -- built below -10m + -- Height gives 1/4 of the effect, light 3/4. Max. effect is 160EU for the array. + -- There are many ways to cheat by using other light sources like lamps. + -- As there is no way to determine if light is sunlight that is just a shame. + -- To take care of some of it solar arrays do not work outside daylight hours or if + -- built below -10m local pos1={} 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, + }) -register_LV_machine ("technic:solar_array_lv","PR") +technic.register_LV_machine ("technic:solar_array_lv","PR") diff --git a/technic/solar_array_mv.lua b/technic/solar_array_mv.lua index abcc027..3eba790 100644 --- a/technic/solar_array_mv.lua +++ b/technic/solar_array_mv.lua @@ -11,9 +11,6 @@ minetest.register_node("technic:solar_array_mv", { sounds = default.node_sound_wood_defaults(), description="MV Solar Array", active = false, - technic_mv_power_machine=1, - internal_EU_buffer=0; - internal_EU_buffer_size=1000; drawtype = "nodebox", paramtype = "light", is_ground_content = true, @@ -28,68 +25,57 @@ minetest.register_node("technic:solar_array_mv", { on_construct = function(pos) local meta = minetest.env:get_meta(pos) meta:set_float("technic_mv_power_machine", 1) - meta:set_float("internal_EU_buffer", 0) - meta:set_float("internal_EU_buffer_size", 1000) - + meta:set_int("MV_EU_supply", 0) meta:set_string("infotext", "MV Solar Array") - meta:set_float("active", false) end, }) -minetest.register_craft({ - output = 'technic:solar_array_mv 1', - recipe = { - {'technic:solar_array_lv', 'technic:solar_array_lv','technic:solar_array_lv'}, - {'technic:solar_array_lv', 'technic:mv_transformer','technic:solar_array_lv'}, - {'default:steel_ingot', 'technic:mv_cable', 'default:steel_ingot'}, - - } +minetest.register_craft( + { + output = 'technic:solar_array_mv 1', + recipe = { + {'technic:solar_array_lv', 'technic:solar_array_lv','technic:solar_array_lv'}, + {'technic:solar_array_lv', 'technic:mv_transformer','technic:solar_array_lv'}, + {'default:steel_ingot', 'technic:mv_cable', 'default:steel_ingot'}, + } }) minetest.register_abm( - {nodenames = {"technic:solar_array_mv"}, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) + {nodenames = {"technic:solar_array_mv"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) -- The action here is to make the solar array produce power -- Power is dependent on the light level and the height above ground -- 130m and above is optimal as it would be above cloud level. - -- Height gives 1/4 of the effect, light 3/4. Max. effect is 720EU for the array. - -- There are many ways to cheat by using other light sources like lamps. - -- As there is no way to determine if light is sunlight that is just a shame. - -- To take care of some of it solar panels do not work outside daylight hours or if - -- built below -10m + -- Height gives 1/4 of the effect, light 3/4. Max. effect is 720EU for the array. + -- There are many ways to cheat by using other light sources like lamps. + -- As there is no way to determine if light is sunlight that is just a shame. + -- To take care of some of it solar panels do not work outside daylight hours or if + -- built below -10m local pos1={} 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*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, + }) -register_MV_machine ("technic:solar_array_mv","PR") +technic.register_MV_machine ("technic:solar_array_mv","PR") diff --git a/technic/solar_panel.lua b/technic/solar_panel.lua index 5b53f5f..96ee744 100644 --- a/technic/solar_panel.lua +++ b/technic/solar_panel.lua @@ -8,9 +8,6 @@ minetest.register_node("technic:solar_panel", { sounds = default.node_sound_wood_defaults(), description="Solar Panel", active = false, - technic_power_machine=1, - internal_EU_buffer=0; - internal_EU_buffer_size=160; drawtype = "nodebox", paramtype = "light", is_ground_content = true, @@ -24,12 +21,9 @@ minetest.register_node("technic:solar_panel", { }, on_construct = function(pos) local meta = minetest.env:get_meta(pos) - meta:set_float("technic_power_machine", 1) - meta:set_float("internal_EU_buffer", 0) - meta:set_float("internal_EU_buffer_size", 160) - - meta:set_string("infotext", "Solar Panel") - meta:set_float("active", false) + meta:set_int("technic_power_machine", 1) + meta:set_int("LV_EU_supply", 0) + meta:set_string("infotext", "LV Solar Panel") end, }) @@ -68,24 +62,16 @@ minetest.register_abm( -- turn on panel only during day time and if sufficient light -- I know this is counter intuitive when cheating by using other light sources underground. if light >= 12 and time_of_day>=0.24 and time_of_day<=0.76 and pos.y > -10 then - local 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.0867+pos1.y/130*0.4333)) if charge_to_give<0 then charge_to_give=0 end if charge_to_give>26 then charge_to_give=26 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 Panel 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) - + meta:set_int("LV_EU_supply", charge_to_give) else meta:set_string("infotext", "Solar Panel is inactive"); - meta:set_float("active",0) + meta:set_int("LV_EU_supply", 0) end end, }) -register_LV_machine ("technic:solar_panel","PR") +technic.register_LV_machine ("technic:solar_panel","PR") diff --git a/technic/sonic_screwdriver.lua b/technic/sonic_screwdriver.lua index 97ec446..1453862 100644 --- a/technic/sonic_screwdriver.lua +++ b/technic/sonic_screwdriver.lua @@ -1,5 +1,5 @@ -sonic_screwdriver_max_charge=15000 -register_power_tool ("technic:sonic_screwdriver",sonic_screwdriver_max_charge) +local sonic_screwdriver_max_charge=15000 +technic.register_HV_power_tool ("technic:sonic_screwdriver",sonic_screwdriver_max_charge) minetest.register_tool("technic:sonic_screwdriver", { description = "Sonic Screwdriver", diff --git a/technic/supply_converter.lua b/technic/supply_converter.lua new file mode 100644 index 0000000..5e04d42 --- /dev/null +++ b/technic/supply_converter.lua @@ -0,0 +1,223 @@ +-- The supply converter is a generic device which can convert from +-- LV to MV and back, and HV to MV and back. +-- The machine will not convert from HV directly to LV. +-- The machine is configured by the wiring below and above it. +-- It is prepared for an upgrade slot if this is to be implemented later. +-- +-- The conversion factor is a constant and the conversion is a lossy operation. +-- +-- It works like this: +-- The top side is setup as the "RE" side, the bottom as the "PR" side. +-- Once the RE side is powered it will deliver power to the other side. +-- Unused power is wasted just like any other producer! +-- +minetest.register_node( + "technic:supply_converter", { + description = "Supply Converter", + tiles = {"technic_mv_down_converter_top.png", "technic_mv_down_converter_bottom.png", "technic_mv_down_converter_side.png", + "technic_mv_down_converter_side.png", "technic_mv_down_converter_side.png", "technic_mv_down_converter_side.png"}, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), + drawtype = "nodebox", + paramtype = "light", + is_ground_content = true, + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_float("technic_hv_power_machine", 1) + meta:set_float("technic_mv_power_machine", 1) + meta:set_float("technic_power_machine", 1) + meta:set_string("infotext", "Supply Converter") + meta:set_float("active", false) + end, + }) + +minetest.register_craft({ + output = 'technic:supply_converter 1', + recipe = { + {'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot','technic:stainless_steel_ingot'}, + {'technic:mv_transformer', 'technic:mv_cable', 'technic:lv_transformer'}, + {'technic:mv_cable', 'technic:rubber', 'technic:lv_cable'}, + } +}) + +minetest.register_abm( + { nodenames = {"technic:supply_converter"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + -- Conversion factors (a picture of V*A - loss) Asymmetric. + local lv_mv_factor = 5 -- division (higher is less efficient) + local mv_lv_factor = 4 -- multiplication (higher is more efficient) + local mv_hv_factor = 5 -- division + local hv_mv_factor = 4 -- multiplication + local max_lv_demand = 2000 -- The increment size pwer supply tier. Determines how many are needed + local max_mv_demand = 2000 -- -""- + local max_hv_demand = 2000 -- -""- + + -- Machine information + local machine_name = "Supply Converter" + local meta = minetest.env:get_meta(pos) + local upgrade = "" -- Replace with expansion slot later?? + + -- High voltage on top, low at bottom regardless of converter direction + local pos_up = {x=pos.x, y=pos.y+1, z=pos.z} + local pos_down = {x=pos.x, y=pos.y-1, z=pos.z} + local meta_up = minetest.env:get_meta(pos_up) + local meta_down = minetest.env:get_meta(pos_down) + local convert_MV_LV = 0 + local convert_LV_MV = 0 + local convert_MV_HV = 0 + local convert_HV_MV = 0 + -- check cabling + if meta_up:get_float("mv_cablelike") == 1 and meta_down:get_float("cablelike") == 1 then + convert_MV_LV = 1 + upgrade = "MV-LV step down" + end + if meta_up:get_float("cablelike") == 1 and meta_down:get_float("mv_cablelike") == 1 then + convert_LV_MV = 1 + upgrade = "LV-MV step up" + end + if meta_up:get_float("mv_cablelike") == 1 and meta_down:get_float("hv_cablelike") == 1 then + convert_MV_HV = 1 + upgrade = "MV-HV step up" + end + if meta_up:get_float("hv_cablelike") == 1 and meta_down:get_float("mv_cablelike") == 1 then + convert_HV_MV = 1 + upgrade = "HV-MV step down" + end + --print("Cabling:"..convert_MV_LV.."|"..convert_LV_MV.."|"..convert_HV_MV.."|"..convert_MV_HV) + + if convert_MV_LV == 0 and convert_LV_MV == 0 and convert_HV_MV == 0 and convert_MV_HV == 0 then + meta:set_string("infotext", machine_name.." has bad cabling") + return + end + + -- The node is programmed with an upgrade slot + -- containing a MV-LV step down, LV-MV step up, HV-MV step down or MV-HV step up unit + + if upgrade == "" then + meta:set_string("infotext", machine_name.." has an empty converter slot"); + technic.unregister_LV_machine("technic:supply_converter") + technic.unregister_MV_machine("technic:supply_converter") + technic.unregister_HV_machine("technic:supply_converter") + meta:set_int("LV_EU_demand", 0) + meta:set_int("LV_EU_supply", 0) + meta:set_int("LV_EU_input", 0) + meta:set_int("MV_EU_demand", 0) + meta:set_int("MV_EU_supply", 0) + meta:set_int("MV_EU_input", 0) + meta:set_int("HV_EU_demand", 0) + meta:set_int("HV_EU_supply", 0) + meta:set_int("HV_EU_input", 0) + return + end + + -- State machine + if upgrade == "MV-LV step down" and convert_MV_LV then + -- Register machine type + technic.register_LV_machine("technic:supply_converter","PR") + technic.register_MV_machine("technic:supply_converter","RE") + + -- Power off automatically if no longer connected to a switching station + technic.switching_station_timeout_count(pos, "MV") + + local eu_input = meta:get_int("MV_EU_input") + if eu_input == 0 then + -- Unpowered - go idle + --hacky_swap_node(pos, machine_node) + meta:set_string("infotext", machine_name.." Unpowered") + meta:set_int("LV_EU_supply", 0) + meta:set_int("MV_EU_supply", 0) + + meta:set_int("LV_EU_demand", 0) + meta:set_int("MV_EU_demand", max_mv_demand) + else + -- MV side has got power to spare + meta:set_string("infotext", machine_name.." is active (MV:"..max_mv_demand.."->LV:"..eu_input*mv_lv_factor..")"); + meta:set_int("LV_EU_supply", eu_input*mv_lv_factor) + end + --------------------------------------------------- + elseif upgrade == "LV-MV step up" and convert_LV_MV then + -- Register machine type + technic.register_LV_machine("technic:supply_converter","RE") + technic.register_MV_machine("technic:supply_converter","PR") + + -- Power off automatically if no longer connected to a switching station + technic.switching_station_timeout_count(pos, "LV") + + local eu_input = meta:get_int("LV_EU_input") + if eu_input == 0 then + -- Unpowered - go idle + --hacky_swap_node(pos, machine_node) + meta:set_string("infotext", machine_name.." Unpowered") + meta:set_int("LV_EU_supply", 0) + meta:set_int("MV_EU_supply", 0) + + meta:set_int("LV_EU_demand", max_lv_demand) + meta:set_int("MV_EU_demand", 0) + else + -- LV side has got power to spare + meta:set_string("infotext", machine_name.." is active (LV:"..max_lv_demand.."->MV:"..eu_input/lv_mv_factor..")"); + meta:set_int("MV_EU_supply", eu_input/lv_mv_factor) + end + --------------------------------------------------- + + elseif upgrade == "HV-MV step down" and convert_HV_MV then + -- Register machine type + technic.register_MV_machine("technic:supply_converter","PR") + technic.register_HV_machine("technic:supply_converter","RE") + + -- Power off automatically if no longer connected to a switching station + technic.switching_station_timeout_count(pos, "HV") + + local eu_input = meta:get_int("HV_EU_input") + if eu_input == 0 then + -- Unpowered - go idle + --hacky_swap_node(pos, machine_node) + meta:set_string("infotext", machine_name.." Unpowered") + meta:set_int("MV_EU_supply", 0) + meta:set_int("HV_EU_supply", 0) + + meta:set_int("MV_EU_demand", 0) + meta:set_int("HV_EU_demand", max_hv_demand) + else + -- HV side has got power to spare + meta:set_string("infotext", machine_name.." is active (HV:"..max_hv_demand.."->MV:"..eu_input*hv_mv_factor..")"); + meta:set_int("MV_EU_supply", eu_input*hv_mv_factor) + end + --------------------------------------------------- + elseif upgrade == "MV-HV step up" and convert_MV_HV then + -- Register machine type + technic.register_MV_machine("technic:supply_converter","RE") + technic.register_HV_machine("technic:supply_converter","PR") + + -- Power off automatically if no longer connected to a switching station + technic.switching_station_timeout_count(pos, "MV") + + local eu_input = meta:get_int("MV_EU_input") + if eu_input == 0 then + -- Unpowered - go idle + --hacky_swap_node(pos, machine_node) + meta:set_string("infotext", machine_name.." Unpowered") + meta:set_int("MV_EU_supply", 0) + meta:set_int("HV_EU_supply", 0) + + meta:set_int("MV_EU_demand", max_mv_demand) + meta:set_int("HV_EU_demand", 0) + else + -- MV side has got power to spare + meta:set_string("infotext", machine_name.." is active (MV:"..max_mv_demand.."->HV:"..eu_input/mv_hv_factor..")"); + meta:set_int("HV_EU_supply", eu_input/mv_hv_factor) + end + --------------------------------------------------- + end + end, +}) diff --git a/technic/switching_station.lua b/technic/switching_station.lua new file mode 100644 index 0000000..7919d5e --- /dev/null +++ b/technic/switching_station.lua @@ -0,0 +1,352 @@ +-- SWITCHING STATION +-- The switching station is the center of all power distribution on an electric network. +-- The station will collect all produced power from producers (PR) and batteries (BA) +-- and distribute it to receivers (RE) and depleted batteries (BA). +-- +-- It works like this: +-- All PR,BA,RE nodes are indexed and tagged with the switching station. +-- The tagging is to allow more stations to be built without allowing a cheat +-- with duplicating power. +-- All the RE nodes are queried for their current EU demand. Those which are off +-- would require no or a small standby EU demand, while those which are on would +-- require more. +-- If the total demand is less than the available power they are all updated with the +-- demand number. +-- If any surplus exists from the PR nodes the batteries will be charged evenly with this. +-- If the total demand requires draw on the batteries they will be discharged evenly. +-- +-- If the total demand is more than the available power all RE nodes will be shut down. +-- We have a brown-out situation. +-- +-- Hence all the power distribution logic resides in this single node. +-- +-- Nodes connected to the network will have one or more of these parameters as meta data: +-- _EU_supply : Exists for PR and BA node types. This is the EU value supplied by the node. Output +-- _EU_demand : Exists for RE and BA node types. This is the EU value the node requires to run. Output +-- _EU_input : Exists for RE and BA node types. This is the actual EU value the network can give the node. Input +-- +-- The reason the LV|MV|HV type is prepended toe meta data is because some machine could require several supplies to work. +-- This way the supplies are separated per network. +technic.DBG = 1 +local dprint = technic.dprint + +minetest.register_craft( + { + output = 'technic:switching_station 1', + recipe = { + {'technic:lv_transformer', 'technic:mv_transformer', 'technic:hv_transformer'}, + {'technic:lv_transformer', 'technic:mv_transformer', 'technic:hv_transformer'}, + {'technic:lv_cable', 'technic:mv_cable', 'technic:hv_cable'}, + } + }) + +minetest.register_node( + "technic:switching_station", + {description = "Switching Station", + tiles = {"technic_mv_down_converter_top.png", "technic_mv_down_converter_bottom.png", "technic_mv_down_converter_side.png", + "technic_mv_down_converter_side.png", "technic_mv_down_converter_side.png", "technic_mv_down_converter_side.png"}, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), + drawtype = "nodebox", + paramtype = "light", + is_ground_content = true, + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_string("infotext", "Switching Station") +-- minetest.chat_send_player(puncher:get_player_name(), "Switching station constructed. Punch the station to shut down the network."); +-- meta:set_int("active", 1) + end, +-- on_punch = function(pos, node, puncher) +-- local meta = minetest.env:get_meta(pos) +-- local active = meta:get_int("active") +-- if active == 1 then +-- meta:set_int("active", 0) +-- minetest.chat_send_player(puncher:get_player_name(), "Electrical network shut down. Punch again to turn it on."); +-- else +-- meta:set_int("active", 1) +-- minetest.chat_send_player(puncher:get_player_name(), "Electrical network turned on. Punch again to shut it down."); +-- end +-- end + }) + +-------------------------------------------------- +-- Functions to help the machines on the electrical network +-------------------------------------------------- +-- This one provides a timeout for a node in case it was disconnected from the network +-- A node must be touched by the station continuously in order to function +technic.switching_station_timeout_count = function(pos, machine_tier) + local meta = minetest.env:get_meta(pos) + timeout = meta:get_int(machine_tier.."_EU_timeout") + --print("Counting timeout "..timeout) + if timeout == 0 then + --print("OFF") + meta:set_int(machine_tier.."_EU_input", 0) + else + --print("ON") + meta:set_int(machine_tier.."_EU_timeout", timeout-1) + end + end + +-------------------------------------------------- +-- Functions to traverse the electrical network +-------------------------------------------------- + +-- Add a wire node to the LV/MV/HV network +local add_new_cable_node = function(nodes,pos) + local i = 1 + repeat + if nodes[i]==nil then break end + if pos.x==nodes[i].x and pos.y==nodes[i].y and pos.z==nodes[i].z then return false end + i=i+1 + until false + nodes[i] = {x=pos.x, y=pos.y, z=pos.z, visited=1} -- copy position + return true + end + +-- Generic function to add found connected nodes to the right classification array +local check_node_subp = function(PR_nodes,RE_nodes,BA_nodes,all_nodes,pos,machines,cablename) + local meta = minetest.env:get_meta(pos) + local name = minetest.env:get_node(pos).name + if meta:get_float(cablename)==1 then + add_new_cable_node(all_nodes,pos) + elseif machines[name] then + --dprint(name.." is a "..machines[name]) + if machines[name] == "PR" then + add_new_cable_node(PR_nodes,pos) + elseif machines[name] == "RE" then + add_new_cable_node(RE_nodes,pos) + elseif machines[name] == "BA" then + add_new_cable_node(BA_nodes,pos) + end + if cablename == "cablelike" then + meta:set_int("LV_EU_timeout", 2) -- Touch node + elseif cablename == "mv_cablelike" then + meta:set_int("MV_EU_timeout", 2) -- Touch node + elseif cablename == "hv_cablelike" then + meta:set_int("HV_EU_timeout", 2) -- Touch node + end + end + end + +-- Traverse a network given a list of machines and a cable type name +local traverse_network = function(PR_nodes,RE_nodes,BA_nodes,all_nodes, i, machines, cablename) + local pos = {x=all_nodes[i].x, y=all_nodes[i].y, z=all_nodes[i].z} -- copy position + pos.x=pos.x+1 + check_node_subp(PR_nodes,RE_nodes,BA_nodes,all_nodes,pos, machines, cablename) + pos.x=pos.x-2 + check_node_subp(PR_nodes,RE_nodes,BA_nodes,all_nodes,pos, machines, cablename) + pos.x=pos.x+1 + + pos.y=pos.y+1 + check_node_subp(PR_nodes,RE_nodes,BA_nodes,all_nodes,pos, machines, cablename) + pos.y=pos.y-2 + check_node_subp(PR_nodes,RE_nodes,BA_nodes,all_nodes,pos, machines, cablename) + pos.y=pos.y+1 + + pos.z=pos.z+1 + check_node_subp(PR_nodes,RE_nodes,BA_nodes,all_nodes,pos, machines, cablename) + pos.z=pos.z-2 + check_node_subp(PR_nodes,RE_nodes,BA_nodes,all_nodes,pos, machines, cablename) + pos.z=pos.z+1 + end + +---------------------------------------------- +-- The action code for the switching station +---------------------------------------------- +minetest.register_abm( + {nodenames = {"technic:switching_station"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.env:get_meta(pos) + local meta1 = nil + local pos1 = {} + local PR_EU = 0 -- EUs from PR nodes + local BA_PR_EU = 0 -- EUs from BA nodes (discharching) + local BA_RE_EU = 0 -- EUs to BA nodes (charging) + local RE_EU = 0 -- EUs to RE nodes + + local network = "" + local all_nodes = {} + local PR_nodes = {} + local BA_nodes = {} + local RE_nodes = {} + +-- -- Possible to turn off the entire network +-- if meta:get_int("active") == 0 then +-- for _,pos1 in pairs(RE_nodes) do +-- meta1 = minetest.env:get_meta(pos1) +-- meta1:set_int("EU_input", 0) +-- end +-- for _,pos1 in pairs(BA_nodes) do +-- meta1 = minetest.env:get_meta(pos1) +-- meta1:set_int("EU_input", 0) +-- end +-- return +-- end + + -- Which kind of network are we on: + pos1 = {x=pos.x, y=pos.y-1, z=pos.z} + all_nodes[1] = pos1 + + meta1 = minetest.env:get_meta(pos1) + if meta1:get_float("cablelike") ==1 then + -- LV type + --dprint("LV type") + network = "LV" + local table_index = 1 + repeat + traverse_network(PR_nodes,RE_nodes,BA_nodes,all_nodes,table_index, technic.LV_machines, "cablelike") + table_index = table_index + 1 + if all_nodes[table_index] == nil then break end + until false + elseif meta1:get_float("mv_cablelike") ==1 then + -- MV type + --dprint("MV type") + network = "MV" + local table_index = 1 + repeat + traverse_network(PR_nodes,RE_nodes,BA_nodes,all_nodes,table_index, technic.MV_machines, "mv_cablelike") + table_index = table_index + 1 + if all_nodes[table_index] == nil then break end + until false + elseif meta1:get_float("hv_cablelike") ==1 then + -- HV type + --dprint("HV type") + network = "HV" + local table_index = 1 + repeat + traverse_network(PR_nodes,RE_nodes,BA_nodes,all_nodes,table_index, technic.HV_machines, "hv_cablelike") + table_index = table_index + 1 + if all_nodes[table_index] == nil then break end + until false + else + -- No type :-) + --dprint("Not connected to a network") + meta:set_string("infotext", "Switching Station - no network") + return + end + --dprint("nodes="..table.getn(all_nodes).." PR="..table.getn(PR_nodes).." BA="..table.getn(BA_nodes).." RE="..table.getn(RE_nodes)) + + -- Strings for the meta data + local eu_demand_str = network.."_EU_demand" + local eu_input_str = network.."_EU_input" + local eu_supply_str = network.."_EU_supply" + local eu_from_fuel_str = network.."_EU_from_fuel" + + -- Get all the power from the PR nodes + local PR_eu_supply = 0 -- Total power + for _,pos1 in pairs(PR_nodes) do + meta1 = minetest.env:get_meta(pos1) + PR_eu_supply = PR_eu_supply + meta1:get_int(eu_supply_str) + end + --dprint("Total PR supply:"..PR_eu_supply) + + -- Get all the demand from the RE nodes + local RE_eu_demand = 0 + for _,pos1 in pairs(RE_nodes) do + meta1 = minetest.env:get_meta(pos1) + RE_eu_demand = RE_eu_demand + meta1:get_int(eu_demand_str) + end + --dprint("Total RE demand:"..RE_eu_demand) + + -- Get all the power from the BA nodes + local BA_eu_supply = 0 + for _,pos1 in pairs(BA_nodes) do + meta1 = minetest.env:get_meta(pos1) + BA_eu_supply = BA_eu_supply + meta1:get_int(eu_supply_str) + end + --dprint("Total BA supply:"..BA_eu_supply) + + -- Get all the demand from the BA nodes + local BA_eu_demand = 0 + for _,pos1 in pairs(BA_nodes) do + meta1 = minetest.env:get_meta(pos1) + BA_eu_demand = BA_eu_demand + meta1:get_int(eu_demand_str) + end + --dprint("Total BA demand:"..BA_eu_demand) + + meta:set_string("infotext", "Switching Station. PR("..(PR_eu_supply+BA_eu_supply)..") RE("..(RE_eu_demand+BA_eu_demand)..")") + + -- If the PR supply is enough for the RE demand supply them all + if PR_eu_supply >= RE_eu_demand then + --dprint("PR_eu_supply"..PR_eu_supply.." >= RE_eu_demand"..RE_eu_demand) + for _,pos1 in pairs(RE_nodes) do + meta1 = minetest.env:get_meta(pos1) + local eu_demand = meta1:get_int(eu_demand_str) + meta1:set_int(eu_input_str, eu_demand) + end + -- We have a surplus, so distribute the rest equally to the BA nodes + -- Let's calculate the factor of the demand + PR_eu_supply = PR_eu_supply - RE_eu_demand + local charge_factor = 0 -- Assume all batteries fully charged + if BA_eu_demand > 0 then + charge_factor = PR_eu_supply / BA_eu_demand + end + for n,pos1 in pairs(BA_nodes) do + meta1 = minetest.env:get_meta(pos1) + local eu_demand = meta1:get_int(eu_demand_str) + meta1:set_int(eu_input_str, math.floor(eu_demand*charge_factor)) + --dprint("Charging battery:"..math.floor(eu_demand*charge_factor)) + end + -- If still a surplus we can start giving back to the fuel burning generators + -- Only full EU packages are given back. The rest is wasted. + if BA_eu_demand == 0 then + for _,pos1 in pairs(PR_nodes) do + meta1 = minetest.env:get_meta(pos1) + if meta1:get_int(eu_from_fuel_str) == 1 then + local eu_supply = meta1:get_int(eu_supply_str) + if PR_eu_supply < eu_supply then + break + else + -- Set the supply to 0 if we did not require it. + meta1:set_int(eu_supply_str, 0) + PR_eu_supply = PR_eu_supply - eu_supply + end + end + end + end + return + end + + -- If the PR supply is not enough for the RE demand we will discharge the batteries too + if PR_eu_supply+BA_eu_supply >= RE_eu_demand then + --dprint("PR_eu_supply "..PR_eu_supply.."+BA_eu_supply "..BA_eu_supply.." >= RE_eu_demand"..RE_eu_demand) + for _,pos1 in pairs(RE_nodes) do + meta1 = minetest.env:get_meta(pos1) + local eu_demand = meta1:get_int(eu_demand_str) + meta1:set_int(eu_input_str, eu_demand) + end + -- We have a deficit, so distribute to the BA nodes + -- Let's calculate the factor of the supply + local charge_factor = 0 -- Assume all batteries depleted + if BA_eu_supply > 0 then + charge_factor = (PR_eu_supply - RE_eu_demand) / BA_eu_supply + end + for n,pos1 in pairs(BA_nodes) do + meta1 = minetest.env:get_meta(pos1) + local eu_supply = meta1:get_int(eu_supply_str) + meta1:set_int(eu_input_str, math.floor(eu_supply*charge_factor)) + --dprint("Discharging battery:"..math.floor(eu_supply*charge_factor)) + end + return + end + + -- If the PR+BA supply is not enough for the RE demand: Shut everything down! + -- Note: another behaviour could also be imagined: provide the average power for all and let the node decide what happens. + -- This is much simpler though: Not enough power for all==no power for all + --print("NO POWER") + for _,pos1 in pairs(RE_nodes) do + meta1 = minetest.env:get_meta(pos1) + meta1:set_int(eu_input_str, 0) + end + end, +}) diff --git a/technic/tool_workshop.lua b/technic/tool_workshop.lua index 1174633..9351c0e 100644 --- a/technic/tool_workshop.lua +++ b/technic/tool_workshop.lua @@ -1,3 +1,5 @@ +-- LV Tool workshop +-- This machine repairs tools. minetest.register_alias("tool_workshop", "technic:tool_workshop") minetest.register_craft({ output = 'technic:tool_workshop', @@ -13,88 +15,108 @@ minetest.register_craftitem("technic:tool_workshop", { stack_max = 99, }) -workshop_formspec = - "invsize[8,9;]".. - "image[1,1;1,2;technic_power_meter_bg.png]".. - "list[current_name;src;3,1;1,1;]".. - "label[0,0;Tool Workshop]".. - "label[1,3;Power level]".. - "list[current_player;main;0,5;8,4;]" +local workshop_formspec = + "invsize[8,9;]".. + "list[current_name;src;3,1;1,1;]".. + "label[0,0;Tool Workshop]".. + "list[current_player;main;0,5;8,4;]" -minetest.register_node("technic:tool_workshop", { - description = "Tool Workshop", - tiles = {"technic_workshop_top.png", "technic_machine_bottom.png", "technic_workshop_side.png", - "technic_workshop_side.png", "technic_workshop_side.png", "technic_workshop_side.png"}, - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - sounds = default.node_sound_wood_defaults(), - technic_power_machine=1, - internal_EU_buffer=0; - internal_EU_buffer_size=2000; +minetest.register_node( + "technic:tool_workshop", + { + description = "Tool Workshop", + tiles = {"technic_workshop_top.png", "technic_machine_bottom.png", "technic_workshop_side.png", + "technic_workshop_side.png", "technic_workshop_side.png", "technic_workshop_side.png"}, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_string("infotext", "Tool Workshop") + meta:set_float("technic_power_machine", 1) + meta:set_string("formspec", workshop_formspec) + local inv = meta:get_inventory() + inv:set_size("src", 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") then + minetest.chat_send_player(player:get_player_name(), "Machine cannot be removed because it is not empty"); + return false + end + return true + end, + }) - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_string("infotext", "Tool Workshop") - meta:set_float("technic_power_machine", 1) - meta:set_float("internal_EU_buffer", 1) - meta:set_float("internal_EU_buffer_size", 2000) - meta:set_string("formspec", workshop_formspec) - local inv = meta:get_inventory() - inv:set_size("src", 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") then - return false - end - return true - end, -}) +minetest.register_abm( + { nodenames = {"technic:tool_workshop"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.env:get_meta(pos) + local eu_input = meta:get_int("LV_EU_input") + local state = meta:get_int("state") + local next_state = state -minetest.register_abm({ - nodenames = {"technic:tool_workshop"}, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - local meta = minetest.env:get_meta(pos) - local charge= meta:get_float("internal_EU_buffer") - local max_charge= meta:get_float("internal_EU_buffer_size") - local load_step=2000 - local load_cost=200 - local inv = meta:get_inventory() - if inv:is_empty("src")==false then - srcstack = inv:get_stack("src", 1) - src_item=srcstack:to_table() - if (src_item["name"]=="technic:water_can" or src_item["name"]=="technic:lava_can") then - load_step=0 - load_cost=0 - end - local load1=tonumber((src_item["wear"])) - if charge>load_cost then - if load1>1 then - if load1-load_step<0 then load_step=load1 load1=1 - else load1=load1-load_step end - charge=charge-load_cost - src_item["wear"]=tostring(load1) - inv:set_stack("src", 1, src_item) - end - end - end - - meta:set_float("internal_EU_buffer",charge) - - - local load = math.floor((charge/max_charge)*100) - meta:set_string("formspec", - "invsize[8,9;]".. - "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. - (load)..":technic_power_meter_fg.png]".. - "list[current_name;src;3,1;1,1;]".. - "label[0,0;Tool Workshop]".. - "label[1,3;Power level]".. - "list[current_player;main;0,5;8,4;]") - end -}) + -- Machine information + local machine_name = "Tool Workshop" + local machine_node = "technic:tool_workshop" + local machine_state_demand = { 50, 150 } + + -- 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() + + if state == 1 then + --hacky_swap_node(pos, machine_node) + meta:set_string("infotext", machine_name.." Idle") + if not inv:is_empty("src") then + next_state = 2 + end + elseif state == 2 then + --hacky_swap_node(pos, machine_node.."_active") + meta:set_string("infotext", machine_name.." Active") -register_LV_machine ("technic:tool_workshop","RE") + if inv:is_empty("src") then + next_state = 1 + else + srcstack = inv:get_stack("src", 1) + src_item=srcstack:to_table() + -- Cannot charge cans + if (src_item["name"]=="technic:water_can" or src_item["name"]=="technic:lava_can") then + return + end + local wear=tonumber(src_item["wear"]) + wear = math.max(1, wear-2000) -- Improve the tool this much every tick + src_item["wear"]=tostring(wear) + inv:set_stack("src", 1, src_item) + 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:tool_workshop","RE") diff --git a/technic/water_mill.lua b/technic/water_mill.lua index 52966ed..e6314f0 100644 --- a/technic/water_mill.lua +++ b/technic/water_mill.lua @@ -1,3 +1,6 @@ +-- A water mill produces LV EUs by exploiting flowing water across it +-- It is a LV EU supplyer and fairly low yield (max 120EUs) +-- It is a little under half as good as the thermal generator. minetest.register_alias("water_mill", "technic:water_mill") minetest.register_craft({ @@ -14,7 +17,7 @@ minetest.register_craftitem("technic:water_mill", { stack_max = 99, }) -water_mill_formspec = +local water_mill_formspec = "invsize[8,4;]".. "image[1,1;1,2;technic_power_meter_bg.png]".. "label[0,0;Water Mill]".. @@ -22,110 +25,98 @@ water_mill_formspec = "list[current_player;main;0,5;8,4;]" -minetest.register_node("technic:water_mill", { - description = "Water Mill", - tiles = {"technic_water_mill_top.png", "technic_machine_bottom.png", "technic_water_mill_side.png", - "technic_water_mill_side.png", "technic_water_mill_side.png", "technic_water_mill_side.png"}, - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - legacy_facedir_simple = true, - sounds = default.node_sound_wood_defaults(), - technic_power_machine=1, - internal_EU_buffer=0; - internal_EU_buffer_size=5000; - burn_time=0; - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_string("infotext", "Water Mill") - meta:set_float("technic_power_machine", 1) - meta:set_float("internal_EU_buffer", 0) - meta:set_float("internal_EU_buffer_size", 3000) - meta:set_string("formspec", water_mill_formspec) - end, +minetest.register_node( + "technic:water_mill", + { + description = "Water Mill", + tiles = {"technic_water_mill_top.png", "technic_machine_bottom.png", "technic_water_mill_side.png", + "technic_water_mill_side.png", "technic_water_mill_side.png", "technic_water_mill_side.png"}, + paramtype2 = "facedir", + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, + legacy_facedir_simple = true, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_string("infotext", "Water Mill") + meta:set_float("technic_power_machine", 1) + meta:set_int("LV_EU_supply", 0) + meta:set_string("formspec", water_mill_formspec) + end, + }) +minetest.register_node( + "technic:water_mill_active", + { + description = "Water Mill", + tiles = {"technic_water_mill_top_active.png", "technic_machine_bottom.png", "technic_water_mill_side.png", + "technic_water_mill_side.png", "technic_water_mill_side.png", "technic_water_mill_side.png"}, + paramtype2 = "facedir", + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, + legacy_facedir_simple = true, + sounds = default.node_sound_wood_defaults(), + drop="technic:water_mill", }) -minetest.register_node("technic:water_mill_active", { - description = "Water Mill", - tiles = {"technic_water_mill_top_active.png", "technic_machine_bottom.png", "technic_water_mill_side.png", - "technic_water_mill_side.png", "technic_water_mill_side.png", "technic_water_mill_side.png"}, - paramtype2 = "facedir", - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1}, - legacy_facedir_simple = true, - sounds = default.node_sound_wood_defaults(), - drop="technic:water_mill", - technic_power_machine=1, - internal_EU_buffer=0; - internal_EU_buffer_size=0; -}) +local check_node_around_mill = function(pos) + local node=minetest.env:get_node(pos) + if node.name=="default:water_flowing" then return 1 end + return 0 + end -minetest.register_abm({ - nodenames = {"technic:water_mill","technic:water_mill_active"}, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) +minetest.register_abm( + { + nodenames = {"technic:water_mill","technic:water_mill_active"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.env:get_meta(pos) + local water_nodes = 0 + local lava_nodes = 0 + local production_level = 0 + local eu_supply = 0 - 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 water_nodes = 0 - local lava_nodes = 0 - local production_level=0 - local load_step=0 - - pos.x=pos.x+1 - local check=check_node_around_mill (pos) - if check==1 then water_nodes=water_nodes+1 end - pos.x=pos.x-2 - check=check_node_around_mill (pos) - if check==1 then water_nodes=water_nodes+1 end - pos.x=pos.x+1 - pos.z=pos.z+1 - check=check_node_around_mill (pos) - if check==1 then water_nodes=water_nodes+1 end - pos.z=pos.z-2 - check=check_node_around_mill (pos) - if check==1 then water_nodes=water_nodes+1 end - pos.z=pos.z+1 + pos.x=pos.x+1 + local check=check_node_around_mill (pos) + if check==1 then water_nodes=water_nodes+1 end + pos.x=pos.x-2 + check=check_node_around_mill (pos) + if check==1 then water_nodes=water_nodes+1 end + pos.x=pos.x+1 + pos.z=pos.z+1 + check=check_node_around_mill (pos) + if check==1 then water_nodes=water_nodes+1 end + pos.z=pos.z-2 + check=check_node_around_mill (pos) + if check==1 then water_nodes=water_nodes+1 end + pos.z=pos.z+1 - if water_nodes==1 then production_level=25 load_step=30 end - if water_nodes==2 then production_level=50 load_step=60 end - if water_nodes==3 then production_level=75 load_step=90 end - if water_nodes==4 then production_level=100 load_step=120 end + if water_nodes==1 then production_level = 25; eu_supply = 30 end + if water_nodes==2 then production_level = 50; eu_supply = 60 end + if water_nodes==3 then production_level = 75; eu_supply = 90 end + if water_nodes==4 then production_level = 100; eu_supply = 120 end - if production_level>0 then - if charge+load_step>max_charge then - load_step=max_charge-charge - end - if load_step>0 then - charge=charge+load_step - meta:set_float("internal_EU_buffer",charge) - end - end + if production_level>0 then + meta:set_int("LV_EU_supply", eu_supply) + end - local load = math.floor((charge/max_charge)*100) - meta:set_string("formspec", - "invsize[8,4;]".. - "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. - (load)..":technic_power_meter_fg.png]".. - "label[0,0;Water Mill]".. - "label[1,3;Power level]".. - "label[4,0;Production at "..tostring(production_level).."%]" - ) + local load = 1 -- math.floor((charge/max_charge)*100) + meta:set_string("formspec", + "invsize[8,4;]".. + "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. + (load)..":technic_power_meter_fg.png]".. + "label[0,0;Water Mill]".. + "label[1,3;Power level]".. + "label[4,0;Production at "..tostring(production_level).."%]" + ) - if production_level>0 and minetest.env:get_node(pos).name=="technic:water_mill" then - hacky_swap_node (pos,"technic:water_mill_active") - return - end - if production_level==0 then hacky_swap_node (pos,"technic:water_mill") end -end -}) + if production_level>0 and minetest.env:get_node(pos).name=="technic:water_mill" then + hacky_swap_node (pos,"technic:water_mill_active") + meta:set_int("LV_EU_supply", 0) + return + end + if production_level==0 then hacky_swap_node (pos,"technic:water_mill") end + end + }) -function check_node_around_mill (pos) -local node=minetest.env:get_node(pos) -if node.name=="default:water_flowing" then return 1 end -return 0 -end - -register_LV_machine ("technic:water_mill","PR") -register_LV_machine ("technic:water_mill_active","PR") +technic.register_LV_machine ("technic:water_mill","PR") +technic.register_LV_machine ("technic:water_mill_active","PR") From 7201aeb6ba1b63afd95b23b44843acb6985f0ad4 Mon Sep 17 00:00:00 2001 From: kpoppel Date: Tue, 2 Jul 2013 22:26:45 +0200 Subject: [PATCH 46/57] Removed down_converters as they are superseeded by the new supply converter. --- technic/down_converter_hv.lua | 225 --------------------------------- technic/down_converter_mv.lua | 226 ---------------------------------- 2 files changed, 451 deletions(-) delete mode 100644 technic/down_converter_hv.lua delete mode 100644 technic/down_converter_mv.lua diff --git a/technic/down_converter_hv.lua b/technic/down_converter_hv.lua deleted file mode 100644 index 0e2e16d..0000000 --- a/technic/down_converter_hv.lua +++ /dev/null @@ -1,225 +0,0 @@ --- The HV down converter will step down HV EUs to MV EUs --- If we take the solar panel as calibration then the --- 1 HVEU = 5 MVEU as we stack 5 MV arrays to get a HV array. --- The downconverter does of course have a conversion loss. --- This loses 30% of the power. --- The converter does not store any energy by itself. -minetest.register_node("technic:down_converter_hv", { - description = "HV Down Converter", - tiles = {"technic_hv_down_converter_top.png", "technic_hv_down_converter_bottom.png", "technic_hv_down_converter_side.png", - "technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png"}, - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - sounds = default.node_sound_wood_defaults(), - drawtype = "nodebox", - paramtype = "light", - is_ground_content = true, - node_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_float("technic_hv_power_machine", 1) - meta:set_float("technic_mv_power_machine", 1) - meta:set_float("internal_EU_buffer",0) - meta:set_float("internal_EU_buffer_size",0) - meta:set_string("infotext", "HV Down Converter") - meta:set_float("active", false) - end, - }) - -minetest.register_craft({ - output = 'technic:down_converter_hv 1', - recipe = { - {'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot','technic:stainless_steel_ingot'}, - {'technic:hv_transformer', 'technic:hv_cable', 'technic:mv_transformer'}, - {'technic:hv_cable', 'technic:rubber', 'technic:mv_cable'}, - } -}) - -minetest.register_abm( - {nodenames = {"technic:down_converter_hv"}, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - -- HV->MV conversion factor - local hv_mv_factor = 5 - -- The maximun charge a single converter can handle. Let's set this to - -- what 5 HV solar arrays can produce - 30% loss (2880*5*0.7) - local max_charge = 10080*hv_mv_factor - - local meta = minetest.env:get_meta(pos) - local meta1 = nil - local pos1 = {} - local available_charge = 0 -- counted in MV units - local used_charge = 0 -- counted in MV units - - -- Index all HV nodes connected to the network - -- HV cable comes in through the bottom - pos1.y = pos.y-1 - pos1.x = pos.x - pos1.z = pos.z - meta1 = minetest.env:get_meta(pos1) - if meta1:get_float("hv_cablelike")~=1 then return end - - local HV_nodes = {} -- HV type - local HV_PR_nodes = {} -- HV type - local HV_BA_nodes = {} -- HV type - - HV_nodes[1] = {} - HV_nodes[1].x = pos1.x - HV_nodes[1].y = pos1.y - HV_nodes[1].z = pos1.z - - local table_index = 1 - repeat - check_HV_node(HV_PR_nodes,nil,HV_BA_nodes,HV_nodes,table_index) - table_index = table_index + 1 - if HV_nodes[table_index] == nil then break end - until false - - --print("HV_nodes: PR="..table.getn(HV_PR_nodes).." BA="..table.getn(HV_BA_nodes)) - - -- Index all MV nodes connected to the network - -- MV cable comes out of the top - pos1.y = pos.y+1 - pos1.x = pos.x - pos1.z = pos.z - meta1 = minetest.env:get_meta(pos1) - if meta1:get_float("mv_cablelike")~=1 then return end - - local MV_nodes = {} -- MV type - local MV_RE_nodes = {} -- MV type - local MV_BA_nodes = {} -- MV type - - MV_nodes[1] = {} - MV_nodes[1].x = pos1.x - MV_nodes[1].y = pos1.y - MV_nodes[1].z = pos1.z - - table_index = 1 - repeat - check_MV_node(nil,MV_RE_nodes,MV_BA_nodes,MV_nodes,table_index) - table_index = table_index + 1 - if MV_nodes[table_index] == nil then break end - until false - - --print("MV_nodes: RE="..table.getn(MV_RE_nodes).." BA="..table.getn(MV_BA_nodes)) - - -- First get available power from all the attached HV suppliers - -- Get the supplier internal EU buffer and read the EUs from it - -- No update yet! - local pos1 --- FIXME: Until further leave the producers out of it and just let the batteries be the hub --- for _,pos1 in ipairs(HV_PR_nodes) do --- meta1 = minetest.env:get_meta(pos1) --- local internal_EU_buffer = meta1:get_float("internal_EU_buffer") --- available_charge = available_charge + meta1:get_float("internal_EU_buffer") * hv_mv_factor --- -- Limit conversion capacity --- if available_charge > max_charge then --- available_charge = max_charge --- break --- end --- end --- --print("Available_charge PR:"..available_charge) - - for _,pos1 in ipairs(HV_BA_nodes) do - meta1 = minetest.env:get_meta(pos1) - local internal_EU_buffer = meta1:get_float("internal_EU_buffer") - available_charge = available_charge + meta1:get_float("internal_EU_buffer") * hv_mv_factor - -- Limit conversion capacity - if available_charge > max_charge then - available_charge = max_charge - break - end - end - --print("Available_charge PR+BA:"..available_charge) - - -- Calculate total number of receivers: - local MV_receivers = table.getn(MV_RE_nodes)+table.getn(MV_BA_nodes) - - -- Next supply power to all connected MV machines - -- Get the power receiver internal EU buffer and give EUs to it - -- Note: for now leave out RE type machines until producers distribute power themselves even without a battery --- for _,pos1 in ipairs(MV_RE_nodes) do --- local meta1 = minetest.env:get_meta(pos1) --- local internal_EU_buffer = meta1:get_float("internal_EU_buffer") --- local internal_EU_buffer_size = meta1:get_float("internal_EU_buffer_size") --- local charge_to_give = math.min(4000, available_charge/MV_receivers) -- power rating limit on the MV wire --- -- How much can this unit take? --- if internal_EU_buffer+charge_to_give > internal_EU_buffer_size then --- charge_to_give=internal_EU_buffer_size-internal_EU_buffer --- end --- -- If we are emptying the supply take the remainder --- if available_charge internal_EU_buffer_size then - charge_to_give=internal_EU_buffer_size-internal_EU_buffer - end - --print("charge_to_give2:"..charge_to_give) - -- If we are emptying the supply take the remainder - if available_charge 0 then - internal_EU_buffer = internal_EU_buffer-charge_to_take - meta1:set_float("internal_EU_buffer",internal_EU_buffer) - end - end - - if used_charge>0 then - meta:set_string("infotext", "HV Down Converter is active (HV:"..available_charge.."/MV:"..used_charge..")"); - meta:set_float("active",1) -- used for setting textures someday maybe - else - meta:set_string("infotext", "HV Down Converter is inactive (HV:"..available_charge.."/MV:"..used_charge..")"); - meta:set_float("active",0) -- used for setting textures someday maybe - return - end - end, -}) - --- This machine does not store energy it receives energy from the HV side and outputs it on the MV side -register_HV_machine ("technic:down_converter_hv","RE") -register_MV_machine ("technic:down_converter_hv","PR") diff --git a/technic/down_converter_mv.lua b/technic/down_converter_mv.lua deleted file mode 100644 index 1d26630..0000000 --- a/technic/down_converter_mv.lua +++ /dev/null @@ -1,226 +0,0 @@ --- The MV down converter will step down MV EUs to LV EUs --- If we take the solar panel as calibration then the --- 1 MVEU = 5 LVEU as we stack 5 LV arrays to get an MV array. --- The downconverter does of course have a conversion loss. --- This loses 30% of the power. --- The converter does not store any energy by itself. -minetest.register_node( - "technic:down_converter_mv", { - description = "MV Down Converter", - tiles = {"technic_mv_down_converter_top.png", "technic_mv_down_converter_bottom.png", "technic_mv_down_converter_side.png", - "technic_mv_down_converter_side.png", "technic_mv_down_converter_side.png", "technic_mv_down_converter_side.png"}, - groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - sounds = default.node_sound_wood_defaults(), - drawtype = "nodebox", - paramtype = "light", - is_ground_content = true, - node_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, - }, - on_construct = function(pos) - local meta = minetest.env:get_meta(pos) - meta:set_float("technic_mv_power_machine", 1) - meta:set_float("technic_power_machine", 1) - meta:set_float("internal_EU_buffer",0) - meta:set_float("internal_EU_buffer_size",0) - meta:set_string("infotext", "MV Down Converter") - meta:set_float("active", false) - end, - }) - -minetest.register_craft({ - output = 'technic:down_converter_mv 1', - recipe = { - {'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot','technic:stainless_steel_ingot'}, - {'technic:mv_transformer', 'technic:mv_cable', 'technic:lv_transformer'}, - {'technic:mv_cable', 'technic:rubber', 'technic:lv_cable'}, - } -}) - -minetest.register_abm( - {nodenames = {"technic:down_converter_mv"}, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - -- MV->LV conversion factor - local mv_lv_factor = 5 - -- The maximun charge a single converter can handle. Let's set this to - -- what 5 MV solar arrays can produce - 30% loss (720*5*0.7) - local max_charge = 2520*mv_lv_factor - - local meta = minetest.env:get_meta(pos) - local meta1 = nil - local pos1 = {} - local available_charge = 0 -- counted in LV units - local used_charge = 0 -- counted in LV units - - -- Index all MV nodes connected to the network - -- MV cable comes in through the bottom - pos1.y = pos.y-1 - pos1.x = pos.x - pos1.z = pos.z - meta1 = minetest.env:get_meta(pos1) - if meta1:get_float("mv_cablelike")~=1 then return end - - local MV_nodes = {} -- MV type - local MV_PR_nodes = {} -- MV type - local MV_BA_nodes = {} -- MV type - - MV_nodes[1] = {} - MV_nodes[1].x = pos1.x - MV_nodes[1].y = pos1.y - MV_nodes[1].z = pos1.z - - local table_index = 1 - repeat - check_MV_node(MV_PR_nodes,nil,MV_BA_nodes,MV_nodes,table_index) - table_index = table_index + 1 - if MV_nodes[table_index] == nil then break end - until false - - --print("MV_nodes: PR="..table.getn(MV_PR_nodes).." BA="..table.getn(MV_BA_nodes)) - - -- Index all LV nodes connected to the network - -- LV cable comes out of the top - pos1.y = pos.y+1 - pos1.x = pos.x - pos1.z = pos.z - meta1 = minetest.env:get_meta(pos1) - if meta1:get_float("cablelike")~=1 then return end - - local LV_nodes = {} -- LV type - local LV_RE_nodes = {} -- LV type - local LV_BA_nodes = {} -- LV type - - LV_nodes[1] = {} - LV_nodes[1].x = pos1.x - LV_nodes[1].y = pos1.y - LV_nodes[1].z = pos1.z - - table_index = 1 - repeat - check_LV_node(nil,LV_RE_nodes,LV_BA_nodes,LV_nodes,table_index) - table_index = table_index + 1 - if LV_nodes[table_index] == nil then break end - until false - - --print("LV_nodes: RE="..table.getn(LV_RE_nodes).." BA="..table.getn(LV_BA_nodes)) - - -- First get available power from all the attached MV suppliers - -- Get the supplier internal EU buffer and read the EUs from it - -- No update yet! - local pos1 --- FIXME: Until further leave the producers out of it and just let the batteries be the hub --- for _,pos1 in ipairs(MV_PR_nodes) do --- meta1 = minetest.env:get_meta(pos1) --- local internal_EU_buffer = meta1:get_float("internal_EU_buffer") --- available_charge = available_charge + meta1:get_float("internal_EU_buffer") * mv_lv_factor --- -- Limit conversion capacity --- if available_charge > max_charge then --- available_charge = max_charge --- break --- end --- end --- print("Available_charge PR:"..available_charge) - - for _,pos1 in ipairs(MV_BA_nodes) do - meta1 = minetest.env:get_meta(pos1) - local internal_EU_buffer = meta1:get_float("internal_EU_buffer") - available_charge = available_charge + meta1:get_float("internal_EU_buffer") * mv_lv_factor - -- Limit conversion capacity - if available_charge > max_charge then - available_charge = max_charge - break - end - end - --print("Available_charge PR+BA:"..available_charge) - - -- Calculate total number of receivers: - local LV_receivers = table.getn(LV_RE_nodes)+table.getn(LV_BA_nodes) - - -- Next supply power to all connected LV machines - -- Get the power receiver internal EU buffer and give EUs to it - -- Note: for now leave out RE type machines until producers distribute power themselves even without a battery --- for _,pos1 in ipairs(LV_RE_nodes) do --- local meta1 = minetest.env:get_meta(pos1) --- local internal_EU_buffer = meta1:get_float("internal_EU_buffer") --- local internal_EU_buffer_size = meta1:get_float("internal_EU_buffer_size") --- local charge_to_give = math.min(1000, available_charge/LV_receivers) -- power rating limit on the LV wire --- -- How much can this unit take? --- if internal_EU_buffer+charge_to_give > internal_EU_buffer_size then --- charge_to_give=internal_EU_buffer_size-internal_EU_buffer --- end --- -- If we are emptying the supply take the remainder --- if available_charge internal_EU_buffer_size then - charge_to_give=internal_EU_buffer_size-internal_EU_buffer - end - --print("charge_to_give2:"..charge_to_give) - -- If we are emptying the supply take the remainder - if available_charge 0 then - internal_EU_buffer = internal_EU_buffer-charge_to_take - meta1:set_float("internal_EU_buffer",internal_EU_buffer) - end - end - - if used_charge>0 then - meta:set_string("infotext", "MV Down Converter is active (MV:"..available_charge.."/LV:"..used_charge..")"); - meta:set_float("active",1) -- used for setting textures someday maybe - else - meta:set_string("infotext", "MV Down Converter is inactive (MV:"..available_charge.."/LV:"..used_charge..")"); - meta:set_float("active",0) -- used for setting textures someday maybe - return - end - end, -}) - --- This machine does not store energy it receives energy from the MV side and outputs it on the LV side -register_MV_machine ("technic:down_converter_mv","RE") -register_LV_machine ("technic:down_converter_mv","PR") From c7207a9cba3293935811baf107be2edbead02943 Mon Sep 17 00:00:00 2001 From: kpoppel Date: Tue, 2 Jul 2013 22:45:08 +0200 Subject: [PATCH 47/57] Silenced the power radiator. --- technic/power_radiator.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/technic/power_radiator.lua b/technic/power_radiator.lua index 383bf87..9a4c84a 100644 --- a/technic/power_radiator.lua +++ b/technic/power_radiator.lua @@ -178,7 +178,7 @@ minetest.register_abm( elseif meta1:get_string("has_supply") == pos.x..pos.y..pos.z then -- The appliance has power from this node. Spend power if it is on. used_charge = math.floor(used_charge+meta1:get_int("EU_charge")/eff_factor) - print("My Lamp ("..pos.x..","..pos.y..","..pos.z..") Used:"..used_charge) + --print("My Lamp ("..pos.x..","..pos.y..","..pos.z..") Used:"..used_charge) end meta:set_string("infotext", "Power Radiator is powered ("..math.floor(used_charge/max_charge*100).."% of maximum power)"); if used_charge == 0 then From ce5dfa311ebc1347e11721c21a83b808a5bbccbd Mon Sep 17 00:00:00 2001 From: m97 Date: Thu, 4 Jul 2013 19:05:00 +0200 Subject: [PATCH 48/57] Add extractor. Add extractor for make more rubber from latex. Moved make dyes from grinder to extractor. --- technic/extractor.lua | 212 ++++++++++++++++++++++++++++++++++++++ technic/grinder.lua | 9 -- technic/init.lua | 1 + unified_inventory/api.lua | 7 +- 4 files changed, 218 insertions(+), 11 deletions(-) create mode 100644 technic/extractor.lua diff --git a/technic/extractor.lua b/technic/extractor.lua new file mode 100644 index 0000000..92ccdd5 --- /dev/null +++ b/technic/extractor.lua @@ -0,0 +1,212 @@ +technic.extractor_recipes ={} + +technic.register_extractor_recipe = function(src, dst) + technic.extractor_recipes[src] = dst + if unified_inventory then + unified_inventory.register_craft( + { + type = "extracting", + output = dst, + items = {src}, + width = 0, + }) + end + end + +-- Receive an ItemStack of result by an ItemStack input +technic.get_extractor_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.extractor_recipes[item_name] then + return ItemStack(technic.extractor_recipes[item_name]) + else + return nil + end + end + + + +technic.register_extractor_recipe("technic:coal_dust","dye:black 2") +technic.register_extractor_recipe("default:cactus","dye:green 2") +technic.register_extractor_recipe("default:dry_shrub","dye:brown 2") +technic.register_extractor_recipe("flowers:geranium","dye:blue 2") +technic.register_extractor_recipe("flowers:dandelion_white","dye:white 2") +technic.register_extractor_recipe("flowers:dandelion_yellow","dye:yellow 2") +technic.register_extractor_recipe("flowers:tulip","dye:orange 2") +technic.register_extractor_recipe("flowers:rose","dye:red 2") +technic.register_extractor_recipe("flowers:viola","dye:violet 2") +technic.register_extractor_recipe("technic:raw_latex","technic:rubber 3") +technic.register_extractor_recipe("moretrees:rubber_tree_trunk_empty","technic:rubber 1") +technic.register_extractor_recipe("moretrees:rubber_tree_trunk","technic:rubber 1") + +minetest.register_alias("extractor", "technic:extractor") +minetest.register_craft({ + output = 'technic:extractor', + recipe = { + {'technic:treetap', 'technic:motor', 'technic:treetap'}, + {'technic:treetap', 'technic:lv_cable', 'technic:treetap'}, + {'','',''}, + } + }) + +minetest.register_craftitem("technic:extractor", { + description = "Extractor", + stack_max = 99, + }) + +local extractor_formspec = + "invsize[8,9;]".. + "label[0,0;Extractor]".. + "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:extractor", + { + description = "Extractor", + 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", "Extractor") + meta:set_float("technic_power_machine", 1) + meta:set_string("formspec", extractor_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:extractor_active", + { + description = "Extractor", + 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_abm( + { nodenames = {"technic:extractor","technic:extractor_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 = "Extractor" + local machine_node = "technic:extractor" + 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_extractor_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_extractor_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:extractor","RE") +technic.register_LV_machine ("technic:extractor_active","RE") + diff --git a/technic/grinder.lua b/technic/grinder.lua index 8b41184..ba78710 100644 --- a/technic/grinder.lua +++ b/technic/grinder.lua @@ -53,15 +53,6 @@ technic.register_grinder_recipe("technic:stainless_steel_ingot","stainless_steel 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") -technic.register_grinder_recipe("technic:coal_dust","dye:black 2") -technic.register_grinder_recipe("default:cactus","dye:green 2") -technic.register_grinder_recipe("default:dry_shrub","dye:brown 2") -technic.register_grinder_recipe("flowers:flower_geranium","dye:blue 2") -technic.register_grinder_recipe("flowers:flower_dandelion_white","dye:white 2") -technic.register_grinder_recipe("flowers:flower_dandelion_yellow","dye:yellow 2") -technic.register_grinder_recipe("flowers:flower_tulip","dye:orange 2") -technic.register_grinder_recipe("flowers:flower_rose","dye:red 2") -technic.register_grinder_recipe("flowers:flower_viola","dye:violet 2") minetest.register_craftitem( "technic:coal_dust", { description = "Coal Dust", diff --git a/technic/init.lua b/technic/init.lua index abe0439..263b6b9 100644 --- a/technic/init.lua +++ b/technic/init.lua @@ -44,6 +44,7 @@ dofile(modpath.."/grinder.lua") dofile(modpath.."/cnc.lua") dofile(modpath.."/cnc_api.lua") dofile(modpath.."/cnc_nodes.lua") +dofile(modpath.."/extractor.lua") --MV machines dofile(modpath.."/wires_mv.lua") diff --git a/unified_inventory/api.lua b/unified_inventory/api.lua index 02c08e9..91681b1 100644 --- a/unified_inventory/api.lua +++ b/unified_inventory/api.lua @@ -230,7 +230,10 @@ unified_inventory.get_formspec = function(player,page) end if craft.type == "alloy" then method="Alloy cooking" - end + end + if craft.type == "extracting" then + method="Extracting" + end formspec = formspec.."label[6,3;"..method.."]" end @@ -558,7 +561,7 @@ unified_inventory.update_recipe = function(player, stack_name, 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 def=unified_inventory.find_item_def(craft["items"][1]) if def then inv:set_stack("build", 1, def) From 6e4ffb48831c8c275b450840830ed835a24d18a5 Mon Sep 17 00:00:00 2001 From: kpoppel Date: Thu, 4 Jul 2013 19:19:45 +0200 Subject: [PATCH 49/57] Fix item wear. --- technic/flashlight.lua | 2 +- technic/sonic_screwdriver.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/technic/flashlight.lua b/technic/flashlight.lua index dd36c31..5f3ea96 100644 --- a/technic/flashlight.lua +++ b/technic/flashlight.lua @@ -161,7 +161,7 @@ local hotbar=inv:get_list("main") charge=meta["charge"] if charge-2>0 then charge =charge-2; - set_RE_wear(item,charge,flashlight_max_charge) + technic.set_RE_wear(item,charge,flashlight_max_charge) meta["charge"]=charge item["metadata"]=set_item_meta(meta) hotbar[i]:replace(item) diff --git a/technic/sonic_screwdriver.lua b/technic/sonic_screwdriver.lua index 1453862..00922f7 100644 --- a/technic/sonic_screwdriver.lua +++ b/technic/sonic_screwdriver.lua @@ -38,7 +38,7 @@ minetest.register_tool("technic:sonic_screwdriver", { charge=charge-100; meta1["charge"]=charge item["metadata"]=set_item_meta(meta1) - set_RE_wear(item,charge,sonic_screwdriver_max_charge) + technic.set_RE_wear(item,charge,sonic_screwdriver_max_charge) itemstack:replace(item) end return itemstack From 9770be430d04c18f1a2db2bfd5b1ef6e02de92e3 Mon Sep 17 00:00:00 2001 From: kpoppel Date: Thu, 4 Jul 2013 20:29:38 +0200 Subject: [PATCH 50/57] Textures. I really need help on some nice ones. --- technic/power_radiator.lua | 4 ++-- technic/supply_converter.lua | 6 +++--- technic/switching_station.lua | 4 ++-- .../textures/technic_hv_down_converter_bottom.png | Bin 653 -> 0 bytes .../textures/technic_hv_down_converter_side.png | Bin 609 -> 0 bytes .../textures/technic_hv_down_converter_top.png | Bin 653 -> 0 bytes ...om.png => technic_supply_converter_bottom.png} | Bin ...side.png => technic_supply_converter_side.png} | Bin ...r_top.png => technic_supply_converter_top.png} | Bin 9 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 technic/textures/technic_hv_down_converter_bottom.png delete mode 100644 technic/textures/technic_hv_down_converter_side.png delete mode 100644 technic/textures/technic_hv_down_converter_top.png rename technic/textures/{technic_mv_down_converter_bottom.png => technic_supply_converter_bottom.png} (100%) rename technic/textures/{technic_mv_down_converter_side.png => technic_supply_converter_side.png} (100%) rename technic/textures/{technic_mv_down_converter_top.png => technic_supply_converter_top.png} (100%) diff --git a/technic/power_radiator.lua b/technic/power_radiator.lua index 9a4c84a..8b0666a 100644 --- a/technic/power_radiator.lua +++ b/technic/power_radiator.lua @@ -87,8 +87,8 @@ local shutdown_inductive_appliances = function(pos) minetest.register_node( "technic:power_radiator", { description = "Power Radiator", - tiles = {"technic_hv_down_converter_top.png", "technic_hv_down_converter_bottom.png", "technic_hv_down_converter_side.png", - "technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png", "technic_hv_down_converter_side.png"}, + tiles = {"technic_lv_cable.png", "technic_lv_cable.png", "technic_lv_cable.png", + "technic_lv_cable.png", "technic_lv_cable.png", "technic_lv_cable.png"}, groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, sounds = default.node_sound_wood_defaults(), drawtype = "nodebox", diff --git a/technic/supply_converter.lua b/technic/supply_converter.lua index 5e04d42..d0714e7 100644 --- a/technic/supply_converter.lua +++ b/technic/supply_converter.lua @@ -14,8 +14,8 @@ minetest.register_node( "technic:supply_converter", { description = "Supply Converter", - tiles = {"technic_mv_down_converter_top.png", "technic_mv_down_converter_bottom.png", "technic_mv_down_converter_side.png", - "technic_mv_down_converter_side.png", "technic_mv_down_converter_side.png", "technic_mv_down_converter_side.png"}, + tiles = {"technic_supply_converter_top.png", "technic_supply_converter_bottom.png", "technic_supply_converter_side.png", + "technic_supply_converter_side.png", "technic_supply_converter_side.png", "technic_supply_converter_side.png"}, groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, sounds = default.node_sound_wood_defaults(), drawtype = "nodebox", @@ -58,7 +58,7 @@ minetest.register_abm( local mv_lv_factor = 4 -- multiplication (higher is more efficient) local mv_hv_factor = 5 -- division local hv_mv_factor = 4 -- multiplication - local max_lv_demand = 2000 -- The increment size pwer supply tier. Determines how many are needed + local max_lv_demand = 2000 -- The increment size power supply tier. Determines how many are needed local max_mv_demand = 2000 -- -""- local max_hv_demand = 2000 -- -""- diff --git a/technic/switching_station.lua b/technic/switching_station.lua index 7919d5e..36133fa 100644 --- a/technic/switching_station.lua +++ b/technic/switching_station.lua @@ -43,8 +43,8 @@ minetest.register_craft( minetest.register_node( "technic:switching_station", {description = "Switching Station", - tiles = {"technic_mv_down_converter_top.png", "technic_mv_down_converter_bottom.png", "technic_mv_down_converter_side.png", - "technic_mv_down_converter_side.png", "technic_mv_down_converter_side.png", "technic_mv_down_converter_side.png"}, + tiles = {"technic_water_mill_top_active.png", "technic_water_mill_top_active.png", "technic_water_mill_top_active.png", + "technic_water_mill_top_active.png", "technic_water_mill_top_active.png", "technic_water_mill_top_active.png"}, groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, sounds = default.node_sound_wood_defaults(), drawtype = "nodebox", diff --git a/technic/textures/technic_hv_down_converter_bottom.png b/technic/textures/technic_hv_down_converter_bottom.png deleted file mode 100644 index 996b2d4cfdcd63908ee512b0f2165c090f861e7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 653 zcmV;80&@L{P)(7T;J|G13}rY z@Tm0bALX;xpEoohhzV*+SA!`%6I7rIR1pK?~cCg+;Y-8Ps>%tTzdJjrt+Cgd69y9@8?Wz>6W zmn7eP`URy+a}9{PuoAw1^9$@oK4KXRI91TgNE$kdM@)YF>1Td>^E?KfYu zkBxWNNu2>Ibc3TxXDySe;pQAq2iG-;83aN6@h5Rj#0&yNp|j{Llv*|Dndt7=Z6IA- zbMoPt8wL1gu#_Sy*zTwdTXBid)#PI`GdONLw|&Rmd3ip_nq(FLx;f%2B_|7e+No-E zCOwq<-~aH{>o3{2XIzBswsZaaA2H)&8@ro|!bOD!%mh0&#&CY9Ul9ZzP+8Ppg$?8B zY7E|6H(!RloeW7z^+p=00000NkvXXu0mjfouVKV diff --git a/technic/textures/technic_hv_down_converter_side.png b/technic/textures/technic_hv_down_converter_side.png deleted file mode 100644 index ab904f1c14f4d6c5c1e001499032a330684b44ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 609 zcmV-n0-pVeP)sj50q#je zK~y-)b(249R6!KQfA`*b@8u6<30ub{iU^8==~oQc=2KXRU%=9Upr1ml{RCDP%9a*Z zHWr38LaGoph3@WqbFalD>zc5)nK>}`%*;9G%FSoPfB*zBK}`t{FeTayD&P*PhzgM% z1fq4MG7`m;f+28gW^@-Qi+CIT|gnAc!fp zR-s}FPLbhC<1*PYw#^!?44-wR@F+qFJUQE=+fWWq4>&%1a7}|ZKi)%QPT)%d)_XC0^z0g5V-9d9!}??6`eBW7h)i0njm6fZG|Hlt0#)~b~RsV)Q& zASzgsP^pZFKtu=+^0Zw^kaPK-)(J_5sF28xtv9#_pZZ^~<)GIeGC3c?Iqa`P@9vO? zqcb7`?;I5s0#K8S=6`-)#g|q_o5{cD#YWGLbdGG)3!hi{zX;OLQ?xR&2O2pbg2?{g z&CBV#`T|su+ECLnOnBh)j{6@@@OGEiTT4OOx(w0*hacbJ?QJ6eK~tGpx%K=}h?PlOWI>Z#Y$cHwGJZ*_C5EcFcr*Zx28Y`Dj00000NkvXXu0mjfvhV^= diff --git a/technic/textures/technic_hv_down_converter_top.png b/technic/textures/technic_hv_down_converter_top.png deleted file mode 100644 index 996b2d4cfdcd63908ee512b0f2165c090f861e7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 653 zcmV;80&@L{P)(7T;J|G13}rY z@Tm0bALX;xpEoohhzV*+SA!`%6I7rIR1pK?~cCg+;Y-8Ps>%tTzdJjrt+Cgd69y9@8?Wz>6W zmn7eP`URy+a}9{PuoAw1^9$@oK4KXRI91TgNE$kdM@)YF>1Td>^E?KfYu zkBxWNNu2>Ibc3TxXDySe;pQAq2iG-;83aN6@h5Rj#0&yNp|j{Llv*|Dndt7=Z6IA- zbMoPt8wL1gu#_Sy*zTwdTXBid)#PI`GdONLw|&Rmd3ip_nq(FLx;f%2B_|7e+No-E zCOwq<-~aH{>o3{2XIzBswsZaaA2H)&8@ro|!bOD!%mh0&#&CY9Ul9ZzP+8Ppg$?8B zY7E|6H(!RloeW7z^+p=00000NkvXXu0mjfouVKV diff --git a/technic/textures/technic_mv_down_converter_bottom.png b/technic/textures/technic_supply_converter_bottom.png similarity index 100% rename from technic/textures/technic_mv_down_converter_bottom.png rename to technic/textures/technic_supply_converter_bottom.png diff --git a/technic/textures/technic_mv_down_converter_side.png b/technic/textures/technic_supply_converter_side.png similarity index 100% rename from technic/textures/technic_mv_down_converter_side.png rename to technic/textures/technic_supply_converter_side.png diff --git a/technic/textures/technic_mv_down_converter_top.png b/technic/textures/technic_supply_converter_top.png similarity index 100% rename from technic/textures/technic_mv_down_converter_top.png rename to technic/textures/technic_supply_converter_top.png From 9a0d3f216619b84dd818aff94efb6738de9b7622 Mon Sep 17 00:00:00 2001 From: kpoppel Date: Thu, 4 Jul 2013 21:33:27 +0200 Subject: [PATCH 51/57] Forcefield now working with updated power scheme. --- README.md | 5 +- technic/forcefield.lua | 196 ++++++++++++++++++++++------------------- technic/init.lua | 2 +- 3 files changed, 109 insertions(+), 94 deletions(-) diff --git a/README.md b/README.md index e93dd50..abec467 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ -technic 0.4.6 +technic 0.4.7 -Technic mod for Minetest 0.4.6 +Technic mod for Minetest 0.4.7 Credits for contributing to the project: Nekogloop ShadowNinja VanessaE Nore/Novatux +kpoppel And many others for ideas/inspiring Licences: diff --git a/technic/forcefield.lua b/technic/forcefield.lua index 8af98f4..98201e8 100644 --- a/technic/forcefield.lua +++ b/technic/forcefield.lua @@ -1,7 +1,9 @@ ---Forcefield mod by ShadowNinja +-- Forcefield mod by ShadowNinja +-- Modified by kpoppel +-- +-- Forcefields are powerful barriers but they consume huge amounts of power. +-- Forcefield Generator is a HV machine. -local forcefield_emitter_buffer_size = 10000 -local forcefield_emitter_power_consumption = 0.8 local forcefield_update_interval = 1 minetest.register_craft({ @@ -13,22 +15,13 @@ minetest.register_craft({ } }) -local function get_forcefield_count(range) - local count = 0 - for x=-range,range do - for y=-range,range do - for z=-range,range do - if ((x*x+y*y+z*z) <= (range * range + range)) then - if (y == 0) or ((range-1) * (range-1) + (range-1) <= x*x+y*y+z*z) then - count = count + 1 - end - end - end - end - end - return count -end - +-- Idea: Let forcefields have different colors by upgrade slot. +-- Idea: Let forcefields add up by detecting if one hits another. +-- ___ __ +-- / \/ \ +-- | | +-- \___/\___/ +-- local function add_forcefield(pos, range) for x=-range,range do for y=-range,range do @@ -66,69 +59,90 @@ local function remove_forcefield(p, range) end end -local forcefield_receive_fields = function(pos, formname, fields, sender) - local meta = minetest.env:get_meta(pos) - local range = meta:get_int("range") - if fields.add then range = range + 1 end - if fields.subtract then range = range - 1 end - if fields.toggle then - if meta:get_int("enabled") == 1 then - meta:set_int("enabled", 0) - else - meta:set_int("enabled", 1) - end - end - if range <= 20 and range >= 0 and meta:get_int("range") ~= range then - remove_forcefield(pos, meta:get_int("range")) - meta:set_int("range", range) - local buffer = meta:get_float("internal_EU_buffer") - local buffer_size = meta:get_float("internal_EU_buffer_size") - local load = math.floor(buffer / buffer_size * 100) - meta:set_string("formspec", get_forcefield_formspec(range, 0)) - end +local get_forcefield_formspec = function(range) + -- return "invsize[8,9;]".. (if upgrades added later - colors for instance) + return "invsize[3,4;]".. + "label[0,0;Forcefield emitter]".. + "label[1,1;Range]".. + "label[1,2;"..range.."]".. + "button[0,2;1,1;subtract;-]".. + "button[2,2;1,1;add;+]".. + "button[0,3;3,1;toggle;Enable/Disable]" -- .. +-- "list[current_player;main;0,5;8,4;]" end -local get_forcefield_formspec = function(range, load) - if not load then load = 0 end - return "invsize[8,9;]".. - "label[0,0;Forcefield emitter]".. - "label[1,3;Power level]".. - "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:".. - load..":technic_power_meter_fg.png]".. - "label[4,1;Range]".. - "label[4,2;"..range.."]".. - "button[3,2;1,1;add;+]".. - "button[5,2;1,1;subtract;-]".. - "button[3,3;3,1;toggle;Enable/Disable]".. - "list[current_player;main;0,5;8,4;]" -end +local forcefield_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.env:get_meta(pos) + local range = meta:get_int("range") + if fields.add then range = range + 1 end + if fields.subtract then range = range - 1 end + if fields.toggle then + if meta:get_int("enabled") == 1 then + meta:set_int("enabled", 0) + else + meta:set_int("enabled", 1) + end + end + -- Smallest field is 5. Anything less is asking for trouble. + -- Largest is 20. It is a matter of pratical node handling. + if range < 5 then range = 5 end + if range > 20 then range = 20 end + + if range <= 20 and range >= 5 and meta:get_int("range") ~= range then + remove_forcefield(pos, meta:get_int("range")) + meta:set_int("range", range) + meta:set_string("formspec", get_forcefield_formspec(range)) + end + end local forcefield_check = function(pos) - local meta = minetest.env:get_meta(pos) - local node = minetest.env:get_node(pos) - local internal_EU_buffer=meta:get_float("internal_EU_buffer") - local internal_EU_buffer_size=meta:get_float("internal_EU_buffer_size") + local meta = minetest.env:get_meta(pos) + local node = minetest.env:get_node(pos) + local eu_input = meta:get_int("HV_EU_input") + local eu_demand = meta:get_int("HV_EU_demand") + local enabled = meta:get_int("enabled") + + -- Power off automatically if no longer connected to a switching station + technic.switching_station_timeout_count(pos, "HV") - local load = math.floor(internal_EU_buffer/internal_EU_buffer_size * 100) - meta:set_string("formspec", get_forcefield_formspec(meta:get_int("range"), load)) + local power_requirement + if enabled == 1 then + power_requirement = math.floor(4*math.pi*math.pow(meta:get_int("range"), 2)) * 1 + else + power_requirement = eu_demand + end - local power_requirement = get_forcefield_count(meta:get_int("range")) * forcefield_emitter_power_consumption - if meta:get_int("enabled") == 1 and internal_EU_buffer >= power_requirement then - if node.name == "technic:forcefield_emitter_off" then - hacky_swap_node(pos, "technic:forcefield_emitter_on") - end - internal_EU_buffer=internal_EU_buffer-power_requirement; - meta:set_float("internal_EU_buffer", internal_EU_buffer) - add_forcefield(pos, meta:get_int("range")) - else - if node.name == "technic:forcefield_emitter_on" then - remove_forcefield(pos, meta:get_int("range")) - hacky_swap_node(pos, "technic:forcefield_emitter_off") - end - end - return true - -end + if eu_input == 0 then + meta:set_string("infotext", "Forcefield Generator Unpowered") + meta:set_int("HV_EU_demand", 100) + if node.name == "technic:forcefield_emitter_on" then + remove_forcefield(pos, meta:get_int("range")) + hacky_swap_node(pos, "technic:forcefield_emitter_off") + meta:set_int("enabled", 0) + end + elseif eu_input == power_requirement then + if meta:get_int("enabled") == 1 then + if node.name == "technic:forcefield_emitter_off" then + hacky_swap_node(pos, "technic:forcefield_emitter_on") + meta:set_string("infotext", "Forcefield Generator Active") + add_forcefield(pos, meta:get_int("range")) + else + -- Range updated. Move the forcefield. + add_forcefield(pos, meta:get_int("range")) + end + else + if node.name == "technic:forcefield_emitter_on" then + remove_forcefield(pos, meta:get_int("range")) + hacky_swap_node(pos, "technic:forcefield_emitter_off") + meta:set_int("HV_EU_demand", 100) + meta:set_string("infotext", "Forcefield Generator Idle") + end + end + else + meta:set_int("HV_EU_demand", power_requirement) + end + return true + end local mesecons = {effector = { action_on = function(pos, node) @@ -150,12 +164,12 @@ minetest.register_node("technic:forcefield_emitter_off", { on_construct = function(pos) minetest.env:get_node_timer(pos):start(forcefield_update_interval) local meta = minetest.env:get_meta(pos) - meta:set_float("technic_power_machine", 1) - meta:set_float("internal_EU_buffer", 0) - meta:set_float("internal_EU_buffer_size", forcefield_emitter_buffer_size) + meta:set_float("technic_hv_power_machine", 1) + meta:set_int("HV_EU_input", 0) + meta:set_int("HV_EU_demand", 0) meta:set_int("range", 10) - meta:set_int("enabled", 1) - meta:set_string("formspec", get_forcefield_formspec(meta:get_int("range", 0))) + meta:set_int("enabled", 0) + meta:set_string("formspec", get_forcefield_formspec(meta:get_int("range"))) meta:set_string("infotext", "Forcefield emitter"); end, mesecons = mesecons @@ -172,19 +186,18 @@ minetest.register_node("technic:forcefield_emitter_on", { on_construct = function(pos) minetest.env:get_node_timer(pos):start(forcefield_update_interval) local meta = minetest.env:get_meta(pos) - meta:set_float("technic_power_machine", 1) - meta:set_float("internal_EU_buffer", 0) - meta:set_float("internal_EU_buffer_size", forcefield_emitter_buffer_size) - meta:set_int("range", 10) - meta:set_int("enabled", 1) - meta:set_string("formspec", get_forcefield_formspec(meta:get_int("range"), 0)) - meta:set_string("infotext", "Forcefield emitter"); +-- meta:set_float("technic_hv_power_machine", 1) +-- meta:set_float("HV_EU_input", 0) +-- meta:set_float("HV_EU_demand", 0) +-- meta:set_int("range", 10) +-- meta:set_int("enabled", 1) + meta:set_string("formspec", get_forcefield_formspec(meta:get_int("range"))) +-- meta:set_string("infotext", "Forcefield emitter"); end, on_dig = function(pos, node, digger) remove_forcefield(pos, minetest.env:get_meta(pos):get_int("range")) return minetest.node_dig(pos, node, digger) end, - technic_power_machine=1, mesecons = mesecons }) @@ -192,6 +205,7 @@ minetest.register_node("technic:forcefield", { description = "Forcefield (you hacker you)", sunlight_propagates = true, drop = '', + light_source = 8, tiles = {{name="technic_forcefield_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}}}, is_ground_content = true, groups = {not_in_creative_inventory=1, unbreakable=1}, @@ -205,5 +219,5 @@ minetest.register_node("technic:forcefield", { }, }) -technic.register_MV_machine("technic:forcefield_emitter_on","RE") -technic.register_MV_machine("technic:forcefield_emitter_off","RE") +technic.register_HV_machine("technic:forcefield_emitter_on","RE") +technic.register_HV_machine("technic:forcefield_emitter_off","RE") diff --git a/technic/init.lua b/technic/init.lua index abe0439..3978aa9 100644 --- a/technic/init.lua +++ b/technic/init.lua @@ -51,7 +51,7 @@ dofile(modpath.."/battery_box_mv.lua") dofile(modpath.."/solar_array_mv.lua") dofile(modpath.."/electric_furnace_mv.lua") dofile(modpath.."/alloy_furnace_mv.lua") ---dofile(modpath.."/forcefield.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") From 73209cc37d61e3c90dbd0c441228faa0c8f312dc Mon Sep 17 00:00:00 2001 From: kpoppel Date: Thu, 4 Jul 2013 21:39:29 +0200 Subject: [PATCH 52/57] Fix cycling power drain on the forcefield. Now it disables itself if no power. --- technic/forcefield.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/technic/forcefield.lua b/technic/forcefield.lua index 98201e8..8ad5410 100644 --- a/technic/forcefield.lua +++ b/technic/forcefield.lua @@ -4,6 +4,8 @@ -- Forcefields are powerful barriers but they consume huge amounts of power. -- Forcefield Generator is a HV machine. +-- How expensive is the generator? Leaves room for upgrades lowering the power drain? +local forcefield_power_drain = 10 -- default 10 local forcefield_update_interval = 1 minetest.register_craft({ @@ -107,7 +109,7 @@ local forcefield_check = function(pos) local power_requirement if enabled == 1 then - power_requirement = math.floor(4*math.pi*math.pow(meta:get_int("range"), 2)) * 1 + power_requirement = math.floor(4*math.pi*math.pow(meta:get_int("range"), 2)) * forcefield_power_drain else power_requirement = eu_demand end @@ -115,10 +117,10 @@ local forcefield_check = function(pos) if eu_input == 0 then meta:set_string("infotext", "Forcefield Generator Unpowered") meta:set_int("HV_EU_demand", 100) + meta:set_int("enabled", 0) if node.name == "technic:forcefield_emitter_on" then remove_forcefield(pos, meta:get_int("range")) hacky_swap_node(pos, "technic:forcefield_emitter_off") - meta:set_int("enabled", 0) end elseif eu_input == power_requirement then if meta:get_int("enabled") == 1 then From e64994d473fce07b2a92bd86a85c6d118ae8ff7d Mon Sep 17 00:00:00 2001 From: kpoppel Date: Sat, 6 Jul 2013 00:17:56 +0200 Subject: [PATCH 53/57] Fix a bug when digging up a small cube light. Fix the power radiator so that it reacts correcty when power is lost. Add punch feature to toggle all attached appliances. --- technic/lighting.lua | 4 ++-- technic/power_radiator.lua | 40 ++++++++++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/technic/lighting.lua b/technic/lighting.lua index 1d4b45f..546e42c 100644 --- a/technic/lighting.lua +++ b/technic/lighting.lua @@ -488,7 +488,7 @@ minetest.register_node('technic:homedecor_glowlight_small_cube_yellow_active', { sounds = default.node_sound_wood_defaults(), groups = { snappy = 3, not_in_creative_inventory=1}, - drop="technic:homedecor_glowlight_cube_yellow", + drop="technic:homedecor_glowlight_small_cube_yellow", on_place = function(itemstack, placer, pointed_thing) technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) return itemstack @@ -569,7 +569,7 @@ minetest.register_node('technic:homedecor_glowlight_small_cube_white_active', { sounds = default.node_sound_wood_defaults(), groups = { snappy = 3, not_in_creative_inventory=1}, - drop="technic:homedecor_glowlight_cube_white", + drop="technic:homedecor_glowlight_small_cube_white", on_place = function(itemstack, placer, pointed_thing) technic_homedecor_rotate_and_place(itemstack, placer, pointed_thing) return itemstack diff --git a/technic/power_radiator.lua b/technic/power_radiator.lua index 8b0666a..4e248b1 100644 --- a/technic/power_radiator.lua +++ b/technic/power_radiator.lua @@ -7,6 +7,10 @@ -- sum(power rating of the attached appliances)/0.6 -- Using inductive power transfer is very inefficient so this is -- set to the factor 0.6. +-- +-- Punching the radiator will toggle the power state of all attached appliances. +-- +local power_radius = 6 ------------------------------------------------------------------ -- API for inductive powered nodes: @@ -29,7 +33,7 @@ technic.inductive_on_construct = function(pos, eu_demand, infotext) local meta = minetest.env:get_meta(pos) meta:set_string("infotext", infotext) meta:set_int("technic_inductive_power_machine", 1) - meta:set_int("MV_EU_demand",eu_demand) -- The power demand of this appliance + meta:set_int("EU_demand",eu_demand) -- The power demand of this appliance meta:set_int("EU_charge",0) -- The actual power draw of this appliance meta:set_string("has_supply","") -- Register whether we are powered or not. For use with several radiators. meta:set_int("active", 0) -- If the appliance can be turned on and off by using it use this. @@ -63,11 +67,11 @@ technic.inductive_on_punch_on = function(pos, eu_charge, swapnode) local shutdown_inductive_appliances = function(pos) -- The supply radius - local rad = 4 + local rad = power_radius -- If the radiator is removed. turn off all appliances in region -- If another radiator is near it will turn on the appliances again local positions = minetest.env:find_nodes_in_area({x=pos.x-rad,y=pos.y-rad,z=pos.z-rad},{x=pos.x+rad,y=pos.y+rad,z=pos.z+rad}, technic.inductive_nodes) - for _,pos1 in ipairs(positions) do + for _,pos1 in pairs(positions) do local meta1 = minetest.env:get_meta(pos1) -- If the appliance is belonging to this node if meta1:get_string("has_supply") == pos.x..pos.y..pos.z then @@ -83,6 +87,18 @@ local shutdown_inductive_appliances = function(pos) end end +local toggle_on_off_inductive_appliances = function(pos, node, puncher) + if pos == nil then return end + -- The supply radius + local rad = power_radius + local positions = minetest.env:find_nodes_in_area({x=pos.x-rad,y=pos.y-rad,z=pos.z-rad},{x=pos.x+rad,y=pos.y+rad,z=pos.z+rad}, technic.inductive_nodes) + for _,pos1 in pairs(positions) do + local meta1 = minetest.env:get_meta(pos1) + if meta1:get_string("has_supply") == pos.x..pos.y..pos.z then + minetest.env:punch_node(pos1) + end + end + end minetest.register_node( "technic:power_radiator", { @@ -114,6 +130,9 @@ minetest.register_node( shutdown_inductive_appliances(pos) return minetest.node_dig(pos, node, digger) end, + on_punch = function(pos, node, puncher) + toggle_on_off_inductive_appliances(pos, node, puncher) + end }) minetest.register_craft( @@ -143,7 +162,7 @@ minetest.register_abm( meta:set_string("infotext", "Power Radiator is unpowered"); -- meta:set_int("active",1) -- used for setting textures someday maybe shutdown_inductive_appliances(pos) - connected_EU_demand = 0 + meta:set_int("connected_EU_demand", 0) elseif eu_input == eu_demand then -- Powered and ready @@ -154,7 +173,7 @@ minetest.register_abm( -- Efficiency factor local eff_factor = 0.6 -- The supply radius - local rad = 6 + local rad = power_radius local meta1 = nil local pos1 = {} @@ -162,23 +181,24 @@ minetest.register_abm( -- Index all nodes within supply range local positions = minetest.env:find_nodes_in_area({x=pos.x-rad,y=pos.y-rad,z=pos.z-rad},{x=pos.x+rad,y=pos.y+rad,z=pos.z+rad}, technic.inductive_nodes) - for _,pos1 in ipairs(positions) do + for _,pos1 in pairs(positions) do local meta1 = minetest.env:get_meta(pos1) -- If not supplied see if this node can handle it. if meta1:get_string("has_supply") == "" then -- if demand surpasses the capacity of this node, don't bother adding it. - local app_eu_demand = meta1:get_int("EU_demand")/eff_factor + local app_eu_demand = math.floor(meta1:get_int("EU_demand")/eff_factor) if connected_EU_demand + app_eu_demand <= max_charge then + --print("I can supply this:"..connected_EU_demand.."|"..app_eu_demand.."<="..max_charge.."|act:"..meta1:get_int("EU_charge")) -- We can power the appliance. Register, and spend power if it is on. connected_EU_demand = connected_EU_demand + app_eu_demand meta1:set_string("has_supply", pos.x..pos.y..pos.z) - used_charge = math.floor(used_charge+meta1:get_int("EU_charge")/eff_factor) + --Always 0: used_charge = math.floor(used_charge+meta1:get_int("EU_charge")/eff_factor) end elseif meta1:get_string("has_supply") == pos.x..pos.y..pos.z then -- The appliance has power from this node. Spend power if it is on. - used_charge = math.floor(used_charge+meta1:get_int("EU_charge")/eff_factor) - --print("My Lamp ("..pos.x..","..pos.y..","..pos.z..") Used:"..used_charge) + used_charge = used_charge+math.floor(meta1:get_int("EU_charge")/eff_factor) + --print("My Lamp ("..pos.x..","..pos.y..","..pos.z..") Used:"..used_charge.."Max:"..max_charge) end meta:set_string("infotext", "Power Radiator is powered ("..math.floor(used_charge/max_charge*100).."% of maximum power)"); if used_charge == 0 then From 4c6546ed56da9b8ac7db490af841d11ef9a10368 Mon Sep 17 00:00:00 2001 From: kpoppel Date: Sat, 6 Jul 2013 00:22:12 +0200 Subject: [PATCH 54/57] Forgot to reset demand on power failure. --- technic/power_radiator.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/technic/power_radiator.lua b/technic/power_radiator.lua index 4e248b1..86a770e 100644 --- a/technic/power_radiator.lua +++ b/technic/power_radiator.lua @@ -163,6 +163,7 @@ minetest.register_abm( -- meta:set_int("active",1) -- used for setting textures someday maybe shutdown_inductive_appliances(pos) meta:set_int("connected_EU_demand", 0) + meta:set_int("MV_EU_demand",1) elseif eu_input == eu_demand then -- Powered and ready From 85d937e1997bcaa833e40df78117d53708ecdccd Mon Sep 17 00:00:00 2001 From: kpoppel Date: Sat, 6 Jul 2013 00:31:48 +0200 Subject: [PATCH 55/57] Made the supply converter reset its supply and demand stats if the cabling is bad. --- technic/supply_converter.lua | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/technic/supply_converter.lua b/technic/supply_converter.lua index d0714e7..bee99d2 100644 --- a/technic/supply_converter.lua +++ b/technic/supply_converter.lua @@ -97,6 +97,15 @@ minetest.register_abm( if convert_MV_LV == 0 and convert_LV_MV == 0 and convert_HV_MV == 0 and convert_MV_HV == 0 then meta:set_string("infotext", machine_name.." has bad cabling") + meta:set_int("LV_EU_demand", 0) + meta:set_int("LV_EU_supply", 0) + meta:set_int("LV_EU_input", 0) + meta:set_int("MV_EU_demand", 0) + meta:set_int("MV_EU_supply", 0) + meta:set_int("MV_EU_input", 0) + meta:set_int("HV_EU_demand", 0) + meta:set_int("HV_EU_supply", 0) + meta:set_int("HV_EU_input", 0) return end From e606b93ac633fd95bb2a65aac6acb94b30abcb14 Mon Sep 17 00:00:00 2001 From: Konstantin Oblaukhov Date: Sat, 6 Jul 2013 15:19:15 +0700 Subject: [PATCH 56/57] Support for multiple-input recipes in extractor. --- technic/extractor.lua | 69 ++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/technic/extractor.lua b/technic/extractor.lua index 92ccdd5..473a7b3 100644 --- a/technic/extractor.lua +++ b/technic/extractor.lua @@ -1,27 +1,23 @@ technic.extractor_recipes ={} -technic.register_extractor_recipe = function(src, dst) - technic.extractor_recipes[src] = dst +technic.register_extractor_recipe = function(src, src_count, dst, dst_count) + technic.extractor_recipes[src] = {src_count = src_count, dst_name = dst, dst_count = dst_count} if unified_inventory then unified_inventory.register_craft( { type = "extracting", - output = dst, - items = {src}, + output = dst.." "..dst_count, + items = {src.." "..src_count}, width = 0, }) end end -- Receive an ItemStack of result by an ItemStack input -technic.get_extractor_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.extractor_recipes[item_name] then - return ItemStack(technic.extractor_recipes[item_name]) +technic.get_extractor_recipe = function(item) + if technic.extractor_recipes[item.name] + and item.count >= technic.extractor_recipes[item.name].src_count then + return technic.extractor_recipes[item.name] else return nil end @@ -29,18 +25,18 @@ technic.get_extractor_recipe = function(itemstack) -technic.register_extractor_recipe("technic:coal_dust","dye:black 2") -technic.register_extractor_recipe("default:cactus","dye:green 2") -technic.register_extractor_recipe("default:dry_shrub","dye:brown 2") -technic.register_extractor_recipe("flowers:geranium","dye:blue 2") -technic.register_extractor_recipe("flowers:dandelion_white","dye:white 2") -technic.register_extractor_recipe("flowers:dandelion_yellow","dye:yellow 2") -technic.register_extractor_recipe("flowers:tulip","dye:orange 2") -technic.register_extractor_recipe("flowers:rose","dye:red 2") -technic.register_extractor_recipe("flowers:viola","dye:violet 2") -technic.register_extractor_recipe("technic:raw_latex","technic:rubber 3") -technic.register_extractor_recipe("moretrees:rubber_tree_trunk_empty","technic:rubber 1") -technic.register_extractor_recipe("moretrees:rubber_tree_trunk","technic:rubber 1") +technic.register_extractor_recipe("technic:coal_dust", 1, "dye:black", 2) +technic.register_extractor_recipe("default:cactus", 1, "dye:green", 2) +technic.register_extractor_recipe("default:dry_shrub", 1, "dye:brown", 2) +technic.register_extractor_recipe("flowers:geranium", 1, "dye:blue", 2) +technic.register_extractor_recipe("flowers:dandelion_white", 1, "dye:white", 2) +technic.register_extractor_recipe("flowers:dandelion_yellow", 1, "dye:yellow", 2) +technic.register_extractor_recipe("flowers:tulip", 1, "dye:orange", 2) +technic.register_extractor_recipe("flowers:rose", 1, "dye:red", 2) +technic.register_extractor_recipe("flowers:viola", 1, "dye:violet", 2) +technic.register_extractor_recipe("technic:raw_latex", 1, "technic:rubber", 3) +technic.register_extractor_recipe("moretrees:rubber_tree_trunk_empty", 1, "technic:rubber", 1) +technic.register_extractor_recipe("moretrees:rubber_tree_trunk", 1, "technic:rubber", 1) minetest.register_alias("extractor", "technic:extractor") minetest.register_craft({ @@ -160,12 +156,25 @@ minetest.register_abm( local inv = meta:get_inventory() local empty = inv:is_empty("src") - + local srcstack = inv:get_stack("src", 1) + local src_item = nil + local recipe = nil + local result = nil + + if srcstack then + src_item = srcstack:to_table() + end + if src_item then + recipe = technic.get_extractor_recipe(src_item) + end + if recipe then + result = {name=recipe.dst_name, count=recipe.dst_count} + end + if state == 1 then hacky_swap_node(pos, machine_node) meta:set_string("infotext", machine_name.." Idle") - local result = technic.get_extractor_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 @@ -181,14 +190,12 @@ minetest.register_abm( 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_extractor_recipe(inv:get_stack("src", 1)) meta:set_int("src_time", 0) - if inv:room_for_item("dst",result) then + if recipe and 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) + srcstack:take_item(recipe.src_count) + inv:set_stack("src", 1, srcstack) -- Put result in "dst" list inv:add_item("dst", result) else From 8be389e774a99ec5d08ca86b3902bb98310fd58d Mon Sep 17 00:00:00 2001 From: Konstantin Oblaukhov Date: Sat, 6 Jul 2013 20:52:41 +0700 Subject: [PATCH 57/57] Enriched Uranium. --- technic/extractor.lua | 1 + technic/items.lua | 6 ++++++ technic/textures/technic_enriched_uranium.png | Bin 0 -> 301 bytes 3 files changed, 7 insertions(+) create mode 100644 technic/textures/technic_enriched_uranium.png diff --git a/technic/extractor.lua b/technic/extractor.lua index 473a7b3..d4fe1cc 100644 --- a/technic/extractor.lua +++ b/technic/extractor.lua @@ -37,6 +37,7 @@ technic.register_extractor_recipe("flowers:viola", 1, "dye:violet", 2) technic.register_extractor_recipe("technic:raw_latex", 1, "technic:rubber", 3) technic.register_extractor_recipe("moretrees:rubber_tree_trunk_empty", 1, "technic:rubber", 1) technic.register_extractor_recipe("moretrees:rubber_tree_trunk", 1, "technic:rubber", 1) +technic.register_extractor_recipe("technic:uranium", 5, "technic:enriched_uranium", 1) minetest.register_alias("extractor", "technic:extractor") minetest.register_craft({ diff --git a/technic/items.lua b/technic/items.lua index 66c5c85..0f23648 100644 --- a/technic/items.lua +++ b/technic/items.lua @@ -10,6 +10,12 @@ minetest.register_craftitem( "technic:doped_silicon_wafer", { on_place_on_ground = minetest.craftitem_place_item, }) +minetest.register_craftitem( "technic:enriched_uranium", { + description = "Enriched Uranium", + inventory_image = "technic_enriched_uranium.png", + on_place_on_ground = minetest.craftitem_place_item, +}) + -- tubes crafting recipes minetest.register_craft({ diff --git a/technic/textures/technic_enriched_uranium.png b/technic/textures/technic_enriched_uranium.png new file mode 100644 index 0000000000000000000000000000000000000000..8759e658a949e5535e28c20b6e0e6fb9c78a21fc GIT binary patch literal 301 zcmV+|0n+}7P)b;z6o$V9kfN;64W=v=EX<6(MrW3eOg%zJCT`HJho~wpzyM7mAt9AYh^lEsD$5d% z-2vf>5ORR_AD`d%`8^x{en#QY+%0a+rE{kW%+wBm90h>qdQ7^HPNiTJ4o#|(lUj}X zMUhhki_K-CR3&^QTb^%bPQ7^R5iAp>Dq%TYQS)80SO6TlzV@F)QN&fyqS< z^(D5VTxi0Fx8D^8PrZ{@K8iB6V>w+NM7|3^77Gj83B+3Bw>>M^%(uMD4O(hjD}trJ z&>siJZ+qlYlS_@38nKq8U}gH_z+B&V4F4lPts;AODdnNq00000NkvXXu0mjfp-g|+ literal 0 HcmV?d00001