npexception

Turtle Ore Dict Sorter

Apr 9th, 2020
1,329
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.01 KB | None | 0 0
  1. local version = 1.61
  2. --  +------------------------+  --
  3. --  |-->  INITIALIZATION  <--|  --
  4. --  +------------------------+  --
  5. if not turtle then
  6.   print("This program can only be")
  7.   print("executed by a turtle.")
  8.   return
  9. end
  10.  
  11. -- UPDATE HANDLING --
  12. if _UD and _UD.su(version, "94eCzump", {...}) then return end
  13.  
  14. local ARGS = {...}
  15.  
  16.  
  17. local stackDrops = false
  18. local config = {}
  19.  
  20. local CONFIG_FILE = "oredict.config"
  21.  
  22. local function writeConfig()
  23.   local file = fs.open(CONFIG_FILE, "w")
  24.   file.write(textutils.serialise(config))
  25.   file.close()
  26. end
  27.  
  28. if fs.exists(CONFIG_FILE) then
  29.   local file = fs.open(CONFIG_FILE, "r")
  30.   local content = file.readAll()
  31.   config = textutils.unserialise(content)
  32.   file.close()
  33. else
  34.   writeConfig()
  35. end
  36.  
  37. -- check if interactive mode is desired
  38. local interactive = false
  39.  
  40. for _,arg in pairs(ARGS) do
  41.   if arg == "interactive" then
  42.     interactive = true
  43.     break
  44.   end
  45. end
  46.  
  47. -- find free slot
  48. local slot = nil
  49. for i=1,16 do
  50.   if turtle.getItemCount(i) == 0 then
  51.     slot = i
  52.     break
  53.   end
  54. end
  55.  
  56. if not slot then
  57.   print("Turtle needs a free slot to")
  58.   print("run this program.")
  59.   return
  60. end
  61. turtle.select(slot)
  62.  
  63. -- find ore dictionary
  64. local od = peripheral.find("oreDictionary")
  65. if not od then
  66.   print("No ore dictionary attached.")
  67.   return
  68. end
  69.  
  70. local term = term
  71. local colors = colors
  72.  
  73. local function statusLine(text)
  74.   local x,y = term.getCursorPos()
  75.   term.setCursorPos(x+2,y)
  76.   print(text)
  77. end
  78.  
  79. local function status(text, color, delay)
  80.   term.clear()
  81.   term.setCursorPos(1,1)
  82.   if term.isColor() then
  83.     term.setTextColor(colors.yellow)
  84.   end
  85.   print(" Ore Dict Item Sorter ")
  86.   print("----------------------")
  87.   print()
  88.  
  89.   if term.isColor() then
  90.     if color == nil then
  91.       color = colors.white
  92.     end
  93.     term.setTextColor(color)
  94.   end
  95.  
  96.   if type(text) == "table" then
  97.     for i=1,#text do
  98.       statusLine(text[i])
  99.     end
  100.   else
  101.     statusLine(text,color)
  102.   end
  103.  
  104.   if term.isColor() then
  105.     term.setTextColor(colors.white)
  106.   end
  107.  
  108.   if delay then
  109.     sleep(delay)
  110.   end
  111. end
  112.  
  113.  
  114. local function itemDetails()
  115.   local details = turtle.getItemDetail()
  116.   return details.name.."#"..tostring(details.damage)
  117. end
  118.  
  119. local function key()
  120.   local event, c = os.pullEvent("char")
  121.   return c
  122. end
  123.  
  124. local function write(text)
  125.   term.clearLine()
  126.   local x,y = term.getCursorPos()
  127.   term.setCursorPos(1,y)
  128.   term.write(text)
  129. end
  130.  
  131. local ignore = {}
  132.  
  133. local function chooseTarget()
  134.   local statusText = {
  135.     "Use as target item?",
  136.     "y_es | n_ext | i_gnore"
  137.   }
  138.   while true do
  139.     local name = itemDetails()
  140.     statusText[3] = name
  141.     status(statusText)
  142.     k = key()
  143.     -- save to config
  144.     if k == "y" then
  145.       local entries = od.getEntries()
  146.       for _,entry in pairs(entries) do
  147.         config[entry] = name
  148.       end
  149.       writeConfig()
  150.       return true
  151.     end
  152.     -- add to ignore list
  153.     if k == "i" then
  154.       ignore[name] = true
  155.       return false
  156.     end
  157.     -- transmute to next item
  158.     if k == "n" then
  159.       od.transmute()
  160.     end
  161.   end
  162. end
  163.  
  164.  
  165. local function unify()
  166.   for _,entry in pairs(od.getEntries()) do
  167.     local target = config[entry]
  168.     if target then
  169.       local name = itemDetails()
  170.       local seen = {name=true}
  171.       -- transmute to target as necessary
  172.       while name ~= target do
  173.         od.transmute()
  174.         name = itemDetails()
  175.         -- check if we tried all possibilities
  176.         if seen[name] then
  177.           -- TODO: log to file
  178.           -- print(entry..": can't transmute '"..name.."' to target item")
  179.           return false
  180.         end
  181.         seen[name] = true
  182.       end
  183.       return true
  184.     end
  185.   end
  186.  
  187.   if interactive then
  188.     local name = itemDetails()
  189.     if ignore[name] then
  190.       return false
  191.     end
  192.     return chooseTarget()
  193.   end
  194. end
  195.  
  196. local function tryAction(name, fn)
  197.   status(name, colors.lightBlue)
  198.   local first = true
  199.   while not fn() do
  200.     if first then
  201.       status("retry "..name, colors.orange)
  202.       first = false
  203.     end
  204.     sleep(1)
  205.   end
  206. end
  207.  
  208. -- wraps drop function to only drop one item at once if configured
  209. local function wrapDrop(dropFn)
  210.   if stackDrops then
  211.     return dropFn
  212.   end
  213.   return function()
  214.     while turtle.getItemCount() > 0 do
  215.       if not dropFn(1) then
  216.         return false
  217.       end
  218.     end
  219.     return true
  220.   end
  221. end
  222.  
  223. -- begin unification process
  224. local suck = turtle.suckDown
  225. local drop = wrapDrop(turtle.drop)
  226. local dropOther = wrapDrop(turtle.dropUp)
  227.  
  228. local counter = 0
  229.  
  230. while true do
  231.   tryAction("suck", suck)
  232.   counter = counter + turtle.getItemCount()
  233.   if unify() or not dropOther then
  234.     -- drop known items
  235.     tryAction("drop", drop)
  236.   else
  237.     -- drop unknown items
  238.     tryAction("drop other", dropOther)
  239.   end
  240.   local monitor = peripheral.find("monitor")
  241.   if monitor then
  242.     monitor.clear()
  243.     monitor.setCursorPos(2,2)
  244.     monitor.write("Items sorted")
  245.     monitor.setCursorPos(4,4)
  246.     monitor.write(tostring(counter))
  247.   end
  248. end
Add Comment
Please, Sign In to add comment