--furnacemonitor.lua
--(( Settings ))--
local textScale = 0.5
---@class FurnaceMonitorSides
---@field topFurn string
---@field monitor string
---@field botFurn string
local _
---@type FurnaceMonitorSides[]
local furnaceMonitorSides = {
{
topFurn = "minecraft:furnace_11817",
monitor = "monitor_4475",
botFurn = "minecraft:furnace_11810",
},
{
topFurn = "minecraft:furnace_11815",
monitor = "monitor_4473",
botFurn = "minecraft:furnace_11812",
},
{
topFurn = "minecraft:furnace_11813",
monitor = "monitor_4474",
botFurn = "minecraft:furnace_11809",
},
{
topFurn = "minecraft:furnace_11818",
monitor = "monitor_4476",
botFurn = "minecraft:furnace_11819",
},
{
topFurn = "minecraft:furnace_11820",
monitor = "monitor_4477",
botFurn = "minecraft:furnace_11821",
},
{
topFurn = "minecraft:furnace_11822",
monitor = "monitor_4478",
botFurn = "minecraft:furnace_11823",
},
}
--(( Types & Static variables ))--
local furnaceBurnableSlot = 1
local furnaceFuelSlot = 2
local furnaceResultSlot = 3
local ticksPerSecond = 20
local ticksPerCookedItem = 10 * ticksPerSecond
local orientation = {
top = 0,
bottom = 1,
}
---@class FurnaceMonitor
---@field furn quarkFurnace
---@field redirect Redirect
---@field orientation integer
local _
--(( Functions ))--
---@param periphType string
---@param side string
---@return Peripheral
local function getPeripheralOfType(periphType, side)
local actualType = peripheral.getType(side)
local periph = peripheral.wrap(side)
if not actualType or not periph then
error(string.format("Expected %s at '%s', got nil.", periphType, side))
end
if actualType ~= periphType then
error(string.format("Expected %s at '%s', got %s.", periphType, side, actualType))
end
return periph
end
---@param side string
---@return Monitor
local function getMonitor(side)
return getPeripheralOfType("monitor", side)
end
---@param side string
---@return quarkFurnace
local function getFurnace(side)
return getPeripheralOfType("minecraft:furnace", side)
end
---@param furn quarkFurnace
---@param redirect Redirect
---@param orientation integer
---@return FurnaceMonitor
local function createFurnMon(furn, redirect, orientation)
---@type FurnaceMonitor
local furnMon = {}
furnMon.furn = furn
furnMon.redirect = redirect
furnMon.orientation = orientation
return furnMon
end
---@param source Redirect
---@param windowHeight integer
---@return Window,Window
local function createWindows(source, windowHeight)
local maxW,maxH = source.getSize()
local botY = maxH - windowHeight + 1
local topWindow = window.create(
source, 1, 1, maxW, windowHeight
)
local botWindow = window.create(
source, 1, botY, maxW, windowHeight
)
return topWindow, botWindow
end
---@param col1 string
---@param col2 string
---@param barWidth integer
---@param fullWidth integer
local function getBlittableBarColors(col1, col2, barWidth, fullWidth)
return col1:rep(barWidth) .. col2:rep(fullWidth - barWidth)
end
---@param r Redirect
---@param title string
---@param x integer
---@param y integer
---@param width integer
---@param ticksPassed integer
---@param ticksTotal integer
---@param rounding fun(ticks:number):integer
local function drawTicksProgress(r, title, x, y, width, ticksPassed, ticksTotal, rounding)
local perc = ticksPassed / ticksTotal
if ticksTotal == 0 then
perc = 0
end
local barWidth = (rounding or math.ceil)(width * perc)
local percX = width - #"100%"
-- constructs string like:
-- " 12 Coal 56% "
local str =
table.concat {
title or "",
string.rep(" ", width),
}:sub(1, percX)
.. string.format("%3.f%%", 100*perc)
local bg = getBlittableBarColors("e", "7", barWidth, width)
local fg
if not title then
fg = getBlittableBarColors("8", "1", barWidth, width)
else
fg = getBlittableBarColors("0", "1", barWidth, width)
end
-- draw bar
r.setCursorPos(x, y)
r.blit(str, fg, bg)
end
---@param inv quarkInventory
---@param slot integer
---@return string|nil
local function getItemDisplayName(inv, slot)
---@type quarkItemMeta
local item = inv.getItemMeta(slot)
if item then
return string.format("%-2i %s", item.count, item. displayName)
end
end
---@param inv quarkInventory
---@return integer,integer
local function calcResultItemCounts(inv)
---@type quarkItemMeta
local resultItems = inv.getItemMeta(furnaceResultSlot)
---@type quarkItemObj
local burnableItems = inv.getItemMeta(furnaceBurnableSlot)
local itemCount = resultItems and resultItems.count or 0
local maxCount = math.min(
resultItems and resultItems.maxCount or 0,
itemCount + (burnableItems and burnableItems.count or 0)
)
return itemCount, maxCount
end
---@param furnMon FurnaceMonitor
local function drawFurnace(furnMon)
local f = furnMon.furn
local r = furnMon.redirect
local x = 1
local w,h = r.getSize()
local barWidth = w
local doneY, burnableY, fuelY, resultY = 1, 2, 4, 3
if furnMon.orientation == orientation.bottom then
doneY = h
end
local burnable = getItemDisplayName(f, furnaceBurnableSlot)
drawTicksProgress(r, burnable, x, burnableY, barWidth, f.getCookTime(), ticksPerCookedItem, math.floor)
local fuel = getItemDisplayName(f, furnaceFuelSlot)
drawTicksProgress(r, fuel, x, fuelY, barWidth, f.getRemainingBurnTime(), f.getBurnTime(), math.ceil)
local result = getItemDisplayName(f, furnaceResultSlot)
local resultItemCount, resultMaxItems = calcResultItemCounts(f)
drawTicksProgress(r, result, x, resultY, barWidth, resultItemCount, resultMaxItems, math.floor)
local bg = colors.black
if resultItemCount == resultMaxItems and resultItemCount > 0 then
bg = colors.lime
end
r.setBackgroundColor(bg)
r.setCursorPos(1,doneY)
r.write(string.rep(" ", w))
end
--(( Main program ))--
---@type FurnaceMonitor[]
local furnMons = {}
for _,v in pairs(furnaceMonitorSides) do
---@type FurnaceMonitorSides
local sides = v
local m = getMonitor(sides.monitor)
local topFurn = getFurnace(sides.topFurn)
local botFurn = getFurnace(sides.botFurn)
m.setBackgroundColor(colors.black)
m.clear()
m.setTextScale(textScale)
local _,h = m.getSize()
local rowHeight = math.floor(h / 2)
local topW,botW = createWindows(m, rowHeight)
table.insert(furnMons, createFurnMon(topFurn, topW, orientation.top))
table.insert(furnMons, createFurnMon(botFurn, botW, orientation.bottom))
end
while true do
for _,v in ipairs(furnMons) do
drawFurnace(v)
end
sleep(.5)
end
--(( EOF ))--
Comments