diff --git a/machines/fluid_generator.lua b/machines/fluid_generator.lua index 7c637fa..2ce89a7 100644 --- a/machines/fluid_generator.lua +++ b/machines/fluid_generator.lua @@ -15,14 +15,25 @@ -- along with this program. If not, see . local S=minetest.get_translator("industrialtest") -local fluidGenerator={} -fluidGenerator.getFormspec=function(pos,config) +-- Common functions +local function onConstruct(pos) + local meta=minetest.get_meta(pos) + local inv=meta:get_inventory() + inv:set_size("charged",1) + inv:set_size("src",1) + inv:set_size("dst",1) + meta:set_float("fluidAmount",0) + meta:set_string("fluid","") +end + +local function getFormspec(self,pos) + local parentFormspec=industrialtest.ActivatedElectricMachine.getFormspec(self,pos) local meta=minetest.get_meta(pos) local fluidPercent=meta:get_float("fluidAmount")/100 local powerPercent=meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity") local fluid=meta:get_string("fluid") - local fuel=config.getFuel(fluid) + local fuel=self.getFuel(fluid) local tile=(fuel and fuel.texture or "industrialtest_gui_fluid_bg.png") local formspec={ "list[context;src;2,1.8;1,1]", @@ -32,219 +43,305 @@ fluidGenerator.getFormspec=function(pos,config) industrialtest.internal.getItemSlotBg(2,4.2,1,1), "list[context;charged;6,3;1,1]", industrialtest.internal.getItemSlotBg(6,3,1,1), - "box[9,1;0.3,4.8;#202020]", - (powerPercent>0 and "box[9,"..(1+4.8-(powerPercent*4.8))..";0.3,"..(powerPercent*4.8)..";#FF1010]" or ""), + self.createPowerIndicatorWidget(powerPercent,9,1), "listring[context;src]", "listring[context;dst]" } - return table.concat(formspec,"") + return parentFormspec..table.concat(formspec,"") end -fluidGenerator.onConstruct=function(pos,meta,inv) - inv:set_size("charged",1) - inv:set_size("src",1) - inv:set_size("dst",1) - meta:set_float("fluidAmount",0) - meta:set_string("fluid","") +local function allowMetadataInventoryMove(pos,fromList,fromIndex,toList,toIndex,count) + if toList=="dst" then + return 0 + end + return count end -fluidGenerator.onTimer=function(pos,elapsed,meta,inv,config) +local function allowMetadataInventoryPut(pos,listname,index,stack,player) + if listname=="dst" then + return 0 + end + return stack:get_count() +end + +local function takeFuelFromItem(self,pos) + local meta=minetest.get_meta(pos) + local inv=meta:get_inventory() local fluidSlot=inv:get_stack("src",1) - local chargedSlot=inv:get_stack("charged",1) - local afterFlow,flowTransferred=industrialtest.api.powerFlow(pos) - local shouldUpdateFormspec=false - local shouldRerunTimer=(afterFlow and meta:get_int("industrialtest.powerAmount")>0) - if fluidSlot:get_count()>0 and meta:get_float("fluidAmount")<=9000 then - local fuel=config.getFuelByItem(fluidSlot:get_name()) - if fuel and (fuel.name==meta:get_string("fluid") or meta:get_string("fluid")=="") then - local leftover=false - local leftoverAddingSucceeded=false - for _,item in ipairs(fuel.storageItems) do - if item.name==fluidSlot:get_name() and item.leftover then - if inv:room_for_item("dst",ItemStack(item.leftover)) then - inv:add_item("dst",ItemStack(item.leftover)) - leftoverAddingSucceeded=true - end - leftover=true + local fluid=meta:get_string("fluid") + local fluidAmount=meta:get_float("fluidAmount") + + if fluidSlot:is_empty() or fluidAmount>9000 then + return false + end + + local fuel=self.getFuelByItem(fluidSlot:get_name()) + if fuel and (fuel.name==fluid or fluid=="") then + local leftover=false + local leftoverAddingSucceeded=false + for _,item in ipairs(fuel.storageItems) do + if item.name==fluidSlot:get_name() and item.leftover then + local leftoverItemstack=ItemStack(item.leftover) + if inv:room_for_item("dst",leftoverItemstack) then + inv:add_item("dst",leftoverItemstack) + leftoverAddingSucceeded=true end - end - if not leftover or leftoverAddingSucceeded then - fluidSlot:take_item() - inv:set_stack("src",1,fluidSlot) - meta:set_string("fluid",fuel.name) - meta:set_float("fluidAmount",meta:get_float("fluidAmount")+1000) - shouldUpdateFormspec=true - shouldRerunTimer=false + leftover=true end end + if not leftover or leftoverAddingSucceeded then + fluidSlot:take_item() + inv:set_stack("src",1,fluidSlot) + meta:set_string("fluid",fuel.name) + meta:set_float("fluidAmount",fluidAmount+1000) + return true + end end - if meta:get_float("fluidAmount")>=50 and not industrialtest.api.isFullyCharged(meta) then - meta:set_float("fluidAmount",meta:get_int("fluidAmount")-50*elapsed) - local toAdd=math.ceil(config.getFuel(meta:get_string("fluid")).calorificValue*elapsed) + + return false +end + +local function generate(self,pos,elapsed) + local meta=minetest.get_meta(pos) + local fluidAmount=meta:get_float("fluidAmount") + + if fluidAmount>0 and not industrialtest.api.isFullyCharged(meta) then + local fluidUsed=math.min(fluidAmount,50) + meta:set_float("fluidAmount",fluidAmount-fluidUsed*elapsed) + local toAdd=math.ceil(self.getFuel(meta:get_string("fluid")).calorificValue*elapsed*fluidUsed/50) industrialtest.api.addPower(meta,toAdd) - shouldUpdateFormspec=true - if config.registerActiveVariant then - minetest.swap_node(pos,{ - name="industrialtest:"..config.name.."_active", - param2=minetest.get_node(pos).param2 - }) - minetest.get_node_timer(pos):start(industrialtest.updateDelay) - else - shouldRerunTimer=true - end + return true end - if chargedSlot:get_count()>0 and meta:get_int("industrialtest.powerAmount")>0 then - if industrialtest.api.transferPowerToItem(meta,chargedSlot,industrialtest.api.lvPowerFlow)>0 then - inv:set_stack("charged",1,chargedSlot) - shouldUpdateFormspec=true - shouldRerunTimer=true - end + + return false +end + +industrialtest.GeothermalGenerator=table.copy(industrialtest.ActivatedElectricMachine) +industrialtest.internal.unpackTableInto(industrialtest.GeothermalGenerator,{ + name="industrialtest:geothermal_generator", + description=S("Geothermal Generator"), + tiles={ + "industrialtest_machine_block.png", + "industrialtest_machine_block.png", + "industrialtest_machine_block.png", + "industrialtest_machine_block.png", + "industrialtest_machine_block.png", + "industrialtest_machine_block.png^industrialtest_geothermal_generator_front.png" + }, + sounds="metal", + facedir=true, + storageLists={ + "src", + "dst", + "charged" + }, + active={ + tiles={ + "industrialtest_machine_block.png", + "industrialtest_machine_block.png", + "industrialtest_machine_block.png", + "industrialtest_machine_block.png", + "industrialtest_machine_block.png", + "industrialtest_machine_block.png^industrialtest_geothermal_generator_front_active.png" + }, + lightSource=10 + }, + powerLists={ + { + list="charged", + direction="o" + } + }, + requiresWrench=true, + hasPowerOutput=true, + capacity=7000, + flow=industrialtest.api.lvPowerFlow, + ioConfig="oooooo", + getFormspec=getFormspec, + getFuel=industrialtest.api.getGeothermalGeneratorFuel, + getFuelByItem=industrialtest.api.getGeothermalGeneratorFuelByItem +}) + +function industrialtest.GeothermalGenerator.onConstruct(self,pos) + onConstruct(pos) + industrialtest.ActivatedElectricMachine.onConstruct(self,pos) +end + +function industrialtest.GeothermalGenerator.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count) + return math.min(allowMetadataInventoryMove(pos,fromList,fromIndex,toList,toIndex,count),industrialtest.ActivatedElectricMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)) +end + +function industrialtest.GeothermalGenerator.allowMetadataInventoryPut(self,pos,listname,index,stack,player) + return math.min(allowMetadataInventoryPut(pos,listname,index,stack,player),industrialtest.ActivatedElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack,player)) +end + +function industrialtest.GeothermalGenerator.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count) + if toList=="src" and takeFuelFromItem(self,pos) then + self:trigger(pos) end - if flowTransferred then + industrialtest.ActivatedElectricMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count) +end + +function industrialtest.GeothermalGenerator.onMetadataInventoryPut(self,pos,listname,index,stack) + if listname=="src" and takeFuelFromItem(self,pos) then + self:trigger(pos) + end + industrialtest.ActivatedElectricMachine.onMetadataInventoryPut(self,pos,listname,index,stack) +end + +function industrialtest.GeothermalGenerator.shouldActivate(self,pos) + local meta=minetest.get_meta(pos) + local fluidAmount=meta:get_float("fluidAmount") + + return fluidAmount>0 and not industrialtest.api.isFullyCharged(meta) +end + +function industrialtest.GeothermalGenerator.shouldDeactivate(self,pos) + local meta=minetest.get_meta(pos) + local fluidAmount=meta:get_float("fluidAmount") + + return fluidAmount<=0 or industrialtest.api.isFullyCharged(meta) +end + +function industrialtest.GeothermalGenerator.activeUpdate(self,pos,elapsed) + local shouldUpdateFormspec=false + + if takeFuelFromItem(self,pos) then shouldUpdateFormspec=true end - return shouldRerunTimer,shouldUpdateFormspec -end -fluidGenerator.metadataChange=function(pos) - minetest.get_node_timer(pos):start(industrialtest.updateDelay) -end - -fluidGenerator.activeOnTimer=function(pos,elapsed,meta,inv,config) - local fluidSlot=inv:get_stack("src",1) - local chargedSlot=inv:get_stack("charged",1) - local afterFlow,flowTransferred=industrialtest.api.powerFlow(pos) - local shouldUpdateFormspec=false - local shouldRerunTimer=(afterFlow and meta:get_int("industrialtest.powerAmount")>0) - - if fluidSlot:get_count()>0 and meta:get_float("fluidAmount")<=9000 then - local fuel=config.getFuelByItem(fluidSlot:get_name()) - if fuel and (fuel.name==meta:get_string("fluid") or meta:get_string("fluid")=="") then - local leftover=false - local leftoverAddingSucceeded=false - for _,item in ipairs(fuel.storageItems) do - if item.name==fluidSlot:get_name() and item.leftover then - if inv:room_for_item("dst",ItemStack(item.leftover)) then - inv:add_item("dst",ItemStack(item.leftover)) - leftoverAddingSucceeded=true - end - leftover=true - end - end - if not leftover or leftoverAddingSucceeded then - fluidSlot:take_item() - inv:set_stack("src",1,fluidSlot) - meta:set_string("fluid",fuel.name) - meta:set_float("fluidAmount",meta:get_float("fluidAmount")+1000) - shouldUpdateFormspec=true - shouldRerunTimer=false - end - end + if generate(self,pos,elapsed) then + shouldUpdateFormspec=true end - if meta:get_float("fluidAmount")>=50 and not industrialtest.api.isFullyCharged(meta) then - meta:set_float("fluidAmount",meta:get_int("fluidAmount")-50*elapsed) - local toAdd=math.ceil(industrialtest.api.getGeothermalGeneratorFuel(meta:get_string("fluid")).calorificValue*elapsed) - industrialtest.api.addPower(meta,toAdd) + + return shouldUpdateFormspec +end + +industrialtest.GeothermalGenerator:register() + +minetest.register_craft({ + type="shaped", + output="industrialtest:geothermal_generator", + recipe={ + {industrialtest.elementKeys.glass,"industrialtest:empty_cell",industrialtest.elementKeys.glass}, + {industrialtest.elementKeys.glass,"industrialtest:empty_cell",industrialtest.elementKeys.glass}, + {"industrialtest:refined_iron_ingot","industrialtest:generator","industrialtest:refined_iron_ingot"} + } +}) + +industrialtest.WaterMill=table.copy(industrialtest.ElectricMachine) +industrialtest.internal.unpackTableInto(industrialtest.WaterMill,{ + name="industrialtest:water_mill", + description=S("Water Mill"), + tiles={ + "industrialtest_machine_block.png", + "industrialtest_machine_block.png", + "industrialtest_machine_block.png^industrialtest_water_mill_side.png", + "industrialtest_machine_block.png^industrialtest_water_mill_side.png", + "industrialtest_machine_block.png^industrialtest_water_mill_side.png", + "industrialtest_machine_block.png^industrialtest_water_mill_side.png" + }, + sounds="metal", + storageLists={ + "src", + "dst", + "charged" + }, + powerLists={ + { + list="charged", + direction="o" + } + }, + requiresWrench=true, + hasPowerOutput=true, + capacity=7000, + flow=industrialtest.api.lvPowerFlow, + ioConfig="oooooo", + getFormspec=getFormspec, + getFuel=industrialtest.api.getWaterMillFuel, + getFuelByItem=industrialtest.api.getWaterMillFuelByItem +}) + +function industrialtest.WaterMill.onConstruct(self,pos) + onConstruct(pos) + industrialtest.ElectricMachine.onConstruct(self,pos) +end + +function industrialtest.WaterMill.canUpdate(self,pos) + local meta=minetest.get_meta(pos) + local fluidAmount=meta:get_float("fluidAmount") + + return fluidAmount>0 and not industrialtest.api.isFullyCharged(meta) +end + +function industrialtest.WaterMill.update(self,pos,elapsed) + local shouldUpdateFormspec=false + local shouldRerunTimer=false + + if takeFuelFromItem(self,pos) then shouldUpdateFormspec=true shouldRerunTimer=true - else - minetest.swap_node(pos,{ - name="industrialtest:"..config.name, - param2=minetest.get_node(pos).param2 - }) - minetest.get_node_timer(pos):start(industrialtest.updateDelay) end - if chargedSlot:get_count()>0 and meta:get_int("industrialtest.powerAmount")>0 then - if industrialtest.api.transferPowerToItem(meta,chargedSlot,industrialtest.api.lvPowerFlow)>0 then - inv:set_stack("charged",1,chargedSlot) - shouldUpdateFormspec=true - shouldRerunTimer=true - end - end - if flowTransferred then + + if generate(self,pos,elapsed) then shouldUpdateFormspec=true + shouldRerunTimer=true end + return shouldRerunTimer,shouldUpdateFormspec end -local function registerFluidGenerator(config) - local definition={ - name=config.name, - displayName=config.displayName, - getFormspec=function(pos) - return fluidGenerator.getFormspec(pos,config) - end, - capacity=7000, - flow=industrialtest.api.lvPowerFlow, - ioConfig="oooooo", - requiresWrench=true, - registerActiveVariant=config.registerActiveVariant, - powerSlots={"charged"}, - storageSlots={"src","dst"}, - sounds="metal", - groups={ - _industrialtest_hasPowerOutput=1 - }, - customKeys={ - tiles={ - "industrialtest_machine_block.png"..(config.customTopTexture and "^"..config.customTopTexture or ""), - "industrialtest_machine_block.png"..(config.customBottomTexture and "^"..config.customBottomTexture or ""), - "industrialtest_machine_block.png"..(config.customRightTexture and "^"..config.customRightTexture or ""), - "industrialtest_machine_block.png"..(config.customLeftTexture and "^"..config.customLeftTexture or ""), - "industrialtest_machine_block.png"..(config.customBackTexture and "^"..config.customBackTexture or ""), - "industrialtest_machine_block.png"..(config.customFrontTexture and "^"..config.customFrontTexture or "") - }, - paramtype2="facedir", - legacy_facedir_simple=true - }, - onConstruct=fluidGenerator.onConstruct, - onTimer=function(pos,elapsed,meta,inv) - return fluidGenerator.onTimer(pos,elapsed,meta,inv,config) - end, - onMetadataInventoryPut=fluidGenerator.metadataChange, - onMetadataInventoryMove=fluidGenerator.metadataChange - } - if config.registerActiveVariant then - definition.activeCustomKeys={ - tiles={ - "industrialtest_machine_block.png"..(config.customTopTexture and "^"..config.customTopTextureActive or ""), - "industrialtest_machine_block.png"..(config.customBottomTexture and "^"..config.customBottomTextureActive or ""), - "industrialtest_machine_block.png"..(config.customRightTexture and "^"..config.customRightTextureActive or ""), - "industrialtest_machine_block.png"..(config.customLeftTexture and "^"..config.customLeftTextureActive or ""), - "industrialtest_machine_block.png"..(config.customBackTexture and "^"..config.customBackTextureActive or ""), - "industrialtest_machine_block.png"..(config.customFrontTexture and "^"..config.customFrontTextureActive or "") - }, - light_source=8 - } - definition.activeOnTimer=function(pos,elapsed,meta,inv) - return fluidGenerator.activeOnTimer(pos,elapsed,meta,inv,config) - end - end - industrialtest.internal.registerMachine(definition) +function industrialtest.WaterMill.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count) + return math.min(allowMetadataInventoryMove(pos,fromList,fromIndex,toList,toIndex,count),industrialtest.ActivatedElectricMachine.allowMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count)) end -registerFluidGenerator({ - name="geothermal_generator", - displayName=S("Geothermal Generator"), - customFrontTexture="industrialtest_geothermal_generator_front.png", - customFrontTextureActive="industrialtest_geothermal_generator_front_active.png", - getFuel=industrialtest.api.getGeothermalGeneratorFuel, - getFuelByItem=industrialtest.api.getGeothermalGeneratorFuelByItem, - registerActiveVariant=true, - reactsToNeighbouringNodes=false -}) +function industrialtest.WaterMill.allowMetadataInventoryPut(self,pos,listname,index,stack,player) + return math.min(allowMetadataInventoryPut(pos,listname,index,stack,player),industrialtest.ActivatedElectricMachine.allowMetadataInventoryPut(self,pos,listname,index,stack,player)) +end + +function industrialtest.WaterMill.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count) + if toList=="src" and takeFuelFromItem(self,pos) then + self:trigger(pos) + end + industrialtest.ElectricMachine.onMetadataInventoryMove(self,pos,fromList,fromIndex,toList,toIndex,count) +end + +function industrialtest.WaterMill.onMetadataInventoryPut(self,pos,listname,index,stack) + if listname=="src" and takeFuelFromItem(self,pos) then + self:trigger(pos) + end + industrialtest.ElectricMachine.onMetadataInventoryPut(self,pos,listname,index,stack) +end + +function industrialtest.WaterMill.action(self,pos) + local meta=minetest.get_meta(pos) + local powerToAdd=0 + local neighbourPositions={ + vector.offset(pos,-1,0,0), + vector.offset(pos,1,0,0), + vector.offset(pos,0,-1,0), + vector.offset(pos,0,1,0), + vector.offset(pos,0,0,-1), + vector.offset(pos,0,0,1) + } + for _,value in ipairs(neighbourPositions) do + local node=minetest.get_node_or_nil(value) + if node then + local fuel=industrialtest.api.getWaterMillFuel(node.name) + if fuel then + powerToAdd=powerToAdd+fuel.calorificValue*0.2 + end + end + end + if industrialtest.api.addPower(meta,powerToAdd)>0 then + self:updateFormspec(pos) + self:trigger(pos) + end +end + +industrialtest.WaterMill:register() -registerFluidGenerator({ - name="water_mill", - displayName=S("Water Mill"), - customLeftTexture="industrialtest_water_mill_side.png", - customRightTexture="industrialtest_water_mill_side.png", - customFrontTexture="industrialtest_water_mill_side.png", - customBackTexture="industrialtest_water_mill_side.png", - getFuel=industrialtest.api.getWaterMillFuel, - getFuelByItem=industrialtest.api.getWaterMillFuelByItem, - registerActiveVariant=false -}) local neighbors={} for key,_ in pairs(industrialtest.api.waterMillFuels) do table.insert(neighbors,key) @@ -255,37 +352,8 @@ minetest.register_abm({ neighbors=neighbors, interval=industrialtest.updateDelay, chance=1, - action=function(pos,node) - local meta=minetest.get_meta(pos) - local inv=meta:get_inventory() - local chargedSlot=inv:get_stack("charged",1) - local powerToAdd=0 - local neighbourPositions={ - vector.offset(pos,-1,0,0), - vector.offset(pos,1,0,0), - vector.offset(pos,0,-1,0), - vector.offset(pos,0,1,0), - vector.offset(pos,0,0,-1), - vector.offset(pos,0,0,1) - } - for _,value in ipairs(neighbourPositions) do - local node=minetest.get_node_or_nil(value) - if node then - local fuel=industrialtest.api.getWaterMillFuel(node.name) - if fuel then - powerToAdd=powerToAdd+fuel.calorificValue*0.2 - end - end - end - if industrialtest.api.addPower(meta,powerToAdd)>0 then - local def=minetest.registered_nodes[node.name] - def._industrialtest_updateFormspec(meta) - end - if chargedSlot:get_count()>0 and meta:get_int("industrialtest.powerAmount")>0 then - if industrialtest.api.transferPowerToItem(meta,chargedSlot,industrialtest.api.lvPowerFlow)>0 then - inv:set_stack("charged",1,chargedSlot) - end - end + action=function(pos) + industrialtest.WaterMill:action(pos) end })