inventory = {} types = { unknown = "unknown", dirt = "dirt", grass = "dirt", sapling = "sapling", log = "wood", wood = "wood", dropoff = "dropoff", --not actual item type, but can be refered to } -- position for each type -- while standing at target location facing desired direction -- turtle should be able to do a turtle.suck() to grab the material -- if dir=up suckUp() if dir=down suckDown() position = {} -- if you have a small tunnel towards your storage for the turtle -- addStoragePathCheckpoint(x,y,z) to add enterance -- ^ can be used multiple times if you have a complicated path -- turtle will follow the path in revese when it exits storageEnterancePath = {} local differenceRecord = {} function update() for slot = 1,16 do local oldType = nil if type(inventory[slot])=="table" then oldType=inventory[slot].type end inventory[slot] = { type = oldType or types.unknown, qty = turtle.getItemCount(slot), } if inventory[slot].qty==0 then inventory[slot].type = nil end end end -- gets all global variables function init( global ) update() setfenv(1,global) end function recordDifference() differenceRecord = {} for slot=1,16 do differenceRecord[slot] = { type = inventory[slot].type, qty = inventory[slot].qty, } end end function getDifference() local difference = {} update() for slot=1,16 do local qtyDifference = inventory[slot].qty - differenceRecord[slot].qty if qtyDifference~=0 or inventory[slot].type~=differenceRecord[slot].type then difference[slot] = {} difference[slot].qty = qtyDifference difference[slot].type = differenceRecord[slot].type if inventory[slot].type~=differenceRecord[slot].type then difference[slot].oldType = differenceRecord[slot].type end end end return difference end function setItemAccess( item,x,y,z,dir ) position[item] = {x=x,y=y,z=z,dir=dir} end function getItemAccess( item ) return position[item].x,position[item].y,position[item].z,position[item].dir end function addStoragePathCheckpoint( x,y,z ) storageEnterancePath[#storageEnterancePath+1] = {x=x,y=y,z=z} end function getStoragePathCheckpoint( step ) if type(storageEnterancePath[step])=="table" then return (storageEnterancePath[step].x or _),(storageEnterancePath[step].y or _),(storageEnterancePath[step].z or _) end end function resetStoragePath() storageEnterancePath = {} end -- reverse = boolean function followStoragePath( reverse ) if type(reverse)~="boolean" then reverse = false end local start = 1 local stop = #storageEnterancePath if reverse then start=stop stop=1 end for step = start,stop,mult(stop-start) do gps.goto(getStoragePathCheckpoint(step)) end end function getItemCount( item ) update() local count = 0 for slot = 1,16 do if inventory[slot].type == item then count = count + inventory[slot].qty end end return count end -- gotoStorageRoom = (boolean) wether or not it should follow the storage path function dropoff( gotoStorageRoom ) if type(gotoStorageRoom)~="boolean" then gotoStorageRoom = false end -- dropoff must have a location local x,y,z,dir = getItemAccess(types.dropoff) if type(x)~="number" or type(y)~="number" or type(z)~="number" or type(dir)~="string" then return false end if gotoStorageRoom then followStoragePath() end gps.goto(x,y,z,dir) for slot=1,16 do local count = turtle.getItemCount(slot) while count~=0 do turtle.select(slot) if dir==gps.up then turtle.dropUp(count) elseif dir==gps.down then turtle.dropDown(count) else turtle.drop(count) end count = turtle.getItemCount(slot) end end -- exit the storage room if gotoStorageRoom then followStoragePath(true) end end -- tries to get item from storage canceles if it has enough -- returns true on success and false when it fails for some reason -- noEnterancePath=true if you dont want it to go through the storage enterance path function getItem( item,minQty,noEnterancePath ) if type(minQty)~="number" then minQty=64 end if type(noEnterancePath)~="boolean" then noEnterancePath=false end -- count quantity already in inventory local qtyRequired = minQty - getItemCount(item) if qtyRequired < 1 then -- already got enough of target item return true end -- item must be obtainable local x,y,z,dir = getItemAccess(item) if type(x)~="number" or type(y)~="number" or type(z)~="number" or type(dir)~="string" then return false end if not noEnterancePath then followStoragePath() end -- check if inv is full update() local invFull = true for slot=1,16 do if inventory[slot].qty == 0 then invFull = false break end end if invFull then dropoff(false) end gps.goto(x,y,z,dir) local qtyInInv-- number repeat recordDifference() if dir == gps.up then turtle.suckUp() elseif dir == gps.down then turtle.suckDown() else turtle.suck() end -- check how many slots changed when you sucked for items local diff = getDifference() local slotsChanged = 0 for slot,item in pairs(diff) do slotsChanged = slotsChanged + 1 end if slotsChanged == 0 then -- didn't obtain anything when trying to get items -- gonna have to loop through again and again --break elseif slotsChanged > 1 then -- more than one slot changed, might be 'cause of player interaction -- go empty out and try again just so we know for sure we can keep track of the item dropoff(false) gps.goto(x,y,z,dir) elseif slotsChanged == 1 then -- one slot changed, record it, gotta keep track of it for slot in pairs(diff) do inventory[slot].type = item end end qtyInInv = getItemCount(item) until qtyInInv >= qtyRequired if not noEnterancePath then followStoragePath(true) end return true end -- example input -- t = { "dirt", "sapling" } minQty = 64: gets 64 dirt and 64 saplings function getItems( t,minQty ) for num,item in ipairs(t) do if num == 1 then followStoragePath(false) end getItem(item,minQty,true) if num == #t then followStoragePath(true) end end end function select( item ) for slot=1,16 do if inventory[slot].type == item then turtle.select(slot) return true end end return false end