From 1e9a2e645e426d2c8aec264bcdc137638102032b Mon Sep 17 00:00:00 2001 From: mrkubax10 Date: Mon, 11 Mar 2024 19:31:21 +0100 Subject: [PATCH] Implement Induction Furnace Induction Furnace allows for faster smelting via double input and output slots. Additionaly it features heat storage which makes it smelt faster when heated. --- init.lua | 1 + machines/induction_furnace.lua | 287 +++++++++++++++++++++++++++++++++ 2 files changed, 288 insertions(+) create mode 100644 machines/induction_furnace.lua diff --git a/init.lua b/init.lua index a845202..b48e145 100644 --- a/init.lua +++ b/init.lua @@ -40,6 +40,7 @@ dofile(modpath.."/machines/electric_furnace.lua") dofile(modpath.."/machines/extractor.lua") dofile(modpath.."/machines/fluid_generator.lua") dofile(modpath.."/machines/generator.lua") +dofile(modpath.."/machines/induction_furnace.lua") dofile(modpath.."/machines/iron_furnace.lua") dofile(modpath.."/machines/macerator.lua") dofile(modpath.."/machines/mass_fabricator.lua") diff --git a/machines/induction_furnace.lua b/machines/induction_furnace.lua new file mode 100644 index 0000000..b7e039e --- /dev/null +++ b/machines/induction_furnace.lua @@ -0,0 +1,287 @@ +-- IndustrialTest +-- Copyright (C) 2024 mrkubax10 + +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. + +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. + +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +local S=minetest.get_translator("industrialtest") + +local inductionFurnace={} +inductionFurnace.opPower=60 +inductionFurnace.efficiency=0.5 + +local function calculateMaxSrcTime(pos) + local meta=minetest.get_meta(pos) + local inv=meta:get_inventory() + local srcList=inv:get_list("src") + + local maxSrcTime=0 + for _,slot in ipairs(srcList) do + local result,_=minetest.get_craft_result({ + method="cooking", + width=1, + items={slot} + }) + maxSrcTime=math.max(maxSrcTime,result.time*inductionFurnace.efficiency) + end + meta:set_float("maxSrcTime",maxSrcTime) +end + +inductionFurnace.getFormspec=function(pos) + local meta=minetest.get_meta(pos) + local powerPercent=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")*100 + local maxSrcTime=meta:get_float("maxSrcTime") + local srcPercent=maxSrcTime>0 and meta:get_float("srcTime")/maxSrcTime*100 or 0 + local heat=meta:get_int("heat") + local formspec + if industrialtest.mtgAvailable then + formspec={ + "list[context;src;3.7,1.8;2,1]", + (powerPercent>0 and "image[3.7,2.8;1,1;industrialtest_gui_electricity_bg.png^[lowpart:"..powerPercent..":industrialtest_gui_electricity_fg.png]" + or "image[3.7,2.8;1,1;industrialtest_gui_electricity_bg.png]"), + "list[context;powerStorage;3.7,3.9;1,1]", + (srcPercent>0 and "image[4.9,2.8;1,1;gui_furnace_arrow_bg.png^[lowpart:"..srcPercent..":gui_furnace_arrow_fg.png^[transformR270]" + or "image[4.9,2.8;1,1;gui_furnace_arrow_bg.png^[transformR270]"), + "list[context;dst;6,2.8;2,1;]", + "list[context;upgrades;9,0.9;1,4]", + "label[0.5,2.8;"..minetest.formspec_escape(S("Heat: @1 %",heat)).."]", + "listring[context;src]", + "listring[context;powerStorage]", + "listring[context;dst]", + "listring[context;upgrades]" + } + elseif industrialtest.mclAvailable then + formspec={ + "list[context;src;3.7,1.8;2,1]", + mcl_formspec.get_itemslot_bg(3.7,1.8,2,1), + (powerPercent>0 and "image[3.7,2.8;1,1;industrialtest_gui_electricity_bg.png^[lowpart:"..powerPercent..":industrialtest_gui_electricity_fg.png]" + or "image[3.7,2.8;1,1;industrialtest_gui_electricity_bg.png]"), + "list[context;powerStorage;3.7,3.9;1,1]", + mcl_formspec.get_itemslot_bg(3.7,3.9,1,1), + (srcPercent>0 and "image[4.9,2.8;1,1;gui_furnace_arrow_bg.png^[lowpart:"..srcPercent..":gui_furnace_arrow_fg.png^[transformR270]" + or "image[4.9,2.8;1,1;gui_furnace_arrow_bg.png^[transformR270]"), + "list[context;dst;6,2.8;2,1;]", + mcl_formspec.get_itemslot_bg(6,2.8,2,1), + "list[context;upgrades;9,0.9;1,4]", + mcl_formspec.get_itemslot_bg(9,0.9,1,4), + "label[0.5,2.8;"..minetest.formspec_escape(S("Heat: @1 %",heat)).."]", + "listring[context;src]", + "listring[context;powerStorage]", + "listring[context;dst]", + "listring[context;upgrades]" + } + end + return table.concat(formspec,"") +end + +inductionFurnace.onConstruct=function(pos,meta,inv) + inv:set_size("src",2) + inv:set_size("dst",2) + inv:set_size("powerStorage",1) + inv:set_size("upgrades",4) + meta:set_int("heat",0) + meta:set_float("srcTime",0) +end + +inductionFurnace.onTimer=function(pos,elapsed,meta,inv) + local shouldRerunTimer=false + local shouldUpdateFormspec=false + local srcList=inv:get_list("src") + local heat=meta:get_int("heat") + + shouldRerunTimer,shouldUpdateFormspec=industrialtest.internal.chargeFromPowerStorageItem(meta,inv) + + if heat>0 then + meta:set_int("heat",math.max(heat-math.max(2*elapsed,1),0)) + shouldRerunTimer=shouldRerunTimer or heat>0 + shouldUpdateFormspec=true + end + + for _,slot in ipairs(srcList) do + if not slot:is_empty() then + local result,after=minetest.get_craft_result({ + method="cooking", + width=1, + items={slot} + }) + if result.time>0 and inv:room_for_item("dst",result.item) then + minetest.swap_node(pos,{ + name="industrialtest:induction_furnace_active", + param2=minetest.get_node(pos).param2 + }) + minetest.get_node_timer(pos):start(industrialtest.updateDelay) + return false,shouldUpdateFormspec + end + end + end + + return shouldRerunTimer,shouldUpdateFormspec +end + +inductionFurnace.allowMetadataInventoryMove=function(pos,fromList,fromIndex,toList,toIndex,count) + if toList=="dst" then + return 0 + end + return count +end + +inductionFurnace.allowMetadataInventoryPut=function(pos,listname,index,stack) + if listname=="dst" then + return 0 + end + return stack:get_count() +end + +inductionFurnace.onMetadataInventoryPut=function(pos,listname) + if listname=="src" then + calculateMaxSrcTime(pos) + end + minetest.get_node_timer(pos):start(industrialtest.updateDelay) +end + +inductionFurnace.onMetadataInventoryMove=function(pos,fromList,fromIndex,toList) + if fromList=="src" or toList=="src" then + calculateMaxSrcTime(pos) + end + minetest.get_node_timer(pos):start(industrialtest.updateDelay) +end + +inductionFurnace.onMetadataInventoryTake=function(pos,listname) + if listname=="src" then + calculateMaxSrcTime(pos) + end + if listname=="dst" then + minetest.get_node_timer(pos):start(industrialtest.updateDelay) + end +end + +inductionFurnace.activeOnTimer=function(pos,elapsed,meta,inv) + local srcList=inv:get_list("src") + local powerAmount=meta:get_int("industrialtest.powerAmount") + local srcTime=meta:get_float("srcTime") + local maxSrcTime=meta:get_float("maxSrcTime") + local heat=meta:get_int("heat") + local speed=industrialtest.api.getMachineSpeed(meta) + local requiredPower=elapsed*inductionFurnace.opPower*speed + + industrialtest.internal.chargeFromPowerStorageItem(meta,inv) + + local shouldContinue=false + local results={} + for _,slot in ipairs(srcList) do + if slot:is_empty() then + table.insert(results,false) + else + local result,after=minetest.get_craft_result({ + method="cooking", + width=1, + items={slot} + }) + if result.time>0 and inv:room_for_item("dst",result.item) then + table.insert(results,result.item) + shouldContinue=true + else + table.insert(results,false) + end + end + end + if not shouldContinue or powerAmount=maxSrcTime then + for i,result in ipairs(results) do + if result then + local multiplier=math.min(srcList[i]:get_count(),speed) + local prevCount=result:get_count() + result:set_count(result:get_count()*multiplier) + local leftover=inv:add_item("dst",result) + srcList[i]:take_item(multiplier-leftover:get_count()/prevCount) + inv:set_stack("src",i,srcList[i]) + end + end + srcTime=0 + end + meta:set_float("srcTime",srcTime) + + if heat<100 then + meta:set_int("heat",math.min(100,heat+speed)) + end + + industrialtest.api.addPower(meta,-requiredPower) + + return true,true +end + +industrialtest.internal.registerMachine({ + name="induction_furnace", + displayName=S("Induction Furnace"), + capacity=industrialtest.api.mvPowerFlow*2, + getFormspec=inductionFurnace.getFormspec, + flow=industrialtest.api.mvPowerFlow, + ioConfig="iiiiii", + requiresWrench=true, + registerActiveVariant=true, + sounds="metal", + powerSlots={"powerStorage"}, + storageSlots={"src","dst","powerStorage","upgrades"}, + groups={ + _industrialtest_hasPowerInput=1 + }, + customKeys={ + tiles={ + "industrialtest_advanced_machine_block.png", + "industrialtest_advanced_machine_block.png", + "industrialtest_advanced_machine_block.png", + "industrialtest_advanced_machine_block.png", + "industrialtest_advanced_machine_block.png", + "industrialtest_advanced_machine_block.png^industrialtest_electric_furnace_front.png" + }, + paramtype2="facedir", + legacy_facedir_simple=true + }, + activeCustomKeys={ + tiles={ + "industrialtest_advanced_machine_block.png", + "industrialtest_advanced_machine_block.png", + "industrialtest_advanced_machine_block.png", + "industrialtest_advanced_machine_block.png", + "industrialtest_advanced_machine_block.png", + "industrialtest_advanced_machine_block.png^industrialtest_electric_furnace_front_active.png" + } + }, + onConstruct=inductionFurnace.onConstruct, + onTimer=inductionFurnace.onTimer, + allowMetadataInventoryMove=inductionFurnace.allowMetadataInventoryMove, + allowMetadataInventoryPut=inductionFurnace.allowMetadataInventoryPut, + onMetadataInventoryPut=inductionFurnace.onMetadataInventoryPut, + onMetadataInventoryMove=inductionFurnace.onMetadataInventoryMove, + onMetadataInventoryTake=inductionFurnace.onMetadataInventoryTake, + activeOnTimer=inductionFurnace.activeOnTimer +}) +minetest.register_craft({ + type="shaped", + output="industrialtest:induction_furnace", + recipe={ + {industrialtest.elementKeys.copperIngot,industrialtest.elementKeys.copperIngot,industrialtest.elementKeys.copperIngot}, + {industrialtest.elementKeys.copperIngot,"industrialtest:electric_furnace",industrialtest.elementKeys.copperIngot}, + {industrialtest.elementKeys.copperIngot,"industrialtest:advanced_machine_block",industrialtest.elementKeys.copperIngot} + } +})