CoderPuppy

[CC1.63] Turtle Crafting Station

Jun 4th, 2014
268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.25 KB | None | 0 0
  1. -- Requires imgui: 5AcWhbc8
  2.  
  3. os.loadAPI('imgui')
  4.  
  5. local function with(base, props)
  6.     local new = {}
  7.     for k, v in pairs(base) do
  8.         new[k] = v
  9.     end
  10.     -- TODO: maybe?
  11.     setmetatable(new, getmetatable(base))
  12.     for k, v in pairs(props) do
  13.         new[k] = v
  14.     end
  15.     return new
  16. end
  17.  
  18. local function concat(a, b)
  19.     local res = {}
  20.     for i, val in ipairs(a) do
  21.         res[#res + 1] = val
  22.     end
  23.     for i, val in ipairs(b) do
  24.         res[#res + 1] = val
  25.     end
  26.     return res
  27. end
  28.  
  29. local function disp(val, visited)
  30.     if type(visited) ~= 'table' then
  31.         visited = {}
  32.     end
  33.  
  34.     if visited[val] == true then
  35.         return 'Circular: ' .. tostring(val)
  36.     elseif type(val) == 'string' then
  37.         return textutils.serialize(val)
  38.     elseif type(val) == 'number' or type(val) == 'boolean' then
  39.         return tostring(val)
  40.     elseif type(val) == 'table' then
  41.         local subVisited = with(visited, {[val] = true})
  42.         local str = tostring(val) .. ' -- {'
  43.         local namedEntries = {}
  44.         local numEntries = {}
  45.         for i, v in ipairs(val) do
  46.             numEntries[i] = disp(v, subVisited)
  47.         end
  48.         for k, v in pairs(val) do
  49.             if type(numEntries[k]) ~= 'string' then
  50.                 namedEntries[#namedEntries + 1] = {k, disp(v, subVisited)}
  51.             end
  52.         end
  53.         -- if #namedEntries == 0 and #numEntries <= 2 then
  54.         --  str = str .. ' ' .. table.concat(numEntries, ', ') .. ' '
  55.         -- else
  56.             for i, v in ipairs(numEntries) do
  57.                 str = str .. '\t'
  58.                 for line in v:gmatch('([^\n\r]+)') do
  59.                     str = str .. '\n\t' .. line .. ''
  60.                 end
  61.                 str = str .. ','
  62.             end
  63.             for i, kv in ipairs(namedEntries) do
  64.                 local k = kv[1]
  65.                 local v = kv[2]
  66.                 if type(k) ~= 'string' or not k:match('^[%a_][%a%d_]*$') then
  67.                     k = '[' .. disp(k, subVisited) .. ']'
  68.                 end
  69.                 str = str .. '\n\t' .. k .. ' = '
  70.                 local first = true
  71.                 for line in v:gmatch('([^\n\r]+)') do
  72.                     if first then
  73.                         str = str .. line .. '\n'
  74.                     else
  75.                         str = str .. '\t' .. line .. '\n'
  76.                     end
  77.                     first = false
  78.                 end
  79.                 str = str:sub(1, -2) .. ';'
  80.             end
  81.             str = str .. '\n'
  82.         -- end
  83.         str = str .. '}'
  84.         return str
  85.     end
  86. end
  87.  
  88. local function checkType(types)
  89.     for i, itemType in ipairs(types) do
  90.         if turtle.compareTo(itemType.slot) then
  91.             return i
  92.         end
  93.     end
  94.  
  95.     local typesI = #types + 1
  96.     types[typesI] = {
  97.         slot = turtle.getSelectedSlot();
  98.         qty = 0;
  99.         slots = {};
  100.         stacksize = turtle.getItemCount(turtle.getSelectedSlot()) + turtle.getItemSpace(turtle.getSelectedSlot());
  101.     }
  102.  
  103.     return typesI
  104. end
  105.  
  106. fs.open('log', 'w').close()
  107. local function log(...)
  108.     local log = fs.open('log', 'a')
  109.     log.write(table.concat({...}, ' ') .. '\n')
  110.     log.close()
  111. end
  112.  
  113. local allSlots = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}
  114. local craftingSlots = {1,2,3,5,6,7,9,10,11}
  115. local ringSlots = {1,2,3,7,11,10,9,5}
  116. local outputSlot = 8
  117. local function getItems(slots)
  118.     local types = {}
  119.     local items = {}
  120.  
  121.     for index, i in ipairs(slots) do
  122.         turtle.select(i)
  123.         local itemType = types[checkType(types)]
  124.         local qty = turtle.getItemCount(i)
  125.         itemType.qty = itemType.qty + qty
  126.         itemType.slots[i] = qty
  127.         items[i] = {
  128.             slot = i;
  129.             qty = qty;
  130.             type = itemType;
  131.         }
  132.     end
  133.  
  134.     return items, types
  135. end
  136.  
  137. local width, height = term.getSize()
  138.  
  139. local off = 0
  140. local buttonWidth = 5
  141. local cursorSlot = 6
  142.  
  143. local n = nil
  144. local success = nil
  145.  
  146. local function swirl()
  147.     local items, types = getItems(ringSlots)
  148.     if items[1].qty >= 1 and
  149.        items[2].qty == 0 and
  150.        items[3].qty == 0 and
  151.        items[5].qty == 0 and
  152.        items[7].qty == 0 and
  153.        items[9].qty == 0 and
  154.        items[10].qty == 0 and
  155.        items[11].qty == 0 then
  156.         turtle.select(1)
  157.         local qty = items[1].qty
  158.         local leftover = qty % 8
  159.         local each = (qty - leftover) / 8
  160.         local amts = {
  161.             [2] = 1; --each + math.min(math.max(0, leftover - 1), 1);
  162.             [3] = 1; --each + math.min(math.max(0, leftover - 2), 1);
  163.             [5] = 1; --each + math.min(math.max(0, leftover - 3), 1);
  164.             [7] = 1; --each + math.min(math.max(0, leftover - 4), 1);
  165.             [9] = 1; --each + math.min(math.max(0, leftover - 5), 1);
  166.             [10] = 1; --each + math.min(math.max(0, leftover - 6), 1);
  167.             [11] = 1; --each + math.min(math.max(0, leftover - 7), 1);
  168.         }
  169.         -- print(disp(amts))
  170.         for i, amt in pairs(amts) do
  171.             if type(i) == 'number' then
  172.                 turtle.transferTo(i, amt)
  173.             end
  174.         end
  175.         turtle.select(cursorSlot)
  176.     elseif items[1].qty >= 1 and
  177.            items[2].qty >= 1 and
  178.            items[3].qty == 0 and
  179.            items[5].qty == 0 and
  180.            items[7].qty == 0 and
  181.            items[9].qty == 0 and
  182.            items[10].qty == 0 and
  183.            items[11].qty == 0 then
  184.         turtle.select(1)
  185.         local qty = items[1].qty
  186.         local leftover = qty % 4
  187.         local each = (qty - leftover) / 4
  188.         local amts = {
  189.             [3] = 1; --each + math.min(math.max(0, leftover - 1), 1);
  190.             [9] = 1; --each + math.min(math.max(0, leftover - 2), 1);
  191.             [11] = 1; --each + math.min(math.max(0, leftover - 3), 1);
  192.         }
  193.         for i, amt in pairs(amts) do
  194.             if type(i) == 'number' then
  195.                 turtle.transferTo(i, amt)
  196.             end
  197.         end
  198.         turtle.select(2)
  199.         local qty = items[2].qty
  200.         local leftover = qty % 4
  201.         local each = (qty - leftover) / 4
  202.         local amts = {
  203.             [5] = 1; --each + math.min(math.max(0, leftover - 1), 1);
  204.             [7] = 1; --each + math.min(math.max(0, leftover - 2), 1);
  205.             [10] = 1; --each + math.min(math.max(0, leftover - 3), 1);
  206.         }
  207.         for i, amt in pairs(amts) do
  208.             if type(i) == 'number' then
  209.                 turtle.transferTo(i, amt)
  210.             end
  211.         end
  212.         turtle.select(cursorSlot)
  213.     else
  214.         turtle.select(1); turtle.transferTo(16)
  215.         turtle.select(5); turtle.transferTo(1)
  216.         turtle.select(9); turtle.transferTo(5)
  217.         turtle.select(10); turtle.transferTo(9)
  218.         turtle.select(11); turtle.transferTo(10)
  219.         turtle.select(7); turtle.transferTo(11)
  220.         turtle.select(3); turtle.transferTo(7)
  221.         turtle.select(2); turtle.transferTo(3)
  222.         turtle.select(16); turtle.transferTo(2)
  223.         turtle.select(cursorSlot)
  224.     end
  225. end
  226.  
  227. local function drop()
  228.     for index, slot in ipairs(concat(craftingSlots, {outputSlot})) do
  229.         turtle.select(slot)
  230.         turtle.dropUp()
  231.     end
  232.     turtle.select(cursorSlot)
  233. end
  234.  
  235. local function craft()
  236.     turtle.select(outputSlot)
  237.     if n == nil then
  238.         success = turtle.craft()
  239.     else
  240.         success = turtle.craft(n)
  241.     end
  242.     turtle.select(cursorSlot)
  243. end
  244.  
  245. local function balance()
  246.     local items, types = getItems(craftingSlots)
  247.     for i, itemType in ipairs(types) do
  248.         if itemType.qty > 0 then
  249.             local nSlots = 0
  250.  
  251.             for slot, qty in pairs(itemType.slots) do
  252.                 nSlots = nSlots + 1
  253.             end
  254.  
  255.             local each = itemType.qty / nSlots
  256.  
  257.             for slot, qty in pairs(itemType.slots) do
  258.                 if qty > each then
  259.                     for lowerSlot, lowerQty in pairs(itemType.slots) do
  260.                         if lowerQty < each then
  261.                             turtle.select(slot)
  262.                             local transfer = math.min(qty - each, each - lowerQty)
  263.                             turtle.transferTo(lowerSlot, transfer)
  264.                             qty = qty - transfer
  265.  
  266.                             if qty <= each then
  267.                                 break
  268.                             end
  269.                         end
  270.                     end
  271.                 end
  272.             end
  273.         end
  274.     end
  275. end
  276.  
  277. local function fill()
  278.     local items, types = getItems(craftingSlots)
  279.     turtle.select(cursorSlot)
  280.     for slot, item in pairs(items) do
  281.         if item.qty == 0 then
  282.             turtle.transferTo(item.slot, 1)
  283.         end
  284.     end
  285. end
  286.  
  287. local function nButton(num, x, y)
  288.     if imgui.button { text = tostring(num), x = x, y = y, bgColor = colors.green, height = 1, width = buttonWidth } then
  289.         if n == nil then
  290.             n = 0
  291.         end
  292.         n = (n * 10) + num
  293.     end
  294. end
  295. local function gui()
  296.     local str = 'Crafting Station'
  297.     imgui.label {
  298.         text = string.rep(' ', (width / 2) - (#str / 2) + 1) .. str .. string.rep(' ', (width / 2) - (#str / 2) + 1);
  299.         x = 1;
  300.         y = 1;
  301.         bgColor = colors.gray;
  302.     }
  303.  
  304.     if imgui.button { text = 'X', x = width, y = 1, bgColor = colors.gray, width = 1, height = 1 } then
  305.         term.setBackgroundColor(colors.black)
  306.         term.clear()
  307.         term.setCursorPos(1, 1)
  308.         error('Exiting', 0)
  309.     end
  310.  
  311.     for i = 2, height - 1 do
  312.         imgui.label {
  313.             text = string.rep(' ', width - 2);
  314.             x = 2;
  315.             y = i;
  316.             bgColor = colors.lightGray;
  317.         }
  318.     end
  319.  
  320.     nButton(1, off + 3, 5)
  321.     nButton(2, off + 3 + buttonWidth + 1, 5)
  322.     nButton(3, off + 3 + buttonWidth * 2 + 2, 5)
  323.  
  324.     nButton(4, off + 3, 7)
  325.     nButton(5, off + 3 + buttonWidth + 1, 7)
  326.     nButton(6, off + 3 + buttonWidth * 2 + 2, 7)
  327.  
  328.     nButton(7, off + 3, 9)
  329.     nButton(8, off + 3 + buttonWidth + 1, 9)
  330.     nButton(9, off + 3 + buttonWidth * 2 + 2, 9)
  331.  
  332.     if imgui.button { text = '+1', x = off + 3, y = 11, bgColor = colors.green, height = 1, width = buttonWidth } then
  333.         n = n + 1
  334.     end
  335.     nButton(0, off + 3 + buttonWidth + 1, 11)
  336.     if imgui.button { text = '-1', x = off + 3 + buttonWidth * 2 + 2, y = 11, bgColor = colors.green, height = 1, width = buttonWidth } then
  337.         n = n - 1
  338.     end
  339.  
  340.     if imgui.button { text = 'All', x = off + 3 + buttonWidth * 3 + 3, y = 5, bgColor = colors.green, height = 1, width = buttonWidth } then
  341.         n = nil
  342.     end
  343.  
  344.     if imgui.button { text = 'Clear', x = off + 3 + buttonWidth * 4 + 4, y = 5, bgColor = colors.green, height = 1, width = buttonWidth + 2 } then
  345.         n = 0
  346.     end
  347.  
  348.     if imgui.button { text = 'Drop', x = off + 3 + buttonWidth * 3 + 3, y = 7, bgColor = colors.green, height = 1, width = buttonWidth } then
  349.         drop()
  350.     end
  351.  
  352.     if imgui.button { text = 'Swirl', x = off + 3 + buttonWidth * 4 + 4, y = 7, bgColor = colors.green, height = 1, width = buttonWidth + 2 } then
  353.         swirl()
  354.     end
  355.  
  356.     if imgui.button { text = 'Bal', x = off + 3 + buttonWidth * 3 + 3, y = 9, bgColor = colors.green, height = 1, width = buttonWidth } then
  357.         balance()
  358.     end
  359.  
  360.     if imgui.button { text = 'Fill', x = off + 3 + buttonWidth * 3 + 3, y = 11, bgColor = colors.green, height = 1, width = buttonWidth } then
  361.         fill()
  362.     end
  363.  
  364.     local craftColor
  365.     if success then
  366.         craftColor = colors.green
  367.         success = nil
  368.     elseif success == nil then
  369.         craftColor = colors.gray
  370.     else
  371.         craftColor = colors.red
  372.     end
  373.     if imgui.button { text = 'Craft', x = off + 3 + buttonWidth * 4 + 4, y = 9, bgColor = craftColor, height = 3, width = buttonWidth * 2 } then
  374.         craft()
  375.         if n == 0 then
  376.             os.queueEvent('update')
  377.         end
  378.         os.startTimer(0.5)
  379.     end
  380.  
  381.     local nstr
  382.     if n == nil then
  383.         nstr = ' All'
  384.     else
  385.         nstr = ' ' .. tostring(n)
  386.     end
  387.     imgui.label {
  388.         text = nstr .. string.rep(' ', width - 4 - #nstr);
  389.         x = 3;
  390.         y = 3;
  391.         bgColor = colors.gray;
  392.     }
  393. end
  394.  
  395. turtle.select(cursorSlot)
  396. while true do
  397.     gui()
  398.  
  399.     term.setBackgroundColor(colors.brown)
  400.     term.clear()
  401.     imgui.draw()
  402.     turtle.select(cursorSlot)
  403.     local ev = {imgui.pullEvent()}
  404.  
  405.     if ev[1] == 'key' then
  406.         if ev[2] == keys.c then
  407.             swirl()
  408.         elseif ev[2] == keys.x then
  409.             drop()
  410.         elseif ev[2] == keys.b then
  411.             balance()
  412.         elseif ev[2] == keys.f then
  413.             fill()
  414.         elseif ev[2] == keys.enter then
  415.             craft()
  416.         elseif ev[2] == keys.a then
  417.             n = nil
  418.         elseif ev[2] == keys.left then
  419.             if (cursorSlot - 1) % 4 ~= 0 then
  420.                 cursorSlot = cursorSlot - 1
  421.             end
  422.             turtle.select(cursorSlot)
  423.         elseif ev[2] == keys.right then
  424.             if (cursorSlot - 1) % 4 ~= 2 then
  425.                 cursorSlot = cursorSlot + 1
  426.             end
  427.             turtle.select(cursorSlot)
  428.         elseif ev[2] == keys.up then
  429.             if cursorSlot > 4 then
  430.                 cursorSlot = cursorSlot - 4
  431.             end
  432.         elseif ev[2] == keys.down then
  433.             if cursorSlot < 8 then
  434.                 cursorSlot = cursorSlot + 4
  435.             end
  436.         end
  437.     elseif ev[1] == 'char' then
  438.         local num = tonumber(ev[2])
  439.         if type(num) == 'number' then
  440.             if n == nil then
  441.                 n = 0
  442.             end
  443.             n = (n * 10) + num
  444.         end
  445.     else
  446.         log(textutils.serialize(ev))
  447.     end
  448.     turtle.select(cursorSlot)
  449. end
Advertisement
Add Comment
Please, Sign In to add comment