From d4f18113a6cba38f3120e9a1da338c3b11f499f3 Mon Sep 17 00:00:00 2001 From: Dystroyer8 Date: Sat, 18 Jul 2026 02:18:31 +0200 Subject: [PATCH] Show dynamic paged Stock Ticker inventory --- README.md | 8 ++- create_factory_test.lua | 124 +++++++++++++++++++++++++++++++--------- 2 files changed, 102 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 67bdfcd..39d3585 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,11 @@ wget https://git.peli-server.de/Dystroyer8/ATM10_CC_Codes/raw/branch/main/create create_factory_test ``` -Der Controller zeigt den Live-Bestand des Stock-Ticker-Netzes und bietet doppelt -zu bestaetigende Testbestellungen fuer `crushing`, `saw:1` und `saw:2`. Er steuert -noch keine Clutches oder sonstigen Redstone-Ausgaenge. +Der Controller zeigt automatisch alle Items des Stock-Ticker-Netzes auf +durchblaetterbaren Lagerseiten und bietet doppelt zu bestaetigende +Testbestellungen fuer `crushing`, `saw:1` und `saw:2`. Pro Verarbeitungslinie +bleibt nur ein Auftrag aktiv, bis sein Ergebnis im Lager erkannt wurde. Er +steuert noch keine Clutches oder sonstigen Redstone-Ausgaenge. ## Zielbild diff --git a/create_factory_test.lua b/create_factory_test.lua index 1c9eb71..e726f8f 100644 --- a/create_factory_test.lua +++ b/create_factory_test.lua @@ -6,18 +6,6 @@ local CONFIRM_SECONDS = 6.0 local JOB_TIMEOUT_SECONDS = 180.0 local LOG_FILE = "factory_test_log.txt" -local trackedItems = { - { id = "create:asurine", label = "Asurine" }, - { id = "minecraft:andesite", label = "Andesite" }, - { id = "create:andesite_alloy", label = "Andesite Alloy" }, - { id = "minecraft:oak_log", label = "Oak Logs" }, - { id = "minecraft:stripped_oak_log", label = "Stripped Oak" }, - { id = "minecraft:oak_planks", label = "Oak Planks" }, - { id = "alltheores:zinc_clump", label = "Zinc Clumps" }, - { id = "alltheores:zinc_nugget", label = "Zinc Nuggets" }, - { id = "create:shaft", label = "Shafts" }, -} - local actions = { { id = "crush_asurine", @@ -98,6 +86,10 @@ local monitor = peripheral.wrap(monitorName) monitor.setTextScale(0.5) local stock = {} +local stockEntries = {} +local stockPage = 1 +local stockPageCount = 1 +local stockPageButtons = {} local buttons = {} local messages = {} local jobs = {} @@ -120,6 +112,14 @@ local function timeText() return textutils.formatTime(os.time(), true) end +local function prettyItemName(itemId) + local path = tostring(itemId):match("^[^:]+:(.+)$") or tostring(itemId) + path = path:gsub("_", " ") + return (path:gsub("(%a)([%w']*)", function(first, rest) + return first:upper() .. rest:lower() + end)) +end + local function appendLog(message) local line = "[" .. timeText() .. "] " .. message messages[#messages + 1] = line @@ -135,7 +135,7 @@ local function appendLog(message) end local function refreshStock() - local ok, result = pcall(peripheral.call, tickerName, "stock") + local ok, result = pcall(peripheral.call, tickerName, "stock", true) if not ok then statusText = "Stock-Ticker-Fehler: " .. tostring(result) statusColor = colors.red @@ -143,12 +143,37 @@ local function refreshStock() end local nextStock = {} + local detailsByName = {} for _, entry in pairs(result or {}) do if type(entry) == "table" and entry.name then nextStock[entry.name] = (nextStock[entry.name] or 0) + (tonumber(entry.count) or 0) + detailsByName[entry.name] = entry end end stock = nextStock + + local nextEntries = {} + for itemId, count in pairs(nextStock) do + local details = detailsByName[itemId] or {} + local displayName = details.displayName + if type(displayName) ~= "string" or displayName == "" then + displayName = prettyItemName(itemId) + end + nextEntries[#nextEntries + 1] = { + id = itemId, + label = displayName, + count = count, + } + end + table.sort(nextEntries, function(a, b) + local aLabel = a.label:lower() + local bLabel = b.label:lower() + if aLabel == bLabel then + return a.id < b.id + end + return aLabel < bLabel + end) + stockEntries = nextEntries return true end @@ -202,6 +227,52 @@ local function center(y, text, foreground, background) writeAt(x, y, text, foreground, background) end +local function drawStockPage(width) + local itemsPerPage = 10 + stockPageCount = math.max(1, math.ceil(#stockEntries / itemsPerPage)) + stockPage = math.max(1, math.min(stockPage, stockPageCount)) + stockPageButtons = {} + + writeAt(3, 3, "<", stockPage > 1 and colors.yellow or colors.gray) + center(3, "LAGERBESTAND " .. tostring(stockPage) .. "/" .. tostring(stockPageCount), colors.cyan) + writeAt(width - 2, 3, ">", stockPage < stockPageCount and colors.yellow or colors.gray) + + stockPageButtons[#stockPageButtons + 1] = { + direction = -1, + x1 = 1, + x2 = math.floor(width / 3), + y = 3, + enabled = stockPage > 1, + } + stockPageButtons[#stockPageButtons + 1] = { + direction = 1, + x1 = math.ceil(width * 2 / 3), + x2 = width, + y = 3, + enabled = stockPage < stockPageCount, + } + + local columnWidth = math.floor((width - 6) / 2) + local leftX = 3 + local rightX = leftX + columnWidth + 2 + local firstIndex = (stockPage - 1) * itemsPerPage + 1 + + for position = 1, itemsPerPage do + local entry = stockEntries[firstIndex + position - 1] + if entry then + local column = (position - 1) % 2 + local row = 4 + math.floor((position - 1) / 2) + local x = column == 0 and leftX or rightX + local maxLabelLength = math.max(8, columnWidth - 14) + local label = entry.label + if #label > maxLabelLength then + label = label:sub(1, maxLabelLength - 1) .. "~" + end + writeAt(x, row, label .. ": " .. formatNumber(entry.count), colors.lime) + end + end +end + local function drawButton(action, x1, y1, x2, y2) local isArmed = armedAction == action.id and os.clock() <= armedUntil local available = stock[action.item] or 0 @@ -255,21 +326,9 @@ local function render() center(1, "CREATE FACTORY - LOGISTIKTEST", colors.cyan) center(2, "Ticker: " .. tickerName .. " | Monitor: " .. monitorName, colors.gray) - local columnWidth = math.floor((width - 6) / 2) - local leftX = 3 - local rightX = leftX + columnWidth + 2 - local firstStockRow = 4 + drawStockPage(width) - for index, item in ipairs(trackedItems) do - local column = (index - 1) % 2 - local row = firstStockRow + math.floor((index - 1) / 2) - local x = column == 0 and leftX or rightX - local amount = formatNumber(stock[item.id] or 0) - local text = item.label .. ": " .. amount - writeAt(x, row, text, (stock[item.id] or 0) > 0 and colors.lime or colors.gray) - end - - local statusRow = firstStockRow + math.ceil(#trackedItems / 2) + 1 + local statusRow = 10 center(statusRow, statusText, statusColor) local buttonTop = statusRow + 2 @@ -357,6 +416,17 @@ local function submit(action) end local function handleTouch(x, y) + for _, pageButton in ipairs(stockPageButtons) do + if y == pageButton.y and x >= pageButton.x1 and x <= pageButton.x2 then + if pageButton.enabled then + stockPage = stockPage + pageButton.direction + statusText = "Lagerseite " .. tostring(stockPage) .. "/" .. tostring(stockPageCount) + statusColor = colors.cyan + end + return + end + end + for _, button in ipairs(buttons) do if x >= button.x1 and x <= button.x2 and y >= button.y1 and y <= button.y2 then if button.activeJob then