Advertisement
Guest User

Untitled

a guest
Oct 20th, 2014
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.32 KB | None | 0 0
  1. --
  2.  
  3. -- ME Multi-Level Emitter using turtle
  4. -- supports custom functions on high or low level, dropping, crafting, compresscobble, redstone etc
  5. -- rename to startup for always on, ctrl-T stops the program
  6.  
  7. --i wonder if i could actually AUTORESET the me system, just gotta detect a crash... i could even recreate current crafting jobs!!!
  8.  
  9. local turtlefacing = "south" --must be set to turtles facing dir
  10. local meside = "south" --must be set to me controller side, should probably be same
  11. local polltimer = 0.5 --you can set this very low to coampraess maximum cobble, higher to reduce me system crash
  12.  
  13. 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!)
  14. --it resets the ME System if no crafting jobs have progressed
  15. --problem: what if there are no jobs, or the jobs dont have source materials
  16. --solution: only use it when you know there will be crafting jobs automatically constantly
  17. --see resetMeSystem() for adjustments
  18. local resetMeMoveThreshold = 50 --how many loops without progress before we reset the system, should be higher to prevent unneeded resets
  19.  
  20. local config = {}
  21.  
  22. local function setup()
  23. -- you must edit this function to change your configuration
  24. -- {"ItemToMeasure", "> or < or anything else for always", ThresholdAmount, FunctionToCall, "DropSide/Arg1", "Arg2"}
  25. -- valid sides are north, south, east, west, up, and down
  26. -- "ItemToMeasure" can be "Name", "ID:-1" (any dmgamount), or "ID:DMG" (specific dmg level is fastest)
  27.  
  28.  
  29. -- config[1] = {"Dirt", ">", 64, dropItemToSide, "up" }
  30. -- config[2] = {"Copper Ingot", "<", 64, dropItemToSide, "north", nil }
  31. -- config[3] = {"Bread", "<", 64, craftItem, nil, nil }
  32. -- config[4] = {"4:0", ">", 96, compress } --compress cobble
  33. -- config[5] = {"2506:0", ">", 8, compress }
  34. -- config[6] = {"2506:1", ">", 8, compress }
  35. -- config[7] = {"2506:2", ">", 8, compress }
  36. -- config[8] = {"2506:3", ">", 8, compress }
  37. -- config[9] = {"2506:4", ">", 8, compress }
  38. -- config[10] = {"2506:5", ">", 8, compress }
  39. -- config[11] = {"2506:6", ">", 8, compress } --up to octuple
  40. -- config[12] = {"Bread", "><", 96, emitRedstone, "right" } --redstone light while compressing
  41.  
  42. --current support function are:
  43. -- dropItemToSide (arg1 is the side to drop to)(sides other than top bottom and front arent working)
  44. -- craftItem (turtle needs to be next to ME Controller to use craftItem)
  45. -- compress (for compressed cobblestone, crafting turtle required, faster than a single cyclic assembler)
  46. -- 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)
  47. -- 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
  48. end
  49.  
  50.  
  51. local me
  52. local mepull
  53. local turtlefacingint = 0
  54. local stack = {}
  55. local available = {}
  56.  
  57. function dropItemToSide(info)
  58. local excess = stack.qty - info.threshold
  59. local maxreps = 25 --drops this many stacks per loop
  60.  
  61. local dropFunc = turtle.drop
  62. if info.side == "top" then dropFunc = turtle.dropUp end
  63. if info.side == "bottom" then dropFunc = turtle.dropDown end
  64.  
  65. 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
  66. if info.side == "right" then turtle.turnRight() me = peripheral.wrap("left") end
  67. if info.side == "back" then turtle.turnLeft() turtle.turnLeft() me = peripheral.wrap("back") end
  68.  
  69.  
  70. stack.qty = excess
  71.  
  72. if info.dmg1 ~= nil and info.dmg1 ~= -1 then
  73. while (stack.qty > 0) and (maxreps > 0) do
  74. me.extractItem(stack, mepull)
  75. stacksize = turtle.getItemCount(1)
  76. if stacksize < 1 then
  77. break
  78. end
  79. maxreps = maxreps - 1
  80. stack.qty = stack.qty - stacksize
  81.  
  82. if not dropFunc() then
  83. break
  84. end
  85. end
  86. else
  87. if info.id1 ~= nil then
  88. for kk, vv in pairs(available) do
  89. if vv.id == info.id1 then
  90. stack.dmg = vv.dmg
  91. while (stack.qty > 0) and (maxreps > 0) do
  92. me.extractItem(stack, mepull)
  93. stacksize = turtle.getItemCount(1)
  94. if stacksize < 1 then
  95. break
  96. end
  97. maxreps = maxreps - 1
  98. stack.qty = stack.qty - stacksize
  99.  
  100. if not dropFunc() then
  101. break
  102. end
  103. end
  104. end
  105. end
  106. else
  107. for kk, vv in pairs(available) do
  108. if vv.name == info.item1 then
  109. stack.id = vv.id
  110. stack.dmg = vv.dmg
  111. while (stack.qty > 0) and (maxreps > 0) do
  112.  
  113. me.extractItem(stack, mepull)
  114. stacksize = turtle.getItemCount(1)
  115. if stacksize < 1 then
  116. break
  117. end
  118. maxreps = maxreps - 1
  119. stack.qty = stack.qty - stacksize
  120.  
  121. if not dropFunc() then
  122. break
  123. end
  124. end
  125. end
  126. end
  127. end
  128. end
  129.  
  130. if info.side == "left" then turtle.turnRight() me = peripheral.wrap(meside) end
  131. if info.side == "right" then turtle.turnLeft() me = peripheral.wrap(meside) end
  132. if info.side == "back" then turtle.turnLeft() turtle.turnLeft() me = peripheral.wrap(meside) end
  133.  
  134. returnInventory()
  135. end
  136.  
  137. function craftItem(info)
  138. stack.qty = info.threshold - stack.qty
  139.  
  140. local jobs = me.getJobList()
  141. for k, v in pairs(jobs) do
  142. if v.id == stack.id and v.dmg == stack.dmg then
  143. stack.qty = stack.qty - v.qty
  144. end
  145. end
  146.  
  147. me.requestCrafting(stack)
  148. end
  149.  
  150. function returnInventory()
  151.  
  152. for slot = 1, 16 do
  153. if turtle.getItemCount(slot) > 0 then
  154. me.insertItem(slot, 64, mepull)
  155. print("Returning Stack To ME")
  156. end
  157. end
  158. end
  159.  
  160. local craftingSlot = {1,2,3,5,6,7,9,10,11}
  161. function compressSmall(info)
  162. stack.qty = me.countOfItemType(stack.id, stack.dmg)
  163. if stack.qty < 9 then return end
  164. if stack.qty > 63 then stack.qty = 63 end
  165.  
  166. local count = math.floor(stack.qty / 9)
  167. stack.qty = count * 9
  168.  
  169. me.extractItem(stack, mepull)
  170. for slot = 2, 9 do
  171. turtle.transferTo(craftingSlot[slot], count)
  172. end
  173. turtle.craft()
  174. returnInventory()
  175. end
  176.  
  177. function compress(info)
  178. stack.qty = me.countOfItemType(stack.id, stack.dmg)
  179. local excess = stack.qty - info.threshold
  180. if excess < 704 then
  181. compressSmall(info)
  182. end
  183.  
  184. local maxreps = 10
  185. stack.qty = 64
  186.  
  187. while (excess >= 704) and (maxreps > 0) do
  188. maxreps = maxreps - 1
  189. for slot = 1, 11 do
  190. me.extractItem(stack, mepull)
  191. end
  192. me.insertItem(4, 64, mepull)
  193. me.insertItem(8, 64, mepull)
  194. turtle.craft()
  195. me.insertItem(1, 64, mepull)
  196. excess = excess - 576
  197. end
  198. end
  199.  
  200. function emitRedstone(info)
  201. if info.arg2 == false then
  202. rs.setOutput(info.side, stack.qty < info.threshold)
  203. else
  204. rs.setOutput(info.side, stack.qty > info.threshold)
  205. end
  206. end
  207.  
  208. local resetMeTicksSinceMovement = 0 --zero
  209. local resetMeJobList = {}
  210.  
  211. function resetMeSystem()
  212. if turtle.dig == nil then return end
  213.  
  214. --test if any jobs have gone down in qty
  215.  
  216. local jobs = me.getJobList()
  217. local founditem = false
  218.  
  219. resetMeTicksSinceMovement = resetMeTicksSinceMovement + 1
  220. for k, v in pairs(resetMeJobList) do
  221. founditem = false
  222. for kk, vv in pairs(jobs) do
  223. if v.id == vv.id and v.dmg == vv.dmg then
  224. founditem = true
  225. if vv.qty < v.qty then
  226. resetMeTicksSinceMovement = 0
  227. end
  228. end
  229. end
  230. if not founditem then
  231. resetMeTicksSinceMovement = 0
  232. end
  233. end
  234. resetMeJobList = jobs
  235. print("reset counter: " .. resetMeTicksSinceMovement)
  236.  
  237. if resetMeTicksSinceMovement < resetMeMoveThreshold then
  238. return
  239. end
  240.  
  241. --we are resetting the ME now
  242.  
  243. returnInventory()
  244. turtle.select(1)
  245. turtle.dig()
  246. sleep(0.1)
  247. turtle.place()
  248. sleep(1)
  249.  
  250. local newjobs = me.getJobList()
  251.  
  252. for k, v in pairs(newjobs) do
  253. for kk, vv in pairs(jobs) do
  254. if v.id == vv.id and v.dmg == vv.dmg then
  255. vv.qty = vv.qty - v.qty
  256. end
  257. end
  258. end
  259.  
  260.  
  261. for k, v in pairs(jobs) do
  262. me.requestCrafting(v)
  263. end
  264. resetMeTicksSinceMovement = 0
  265. end
  266.  
  267.  
  268.  
  269.  
  270. local direction = {[0]="east", [1]="south", [2]="west", [3]="north"}
  271. local side = {[0]="front", [1]="right", [2]="back", [3]="left"}
  272.  
  273. local function sideToDirection(side)
  274. if side == "front" then
  275. return direction[turtlefacingint%4]
  276. end
  277. if side == "right" then
  278. return direction[(turtlefacingint+1)%4]
  279. end
  280. if side == "back" then
  281. return direction[(turtlefacingint+2)%4]
  282. end
  283. if side == "left" then
  284. return direction[(turtlefacingint+3)%4]
  285. end
  286. if side == "top" then
  287. return "up"
  288. end
  289. if side == "bottom" then
  290. return "down"
  291. end
  292. return side
  293. end
  294.  
  295. local function directionToSide(dir)
  296. if dir == "east" then
  297. return side[(-turtlefacingint+4)%4]
  298. end
  299. if dir == "south" then
  300. return side[(-turtlefacingint+5)%4]
  301. end
  302. if dir == "west" then
  303. return side[(-turtlefacingint+6)%4]
  304. end
  305. if dir == "north" then
  306. return side[(-turtlefacingint+7)%4]
  307. end
  308. if dir == "up" then
  309. return "top"
  310. end
  311. if dir == "down" then
  312. return "bottom"
  313. end
  314. return dir
  315. end
  316.  
  317. local function negateDirection(dir)
  318.  
  319. if dir == "east" then return "west" end
  320. if dir == "west" then return "east" end
  321. if dir == "north" then return "south" end
  322. if dir == "south" then return "north" end
  323. if dir == "up" then return "down" end
  324. if dir == "down" then return "up" end
  325. return dir
  326.  
  327. end
  328.  
  329. local function processConfig()
  330. local id, dmg
  331. local pretty = {}
  332.  
  333. if turtlefacing == "east" then turtlefacingint = 0 end
  334. if turtlefacing == "south" then turtlefacingint = 1 end
  335. if turtlefacing == "west" then turtlefacingint = 2 end
  336. if turtlefacing == "north" then turtlefacingint = 3 end
  337.  
  338. mepull = negateDirection(sideToDirection(meside))
  339. meside = directionToSide(meside)
  340.  
  341. for k, v in pairs(config) do
  342. print("Processing config item " .. k)
  343. pretty[k] = {}
  344.  
  345. pretty[k].item1 = v[1];
  346. pretty[k].id1, pretty[k].dmg1 = string.match(v[1], "([0-9-]+):([0-9-]+)")
  347.  
  348. pretty[k].compare = v[2]
  349. pretty[k].threshold = v[3]
  350. pretty[k].func = v[4]
  351.  
  352. pretty[k].arg1 = v[5];
  353. pretty[k].pull = negateDirection(sideToDirection(v[5]))
  354. pretty[k].side = directionToSide(v[5])
  355.  
  356. pretty[k].arg2 = v[6];
  357.  
  358. pretty[k].id1 = tonumber(pretty[k].id1)
  359. pretty[k].dmg1 = tonumber(pretty[k].dmg1)
  360. pretty[k].id2 = tonumber(pretty[k].id2)
  361. pretty[k].dmg2 = tonumber(pretty[k].dmg2)
  362. end
  363.  
  364. config = pretty
  365. end
  366.  
  367. print("Running Setup")
  368. setup()
  369. print("Processing Config")
  370. processConfig()
  371.  
  372. --reorient the turtle, and find the me controller
  373. for s = 1, 4 do
  374. me = peripheral.wrap(meside)
  375. if me ~= nil and me.getJobList ~= nil then
  376. break
  377. end
  378. turtle.turnRight()
  379. if s == 4 then
  380. print("ME Controller Not Found")
  381. return
  382. end
  383. end
  384.  
  385. turtle.select(1)
  386.  
  387. local hitthreshold = "false"
  388.  
  389. while true do
  390. returnInventory()
  391. available = me.getAvailableItems()
  392. for k, v in pairs(config) do
  393. hitthreshold = "false"
  394.  
  395. --count items
  396. stack.id = nil
  397. if v.dmg1 ~= nil and v.dmg1 ~= -1 then
  398. stack.qty = me.countOfItemType(v.id1, v.dmg1)
  399. stack.id = v.id1
  400. stack.dmg = v.dmg1
  401. else
  402. stack.qty = 0
  403. if v.id1 ~= nil then
  404. for kk, vv in pairs(available) do
  405. if vv.id == v.id1 then
  406. stack.id = vv.id
  407. stack.dmg = vv.dmg
  408. stack.qty = stack.qty + vv.qty
  409. end
  410. end
  411. else
  412. for kk, vv in pairs(available) do
  413. if vv.name == v.item1 then
  414. stack.id = vv.id
  415. stack.dmg = vv.dmg
  416. stack.qty = stack.qty + vv.qty
  417. end
  418. end
  419. end
  420. end
  421.  
  422. if stack.id ~= nil then
  423. hitthreshold = "true"
  424. if v.compare == ">" then
  425. if stack.qty <= v.threshold then
  426. hitthreshold = "false"
  427. end
  428. end
  429. if v.compare == "<" then
  430. if stack.qty >= v.threshold then
  431. hitthreshold = "false"
  432. end
  433. end
  434. print("#" .. k .. " " .. v.item1 .. " * " .. stack.qty .. " " .. v.compare .. " " .. v.threshold .. " = " .. hitthreshold)
  435. if hitthreshold == "true" then
  436. v.func(v)
  437. end
  438. end
  439. end
  440. sleep(polltimer)
  441. resetMeSystem()
  442. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement