Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ---(( Types ))---
- ---@class ItemInfoX : ItemInfo
- ---@field slot integer
- ---(( Functions ))---
- ---@param inv inventory
- ---@return table<integer, ItemInfoX>
- local function listItems(inv)
- local items = inv.list()
- for key, item in pairs(items) do
- item.slot = key
- end
- return items
- end
- ---@param item ItemInfo
- ---@return string
- local function getItemNormalizedName(item)
- if item.displayName then
- return item.displayName:lower()
- end
- return select(1, item.name:gsub("[^:]+:", ""))
- end
- ---@param a ItemInfoX
- ---@param b ItemInfoX
- ---@return boolean
- local function compareItems(a, b)
- local nameA = getItemNormalizedName(a)
- local nameB = getItemNormalizedName(b)
- if nameA ~= nameB then
- return nameA < nameB
- end
- if a.count ~= b.count then
- return a.count > b.count
- end
- return a.slot < b.slot
- end
- ---@param unsorted table<integer,ItemInfoX>
- local function sortItemsTable(unsorted)
- ---@type ItemInfoX[]
- local items = {}
- for _, item in pairs(unsorted) do
- table.insert(items, item)
- end
- table.sort(items, compareItems)
- return items
- end
- ---@param inv inventory
- ---@param state table<integer, ItemInfoX>
- local function findEmptySlot(inv, state)
- local nextEmpty = #state + 1
- if nextEmpty > inv.size() then
- error("Failed to find empty slot in inventory")
- end
- return nextEmpty
- end
- ---@param inv inventory
- ---@param state table<integer, ItemInfoX>
- ---@param fromSlot integer
- ---@param toSlot integer
- local function moveItems(inv, state, fromSlot, toSlot)
- if not state[fromSlot] then
- error(string.format("move items from slot %d to %d: source slot is empty", fromSlot, toSlot))
- end
- if state[toSlot] then
- error(string.format("move items from slot %d to %d: target slot is not empty", fromSlot, toSlot))
- end
- local invName = peripheral.getName(inv)
- inv.pushItems(invName, fromSlot, nil, toSlot)
- state[toSlot] = state[fromSlot]
- state[fromSlot] = nil
- state[toSlot].slot = toSlot
- end
- ---@param inv inventory
- ---@param state table<integer, ItemInfoX>
- ---@param item ItemInfoX
- ---@param toSlot integer
- local function performSortItem(inv, state, item, toSlot)
- if state[toSlot] then
- local empty = findEmptySlot(inv, state)
- moveItems(inv, state, toSlot, empty)
- end
- moveItems(inv, state, item.slot, toSlot)
- end
- ---@param key integer
- ---@param item ItemInfoX
- ---@return boolean
- local function shouldSort(key, item)
- return key ~= item.slot
- end
- ---@param inv inventory
- ---@param state table<integer, ItemInfoX>
- ---@param sorted ItemInfoX[]
- ---@param sortOps integer
- local function performSort(inv, state, sorted, sortOps)
- local fgColor = term.getTextColor()
- term.setTextColor(colors.gray)
- local lines = write(string.format("|%s|", string.rep("-", sortOps)))
- term.setTextColor(colors.yellow)
- local _, y = term.getCursorPos()
- term.setCursorPos(1, y - lines)
- write("|")
- for key, item in ipairs(sorted) do
- if shouldSort(key, item) then
- performSortItem(inv, state, item, key)
- write("=")
- end
- end
- write("|")
- print()
- term.setTextColor(fgColor)
- end
- ---@param side string?
- ---@return inventory
- local function findChest(side)
- if side then
- local p = peripheral.wrap(side)
- if not p then
- error(string.format('No peripheral at "%s"', side))
- end
- if not peripheral.hasType(p, "inventory") then
- error(string.format('Peripheral at "%s" is not an "inventory" type', side))
- end
- return p
- end
- if peripheral.hasType("front", "inventory") then
- return peripheral.wrap("front")
- end
- local chest = peripheral.find("inventory")
- return chest
- end
- ---(( Program ))---
- local chest = findChest(...)
- if chest == nil then
- print("No inventory peripheral found.")
- return
- end
- local origItems = listItems(chest)
- local sortedItems = sortItemsTable(origItems)
- print(string.format('Sorting "%s" with %d items...', peripheral.getName(chest), #sortedItems))
- local sortOps = 0
- for key, item in ipairs(sortedItems) do
- if shouldSort(key, item) then
- sortOps = sortOps + 1
- end
- end
- if sortOps == 0 then
- print("Already sorted.")
- return
- end
- performSort(chest, origItems, sortedItems, sortOps)
- print("Sorting done")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement