Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local totalConsumedFile = "total_consumed"
- local manaBeanItemId = 25366
- --The text colors for the aspects
- local aspectColors = dofile("aspect_colors")
- local refreshTime = 30
- --All managed aspects. Only aspects for which there is a jar are listed here
- local aspects
- --Table of tables which hold the peripheral handles for all jars to a given aspect
- local jarHandles
- --The Logistics Pipes ItemIdentifiers for all available mana beans
- local itemIdents = {}
- --The amount of essentia in the jars
- local jarAmount
- --The amount of mana beans available
- local stockAmount
- --The total consumption of all mana beans
- local totalConsumed
- --The Logistics Pipe peripheral handle
- local lp
- --The monitor peripheral handle
- local mon
- --Windows
- local winAspects
- local winContr
- local winRefill
- local colWidth = 19
- local lines = 20
- --Modes: available, stock, total, statistics, capacity, percentage
- local aspectMode = "available"
- --States: aspects, refill
- local state = "aspects"
- local timerRefresh
- local refAspect
- local refAmount
- local refCurrent
- local refMaximum
- local refCapacity
- ----------------------------------------------------------------
- function wrapLp()
- lp = peripheral.find("LogisticsPipes:Request")
- if not lp then
- error("No logistics request pipe found")
- end
- end
- ----------------------------------------------------------------
- function wrapMonitor()
- mon = peripheral.find("monitor")
- if not mon then
- error("No monitor found")
- end
- mon.setBackgroundColor(colors.black)
- mon.setTextColor(colors.white)
- mon.clear()
- mon.setTextScale(1)
- end
- ----------------------------------------------------------------
- function wrapJars()
- aspects = {}
- jarHandles = {}
- jarAmount = {}
- local per = peripheral.getNames()
- for i = 1, #per do
- local pt = peripheral.getType(per[i])
- if pt == "tilejar" or pt == "tilejarvoid" then
- local jar = peripheral.wrap(per[i])
- local asp = jar.getAspects()[1]
- if not asp then
- error("The jar \""..per[i].."\" is unlabeled and empty!")
- end
- local aspect = string.lower(asp.name)
- local count = asp.quantity
- if not jarHandles[aspect] then
- jarHandles[aspect] = {jar}
- jarAmount[aspect] = count
- table.insert(aspects, aspect)
- else
- table.insert(jarHandles[aspect], jar)
- jarAmount[aspect] = jarAmount[aspect] + count
- end
- end
- end
- table.sort(aspects)
- end
- ----------------------------------------------------------------
- function updateJars()
- print("Updating jar values")
- for aspect, handles in pairs(jarHandles) do
- jarAmount[aspect] = 0
- for _, jar in pairs(handles) do
- local asp = jar.getAspects()[1]
- if not asp then
- error("One of the jars that used to hold "..aspect.." is unlabeled and empty!")
- end
- jarAmount[aspect] = jarAmount[aspect] + asp.quantity
- end
- end
- end
- ----------------------------------------------------------------
- function warning(...)
- term.setTextColor(colors.orange)
- print("Warning: ", ...)
- term.setTextColor(colors.white)
- end
- ----------------------------------------------------------------
- --Returns the aspect of the mana bean referred to by ident
- function getAspectFromIdent(ident)
- local nbt = ident.getTagCompound()
- return nbt.value.Aspects.value[1].value.key.value
- end
- ----------------------------------------------------------------
- function updateStock()
- print("Updating stock values")
- stockAmount = {}
- items = lp.getAvailableItems()
- for i = 1, #items do
- local ident = items[i].getValue1()
- if ident.getId() == manaBeanItemId then
- local aspect = getAspectFromIdent(ident)
- local count = items[i].getValue2()
- itemIdents[aspect] = ident
- stockAmount[aspect] = count
- end
- end
- end
- ----------------------------------------------------------------
- function loadFromFile(file)
- local f = fs.open(file, "r")
- if not f then
- return nil
- end
- local ret = textutils.unserialize(f.readAll())
- f.close()
- return ret
- end
- ----------------------------------------------------------------
- function storeToFile(val, file)
- local f = fs.open(file, "w")
- if not f then return false end
- f.write(textutils.serialize(val))
- f.close()
- return true
- end
- ----------------------------------------------------------------
- --A simple stable sort algorithm
- function insertionSort(tbl, cmp)
- cmp = cmp or function(a, b) return a < b end
- for i = 2, #tbl do
- local el = tbl[i]
- local j = i
- while j > 1 and cmp(el, tbl[j-1]) do
- tbl[j] = tbl[j-1]
- j = j-1
- end
- tbl[j] = el
- end
- end
- ----------------------------------------------------------------
- function displayJars(colWidth, lines, mode)
- local winAspects = winAspects
- winAspects.setVisible(false)
- winAspects.clear()
- local x, y = 1, 1
- for i = 1, #aspects do
- winAspects.setTextColor(aspectColors[aspects[i]] or colors.white)
- winAspects.setCursorPos(x, y)
- winAspects.write(firstToUpper(aspects[i]))
- winAspects.setCursorPos(x+13, y)
- local ava = jarAmount[aspects[i]]
- local sto = stockAmount[aspects[i]] or 0
- local stat = totalConsumed[aspects[i]] or 0
- local cap = 64 * #jarHandles[aspects[i]]
- local dstr = ""
- if mode == "available" then
- dstr = string.format("%4d", ava)
- elseif mode == "stock" then
- dstr = string.format("%4d", sto)
- elseif mode == "total" then
- dstr = string.format("%4d", ava + sto)
- elseif mode == "statistics" then
- dstr = string.format("%4d", stat)
- elseif mode == "capacity" then
- dstr = string.format("%4d", cap)
- elseif mode == "percentage" then
- dstr = string.format("%3d%%", 100*ava/cap)
- end
- winAspects.write(dstr)
- if y < lines then
- y = y+1
- else
- y = 1
- x = x + colWidth
- end
- end
- winAspects.setVisible(true)
- winContr.redraw()
- end
- ----------------------------------------------------------------
- function doRequest(aspect, amount)
- if amount == 0 then return true end
- local ident = itemIdents[aspect]
- if not ident then
- warning("No item identifier for ", aspect)
- return false
- end
- local res = lp.makeRequest(ident, amount)
- if res ~= "DONE" then
- warning("Request for ", amount, " x ", aspect, " failed: ", res)
- return false
- end
- print("Successfully requested ", amount, " x ", aspect)
- totalConsumed[aspect] = (totalConsumed[aspect] or 0) + amount
- if stockAmount[aspect] then
- stockAmount[aspect] = stockAmount[aspect] - amount
- end
- storeToFile(totalConsumed, totalConsumedFile)
- return true
- end
- ----------------------------------------------------------------
- function firstToUpper(str)
- return str:gsub("^%l", string.upper)
- end
- ----------------------------------------------------------------
- function drawModeButton(mode)
- if aspectMode == mode then
- winContr.setBackgroundColor(colors.red)
- else
- winContr.setBackgroundColor(colors.blue)
- end
- if mode == "available" then
- winContr.setCursorPos(2,2)
- winContr.write(" Available ")
- elseif mode == "stock" then
- winContr.setCursorPos(2,3)
- winContr.write(" Stocked ")
- elseif mode == "total" then
- winContr.setCursorPos(2,4)
- winContr.write(" Total ")
- elseif mode == "statistics" then
- winContr.setCursorPos(14,2)
- winContr.write(" Statistics ")
- elseif mode == "capacity" then
- winContr.setCursorPos(14,3)
- winContr.write(" Capacity ")
- elseif mode == "percentage" then
- winContr.setCursorPos(14,4)
- winContr.write(" Percentage ")
- end
- end
- ----------------------------------------------------------------
- function drawRefreshButton()
- winContr.setCursorPos(27,2)
- winContr.write(" ")
- winContr.setCursorPos(27,3)
- winContr.write(" Refresh ")
- winContr.setCursorPos(27,4)
- winContr.write(" ")
- end
- ----------------------------------------------------------------
- function drawOptionsButton()
- winContr.setCursorPos(39,2)
- winContr.write(" ")
- winContr.setCursorPos(39,3)
- winContr.write(" Options ")
- winContr.setCursorPos(39,4)
- winContr.write(" ")
- end
- ----------------------------------------------------------------
- function changeAspectMode(mode)
- if aspectMode == mode then return end
- local oldMode = aspectMode
- aspectMode = mode
- drawModeButton(oldMode)
- drawModeButton(mode)
- displayJars(colWidth, lines, mode)
- end
- ----------------------------------------------------------------
- function changeState(nst)
- if state == nst then return end
- if state == "aspects" then
- winAspects.setVisible(false)
- elseif state == "refill" then
- winRefill.setVisible(false)
- end
- if nst == "aspects" then
- displayJars(colWidth, lines, aspectMode)
- timerRefresh = os.startTimer(refreshTime)
- elseif nst == "refill" then
- refCurrent = jarAmount[refAspect]
- refMaximum = refCurrent + (stockAmount[refAspect] or 0)
- refCapacity = 64*#jarHandles[refAspect]
- winRefill.setTextColor(aspectColors[refAspect] or colors.white)
- winRefill.setBackgroundColor(colors.black)
- winRefill.setCursorPos(22, 5)
- winRefill.write(firstToUpper(refAspect).." ")
- winRefill.setTextColor(colors.white)
- winRefill.setCursorPos(14, 7)
- winRefill.write(string.format("%6d", refCurrent))
- winRefill.setCursorPos(14, 8)
- winRefill.write(string.format("%6d", refMaximum))
- winRefill.setCursorPos(14, 9)
- winRefill.write(string.format("%6d", refCapacity))
- winRefill.setVisible(true)
- changeRefAmount(refCurrent)
- end
- state = nst
- end
- ----------------------------------------------------------------
- function changeRefAmount(amount)
- refAmount = math.min(math.max(refCurrent, amount), refMaximum, refCapacity)
- winRefill.setBackgroundColor(colors.gray)
- winRefill.setCursorPos(31, 7)
- winRefill.write(string.format(" %3d ", refAmount-refCurrent))
- winRefill.setCursorPos(31, 8)
- winRefill.write(string.format(" %3d ", refAmount))
- end
- ----------------------------------------------------------------
- --Main
- print("Wrapping request pipe and monitor")
- wrapLp()
- wrapMonitor()
- print("Finding and wrapping all jars")
- wrapJars()
- print("Searching for mana beans")
- updateStock()
- print("Loading total consumed file ", totalConsumedFile)
- totalConsumed = loadFromFile(totalConsumedFile) or {}
- print("Creating Windows")
- winAspects = window.create(mon, 1, 1, 60, 26, true)
- winContr = window.create(winAspects, 1, 21, 60, 4, false)
- drawModeButton("available")
- drawModeButton("stock")
- drawModeButton("total")
- drawModeButton("statistics")
- drawModeButton("capacity")
- drawModeButton("percentage")
- --drawOptionsButton()
- drawRefreshButton()
- winContr.setVisible(true)
- displayJars(colWidth, lines, aspectMode)
- winRefill = window.create(mon, 1, 1, 60, 26, false)
- winRefill.setCursorPos(4, 5)
- winRefill.write("Aspect to refill:")
- winRefill.setCursorPos(4, 7)
- winRefill.write("Current:")
- winRefill.setCursorPos(4, 8)
- winRefill.write("Maximum:")
- winRefill.setCursorPos(4, 9)
- winRefill.write("Capacity:")
- winRefill.setCursorPos(23, 7)
- winRefill.write(" Plus: ")
- winRefill.setCursorPos(23, 8)
- winRefill.write(" Total: ")
- winRefill.setBackgroundColor(colors.blue)
- winRefill.setCursorPos(4, 11)
- winRefill.write(" +1 ")
- winRefill.setCursorPos(13, 11)
- winRefill.write(" +5 ")
- winRefill.setCursorPos(22, 11)
- winRefill.write(" +32 ")
- winRefill.setCursorPos(4, 13)
- winRefill.write(" -1 ")
- winRefill.setCursorPos(13, 13)
- winRefill.write(" -5 ")
- winRefill.setCursorPos(22, 13)
- winRefill.write(" -32 ")
- winRefill.setCursorPos(31, 11)
- winRefill.write(" ")
- winRefill.setCursorPos(31, 12)
- winRefill.write(" Max ")
- winRefill.setCursorPos(31, 13)
- winRefill.write(" ")
- winRefill.setCursorPos(7, 15)
- winRefill.write(" ")
- winRefill.setCursorPos(7, 16)
- winRefill.write(" OK ")
- winRefill.setCursorPos(7, 17)
- winRefill.write(" ")
- winRefill.setCursorPos(25, 15)
- winRefill.write(" ")
- winRefill.setCursorPos(25, 16)
- winRefill.write(" Cancel ")
- winRefill.setCursorPos(25, 17)
- winRefill.write(" ")
- print("Initiation successful")
- local quit = false
- local timerFlash
- timerRefresh = os.startTimer(refreshTime)
- while not quit do
- local event, param1, param2, param3 = os.pullEvent()
- if state == "aspects" then
- if event == "monitor_touch" then
- local x, y = param2, param3
- if y <= lines then
- local asp = y + lines * math.floor(x/colWidth)
- refAspect = aspects[asp]
- if refAspect then changeState("refill") end
- else
- if x >= 2 and x <= 12 then
- if y == 22 then
- changeAspectMode("available")
- elseif y == 23 then
- changeAspectMode("stock")
- elseif y == 24 then
- changeAspectMode("total")
- end
- elseif x >= 14 and x <= 25 then
- if y == 22 then
- changeAspectMode("statistics")
- elseif y == 23 then
- changeAspectMode("capacity")
- elseif y == 24 then
- changeAspectMode("percentage")
- end
- elseif x >= 27 and x <= 37 and y >= 22 and y <= 24 then
- winContr.setBackgroundColor(colors.red)
- drawRefreshButton()
- updateJars()
- updateStock()
- displayJars(colWidth, lines, aspectMode)
- timerRefresh = os.startTimer(refreshTime)
- timerFlash = os.startTimer(0.15)
- elseif x >= 39 and x <= 49 and y >= 22 and y <= 24 then
- quit = true
- end
- end
- elseif event == "timer" then
- if param1 == timerRefresh then
- winContr.setBackgroundColor(colors.red)
- drawRefreshButton()
- updateJars()
- updateStock()
- displayJars(colWidth, lines, aspectMode)
- timerRefresh = os.startTimer(refreshTime)
- timerFlash = os.startTimer(0.15)
- elseif param1 == timerFlash then
- winContr.setBackgroundColor(colors.blue)
- drawRefreshButton()
- end
- end
- elseif state == "refill" then
- if event == "monitor_touch" then
- local x, y = param2, param3
- if y == 11 and x >= 4 and x <= 11 then
- changeRefAmount(refAmount+1)
- elseif y == 13 and x >= 4 and x <= 11 then
- changeRefAmount(refAmount-1)
- elseif y == 11 and x >= 13 and x <= 20 then
- changeRefAmount(refAmount+5)
- elseif y == 13 and x >= 13 and x <= 20 then
- changeRefAmount(refAmount-5)
- elseif y == 11 and x >= 22 and x <= 29 then
- changeRefAmount(refAmount+32)
- elseif y == 13 and x >= 22 and x <= 29 then
- changeRefAmount(refAmount-32)
- elseif y >= 11 and y <= 13 and x >= 31 and x <= 37 then
- changeRefAmount(math.huge)
- elseif y >= 15 and y <= 17 and x >= 7 and x <= 16 then
- doRequest(refAspect, refAmount-refCurrent)
- changeState("aspects")
- elseif y >= 15 and y <= 17 and x >= 25 and x <= 34 then
- changeState("aspects")
- end
- end
- end
- end
- mon.clear()
- print("Program successfully ended")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement