Add smelter dashboard functionality and manage disabled recipes

This commit is contained in:
MayaTheShy
2026-03-15 22:49:16 -04:00
parent ce430efc4d
commit 6a70298535

View File

@@ -9,6 +9,8 @@ local SCAN_INTERVAL = 3 -- seconds between background scans
local SMELT_INTERVAL = 3 -- seconds between furnace checks
local SMELT_RESERVE = 64 -- keep at least 1 stack of each raw material
local CACHE_FILE = ".inventory_cache" -- persistent cache file
local SMELTER_MONITOR_SIDE = "top"
local DISABLED_RECIPES_FILE = ".disabled_recipes"
-------------------------------------------------
-- Furnace types to manage
@@ -115,6 +117,8 @@ local cache = {
usedRatio = 0,
dropperOk = false,
barrelOk = false,
furnaceCount = 0,
furnaceStatus = {}, -- per-furnace { name, type, input, fuel, output, active }
}
-------------------------------------------------
@@ -154,6 +158,27 @@ local function getFurnaces()
return furnaces
end
local function refreshFurnaceStatus()
local furnaces = getFurnaces()
local status = {}
for _, fname in ipairs(furnaces) do
local furnace = peripheral.wrap(fname)
if furnace then
local contents = furnace.list()
local entry = {
name = fname,
type = peripheral.getType(fname),
input = contents[SLOT_INPUT] or nil,
fuel = contents[SLOT_FUEL] or nil,
output = contents[SLOT_OUTPUT] or nil,
active = (contents[SLOT_INPUT] ~= nil and contents[SLOT_FUEL] ~= nil),
}
table.insert(status, entry)
end
end
cache.furnaceStatus = status
end
local function scanInventory(deviceName)
local inv = peripheral.wrap(deviceName)
if not inv then return {} end
@@ -239,6 +264,9 @@ local function refreshCache(onProgress)
end
cache.furnaceCount = furnaceCount
-- Scan furnace contents for smelter dashboard
refreshFurnaceStatus()
activity.scanning = false
-- Persist cache to disk
@@ -255,6 +283,7 @@ local function refreshCache(onProgress)
dropperOk = cache.dropperOk,
barrelOk = cache.barrelOk,
furnaceCount = cache.furnaceCount,
furnaceStatus = cache.furnaceStatus,
savedAt = os.epoch("utc"),
}
local f = fs.open(CACHE_FILE, "w")
@@ -283,6 +312,7 @@ local function loadCacheFromDisk()
cache.dropperOk = data.dropperOk or false
cache.barrelOk = data.barrelOk or false
cache.furnaceCount = data.furnaceCount or 0
cache.furnaceStatus = data.furnaceStatus or {}
else
error("invalid cache data")
end
@@ -299,18 +329,25 @@ end
-------------------------------------------------
local mon = nil
local monName = nil
local smelterMon = nil
local smelterMonName = nil
local function setupMonitor()
mon = peripheral.wrap(MONITOR_SIDE)
-- If the side has a modem instead of a direct monitor, find it by type
if mon and not mon.setTextScale then
if mon and mon.setTextScale then
monName = MONITOR_SIDE
else
mon = nil
end
if not mon then
-- Search for a monitor on the network
local name = peripheral.find("monitor")
if name then
mon = name
-- Search for a monitor on the network (skip smelter side)
for _, name in ipairs(peripheral.getNames()) do
if peripheral.getType(name) == "monitor" and name ~= SMELTER_MONITOR_SIDE then
mon = peripheral.wrap(name)
monName = name
break
end
end
end
if not mon then return false end
@@ -319,6 +356,29 @@ local function setupMonitor()
return true
end
local function setupSmelterMonitor()
smelterMon = peripheral.wrap(SMELTER_MONITOR_SIDE)
if smelterMon and smelterMon.setTextScale then
smelterMonName = SMELTER_MONITOR_SIDE
else
smelterMon = nil
end
if not smelterMon then
-- Search for a second monitor on the network
for _, name in ipairs(peripheral.getNames()) do
if peripheral.getType(name) == "monitor" and name ~= monName then
smelterMon = peripheral.wrap(name)
smelterMonName = name
break
end
end
end
if not smelterMon then return false end
smelterMon.setTextScale(0.5)
smelterMon.clear()
return true
end
-------------------------------------------------
-- UI State
-------------------------------------------------
@@ -345,6 +405,41 @@ local kbRows = {
{"Z","X","C","V","B","N","M"},
}
-------------------------------------------------
-- Smelter dashboard state
-------------------------------------------------
local smelterView = "status" -- "status" or "recipes"
local smelterPage = 1
local smelterTotalPages = 1
local smelterTouchZones = {}
local smelterPendingZones = {}
local smelterNeedsRedraw = true
local smeltingPaused = false
local disabledRecipes = {} -- { ["minecraft:raw_iron"] = true }
local function loadDisabledRecipes()
if not fs.exists(DISABLED_RECIPES_FILE) then return end
pcall(function()
local f = fs.open(DISABLED_RECIPES_FILE, "r")
local raw = f.readAll()
f.close()
local data = textutils.unserialise(raw)
if type(data) == "table" then
if data.disabled then disabledRecipes = data.disabled end
if data.paused ~= nil then smeltingPaused = data.paused end
end
end)
end
local function saveDisabledRecipes()
pcall(function()
local f = fs.open(DISABLED_RECIPES_FILE, "w")
f.write(textutils.serialise({ disabled = disabledRecipes, paused = smeltingPaused }))
f.close()
end)
end
-- Get items filtered by search query
local function getFilteredItems()
local filtered = {}
@@ -377,6 +472,22 @@ local function hitTest(x, y)
return nil, nil
end
local function addSmelterZone(x1, y1, x2, y2, action, data)
table.insert(smelterPendingZones, {
x1 = x1, y1 = y1, x2 = x2, y2 = y2,
action = action, data = data
})
end
local function smelterHitTest(x, y)
for _, zone in ipairs(smelterTouchZones) do
if x >= zone.x1 and x <= zone.x2 and y >= zone.y1 and y <= zone.y2 then
return zone.action, zone.data
end
end
return nil, nil
end
-------------------------------------------------
-- Drawing helpers (write to draw target)
-------------------------------------------------