Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local util = dofile("util.lua")
- local __ = dofile("underscore.lua")
- local recipes = dofile("recipes.lua")
- local Screen = dofile("screen.lua")
- local config = dofile("config.lua")
- local stock = dofile("stock.lua")
- local Item, ItemSet = dofile("items.lua")
- local deque = dofile("deque.lua")
- local autostock = dofile("autostock.lua")
- local destinations = config.destinations
- local screen = Screen:new(peripheral.wrap(config.monitor))
- local me = peripheral.wrap(config.me)
- 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)
- local request_chest = peripheral.wrap(config.request_chest)
- local me_chest_name = config.me_chest_name
- local me_chest_location = config.me_chest_location
- local item_name_length = 37
- local screen_length = 71
- rednet.open("right")
- screen:reset()
- string.rpad = function(str, len, char)
- if char == nil then char = ' ' end
- return string.rep(char, len - #str) .. str
- end
- string.lpad = function(str, len, char)
- if char == nil then char = ' ' end
- return str .. string.rep(char, len - #str)
- end
- local craft_queue = deque.new()
- local function message_reader()
- while true do
- local e,p1,p2,p3,p4,p5 = os.pullEvent()
- if e == 'modem_message' then
- local count = 1
- if p4.message[2] then
- count = tonumber(p4.message[2]) or 1
- end
- print("craft enqueued: "..tostring(count).." "..tostring(p4.message[1]))
- craft_queue:push_right({name=p4.message[1], count=count})
- end
- end
- end
- local crafter = {}
- local function main()
- while true do
- if not craft_queue:is_empty() then
- local craft_request = craft_queue:pop_left()
- local name = craft_request.name
- local count = craft_request.count
- screen:full_reset()
- if name ~= nil then
- if count == 1 then
- crafter.craft(name)
- else
- crafter.multicraft(name, count)
- end
- screen:push("finished")
- screen:reset()
- end
- else
- crafter.check_requests()
- end
- os.sleep(1)
- end
- end
- crafter.multicraft = function(name, count)
- for i=1,count do
- screen:full_reset()
- screen:push_and_indent(name .. " ("..i.."/"..count..")", 2)
- screen:reset()
- crafter.craft(name)
- end
- screen:reset_stack()
- screen:push_and_indent(name .. " ("..count.."/"..count..")", 2)
- end
- local last_request_check = os.clock()
- crafter.check_requests = function()
- if os.clock() < last_request_check + 5 then
- return
- end
- last_request_check = os.clock()
- local size = request_chest.size()
- for i=1,size do
- local item = request_chest.getItem(i)
- if item ~= nil then
- local meta = item.getMetadata()
- local name = meta.displayName
- local count = meta.count
- if config.request_multipliers[name] ~= nil then
- count = count * config.request_multipliers[name]
- end
- request_chest.pushItems(me_chest_name, i)
- crafter.import_me_chest()
- crafter.multicraft(name, count)
- screen:push("finished")
- screen:reset()
- return
- end
- end
- end
- crafter.bulk_craft = function(name, count)
- end
- crafter.get_buffer_chest = function()
- -- get first buffer chest not in use
- return __.detect(buffer_chests, function(c) return not c.in_use end)
- end
- local status = {crafting = "crafting", missing = "missing", ready = "ready"}
- local status_dots =
- (function()
- local dots = ". "
- local len = 2
- local maxlen, _ = screen:get_size()
- while len < maxlen do
- dots = dots..". "
- len = len + 2
- end
- return dots
- end)()
- crafter.format_status_message = function(name, status, screen)
- return name..status
- end
- local use_format_dots = false
- crafter.format_status_message_alt = function(name, status, screen)
- if status == "" then
- return name
- end
- local RIGHT_PADDING = 3
- local indent = screen:get_indent()
- local status_length = string.len(status)
- local screen_length, _ = screen:get_size()
- local message = string.lpad(name, item_name_length - indent)
- local message_length = string.len(message)
- if not use_format_dots then
- local right_remainder = screen_length - indent - message_length - RIGHT_PADDING
- message = message .. string.rpad(status, right_remainder)
- else
- message = name
- message_length = string.len(message)
- message = message .. string.sub(status_dots, message_length + 1, screen_length - status_length - indent - 3) .. status
- end
- return message
- end
- crafter.format_status_message = crafter.format_status_message_alt
- crafter.craft = function(name, is_subcraft)
- is_subcraft = is_subcraft or false
- local buffer_chest = crafter.get_buffer_chest()
- if buffer_chest == nil then
- error("No buffer chest available")
- return
- end
- local recipe = recipes[name]
- if not is_subcraft then
- screen:push_and_indent(name, 2)
- else
- screen:push_and_indent(crafter.format_status_message(name, status.crafting, screen), 2)
- end
- screen:reset()
- for i,item in ipairs(recipe.items) do
- local item_name = item.name
- local display_name = item:get_display_name()
- local finished = false
- local success, ae2_item = crafter.get_item(item)
- if success and (ae2_item ~= nil) then
- local item_meta = ae2_item.getMetadata()
- if crafter.get_ae2(item) then
- screen:push(crafter.format_status_message(item_meta.displayName, status.ready, screen))
- screen:reset()
- finished = true
- end
- end
- if item.recipe ~= nil and not finished then
- crafter.craft(item.recipe, true)
- crafter.wait_for_item(item)
- screen:pop_many(2)
- screen:push(crafter.format_status_message(item.recipe, status.ready, screen))
- screen:reset()
- finished = true
- end
- if success and (ae2_item ~= nil) and not finished then
- local item_meta = ae2_item.getMetadata()
- if crafter.get_or_craft_ae2(item) then
- screen:push(crafter.format_status_message(item_meta.displayName, status.ready, screen))
- screen:reset()
- finished = true
- else
- screen:push(item_meta.displayName)
- screen:reset()
- end
- else
- if item.recipe == nil and not finished then
- screen:push_error(crafter.format_status_message(display_name, status.missing, screen))
- screen:reset()
- crafter.wait_for_item(item)
- screen:pop()
- screen:push(crafter.format_status_message(display_name, status.ready, screen))
- screen:reset()
- end
- end
- crafter.export_to_buffer_chest(item, buffer_chest)
- end
- if destinations[name] and peripheral.isPresent(destinations[name]) then
- crafter.transfer_chest(buffer_chest.peripheral, destinations[name])
- buffer_chest.in_use = false
- else
- screen:push("unable to find destination: " .. tostring(destinations[name]))
- screen:reset()
- crafter.import_buffer_chest(buffer_chest)
- exit() -- this crashes the program, which works, I guess
- end
- screen:pop_many(#recipe.items)
- screen:reset()
- end
- crafter.wait_for_item = function(item)
- while true do
- local success, ae2item = crafter.get_item(item)
- if success and (ae2item ~= nil) then
- local meta = ae2item.getMetadata()
- local missing = (item.count or 1) - meta.count
- if missing <= 0 then
- return
- end
- end
- os.sleep(1)
- end
- end
- crafter.export_to_buffer_chest = function(item, buffer_chest)
- local success, ae2item = crafter.get_item(item)
- if success and (ae2item ~= nil) then
- local count = item.count or 1
- local exported = ae2item.export(me_chest_location, count)
- crafter.transfer_chest(peripheral.wrap(me_chest_name), buffer_chest.name)
- buffer_chest.in_use = true
- else
- error("couldn't export " .. tostring(item.name))
- end
- end
- crafter.transfer_chest = function(from, to)
- local i = 1
- while true do
- local count = from.pushItems(to, i)
- if count == 0 then
- break
- end
- i = i + 1
- end
- end
- crafter.import_buffer_chest = function(buffer_chest)
- local chest = buffer_chest.peripheral
- local i = 1
- buffer_chest.in_use = false
- while true do
- local count = chest.pushItems(me_chest_name, i)
- if count == 0 then
- break
- end
- i = i + 1
- end
- crafter.import_me_chest()
- end
- crafter.import_me_chest = function()
- local i = 1
- while true do
- local count = me.pullItems(me_chest_location, i)
- if count == 0 then
- return
- end
- i = i + 1
- end
- end
- crafter.get_item = function(item)
- return pcall(me.findItem, item)
- end
- crafter.get_ae2 = function(item)
- local success, ae2item = pcall(me.findItem, item)
- if success then
- if ae2item ~= nil then
- local meta = ae2item.getMetadata()
- local missing = (item.count or 1) - meta.count
- if missing > 0 then
- return false
- end
- return true
- end
- end
- return false
- end
- crafter.get_or_craft_ae2 = function(item)
- local success, ae2item = pcall(me.findItem, item)
- if success then
- if ae2item ~= nil then
- local meta = ae2item.getMetadata()
- local missing = (item.count or 1) - meta.count
- if missing > 0 then
- local craft = ae2item.craft(missing)
- if craft ~= nil then
- screen:push(crafter.format_status_message(meta.displayName, status.crafting, screen))
- screen:reset()
- while not craft.isFinished() do
- os.sleep(1)
- if craft.isCanceled() then break end
- end
- screen:pop_many(1)
- screen:reset()
- return craft.isFinished()
- end
- else
- screen:reset()
- return true
- end
- end
- end
- return false
- end
- __.each(buffer_chests, function(chest) crafter.import_buffer_chest(chest) end)
- parallel.waitForAll(main, message_reader, autostock)
Advertisement
Add Comment
Please, Sign In to add comment