Загрузка данных
-- Auto-detect output: Advanced Monitor or Computer Screen
local monitor = peripheral.find("monitor")
local target_term = monitor or term
-- Find Storage System
local storage = peripheral.find("functionalstorage:storage_controller") or
peripheral.find("sophisticatedstorage:storage_controller") or
peripheral.find("inventory")
if not storage then
error("Error: Storage Controller not found!")
end
-- Configuration
local UPDATE_INTERVAL = 1.0
local WINDOW_SIZE = 10
local active_tab = "Main" -- Active tab state: "Main" or "Resources"
-- Databases
local last_counts = {}
local history = {}
-- Screen Size Dimensions
local width, height = target_term.getSize()
-- Color handling helper for standard vs advanced computers
local function setColors(text_col, bg_col)
if target_term.isColor() then
target_term.setTextColor(text_col)
target_term.setBackgroundColor(bg_col)
end
end
-- Fetch item counts from the inventory system
local function getInventoryCounts()
local counts = {}
local items = storage.list()
for _, item in pairs(items) do
if item and item.name then
counts[item.name] = (counts[item.name] or 0) + item.count
end
end
return counts
end
-- Render top navigation bar
local function drawUI()
setColors(colors.white, colors.gray)
target_term.clear()
-- Draw top bar background
setColors(colors.white, colors.black)
for y = 1, 2 do
target_term.setCursorPos(1, y)
target_term.write(string.rep(" ", width))
end
-- Render Main Tab Button
if active_tab == "Main" then
setColors(colors.yellow, colors.lightGray)
else
setColors(colors.white, colors.black)
end
target_term.setCursorPos(2, 1)
target_term.write(" [ Home ] ")
-- Render Resources Tab Button
if active_tab == "Resources" then
setColors(colors.yellow, colors.lightGray)
else
setColors(colors.white, colors.black)
end
target_term.setCursorPos(14, 1)
target_term.write(" [ Resources ] ")
setColors(colors.white, colors.gray)
end
-- Render Resources Page Content
local function drawResourcesPage(current_counts)
setColors(colors.white, colors.gray)
-- Table Header
target_term.setCursorPos(2, 4)
target_term.write(string.format("%-16s | %-8s | %-8s", "Resource", "Total", "Gain/s"))
target_term.setCursorPos(2, 5)
target_term.write(string.rep("-", width - 2))
local line = 6
for name, hist in pairs(history) do
local total_diff = 0
for _, entry in ipairs(hist) do
total_diff = total_diff + entry.diff
end
local avg_gain = total_diff / WINDOW_SIZE
local current_total = current_counts[name] or 0
local short_name = name:match(":(.+)$") or name
-- Display items currently in system or items with a change rate
if current_total > 0 or math.abs(avg_gain) > 0.01 then
target_term.setCursorPos(2, line)
local trunc_name = short_name:sub(1, 16)
if avg_gain > 0 then
setColors(colors.green, colors.gray)
target_term.write(string.format("%-16s | %-8d | +%.2f", trunc_name, current_total, avg_gain))
elseif avg_gain < 0 then
setColors(colors.red, colors.gray)
target_term.write(string.format("%-16s | %-8d | %.2f", trunc_name, current_total, avg_gain))
else
setColors(colors.white, colors.gray)
target_term.write(string.format("%-16s | %-8d | 0.00", trunc_name, current_total))
end
line = line + 1
if line > height - 1 then break end
end
end
end
-- Render Home Page Content
local function drawMainPage()
setColors(colors.white, colors.gray)
target_term.setCursorPos(2, 4)
target_term.write("Welcome to Storage Monitor OS!")
target_term.setCursorPos(2, 6)
target_term.write("Click on [ Resources ] tab above")
target_term.setCursorPos(2, 7)
target_term.write("to view live item tracking stats.")
end
-- Handle Touch and Click Events
local function handleClicks()
while true do
local event, side, x, y = os.pullEvent()
if event == "mouse_click" or event == "monitor_touch" then
-- Check if click is inside the top menu bounds
if y == 1 or y == 2 then
if x >= 2 and x <= 11 then
active_tab = "Main"
elseif x >= 14 and x <= 28 then
active_tab = "Resources"
end
-- Force instant UI refresh on interaction
drawUI()
if active_tab == "Main" then drawMainPage() else drawResourcesPage(last_counts) end
end
end
end
end
-- Main Data Tracking Loop
local function dataLoop()
last_counts = getInventoryCounts()
while true do
local current_counts = getInventoryCounts()
local current_time = os.epoch("utc") / 1000
local all_items = {}
for name in pairs(last_counts) do all_items[name] = true end
for name in pairs(current_counts) do all_items[name] = true end
for name in pairs(all_items) do
local old_val = last_counts[name] or 0
local new_val = current_counts[name] or 0
local diff = new_val - old_val
if not history[name] then history[name] = {} end
table.insert(history[name], { time = current_time, diff = diff })
while #history[name] > 0 and (current_time - history[name].time) > WINDOW_SIZE do
table.remove(history[name], 1)
end
end
-- Refresh display layout
drawUI()
if active_tab == "Main" then
drawMainPage()
elseif active_tab == "Resources" then
drawResourcesPage(current_counts)
end
last_counts = current_counts
os.sleep(UPDATE_INTERVAL)
end
end
-- Start parallel processes (Data tracking + Event listener)
parallel.waitForAny(dataLoop, handleClicks)