Elsys656 0 Posted February 25, 2016 Share Posted February 25, 2016 Here's a program to automate the creation of plates in the compressor its intended to be used with AE2 bothered me there was no really good way of automating this other than multiple compressors and full stacks of items to force the correct pattern. Changelog: changed to auto-detect primary database component address Planned Changes: If possible read AE crafting request to determine recipe and handle accordingly instead of via deduction should make setup smaller and more reliable. Picture of setup Diagram with descriptions Using enderIO to wire it up however you can use AE2 cables just as easily [ME Interface] --has patterns for heavy duty plate 1 2 and 3 pointed to hopper | V [Hopper] [ME Interface] --has patterns for simple plate materials steel,aluminum,copper etc. Is behind chest pointed to it | ^ V | [Robot] ------------------------>[Chest] --Can move chest to left of robot if you want to adjust the code to turn left instead of right :Inventory Controller | :Database | | | V V [Electric Compressor] ----> [Hopper] | V [Hopper] | V [ME Import Bus] --Any available side of hopper Robot code improvements can most likely be made feel free to post them or pm them to me, I use LUA regularly but I'm not a guru or anything. function print_r ( t ) local print_r_cache={} local function sub_print_r(t,indent) if (print_r_cache[tostring(t)]) then print(indent.."*"..tostring(t)) else print_r_cache[tostring(t)]=true if (type(t)=="table") then for pos,val in pairs(t) do if (type(val)=="table") then print(indent.."["..pos.."] => "..tostring(t).." {") sub_print_r(val,indent..string.rep(" ",string.len(pos)+8)) print(indent..string.rep(" ",string.len(pos)+6).."}") elseif (type(val)=="string") then print(indent.."["..pos..'] => "'..val..'"') else print(indent.."["..pos.."] => "..tostring(val)) end end else print(indent..tostring(t)) end end end if (type(t)=="table") then print(tostring(t).." {") sub_print_r(t," ") print("}") else sub_print_r(t," ") end print() end local event = require "event" -- load event table and store the pointer to it in event local component = require "component" local sides = require "sides" local robot = require "robot" local invCon = component.inventory_controller local db = component.database local dba = component.database.address local craft = false local timer = nil component = nil local steel = false local aluminum = false local bronze = false local craftingStacks = {} local running = true -- state variable so the loop can terminate --[[update methods]] function updateRobot() local invSize = robot.inventorySize() for i = 1, invSize do local result = invCon.getStackInInternalSlot(i) if result ~= nil then db.clear(i) invCon.storeInternal(i,dba,i) if result.name == "GalacticraftCore:item.basicItem" then print("Slot :"..i.."/"..invSize.." contains "..result.size.." of "..result.name..":"..result.damage.." Galacticraft Item Found!") if result.damage == 9 or result.damage == 8 or result.damage == 10 then print("Slot :"..i.."/"..invSize.." contains "..result.size.." of "..result.name..":"..result.damage.." Material Stack Found!") if result.damage == 9 then steel = true elseif result.damage == 8 then aluminum = true elseif result.damage == 10 then bronze = true end craftingStacks[db.computeHash(i)] = {["slot"] = i, ["damage"] = result.damage} print("Indexing result as "..db.computeHash(i)) end else print("Slot :"..i.."/"..invSize.." contains "..result.size.." of "..result.name..":"..result.damage) end else print("Slot :"..i.."/"..invSize.." is Empty") db.clear(i) end end if not craft then if timer ~= nil then event.cancel(timer) timer = nil end print("crafting qued") timer = event.timer(5,craftIfPossible) end end function doCraft() craft = true print("Starting Crafting!") for hash, value in pairs(craftingStacks) do local dbIndex = db.indexOf(hash) if dbIndex > 0 then if invCon.getStackInInternalSlot(value.slot).size >= 2 then if value.damage == 9 then print("Inserting steel from stack in slot "..value.slot) robot.select(value.slot) repeat local moved = invCon.dropIntoSlot(sides.bottom, 4, 1) moved = invCon.dropIntoSlot(sides.bottom, 7, 1) until moved == false print("Stack of steel depleted") elseif value.damage == 8 then print("Inserting aluminum from stack in slot "..value.slot) robot.select(value.slot) repeat local moved = invCon.dropIntoSlot(sides.bottom, 5, 1) moved = invCon.dropIntoSlot(sides.bottom, 8, 1) until moved == false print("Stack of aluminum depleted") elseif value.damage == 10 then print("Inserting bronze from stack in slot "..value.slot) robot.select(value.slot) repeat local moved = invCon.dropIntoSlot(sides.bottom, 6, 1) moved = invCon.dropIntoSlot(sides.bottom, 9, 1) until moved == false print("Stack of bronze depleted") end --unset stack as it no longer exists craftingStacks[hash] = nil print("Crafting successful with items in slot "..value.slot) else print("Cannot craft with stack due to insuficient items in slot "..value.slot) end else print("Crafting failed with stack in slot "..value.slot) craftingStacks[hash] = nil end end robot.select(1) print("Crafting processing check compressor for status") craft = false steel = false aluminum = false bronze = false end function craftIfPossible() --[[ table for pattern reference only local pattern = {[4] = 9, [5] = 8, [6] = 10, [7] = 9, [8] = 8, [9] = 10} ]] print("Checking material requirements") if steel == true and aluminum == true and bronze == true then doCraft() end timer = nil end function passthru(slot) robot.turnRight() for i=4, 12 do local compressorStack = invCon.getStackInSlot(sides.front, i) local robotStack = invCon.getStackInInternalSlot(slot) if robotStack ~= nil then if compressorStack ~= nil then if compressorStack.name == robotStack.name and compressorStack.damage == robotStack.damage then local spaceRemaining = compressorStack.maxSize - compressorStack.size if robotStack.size >= spaceRemaining then robot.select(slot) repeat local moved = invCon.dropIntoSlot(sides.front, i) until moved == false break else robot.select(slot) repeat local moved = invCon.dropIntoSlot(sides.front, i, spaceRemaining) until moved == false end end else robot.select(slot) repeat local moved = invCon.dropIntoSlot(sides.front, i) until moved == false end end end robot.turnLeft() robot.select(1) end --[[event handlers]] function unknownEvent() -- do nothing if the event wasn't relevant end -- table that holds all event handlers, and in case no match can be found returns the dummy function unknownEvent local myEventHandlers = setmetatable({}, { __index = function() return unknownEvent end }) --when robot inventory changes update database function myEventHandlers.inventory_changed(slot) local inStack = invCon.getStackInInternalSlot(slot) local query = db.get(slot) if query ~= nil then local result = invCon.compareToDatabase(slot,dba,slot) if not result then db.clear(slot) invCon.storeInternal(slot,dba,slot) print("Updating existing item in slot "..slot) end else invCon.storeInternal(slot,dba,slot) print("Storing new item in slot "..slot) end if inStack ~= nil then if inStack.name == "GalacticraftCore:item.basicItem" then print("Slot :"..slot.." contains "..inStack.size.." of "..inStack.name..":"..inStack.damage.." Galacticraft Item Found!") if inStack.damage == 9 or inStack.damage == 8 or inStack.damage == 10 then print("Slot :"..slot.." contains "..inStack.size.." of "..inStack.name..":"..inStack.damage.." Material Stack Found!") if inStack.damage == 9 then steel = true elseif inStack.damage == 8 then aluminum = true elseif inStack.damage == 10 then bronze = true end craftingStacks[db.computeHash(slot)] = {["slot"] = slot, ["damage"] = inStack.damage} print("Indexing stack as "..db.computeHash(slot)) else passthru(slot) return end else passthru(slot) return end else db.clear(slot) end if not craft then if timer ~= nil then event.cancel(timer) timer = nil end print("crafting qued") timer = event.timer(5,craftIfPossible) end end -- The main event handler as function to separate eventID from the remaining arguments function handleEvent(eventID, ...) if (eventID) then -- can be nil if no event was pulled for some time myEventHandlers[eventID](...) -- call the appropriate event handler with all remaining arguments end end --[[Init method before we hit the loop]] function initalize() print("Running program initalization.") updateRobot() end initalize() -- main event loop which processes all events, or sleeps if there is nothing to do while running do handleEvent(event.pull()) -- sleeps until an event is available, then process it end I've noticed if your game lags sometimes the items will get stuck in the compressor or the bot will not dump them into the inventory code needs error checking for those cases. Quote Link to post Share on other sites
Subtixx 5 Posted August 29, 2016 Share Posted August 29, 2016 I don't know what you mean, but compressors can be easily automated. I did it with EnderIO item conduits with speed downgrade upgrades. I guess it also can work with item ducts and servos (which are set to a stack size of 1). Quote Link to post Share on other sites