-- program to manage a cargo elevator -- yes, i am aware i could just use the computer to transfer packages at this -- point, but where's the fun in that? local FLOORS = { { match = function (input) local first_char = string.sub(input, 1, 1) return first_char == "A" or first_char == "W" end, detect = function () return redstone.getInput("top") end, call = function () redstone.setOutput("top", true) os.sleep(0.5) redstone.setOutput("top", false) end, storage = "create:item_vault_17", elevator_storage = "create:portable_storage_interface_11", }, { match = function (input) local first_char = string.sub(input, 1, 1) return first_char == "F" end, detect = function () local relay = "redstone_relay_21" return peripheral.call(relay, "getInput", "top") end, call = function () local relay = "redstone_relay_21" peripheral.call(relay, "setOutput", "top", true) os.sleep(0.5) peripheral.call(relay, "setOutput", "top", false) end, storage = "create:item_vault_18", elevator_storage = "create:portable_storage_interface_8", }, { match = function (input) local first_char = string.sub(input, 1, 1) return first_char == "L" end, detect = function () local relay = "redstone_relay_22" return peripheral.call(relay, "getInput", "top") end, call = function () local relay = "redstone_relay_22" peripheral.call(relay, "setOutput", "top", true) os.sleep(0.5) peripheral.call(relay, "setOutput", "top", false) end, storage = "create:item_vault_19", elevator_storage = "create:portable_storage_interface_9", }, { match = function (input) local first_char = string.sub(input, 1, 1) return first_char == "E" end, detect = function () local relay = "redstone_relay_23" return peripheral.call(relay, "getInput", "top") end, call = function () local relay = "redstone_relay_23" peripheral.call(relay, "setOutput", "top", true) os.sleep(0.5) peripheral.call(relay, "setOutput", "top", false) end, storage = "create:item_vault_20", elevator_storage = "create:portable_storage_interface_10", }, } local SLEEP_T = 5 local PKG_QUEUE = { insert = function (self, floor_i) local is_in = function (item, list) for _, l_item in ipairs(list) do if l_item == item then return true end end return false end if not is_in(floor_i, self.queue) then table.insert(self.queue, floor_i) end end, check_floors = function (self, floors) for i, floor in pairs(floors) do if #(peripheral.call(floor.storage, "list")) > 0 then self:insert(i) end end end, check_cargo = function (self, inv, floors) for slot, item in pairs(peripheral.call(inv, "list")) do local item_detail = peripheral.call(inv, "getItemDetail", slot) for i, floor in ipairs(floors) do if item_detail.package ~= nil and floor.match(item_detail.package.getAddress()) then self:insert(i) break end end end end, transfer_all = function (self, src, dest, floors) -- assumption: this always transfers into the cargo box for slot, item in pairs(peripheral.call(src, "list")) do local item_detail = peripheral.call(src, "getItemDetail", slot) for i, floor in ipairs(floors) do if item_detail.package ~= nil and floor.match(item_detail.package.getAddress()) then self:insert(i) peripheral.call(src, "pushItems", dest, slot) break end end end end, transfer_matching = function (self, src, dest, match_f) -- assumption: this always transfers out of the cargo box for slot, item in pairs(peripheral.call(src, "list")) do local item_detail = peripheral.call(src, "getItemDetail", slot) if item_detail.package ~= nil and match_f(item_detail.package.getAddress()) then peripheral.call(src, "pushItems", dest, slot) end end end, get_next_floor = function (self) return table.remove(self.queue, 1) end, queue = {}, } function run (floors, queue, first_run) local next_floor = nil queue:check_floors(floors) for i, floor in pairs(floors) do if floor.detect() then if first_run then queue:check_cargo(floor.elevator_storage, floors) end queue:transfer_all(floor.storage, floor.elevator_storage, floors) queue:transfer_matching( floor.elevator_storage, floor.storage, floor.match ) next_floor = queue:get_next_floor() end end if next_floor ~= nil then floors[next_floor].call() end os.sleep(SLEEP_T) return run(floors, queue, false) end if arg ~= nil and arg[1] == "run" then run(FLOORS, PKG_QUEUE, true) end