diff --git a/compacting-storage.lua b/compacting-storage.lua index 4dbe0fb..363b665 100644 --- a/compacting-storage.lua +++ b/compacting-storage.lua @@ -6,42 +6,11 @@ -- constants -local MAIN_TICKER = "" -local REQUEST_TICKER = "" -local CRAFTING_REQUESTER = "" -local STORAGE_ADDR = "" -local COMPACTING_ADDR = "" -local UNPACKING_ADDR = "" +local INVENTORY = "left" local SLEEP_TIME = 30 local NUGGET_RATIO = 63 -- amount of nuggets per craft local BLOCK_RATIO = 7 -- amount of blocks per craft -local ITEM_TYPES = { - iron = { - nugget = "minecraft", - ingot = "minecraft", - block = "minecraft", - }, - copper = { - nugget = "create", - ingot = "minecraft", - block = "minecraft", - }, - zinc = { - nugget = "create", - ingot = "create", - block = "create", - }, - gold = { - nugget = "minecraft", - ingot = "minecraft", - block = "minecraft", - }, - electrum = { - nugget = "createaddition", - ingot = "createaddition", - block = "createaddition", - }, -} +local ITEM_TYPES = { "iron", "copper", "zinc", "gold", "electrum" } local STACKS = 64 local NUGGETS = 1 @@ -52,90 +21,100 @@ local BLOCKS = 81 local MIN_NUM = (4 * STACKS * NUGGETS) + (4 * STACKS * INGOTS) local MAX_NUM = (8 * STACKS * NUGGETS) + (8 * STACKS * INGOTS) -local getName = { - nugget = function (item_type) - return ("%s:%s_nugget"):format( - ITEM_TYPES[item_type].nugget, - item_type - ) - end, - ingot = function (item_type) - return ("%s:%s_ingot"):format( - ITEM_TYPES[item_type].ingot, - item_type - ) - end, - block = function (item_type) - return ("%s:%s_block"):format( - ITEM_TYPES[item_type].block, - item_type - ) - end, -} +-- TODO map targets to specific relays and faces +-- Key - 1: nuggets_to_ingots, 2: ingots_to_blocks, 3: blocks_to_ingots, +-- 4: ingots_to_nuggets, 5: enable/disable production +local target = {} +target.iron = {} +target.iron[1] = "0:front" +target.iron[2] = "0:top" +target.iron[3] = "0:back" +target.iron[4] = "16:front" +target.iron[5] = "17:back" +target.copper = {} +target.copper[1] = "1:front" +target.copper[2] = "1:top" +target.copper[3] = "1:back" +target.copper[4] = "16:top" +target.copper[5] = "18:front" +target.zinc = {} +target.zinc[1] = "2:front" +target.zinc[2] = "2:top" +target.zinc[3] = "2:back" +target.zinc[4] = "16:back" +target.zinc[5] = "18:top" +target.gold = {} +target.gold[1] = "3:front" +target.gold[2] = "3:top" +target.gold[3] = "3:back" +target.gold[4] = "17:front" +target.gold[5] = "18:back" +target.electrum = {} +target.electrum[1] = "4:front" +target.electrum[2] = "4:top" +target.electrum[3] = "4:back" +target.electrum[4] = "17:top" -- basic actions -function craft (requester, item_type, conversion_type) - -- conversion_type key: 1, nuggets to ingots; 2, ingots to blocks; - -- 3, blocks to ingots; 4, ingots to nuggets - local convert = { - getName.nugget, - getName.ingot, - getName.block, - getName.ingot, - } - local name = convert[conversion_type](item_type) - local compacting = conversion_type <= 2 - local count, address - if compacting then - count = NUGGET_RATIO - address = COMPACTING_ADDR - else - count = BLOCK_RATIO - address = UNPACKING_ADDR - end - requester.setAddress(address) - requester.setRequest({ name = name, count = count }) - requester.request() +function craft (item_type, conversion_type) + -- TODO double check this + local relay_num, face = string.match( + target[item_type][conversion_type], + "(%d+):(%l+)" + ) + local periph = string.format("redstone_relay_%d", relay_num) + peripheral.call(periph, "setOutput", face, true) + os.sleep(0.1) + peripheral.call(periph, "setOutput", face, false) end -function craft_multiple (requester, item_type, conversion_type, count) +function craft_multiple (item_type, conversion_type, count) if count < 1 then return else - craft(requester, item_type, conversion_type) + craft(item_type, conversion_type) os.sleep(1) - return craft_multiple(requester, item_type, conversion_type, count - 1) + return craft_multiple(item_type, conversion_type, count - 1) end end -function execute_crafts (requester, item_type, crafts) - local num_crafts = crafts.nugget +function execute_crafts (item_type, crafts) + local num_crafts = crafts.nuggets if num_crafts > 0 then print(("Crafting %s nuggets"):format(item_type)) - craft_multiple(requester, item_type, 4, num_crafts) + craft_multiple(item_type, 4, num_crafts) elseif num_crafts < 0 then print(("Crafting %s ingots"):format(item_type)) - craft_multiple(requester, item_type, 1, -num_crafts) + craft_multiple(item_type, 1, -num_crafts) end - num_crafts = crafts.block + num_crafts = crafts.blocks if num_crafts > 0 then print(("Crafting %s blocks"):format(item_type)) - craft_multiple(requester, item_type, 2, num_crafts) + craft_multiple(item_type, 2, num_crafts) elseif num_crafts < 0 then print(("Crafting %s ingots"):format(item_type)) - craft_multiple(requester, item_type, 3, -num_crafts) + craft_multiple(item_type, 3, -num_crafts) end end -function request_more (ticker, item_type) - ticker.requestFiltered(STORAGE_ADDR, { name = getName.nugget(item_type) }) +function set_production (item_type, produce) + local target_string = target[item_type][5] + if target_string == nil then return end + local relay_num, face = string.match( + target_string, + "(%d+):(%l+)" + ) + local periph = string.format("redstone_relay_%d", relay_num) + -- ON is disable production + if produce then print(("Producing %s"):format(item_type)) end + peripheral.call(periph, "setOutput", face, not produce) end -- logic -function sum_items (inv_f) +function sum_items (inv) local result = {} - for _, item in pairs(inv_f()) do + for _, item in pairs(inv.list()) do if result[item.name] == nil then result[item.name] = 0 end result[item.name] = result[item.name] + item.count end @@ -143,13 +122,14 @@ function sum_items (inv_f) end function dist_to_num (dist) - return dist.nugget + (dist.ingot * INGOTS) + (dist.block * BLOCKS) + return dist.nuggets + dist.ingots * INGOTS + dist.blocks * BLOCKS end function get_dist (item_type, items) - local dist = { nugget = 0, ingot = 0, block = 0 } + local dist = { nuggets = 0, ingots = 0, blocks = 0 } for item, count in pairs(items) do local type, form = item:match":(%l-)_(%l*)" + form = string.format("%ss", form) if type == item_type and dist[form] ~= nil then dist[form] = dist[form] + count end @@ -158,51 +138,52 @@ function get_dist (item_type, items) end function decide_dist (num) - local dist = { nugget = 0, ingot = 0, block = 0 } + local dist = { nuggets = 0, ingots = 0, blocks = 0 } if num > MAX_NUM then local excess = num - MAX_NUM - dist.block = math.floor(excess / BLOCKS) - num = num - (dist.block * BLOCKS) + dist.blocks = math.floor(excess / BLOCKS) + num = num - (dist.blocks * BLOCKS) end local balance = math.floor(num / 10) - dist.nugget, dist.ingot = balance, balance + dist.nuggets, dist.ingots = balance, balance num = num - (balance * 10) - dist.nugget = dist.nugget + num + dist.nuggets = dist.nuggets + num return dist end function get_diff (dist1, dist2) return { - nugget = dist1.nugget - dist2.nugget, - ingot = dist1.ingot - dist2.ingot, - block = dist1.block - dist2.block + nuggets = dist1.nuggets - dist2.nuggets, + ingots = dist1.ingots - dist2.ingots, + blocks = dist1.blocks - dist2.blocks } end function filter_clamp (diff, current_dist) -- reduce diff numbers to what can be crafted using current resources - if diff.block > 0 then - diff.block = math.min( - diff.block - (diff.block % BLOCK_RATIO), - math.floor(current_dist.ingot / 9) + if diff.blocks > 0 then + diff.blocks = math.min( + diff.blocks - (diff.blocks % BLOCK_RATIO), + math.floor(current_dist.ingots / 9) ) end - if diff.nugget > 0 then - diff.nugget = math.min( - diff.nugget - (diff.nugget % NUGGET_RATIO), - current_dist.ingot * 9 + if diff.nuggets > 0 then + diff.nuggets = math.min( + diff.nuggets - (diff.nuggets % NUGGET_RATIO), + current_dist.ingots * 9 ) end - diff.ingot = (-diff.nugget / 9) + (-diff.block * 9) + diff.ingots = (-diff.nuggets / 9) + (-diff.blocks * 9) return diff end function diff_to_crafts (diff) + -- TODO double-check this one -- go from one end e.g. nuggets to the other e.g. blocks, removing -- from the diff to create crafts until the diff is empty local crafts = {} - crafts.nugget = math.floor(diff.nugget / NUGGET_RATIO) - crafts.block = math.floor(diff.block / BLOCK_RATIO) + crafts.nuggets = math.floor(diff.nuggets / NUGGET_RATIO) + crafts.blocks = math.floor(diff.blocks / BLOCK_RATIO) return crafts end @@ -215,35 +196,24 @@ function print_counts (items) end end -local main_t = peripheral.wrap(MAIN_TICKER) -local request_t = peripheral.wrap(REQUEST_TICKER) -local craft_requester = peripheral.wrap(CRAFTING_REQUESTER) -craft_requester.setConfiguration("strict") -local requesting = {} while true do -- 1. Sum items in inventory and organize by item type - local items = sum_items(main_t.stock) + local items = sum_items(peripheral.wrap(INVENTORY)) -- print_counts(items) -- 2. either work towards a desired distribution or create more resources - for item_type, _ in pairs(ITEM_TYPES) do + for _, item_type in ipairs(ITEM_TYPES) do local current_dist = get_dist(item_type, items) local num = dist_to_num(current_dist) + if num > MAX_NUM then set_production(item_type, false) end if num > MIN_NUM then local desired_dist = decide_dist(num) local diff = get_diff(desired_dist, current_dist) diff = filter_clamp(diff, current_dist) local crafts = diff_to_crafts(diff) - execute_crafts(craft_requester, item_type, crafts) + execute_crafts(item_type, crafts) else - requesting[item_type] = true - end - if num > MAX_NUM then - -- keep requesting until above MAX_NUM - requesting[item_type] = false - end - if requesting[item_type] then - request_more(request_t, item_type) + set_production(item_type, true) end end