Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --
- -- ME Multi-Level Emitter using turtle
- -- supports custom functions on high or low level, dropping, crafting, compresscobble, redstone etc
- -- rename to startup for always on, ctrl-T stops the program
- --i wonder if i could actually AUTORESET the me system, just gotta detect a crash... i could even recreate current crafting jobs!!!
- local turtlefacing = "south" --must be set to turtles facing dir
- local meside = "south" --must be set to me controller side, should probably be same
- local polltimer = 0.5 --you can set this very low to coampraess maximum cobble, higher to reduce me system crash
- local enableMeSystemReset = true --this is only available with Mining Turtle (maybe you could change the dig/place behavior)(you could use both a crafty and a mining turtle, more speed!)
- --it resets the ME System if no crafting jobs have progressed
- --problem: what if there are no jobs, or the jobs dont have source materials
- --solution: only use it when you know there will be crafting jobs automatically constantly
- --see resetMeSystem() for adjustments
- local resetMeMoveThreshold = 50 --how many loops without progress before we reset the system, should be higher to prevent unneeded resets
- local config = {}
- local function setup()
- -- you must edit this function to change your configuration
- -- {"ItemToMeasure", "> or < or anything else for always", ThresholdAmount, FunctionToCall, "DropSide/Arg1", "Arg2"}
- -- valid sides are north, south, east, west, up, and down
- -- "ItemToMeasure" can be "Name", "ID:-1" (any dmgamount), or "ID:DMG" (specific dmg level is fastest)
- -- config[1] = {"Dirt", ">", 64, dropItemToSide, "up" }
- -- config[2] = {"Copper Ingot", "<", 64, dropItemToSide, "north", nil }
- -- config[3] = {"Bread", "<", 64, craftItem, nil, nil }
- -- config[4] = {"4:0", ">", 96, compress } --compress cobble
- -- config[5] = {"2506:0", ">", 8, compress }
- -- config[6] = {"2506:1", ">", 8, compress }
- -- config[7] = {"2506:2", ">", 8, compress }
- -- config[8] = {"2506:3", ">", 8, compress }
- -- config[9] = {"2506:4", ">", 8, compress }
- -- config[10] = {"2506:5", ">", 8, compress }
- -- config[11] = {"2506:6", ">", 8, compress } --up to octuple
- -- config[12] = {"Bread", "><", 96, emitRedstone, "right" } --redstone light while compressing
- --current support function are:
- -- dropItemToSide (arg1 is the side to drop to)(sides other than top bottom and front arent working)
- -- craftItem (turtle needs to be next to ME Controller to use craftItem)
- -- compress (for compressed cobblestone, crafting turtle required, faster than a single cyclic assembler)
- -- emitRedstone (use "anything else" instead of "> or <", arg1 should be the redstone side, arg2 should be true for high=on, false for high=off)(dont use a side that has a modem or crafting table attached)
- -- FunctionToCall can be any function, it is called when the threshold is met, is passed a (processed) copy of the config item, also stack var will be set to total qty of item, with last seen id and dmg vals
- end
- local me
- local mepull
- local turtlefacingint = 0
- local stack = {}
- local available = {}
- function dropItemToSide(info)
- local excess = stack.qty - info.threshold
- local maxreps = 25 --drops this many stacks per loop
- local dropFunc = turtle.drop
- if info.side == "top" then dropFunc = turtle.dropUp end
- if info.side == "bottom" then dropFunc = turtle.dropDown end
- if info.side == "left" then turtle.turnLeft() me = peripheral.wrap("right") end --turning breaks the wrap, so we fix it, this relies on ME Controller being in front of turtle
- if info.side == "right" then turtle.turnRight() me = peripheral.wrap("left") end
- if info.side == "back" then turtle.turnLeft() turtle.turnLeft() me = peripheral.wrap("back") end
- stack.qty = excess
- if info.dmg1 ~= nil and info.dmg1 ~= -1 then
- while (stack.qty > 0) and (maxreps > 0) do
- me.extractItem(stack, mepull)
- stacksize = turtle.getItemCount(1)
- if stacksize < 1 then
- break
- end
- maxreps = maxreps - 1
- stack.qty = stack.qty - stacksize
- if not dropFunc() then
- break
- end
- end
- else
- if info.id1 ~= nil then
- for kk, vv in pairs(available) do
- if vv.id == info.id1 then
- stack.dmg = vv.dmg
- while (stack.qty > 0) and (maxreps > 0) do
- me.extractItem(stack, mepull)
- stacksize = turtle.getItemCount(1)
- if stacksize < 1 then
- break
- end
- maxreps = maxreps - 1
- stack.qty = stack.qty - stacksize
- if not dropFunc() then
- break
- end
- end
- end
- end
- else
- for kk, vv in pairs(available) do
- if vv.name == info.item1 then
- stack.id = vv.id
- stack.dmg = vv.dmg
- while (stack.qty > 0) and (maxreps > 0) do
- me.extractItem(stack, mepull)
- stacksize = turtle.getItemCount(1)
- if stacksize < 1 then
- break
- end
- maxreps = maxreps - 1
- stack.qty = stack.qty - stacksize
- if not dropFunc() then
- break
- end
- end
- end
- end
- end
- end
- if info.side == "left" then turtle.turnRight() me = peripheral.wrap(meside) end
- if info.side == "right" then turtle.turnLeft() me = peripheral.wrap(meside) end
- if info.side == "back" then turtle.turnLeft() turtle.turnLeft() me = peripheral.wrap(meside) end
- returnInventory()
- end
- function craftItem(info)
- stack.qty = info.threshold - stack.qty
- local jobs = me.getJobList()
- for k, v in pairs(jobs) do
- if v.id == stack.id and v.dmg == stack.dmg then
- stack.qty = stack.qty - v.qty
- end
- end
- me.requestCrafting(stack)
- end
- function returnInventory()
- for slot = 1, 16 do
- if turtle.getItemCount(slot) > 0 then
- me.insertItem(slot, 64, mepull)
- print("Returning Stack To ME")
- end
- end
- end
- local craftingSlot = {1,2,3,5,6,7,9,10,11}
- function compressSmall(info)
- stack.qty = me.countOfItemType(stack.id, stack.dmg)
- if stack.qty < 9 then return end
- if stack.qty > 63 then stack.qty = 63 end
- local count = math.floor(stack.qty / 9)
- stack.qty = count * 9
- me.extractItem(stack, mepull)
- for slot = 2, 9 do
- turtle.transferTo(craftingSlot[slot], count)
- end
- turtle.craft()
- returnInventory()
- end
- function compress(info)
- stack.qty = me.countOfItemType(stack.id, stack.dmg)
- local excess = stack.qty - info.threshold
- if excess < 704 then
- compressSmall(info)
- end
- local maxreps = 10
- stack.qty = 64
- while (excess >= 704) and (maxreps > 0) do
- maxreps = maxreps - 1
- for slot = 1, 11 do
- me.extractItem(stack, mepull)
- end
- me.insertItem(4, 64, mepull)
- me.insertItem(8, 64, mepull)
- turtle.craft()
- me.insertItem(1, 64, mepull)
- excess = excess - 576
- end
- end
- function emitRedstone(info)
- if info.arg2 == false then
- rs.setOutput(info.side, stack.qty < info.threshold)
- else
- rs.setOutput(info.side, stack.qty > info.threshold)
- end
- end
- local resetMeTicksSinceMovement = 0 --zero
- local resetMeJobList = {}
- function resetMeSystem()
- if turtle.dig == nil then return end
- --test if any jobs have gone down in qty
- local jobs = me.getJobList()
- local founditem = false
- resetMeTicksSinceMovement = resetMeTicksSinceMovement + 1
- for k, v in pairs(resetMeJobList) do
- founditem = false
- for kk, vv in pairs(jobs) do
- if v.id == vv.id and v.dmg == vv.dmg then
- founditem = true
- if vv.qty < v.qty then
- resetMeTicksSinceMovement = 0
- end
- end
- end
- if not founditem then
- resetMeTicksSinceMovement = 0
- end
- end
- resetMeJobList = jobs
- print("reset counter: " .. resetMeTicksSinceMovement)
- if resetMeTicksSinceMovement < resetMeMoveThreshold then
- return
- end
- --we are resetting the ME now
- returnInventory()
- turtle.select(1)
- turtle.dig()
- sleep(0.1)
- turtle.place()
- sleep(1)
- local newjobs = me.getJobList()
- for k, v in pairs(newjobs) do
- for kk, vv in pairs(jobs) do
- if v.id == vv.id and v.dmg == vv.dmg then
- vv.qty = vv.qty - v.qty
- end
- end
- end
- for k, v in pairs(jobs) do
- me.requestCrafting(v)
- end
- resetMeTicksSinceMovement = 0
- end
- local direction = {[0]="east", [1]="south", [2]="west", [3]="north"}
- local side = {[0]="front", [1]="right", [2]="back", [3]="left"}
- local function sideToDirection(side)
- if side == "front" then
- return direction[turtlefacingint%4]
- end
- if side == "right" then
- return direction[(turtlefacingint+1)%4]
- end
- if side == "back" then
- return direction[(turtlefacingint+2)%4]
- end
- if side == "left" then
- return direction[(turtlefacingint+3)%4]
- end
- if side == "top" then
- return "up"
- end
- if side == "bottom" then
- return "down"
- end
- return side
- end
- local function directionToSide(dir)
- if dir == "east" then
- return side[(-turtlefacingint+4)%4]
- end
- if dir == "south" then
- return side[(-turtlefacingint+5)%4]
- end
- if dir == "west" then
- return side[(-turtlefacingint+6)%4]
- end
- if dir == "north" then
- return side[(-turtlefacingint+7)%4]
- end
- if dir == "up" then
- return "top"
- end
- if dir == "down" then
- return "bottom"
- end
- return dir
- end
- local function negateDirection(dir)
- if dir == "east" then return "west" end
- if dir == "west" then return "east" end
- if dir == "north" then return "south" end
- if dir == "south" then return "north" end
- if dir == "up" then return "down" end
- if dir == "down" then return "up" end
- return dir
- end
- local function processConfig()
- local id, dmg
- local pretty = {}
- if turtlefacing == "east" then turtlefacingint = 0 end
- if turtlefacing == "south" then turtlefacingint = 1 end
- if turtlefacing == "west" then turtlefacingint = 2 end
- if turtlefacing == "north" then turtlefacingint = 3 end
- mepull = negateDirection(sideToDirection(meside))
- meside = directionToSide(meside)
- for k, v in pairs(config) do
- print("Processing config item " .. k)
- pretty[k] = {}
- pretty[k].item1 = v[1];
- pretty[k].id1, pretty[k].dmg1 = string.match(v[1], "([0-9-]+):([0-9-]+)")
- pretty[k].compare = v[2]
- pretty[k].threshold = v[3]
- pretty[k].func = v[4]
- pretty[k].arg1 = v[5];
- pretty[k].pull = negateDirection(sideToDirection(v[5]))
- pretty[k].side = directionToSide(v[5])
- pretty[k].arg2 = v[6];
- pretty[k].id1 = tonumber(pretty[k].id1)
- pretty[k].dmg1 = tonumber(pretty[k].dmg1)
- pretty[k].id2 = tonumber(pretty[k].id2)
- pretty[k].dmg2 = tonumber(pretty[k].dmg2)
- end
- config = pretty
- end
- print("Running Setup")
- setup()
- print("Processing Config")
- processConfig()
- --reorient the turtle, and find the me controller
- for s = 1, 4 do
- me = peripheral.wrap(meside)
- if me ~= nil and me.getJobList ~= nil then
- break
- end
- turtle.turnRight()
- if s == 4 then
- print("ME Controller Not Found")
- return
- end
- end
- turtle.select(1)
- local hitthreshold = "false"
- while true do
- returnInventory()
- available = me.getAvailableItems()
- for k, v in pairs(config) do
- hitthreshold = "false"
- --count items
- stack.id = nil
- if v.dmg1 ~= nil and v.dmg1 ~= -1 then
- stack.qty = me.countOfItemType(v.id1, v.dmg1)
- stack.id = v.id1
- stack.dmg = v.dmg1
- else
- stack.qty = 0
- if v.id1 ~= nil then
- for kk, vv in pairs(available) do
- if vv.id == v.id1 then
- stack.id = vv.id
- stack.dmg = vv.dmg
- stack.qty = stack.qty + vv.qty
- end
- end
- else
- for kk, vv in pairs(available) do
- if vv.name == v.item1 then
- stack.id = vv.id
- stack.dmg = vv.dmg
- stack.qty = stack.qty + vv.qty
- end
- end
- end
- end
- if stack.id ~= nil then
- hitthreshold = "true"
- if v.compare == ">" then
- if stack.qty <= v.threshold then
- hitthreshold = "false"
- end
- end
- if v.compare == "<" then
- if stack.qty >= v.threshold then
- hitthreshold = "false"
- end
- end
- print("#" .. k .. " " .. v.item1 .. " * " .. stack.qty .. " " .. v.compare .. " " .. v.threshold .. " = " .. hitthreshold)
- if hitthreshold == "true" then
- v.func(v)
- end
- end
- end
- sleep(polltimer)
- resetMeSystem()
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement