jille_Jr icon

CC: Furnace monitor (via Quark)

jille_Jr | PRO | 11/21/20 04:03:35 PM UTC (Edited) | 0 ⭐ | 1801 👁️ | Never ⏰ | []
Lua |

6.71 KB

|

None

|

0 👍

/

0 👎

--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