-- IndustrialTest -- Copyright (C) 2023 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") industrialtest.api={} industrialtest.api.maceratorRecipes={} -- \brief Adds power storage to metadata -- \param capacity How much EU item/node can store -- \param flow How much EU can flow in or out item/node per industrialtest.updateDelay -- \param ioConfig Input/Output configuration in following side order: -X, +X, -Y, +Y, -Z, +Z -- a - bidirectional, i - input, o - output -- \returns nil industrialtest.api.addPowerStorage=function(meta,capacity,flow,ioConfig) meta:set_int("industrialtest.powerCapacity",capacity) meta:set_int("industrialtest.powerFlow",flow) meta:set_int("industrialtest.powerAmount",0) meta:set_string("industrialtest.ioConfig",ioConfig) end industrialtest.api.hasPowerStorage=function(meta) local values={"industrialtest.powerCapacity","industrialtest.powerFlow","industrialtest.powerAmount","industrialtest.ioConfig"} for _,value in ipairs(values) do if not meta:contains(value) then return false end end return true end industrialtest.api.updateItemPowerText=function(itemstack) local meta=itemstack:get_meta() local def=minetest.registered_tools[itemstack:get_name()] meta:set_string("description",S("@1\n@2 / @3 EU",def.description,meta:get_int("industrialtest.powerAmount"),meta:get_int("industrialtest.powerCapacity"))) itemstack:set_wear(65535-meta:get_int("industrialtest.powerAmount")/meta:get_int("industrialtest.powerCapacity")*65534) end industrialtest.api.preparePowerStorageItem=function(itemstack) local meta=itemstack:get_meta() local def=minetest.registered_tools[itemstack:get_name()] if industrialtest.api.hasPowerStorage(meta) or not def or not def._industrialtest_powerStorage or not def._industrialtest_powerCapacity or not def._industrialtest_powerFlow then return false end industrialtest.api.addPowerStorage(meta,def._industrialtest_powerCapacity,def._industrialtest_powerFlow,"n/a") industrialtest.api.updateItemPowerText(itemstack) return true end industrialtest.api.prepareToolItem=function(itemstack) local def=minetest.registered_tools[itemstack:get_name()] if not def or not def._industrialtest_tool or not def.tool_capabilities or not def.tool_capabilities.uses then return false end local meta=itemstack:get_meta() meta:set_int("industrialtest.uses",def.tool_capabilities.uses) return true end industrialtest.api.afterToolUse=function(itemstack) local meta=itemstack:get_meta() local def=minetest.registered_tools[itemstack:get_name()] if not def or not def._industrialtest_tool or not def.tool_capabilities or not def.tool_capabilities.uses then return end if not meta:contains("industrialtest.uses") then industrialtest.prepareToolItem(itemstack) end local uses=meta:get_int("industrialtest.uses")-1 if uses==0 then itemstack:set_count(0) minetest.sound_play({name="default_tool_breaks"},{ gain=1, fade=0, pitch=1 },true) return end meta:set_int("industrialtest.uses",uses) itemstack:set_wear(65535-uses/def.tool_capabilities.uses*65535) end industrialtest.api.isFullyCharged=function(meta) return meta:get_int("industrialtest.powerAmount")>=meta:get_int("industrialtest.powerCapacity") end industrialtest.api.addPower=function(meta,amount) local powerAmount=meta:get_int("industrialtest.powerAmount") local powerCapacity=meta:get_int("industrialtest.powerCapacity") if powerAmount+amount>powerCapacity then local addedAmount=powerCapacity-powerAmount meta:set_int("industrialtest.powerAmount",powerCapacity) return addedAmount end meta:set_int("industrialtest.powerAmount",powerAmount+amount) return amount end industrialtest.api.addPowerToItem=function(itemstack,amount) local meta=itemstack:get_meta() if not industrialtest.api.hasPowerStorage(meta) then return 0 end local added=industrialtest.api.addPower(meta,amount) industrialtest.api.updateItemPowerText(itemstack) return added end industrialtest.api.transferPower=function(srcMeta,destMeta,amount) local currentFlow=math.min(srcMeta:get_int("industrialtest.powerAmount"),amount) if currentFlow==0 then return 0 end local actualFlow=industrialtest.api.addPower(destMeta,currentFlow) srcMeta:set_int("industrialtest.powerAmount",srcMeta:get_int("industrialtest.powerAmount")-actualFlow) return actualFlow end industrialtest.api.transferPowerToItem=function(srcMeta,itemstack,amount) local currentFlow=math.min(srcMeta:get_int("industrialtest.powerAmount"),amount) if currentFlow==0 then return 0 end local actualFlow=industrialtest.api.addPowerToItem(itemstack,currentFlow) srcMeta:set_int("industrialtest.powerAmount",srcMeta:get_int("industrialtest.powerAmount")-actualFlow) return actualFlow end industrialtest.api.powerFlow=function(pos) local meta=minetest.get_meta(pos) if not industrialtest.api.hasPowerStorage(meta) then return false end 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) } local neighbours={} for key,value in ipairs(neighbourPositions) do neighbours[key]=minetest.get_meta(value) end local neighboursContainingPower=0 for key,value in ipairs(neighbours) do local side=industrialtest.api.getOppositeSide(key) if industrialtest.api.hasPowerStorage(value) and industrialtest.api.isPowerInput(value,side) then neighboursContainingPower=neighboursContainingPower+1 else neighbourPositions[key]=0 neighbours[key]=0 end end if neighboursContainingPower==0 then return false end local powerFlow=meta:get_int("industrialtest.powerFlow") local powerDistribution=math.floor(powerFlow/neighboursContainingPower) -- TODO: if supplying machine power flow is too large for receiving machine to handle then that machine should explode local roomAvailable=false local transferred=false for key,value in ipairs(neighbours) do if industrialtest.api.isPowerOutput(meta,key) and value~=0 then if industrialtest.api.transferPower(meta,value,powerDistribution)>0 then transferred=true end local def=minetest.registered_nodes[minetest.get_node(neighbourPositions[key]).name] if def then local updateFormspec=def._industrialtest_updateFormspec if updateFormspec then updateFormspec(value) end local onPowerFlow=def._industrialtest_onPowerFlow if onPowerFlow and transferred then onPowerFlow(neighbourPositions[key],industrialtest.api.getOppositeSide(key)) end end minetest.get_node_timer(neighbourPositions[key]):start(industrialtest.updateDelay) if not industrialtest.api.isFullyCharged(value) then roomAvailable=true end end end return roomAvailable,transferred end industrialtest.api.triggerNeighbours=function(pos) 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 key,value in ipairs(neighbourPositions) do local meta=minetest.get_meta(value) local side=industrialtest.api.getOppositeSide(key) if industrialtest.api.hasPowerStorage(meta) and industrialtest.api.isPowerOutput(meta,side) then minetest.get_node_timer(value):start(industrialtest.updateDelay) end end end industrialtest.api.getOppositeSide=function(side) return (side%2==0 and side-1 or side+1) end industrialtest.api.getConnections=function(pos) local result={} 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) } local index=1 for key,value in ipairs(neighbourPositions) do local meta=minetest.get_meta(value) if industrialtest.api.hasPowerStorage(meta) then result[index]=key index=index+1 end end return result end industrialtest.api.changeIoConfig=function(meta,side,mode) local ioConfig=meta:get_string("industrialtest.ioConfig") ioConfig=string.sub(ioConfig,1,side-1)..mode..string.sub(ioConfig,side+1) meta:set_string("industrialtest.ioConfig",ioConfig) end industrialtest.api.isPowerInput=function(meta,side) local ioConfig=meta:get_string("industrialtest.ioConfig") local mode=string.sub(ioConfig,side,side) return (mode=="i" or mode=="a") end industrialtest.api.isPowerOutput=function(meta,side) local ioConfig=meta:get_string("industrialtest.ioConfig") local mode=string.sub(ioConfig,side,side) return (mode=="o" or mode=="a") end industrialtest.api.registerMaceratorRecipe=function(config) local definition={ output=config.output or "", recipe=config.recipe or "", time=config.time or 2 } industrialtest.api.maceratorRecipes[definition.recipe]=definition end industrialtest.api.getMaceratorRecipeResult=function(recipe) return industrialtest.api.maceratorRecipes[recipe] end