rkinasz

crafter.lua

Feb 27th, 2019
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.97 KB | None | 0 0
  1.  
  2. local util = dofile("util.lua")
  3. local __ = dofile("underscore.lua")
  4. local recipes = dofile("recipes.lua")
  5. local Screen = dofile("screen.lua")
  6. local config = dofile("config.lua")
  7. local stock = dofile("stock.lua")
  8. local Item, ItemSet = dofile("items.lua")
  9. local deque = dofile("deque.lua")
  10. local autostock = dofile("autostock.lua")
  11.  
  12. local destinations = config.destinations
  13.  
  14. local screen = Screen:new(peripheral.wrap(config.monitor))
  15. local me = peripheral.wrap(config.me)
  16.  
  17. local buffer_chests = __.map(config.buffer_chests, function(i) return {name="minecraft:ironchest_diamond_"..i, peripheral=peripheral.wrap("minecraft:ironchest_diamond_"..i), in_use=false} end)
  18.  
  19. local request_chest = peripheral.wrap(config.request_chest)
  20.  
  21. local me_chest_name = config.me_chest_name
  22. local me_chest_location = config.me_chest_location
  23.  
  24. local item_name_length = 37
  25. local screen_length = 71
  26.  
  27. rednet.open("right")
  28. screen:reset()
  29.  
  30. string.rpad = function(str, len, char)
  31.   if char == nil then char = ' ' end
  32.   return string.rep(char, len - #str) .. str
  33. end
  34.  
  35. string.lpad = function(str, len, char)
  36.   if char == nil then char = ' ' end
  37.   return str .. string.rep(char, len - #str)
  38. end
  39.  
  40. local craft_queue = deque.new()
  41.  
  42. local function message_reader()
  43.   while true do
  44.     local e,p1,p2,p3,p4,p5 = os.pullEvent()
  45.     if e == 'modem_message' then
  46.       local count = 1
  47.       if p4.message[2] then
  48.         count = tonumber(p4.message[2]) or 1
  49.       end
  50.       print("craft enqueued: "..tostring(count).." "..tostring(p4.message[1]))
  51.       craft_queue:push_right({name=p4.message[1], count=count})
  52.     end
  53.   end
  54. end
  55.  
  56. local crafter = {}
  57.  
  58. local function main()
  59.   while true do
  60.     if not craft_queue:is_empty() then
  61.       local craft_request = craft_queue:pop_left()
  62.       local name = craft_request.name
  63.       local count = craft_request.count
  64.  
  65.       screen:full_reset()
  66.  
  67.       if name ~= nil then
  68.         if count == 1 then
  69.           crafter.craft(name)
  70.         else
  71.           crafter.multicraft(name, count)
  72.         end
  73.         screen:push("finished")
  74.         screen:reset()
  75.       end
  76.     else
  77.       crafter.check_requests()
  78.     end
  79.     os.sleep(1)
  80.   end
  81. end
  82.  
  83. crafter.multicraft = function(name, count)
  84.   for i=1,count do
  85.     screen:full_reset()
  86.     screen:push_and_indent(name .. " ("..i.."/"..count..")", 2)
  87.     screen:reset()
  88.     crafter.craft(name)
  89.   end
  90.   screen:reset_stack()
  91.   screen:push_and_indent(name .. " ("..count.."/"..count..")", 2)
  92. end
  93.  
  94. local last_request_check = os.clock()
  95.  
  96. crafter.check_requests = function()
  97.   if os.clock() < last_request_check + 5 then
  98.     return
  99.   end
  100.   last_request_check = os.clock()
  101.   local size = request_chest.size()
  102.   for i=1,size do
  103.     local item = request_chest.getItem(i)
  104.     if item ~= nil then
  105.       local meta = item.getMetadata()
  106.       local name = meta.displayName
  107.       local count = meta.count
  108.       if config.request_multipliers[name] ~= nil then
  109.         count = count * config.request_multipliers[name]
  110.       end
  111.       request_chest.pushItems(me_chest_name, i)
  112.       crafter.import_me_chest()
  113.       crafter.multicraft(name, count)
  114.       screen:push("finished")
  115.       screen:reset()
  116.       return
  117.     end
  118.   end
  119. end
  120.  
  121. crafter.bulk_craft = function(name, count)
  122.  
  123. end
  124.  
  125. crafter.get_buffer_chest = function()
  126.   -- get first buffer chest not in use
  127.   return __.detect(buffer_chests, function(c) return not c.in_use end)
  128. end
  129.  
  130. local status = {crafting = "crafting", missing = "missing", ready = "ready"}
  131.  
  132. local status_dots =
  133.   (function()
  134.     local dots = ". "
  135.     local len = 2
  136.     local maxlen, _ = screen:get_size()
  137.     while len < maxlen do
  138.       dots = dots..". "
  139.       len = len + 2
  140.     end
  141.     return dots
  142.   end)()
  143.  
  144. crafter.format_status_message = function(name, status, screen)
  145.   return name..status
  146. end
  147.  
  148. local use_format_dots = false
  149.  
  150. crafter.format_status_message_alt = function(name, status, screen)
  151.   if status == "" then
  152.     return name
  153.   end
  154.  
  155.   local RIGHT_PADDING = 3
  156.   local indent = screen:get_indent()
  157.   local status_length = string.len(status)
  158.   local screen_length, _ = screen:get_size()
  159.   local message = string.lpad(name, item_name_length - indent)
  160.   local message_length = string.len(message)
  161.   if not use_format_dots then
  162.     local right_remainder = screen_length - indent - message_length - RIGHT_PADDING
  163.     message = message .. string.rpad(status, right_remainder)
  164.   else
  165.     message = name
  166.     message_length = string.len(message)
  167.     message = message .. string.sub(status_dots, message_length + 1, screen_length - status_length - indent - 3) .. status
  168.   end
  169.  
  170.   return message
  171. end
  172.  
  173. crafter.format_status_message = crafter.format_status_message_alt
  174.  
  175. crafter.craft = function(name, is_subcraft)
  176.   is_subcraft = is_subcraft or false
  177.  
  178.   local buffer_chest = crafter.get_buffer_chest()
  179.   if buffer_chest == nil then
  180.     error("No buffer chest available")
  181.     return
  182.   end
  183.  
  184.   local recipe = recipes[name]
  185.   if not is_subcraft then
  186.     screen:push_and_indent(name, 2)
  187.   else
  188.     screen:push_and_indent(crafter.format_status_message(name, status.crafting, screen), 2)
  189.   end
  190.   screen:reset()
  191.   for i,item in ipairs(recipe.items) do
  192.     local item_name = item.name
  193.     local display_name = item:get_display_name()
  194.     local finished = false
  195.     local success, ae2_item = crafter.get_item(item)
  196.    
  197.     if success and (ae2_item ~= nil) then
  198.       local item_meta = ae2_item.getMetadata()
  199.       if crafter.get_ae2(item) then
  200.         screen:push(crafter.format_status_message(item_meta.displayName, status.ready, screen))
  201.         screen:reset()
  202.         finished = true
  203.       end
  204.     end
  205.  
  206.     if item.recipe ~= nil and not finished then
  207.       crafter.craft(item.recipe, true)
  208.       crafter.wait_for_item(item)
  209.       screen:pop_many(2)
  210.       screen:push(crafter.format_status_message(item.recipe, status.ready, screen))
  211.       screen:reset()
  212.       finished = true
  213.     end
  214.  
  215.     if success and (ae2_item ~= nil) and not finished then
  216.       local item_meta = ae2_item.getMetadata()
  217.      
  218.       if crafter.get_or_craft_ae2(item) then
  219.         screen:push(crafter.format_status_message(item_meta.displayName, status.ready, screen))
  220.         screen:reset()
  221.         finished = true
  222.       else
  223.         screen:push(item_meta.displayName)
  224.         screen:reset()
  225.       end
  226.     else
  227.       if item.recipe == nil and not finished then
  228.         screen:push_error(crafter.format_status_message(display_name, status.missing, screen))
  229.         screen:reset()
  230.         crafter.wait_for_item(item)
  231.         screen:pop()
  232.         screen:push(crafter.format_status_message(display_name, status.ready, screen))
  233.         screen:reset()
  234.       end
  235.     end
  236.    
  237.     crafter.export_to_buffer_chest(item, buffer_chest)
  238.   end
  239.  
  240.   if destinations[name] and peripheral.isPresent(destinations[name]) then
  241.     crafter.transfer_chest(buffer_chest.peripheral, destinations[name])
  242.     buffer_chest.in_use = false
  243.   else
  244.     screen:push("unable to find destination: " .. tostring(destinations[name]))
  245.     screen:reset()
  246.     crafter.import_buffer_chest(buffer_chest)
  247.     exit() -- this crashes the program, which works, I guess
  248.   end
  249.  
  250.   screen:pop_many(#recipe.items)
  251.   screen:reset()
  252. end
  253.  
  254. crafter.wait_for_item = function(item)
  255.   while true do
  256.     local success, ae2item = crafter.get_item(item)
  257.     if success and (ae2item ~= nil) then
  258.       local meta = ae2item.getMetadata()
  259.       local missing = (item.count or 1) - meta.count
  260.       if missing <= 0 then
  261.         return
  262.       end
  263.     end
  264.     os.sleep(1)
  265.   end
  266. end
  267.  
  268. crafter.export_to_buffer_chest = function(item, buffer_chest)
  269.   local success, ae2item = crafter.get_item(item)
  270.   if success and (ae2item ~= nil) then
  271.     local count = item.count or 1    
  272.     local exported = ae2item.export(me_chest_location, count)
  273.     crafter.transfer_chest(peripheral.wrap(me_chest_name), buffer_chest.name)
  274.     buffer_chest.in_use = true
  275.   else
  276.     error("couldn't export " .. tostring(item.name))
  277.   end
  278. end
  279.  
  280. crafter.transfer_chest = function(from, to)
  281.   local i = 1
  282.   while true do
  283.     local count = from.pushItems(to, i)
  284.     if count == 0 then
  285.       break
  286.     end
  287.     i = i + 1
  288.   end
  289. end
  290.  
  291.  
  292. crafter.import_buffer_chest = function(buffer_chest)
  293.   local chest = buffer_chest.peripheral
  294.   local i = 1
  295.   buffer_chest.in_use = false
  296.   while true do
  297.     local count = chest.pushItems(me_chest_name, i)
  298.     if count == 0 then
  299.       break
  300.     end
  301.     i = i + 1
  302.   end
  303.   crafter.import_me_chest()
  304. end
  305.  
  306. crafter.import_me_chest = function()
  307.   local i = 1
  308.   while true do
  309.     local count = me.pullItems(me_chest_location, i)
  310.     if count == 0 then
  311.       return
  312.     end
  313.     i = i + 1
  314.   end
  315. end
  316.  
  317. crafter.get_item = function(item)
  318.   return pcall(me.findItem, item)
  319. end
  320.  
  321. crafter.get_ae2 = function(item)
  322.   local success, ae2item = pcall(me.findItem, item)
  323.   if success then
  324.     if ae2item ~= nil then
  325.       local meta = ae2item.getMetadata()
  326.       local missing = (item.count or 1) - meta.count
  327.       if missing > 0 then
  328.         return false
  329.       end
  330.       return true
  331.     end
  332.   end
  333.   return false
  334. end
  335.  
  336. crafter.get_or_craft_ae2 = function(item)
  337.   local success, ae2item = pcall(me.findItem, item)
  338.   if success then
  339.     if ae2item ~= nil then
  340.       local meta = ae2item.getMetadata()
  341.       local missing = (item.count or 1) - meta.count
  342.       if missing > 0 then
  343.         local craft = ae2item.craft(missing)
  344.         if craft ~= nil then
  345.           screen:push(crafter.format_status_message(meta.displayName, status.crafting, screen))
  346.           screen:reset()
  347.           while not craft.isFinished() do
  348.             os.sleep(1)
  349.             if craft.isCanceled() then break end
  350.           end
  351.           screen:pop_many(1)
  352.           screen:reset()
  353.           return craft.isFinished()
  354.         end
  355.       else
  356.         screen:reset()
  357.         return true
  358.       end
  359.     end
  360.   end
  361.   return false
  362. end
  363.  
  364. __.each(buffer_chests, function(chest) crafter.import_buffer_chest(chest) end)
  365.  
  366. parallel.waitForAll(main, message_reader, autostock)
Advertisement
Add Comment
Please, Sign In to add comment