diff options
author | kpoppel <poulsen.kim@gmail.com> | 2013-07-02 00:03:36 +0200 |
---|---|---|
committer | kpoppel <poulsen.kim@gmail.com> | 2013-07-02 00:03:36 +0200 |
commit | ee5c6c23fab97f1bd1b217a654b72606938619b6 (patch) | |
tree | b2819d4099ecad1d5dbe29c484bd9d8da9102669 | |
parent | 37d9d94c44cbadc7e6550efc22612c7c605a9040 (diff) |
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.
33 files changed, 3602 insertions, 3185 deletions
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 - -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, +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]" + +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_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) - 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]") - - 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("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 (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: - +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) + 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 = "Electric Alloy Furnace" + local machine_node = "technic:alloy_furnace" + local machine_state_demand = { 50, 600 } + + -- 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 + + -- 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 + + if recipe then + print("recipe "..recipe.dst_name.." : result "..result.name.." : empty "..empty.." : src_item1 "..src_item1.name.." : src_item2 "..src_item2.name) + end + + 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 + + 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") + +-------------------------------------------------- +-- 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 - srcstack = inv:get_stack("src", 1) + -- Get what to cook if anything + local 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 + 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 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 + 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 + 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 - local fuel = nil - local fuellist = inv:get_list("fuel") - + -- 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 + recipe = technic.get_alloy_recipe(src_item1,src_item2) + end - 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}) + 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 - 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 + -- Next take a hard look at the fuel situation + local fuel = nil + local fuellist = inv:get_list("fuel") + + if fuellist then + fuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) 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 + 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 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, - - 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_alloys(pos,x_velocity,z_velocity) end - end - meta:set_float("tube_time", tube_time) +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 - 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) +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 - 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]") + 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 inv = meta:get_inventory() +minetest.register_abm( + {nodenames = {"technic:mv_alloy_furnace","technic:mv_alloy_furnace_active"}, + interval = 1, + chance = 1, - local furnace_is_cookin = meta:get_int("furnace_is_cookin") + 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 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 - - if src_item1 and src_item2 then - dst_index=get_cook_result(src_item1,src_item2) - end + -- 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 -- + -- 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) - 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 + -- 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 - 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 - -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 power_tools = technic.LV_power_tools + +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 load<item_max_charge and charge>0 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 charge<max_charge then + if charge+load_step>max_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 load1<item_max_charge and charge>0 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 charge<max_charge then - if charge+load_step>max_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 charge<max_charge then - if internal_EU_buffer-charge_to_take<=0 then - charge_to_take=internal_EU_buffer - end - if charge_to_take>0 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 load<item_max_charge and charge>0 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 charge<max_charge then + if charge+load_step>max_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 load1<item_max_charge and charge>0 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 charge<max_charge then - if charge+load_step>max_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 charge<max_charge then - if internal_EU_buffer-charge_to_take<=0 then - charge_to_take=internal_EU_buffer - end - if charge_to_take>0 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 - - -- 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; + 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 - 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 load<item_max_charge and charge>0 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 charge<max_charge then + if charge+load_step>max_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 load1<item_max_charge and charge>0 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 charge<max_charge then - if charge+load_step>max_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 charge<max_charge then - if internal_EU_buffer-charge_to_take<=0 then - charge_to_take=internal_EU_buffer - end - if charge_to_take>0 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 - - -- 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; + 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 - 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") + + 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 + }) -register_LV_machine ("technic:cnc","RE") -register_LV_machine ("technic:cnc_active","RE") +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, -}) - -minetest.register_abm({ - nodenames = {"technic:mv_electric_furnace","technic:mv_electric_furnace_active"}, - interval = 1, - chance = 1, + 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, + }) - action = function(pos, node, active_object_count, active_object_count_wider) +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 - 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 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 - local furnace_is_cookin = meta:get_float("furnace_is_cookin") - - - local srclist = inv:get_list("src") - local cooked=nil +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 - if srclist then - cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) + -- 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 + + -- Power off automatically if no longer connected to a switching station + technic.switching_station_timeout_count(pos, "MV") + -- Execute always logic + -- CODE HERE -- - 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 + -- 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 - - - - 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 - - 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) - - 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 +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") - 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 + -- 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 - 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;]" - ) + -- 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 - if burn_time==0 then - hacky_swap_node (pos,"technic:generator") - end + 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;]" + ) - end -}) + if burn_time==0 then + hacky_swap_node (pos,"technic:generator") + 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) + local meta = minetest.env:get_meta(pos) + local water_nodes = 0 + local lava_nodes = 0 + local production_level = 0 + local eu_supply = 0 -minetest.register_abm({ - nodenames = {"technic:geothermal","technic:geothermal_active"}, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) + -- 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 - 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-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 - 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+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 -}) - -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 + 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 + }) -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 ={} - -registered_grinder_recipes_count=1 - -function register_grinder_recipe (string1,string2) -grinder_recipes[registered_grinder_recipes_count]={} -grinder_recipes[registered_grinder_recipes_count].src_name=string1 -grinder_recipes[registered_grinder_recipes_count].dst_name=string2 -registered_grinder_recipes_count=registered_grinder_recipes_count+1 -if unified_inventory then - unified_inventory.register_craft({ - type = "grinding", - output = string2, - items = {string1}, - width = 0, - }) - end -end - -register_grinder_recipe("default:stone","default:sand") -register_grinder_recipe("default:cobble","default:gravel") -register_grinder_recipe("default:gravel","default:dirt") -register_grinder_recipe("default:desert_stone","default:desert_sand") -register_grinder_recipe("default:iron_lump","technic:iron_dust 2") -register_grinder_recipe("default:steel_ingot","technic:iron_dust 1") -register_grinder_recipe("default:coal_lump","technic:coal_dust 2") -register_grinder_recipe("default:copper_lump","technic:copper_dust 2") -register_grinder_recipe("default:copper_ingot","technic:copper_dust 1") -register_grinder_recipe("default:gold_lump","technic:gold_dust 2") -register_grinder_recipe("default:gold_ingot","technic:gold_dust 1") ---register_grinder_recipe("default:bronze_ingot","technic:bronze_dust 1") -- Dust does not exist yet ---register_grinder_recipe("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.grinder_recipes ={} + +technic.register_grinder_recipe = function(src, dst) + technic.grinder_recipes[src] = dst + if unified_inventory then + unified_inventory.register_craft( + { + type = "grinding", + output = dst, + items = {src}, + width = 0, + }) + end + end + +-- Receive an ItemStack of result by an ItemStack input +technic.get_grinder_recipe = function(itemstack) + local src_item = itemstack:to_table() + if src_item == nil then + return nil + end + local item_name = src_item["name"] + if technic.grinder_recipes[item_name] then + return ItemStack(technic.grinder_recipes[item_name]) + else + return nil + end + end + + +technic.register_grinder_recipe("default:stone","default:sand") +technic.register_grinder_recipe("default:cobble","default:gravel") +technic.register_grinder_recipe("default:gravel","default:dirt") +technic.register_grinder_recipe("default:desert_stone","default:desert_sand") +technic.register_grinder_recipe("default:iron_lump","technic:iron_dust 2") +technic.register_grinder_recipe("default:steel_ingot","technic:iron_dust 1") +technic.register_grinder_recipe("default:coal_lump","technic:coal_dust 2") +technic.register_grinder_recipe("default:copper_lump","technic:copper_dust 2") +technic.register_grinder_recipe("default:copper_ingot","technic:copper_dust 1") +technic.register_grinder_recipe("default:gold_lump","technic:gold_dust 2") +technic.register_grinder_recipe("default:gold_ingot","technic:gold_dust 1") +--technic.register_grinder_recipe("default:bronze_ingot","technic:bronze_dust 1") -- Dust does not exist yet +--technic.register_grinder_recipe("home_decor:brass_ingot","technic:brass_dust 1") -- needs check for the mod +technic.register_grinder_recipe("moreores:tin_lump","technic:tin_dust 2") +technic.register_grinder_recipe("moreores:tin_ingot","technic:tin_dust 1") +technic.register_grinder_recipe("moreores:silver_lump","technic:silver_dust 2") +technic.register_grinder_recipe("moreores:silver_ingot","technic:silver_dust 1") +technic.register_grinder_recipe("moreores:mithril_lump","technic:mithril_dust 2") +technic.register_grinder_recipe("moreores:mithril_ingot","technic:mithril_dust 1") +technic.register_grinder_recipe("technic:chromium_lump","technic:chromium_dust 2") +technic.register_grinder_recipe("technic:chromium_ingot","technic:chromium_dust 1") +technic.register_grinder_recipe("technic:stainless_steel_ingot","stainless_steel_dust 1") +technic.register_grinder_recipe("technic:brass_ingot","technic:brass_dust 1") +technic.register_grinder_recipe("technic:zinc_lump","technic:zinc_dust 2") +technic.register_grinder_recipe("technic:zinc_ingot","technic:zinc_dust 1") +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, -}) - -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;]" - - -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) - 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 + description = "Grinder", + stack_max = 99, + }) + +local grinder_formspec = + "invsize[8,9;]".. + "label[0,0;Grinder]".. + "list[current_name;src;3,1;1,1;]".. + "list[current_name;dst;5,1;2,2;]".. + "list[current_player;main;0,5;8,4;]" + +minetest.register_node( + "technic:grinder", + { + description = "Grinder", + tiles = {"technic_lv_grinder_top.png", "technic_lv_grinder_bottom.png", "technic_lv_grinder_side.png", + "technic_lv_grinder_side.png", "technic_lv_grinder_side.png", "technic_lv_grinder_front.png"}, + paramtype2 = "facedir", + groups = {cracky=2}, + legacy_facedir_simple = true, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + local meta = minetest.env:get_meta(pos) + meta:set_string("infotext", "Grinder") + meta:set_float("technic_power_machine", 1) + meta:set_string("formspec", grinder_formspec) + local inv = meta:get_inventory() + inv:set_size("src", 1) + inv:set_size("dst", 4) + end, + can_dig = function(pos,player) + local meta = minetest.env:get_meta(pos); + local inv = meta:get_inventory() + if not inv:is_empty("src") or not inv:is_empty("dst") then + minetest.chat_send_player(player:get_player_name(), "Machine cannot be removed because it is not empty"); + return false + else + return true + end end, -}) - -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 + }) + +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_abm({ - nodenames = {"technic:grinder","technic:grinder_active"}, - interval = 1, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - - local meta = minetest.env:get_meta(pos) - local charge= meta:get_float("internal_EU_buffer") - local max_charge= meta:get_float("internal_EU_buffer_size") - local grind_cost=200 - - local load = math.floor((charge/max_charge)*100) - meta:set_string("formspec", - "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 inv = meta:get_inventory() - local srclist = inv:get_list("src") - if inv:is_empty("src") then meta:set_float("grinder_on",0) end - - if (meta:get_float("grinder_on") == 1) then - if charge>=grind_cost then - charge=charge-grind_cost; - meta:set_float("internal_EU_buffer",charge) - meta:set_float("src_time", meta:get_float("src_time") + 1) - if meta:get_float("src_time") >= meta:get_float("grind_time") then - -- check if there's room for output in "dst" list - grinded = get_grinded_item (inv:get_stack("src", 1)) - if inv:room_for_item("dst",grinded) then - -- Put result in "dst" list - inv:add_item("dst", grinded) - -- take stuff from "src" list - srcstack = inv:get_stack("src", 1) - srcstack:take_item() - inv:set_stack("src", 1, srcstack) - if inv:is_empty("src") then meta:set_float("grinder_on",0) end - else - print("Grinder inventory full!") - end - meta:set_float("src_time", 0) - end - end - end - if (meta:get_float("grinder_on")==0) then - local grinded=nil - if not inv:is_empty("src") then - grinded = get_grinded_item (inv:get_stack("src", 1)) - if grinded then - meta:set_float("grinder_on",1) - hacky_swap_node(pos,"technic:grinder_active") - meta:set_string("infotext", "Grinder Active") - grind_time=4 - meta:set_float("grind_time",grind_time) - meta:set_float("src_time", 0) - return - end - else - hacky_swap_node(pos,"technic:grinder") - meta:set_string("infotext", "Grinder Inactive") - end - end - end -}) - -function get_grinded_item (items) -new_item =nil -src_item=items:to_table() -item_name=src_item["name"] - -local counter=registered_grinder_recipes_count-1 -for i=1, counter,1 do - if grinder_recipes[i].src_name==item_name then return ItemStack(grinder_recipes[i].dst_name) end -end -return nil -end - -register_LV_machine ("technic:grinder","RE") -register_LV_machine ("technic:grinder_active","RE") + }) + +minetest.register_abm( + { nodenames = {"technic:grinder","technic:grinder_active"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + -- Run a machine through its states. Takes the same arguments as the ABM action + -- and adds the machine's states and any extra data which is needed by the machine. + -- A machine is characterized by running through a set number of states (usually 2: + -- Idle and active) in some order. A state decides when to move to the next one + -- and the machine only changes state if it is powered correctly. + -- The machine will automatically shut down if disconnected from power in some fashion. + local meta = minetest.env:get_meta(pos) + local eu_input = meta:get_int("LV_EU_input") + local state = meta:get_int("state") + local next_state = state + + -- Machine information + local machine_name = "Grinder" + local machine_node = "technic:grinder" + local machine_state_demand = { 50, 300 } + + -- Setup meta data if it does not exist. state is used as an indicator of this + if state == 0 then + meta:set_int("state", 1) + meta:set_int("LV_EU_demand", machine_state_demand[1]) + meta:set_int("LV_EU_input", 0) + return + end + + -- Power off automatically if no longer connected to a switching station + technic.switching_station_timeout_count(pos, "LV") + + -- State machine + if eu_input == 0 then + -- unpowered - go idle + hacky_swap_node(pos, machine_node) + meta:set_string("infotext", machine_name.." Unpowered") + next_state = 1 + elseif eu_input == machine_state_demand[state] then + -- Powered - do the state specific actions + + local inv = meta:get_inventory() + local empty = inv:is_empty("src") + + if state == 1 then + hacky_swap_node(pos, machine_node) + meta:set_string("infotext", machine_name.." Idle") + + local result = technic.get_grinder_recipe(inv:get_stack("src", 1)) + if not empty and result and inv:room_for_item("dst",result) then + meta:set_int("src_time", 0) + next_state = 2 + end + + elseif state == 2 then + hacky_swap_node(pos, machine_node.."_active") + meta:set_string("infotext", machine_name.." Active") + + if empty then + next_state = 1 + else + meta:set_int("src_time", meta:get_int("src_time") + 1) + if meta:get_int("src_time") == 4 then -- 4 ticks per output + -- check if there's room for output in "dst" list + local result = technic.get_grinder_recipe(inv:get_stack("src", 1)) + + meta:set_int("src_time", 0) + if inv:room_for_item("dst",result) then + -- take stuff from "src" list + srcstack = inv:get_stack("src", 1) + srcstack:take_item() + inv:set_stack("src", 1, srcstack) + -- Put result in "dst" list + inv:add_item("dst", result) + else + -- all full: go idle + next_state = 1 + end + end + end + end + end + -- Change state? + if next_state ~= state then + meta:set_int("LV_EU_demand", machine_state_demand[next_state]) + meta:set_int("state", next_state) + end + end + }) + +technic.register_LV_machine ("technic:grinder","RE") +technic.register_LV_machine ("technic:grinder_active","RE") 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]" - +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 --]" -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, +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, + }) - 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 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") -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 -}) + 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 + }) -register_LV_machine ("technic:music_player","RE") +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 <name>_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: +-- <LV|MV|HV>_EU_supply : Exists for PR and BA node types. This is the EU value supplied by the node. Output +-- <LV|MV|HV>_EU_demand : Exists for RE and BA node types. This is the EU value the node requires to run. Output +-- <LV|MV|HV>_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") + + 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 + }) -register_LV_machine ("technic:tool_workshop","RE") +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", - technic_power_machine=1, - internal_EU_buffer=0; - internal_EU_buffer_size=0; +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_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 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 - 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 +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 - 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 -}) - -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 + 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 + }) -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") |