diff --git a/machines/induction_furnace.lua b/machines/induction_furnace.lua index 61ead22..a59506c 100644 --- a/machines/induction_furnace.lua +++ b/machines/induction_furnace.lua @@ -15,29 +15,65 @@ -- along with this program. If not, see <http://www.gnu.org/licenses/>. local S=minetest.get_translator("industrialtest") +industrialtest.InductionFurnace=table.copy(industrialtest.ActivatedElectricMachine) +industrialtest.internal.unpackTableInto(industrialtest.InductionFurnace,{ + name="industrialtest:induction_furnace", + description=S("Induction Furnace"), + 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" + }, + sounds="metal", + requiresWrench=true, + facedir=true, + storageLists={ + "src", + "dst", + "upgrades", + "powerStorage" + }, + powerLists={ + { + list="powerStorage", + direction="i" + } + }, + active={ + 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" + } + }, + capacity=industrialtest.api.mvPowerFlow*2, + flow=industrialtest.api.mvPowerFlow, + hasPowerInput=true, + ioConfig="iiiiii", + _opPower=60, + _efficiency=0.5 +}) -local inductionFurnace={} -inductionFurnace.opPower=60 -inductionFurnace.efficiency=0.5 - -local function calculateMaxSrcTime(pos) +function industrialtest.InductionFurnace.onConstruct(self,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) + 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) + industrialtest.ActivatedElectricMachine.onConstruct(self,pos) end -inductionFurnace.getFormspec=function(pos) +function industrialtest.InductionFurnace.getFormspec(self,pos) + local parentFormspec=industrialtest.ActivatedElectricMachine.getFormspec(self,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") @@ -60,32 +96,74 @@ inductionFurnace.getFormspec=function(pos) "listring[context;src]", "listring[context;dst]" } - return table.concat(formspec,"") + return parentFormspec..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 +function industrialtest.InductionFurnace.update(self,pos,elapsed,meta,inv) local srcList=inv:get_list("src") local heat=meta:get_int("heat") - - shouldRerunTimer,shouldUpdateFormspec=industrialtest.internal.chargeFromPowerStorageItem(meta,inv) + local shouldRerunTimer=false + local shouldUpdateFormspec=false if heat>0 then meta:set_int("heat",math.max(heat-math.max(2*elapsed,1),0)) - shouldRerunTimer=shouldRerunTimer or heat>0 + shouldRerunTimer=true shouldUpdateFormspec=true end + return shouldRerunTimer,shouldUpdateFormspec +end + +function industrialtest.InductionFurnace.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count) + if toList=="dst" then + return 0 + end + return industrialtest.ActivatedElectricMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count) +end + +function industrialtest.InductionFurnace.allowMetadataInventoryPut(self,pos,listname,index,stack) + if listname=="dst" then + return 0 + end + return industrialtest.ActivatedElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack) +end + +function industrialtest.InductionFurnace.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count) + industrialtest.ActivatedElectricMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count) + if fromList=="src" or toList=="src" then + self:calculateMaxSrcTime(pos) + end + if fromList=="src" and self.isInputEmpty(pos) then + local meta=minetest.get_meta(pos) + meta:set_float("srcTime",-1) + meta:set_float("maxSrcTime",0) + self:updateFormspec(pos) + elseif toList=="src" or (fromList=="dst" and not self.isOutputFull(pos)) then + self:triggerIfNeeded(pos) + end +end + +function industrialtest.InductionFurnace.onMetadataInventoryPut(self,pos,listname,index,stack,player) + industrialtest.ActivatedElectricMachine.onMetadataInventoryPut(self,pos,listname,index,stack,player) + if listname=="src" then + self:calculateMaxSrcTime(pos) + self:triggerIfNeeded(pos) + end +end + +function industrialtest.InductionFurnace.onMetadataInventoryTake(self,pos,listname,index,stack) + if listname=="src" then + self:calculateMaxSrcTime(pos) + elseif listname=="dst" and not self.isOutputFull(pos) then + self:triggerIfNeeded(pos) + end +end + +function industrialtest.InductionFurnace.shouldActivate(self,pos) + local meta=minetest.get_meta(pos) + local inv=meta:get_inventory() + local srcList=inv:get_list("src") + for _,slot in ipairs(srcList) do if not slot:is_empty() then local result,after=minetest.get_craft_result({ @@ -94,68 +172,27 @@ inductionFurnace.onTimer=function(pos,elapsed,meta,inv) 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 + return meta:get_int("industrialtest.powerAmount")>=self._opPower end end end - return shouldRerunTimer,shouldUpdateFormspec + return false end -inductionFurnace.allowMetadataInventoryMove=function(pos,fromList,fromIndex,toList,toIndex,count) - if toList=="dst" then - return 0 - end - return count +function industrialtest.InductionFurnace.shouldDeactivate(self,pos) + return not self:shouldActivate(pos) 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) +function industrialtest.InductionFurnace.activeUpdate(self,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 + local requiredPower=elapsed*self._opPower*speed - industrialtest.internal.chargeFromPowerStorageItem(meta,inv) - - local shouldContinue=false local results={} for _,slot in ipairs(srcList) do if slot:is_empty() then @@ -168,23 +205,13 @@ inductionFurnace.activeOnTimer=function(pos,elapsed,meta,inv) }) 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<requiredPower then - meta:set_float("srcTime",0) - minetest.swap_node(pos,{ - name="industrialtest:induction_furnace", - param2=minetest.get_node(pos).param2 - }) - minetest.get_node_timer(pos):start(industrialtest.updateDelay) - return false,true - end - srcTime=srcTime+elapsed*(1+heat/100) + srcTime=srcTime+elapsed*(1+heat/200) if srcTime>=maxSrcTime then for i,result in ipairs(results) do if result then @@ -206,55 +233,56 @@ inductionFurnace.activeOnTimer=function(pos,elapsed,meta,inv) industrialtest.api.addPower(meta,-requiredPower) - return true,true + return 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 -}) +function industrialtest.InductionFurnace.calculateMaxSrcTime(self,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*self._efficiency) + end + meta:set_float("maxSrcTime",maxSrcTime) +end + +function industrialtest.InductionFurnace.isInputEmpty(pos) + local meta=minetest.get_meta(pos) + local inv=meta:get_inventory() + local srcList=inv:get_list("src") + + for _,slot in ipairs(srcList) do + if not slot:is_empty() then + return false + end + end + + return true +end + +function industrialtest.InductionFurnace.isOutputFull(pos) + local meta=minetest.get_meta(pos) + local inv=meta:get_inventory() + local dstList=inv:get_list("dst") + + for _,slot in ipairs(dstList) do + if slot:get_free_space()>0 then + return false + end + end + + return true +end + +industrialtest.InductionFurnace:register() + minetest.register_craft({ type="shaped", output="industrialtest:induction_furnace",