Advertisement
Guest User

essentia

a guest
Aug 1st, 2014
276
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.11 KB | None | 0 0
  1. local totalConsumedFile = "total_consumed"
  2. local manaBeanItemId = 25366
  3. --The text colors for the aspects
  4. local aspectColors = dofile("aspect_colors")
  5. local refreshTime = 30
  6.  
  7. --All managed aspects. Only aspects for which there is a jar are listed here
  8. local aspects
  9. --Table of tables which hold the peripheral handles for all jars to a given aspect
  10. local jarHandles
  11. --The Logistics Pipes ItemIdentifiers for all available mana beans
  12. local itemIdents = {}
  13. --The amount of essentia in the jars
  14. local jarAmount
  15. --The amount of mana beans available
  16. local stockAmount
  17. --The total consumption of all mana beans
  18. local totalConsumed
  19.  
  20. --The Logistics Pipe peripheral handle
  21. local lp
  22. --The monitor peripheral handle
  23. local mon
  24.  
  25. --Windows
  26. local winAspects
  27. local winContr
  28. local winRefill
  29.  
  30. local colWidth = 19
  31. local lines = 20
  32.  
  33. --Modes: available, stock, total, statistics, capacity, percentage
  34. local aspectMode = "available"
  35. --States: aspects, refill
  36. local state = "aspects"
  37.  
  38. local timerRefresh
  39.  
  40. local refAspect
  41. local refAmount
  42. local refCurrent
  43. local refMaximum
  44. local refCapacity
  45.  
  46. ----------------------------------------------------------------
  47. function wrapLp()
  48.   lp = peripheral.find("LogisticsPipes:Request")
  49.   if not lp then
  50.     error("No logistics request pipe found")
  51.   end
  52. end
  53.  
  54. ----------------------------------------------------------------
  55. function wrapMonitor()
  56.   mon = peripheral.find("monitor")
  57.   if not mon then
  58.     error("No monitor found")
  59.   end
  60.   mon.setBackgroundColor(colors.black)
  61.   mon.setTextColor(colors.white)
  62.   mon.clear()
  63.   mon.setTextScale(1)
  64. end
  65.  
  66. ----------------------------------------------------------------
  67. function wrapJars()
  68.   aspects = {}
  69.   jarHandles = {}
  70.   jarAmount = {}
  71.  
  72.   local per = peripheral.getNames()
  73.   for i = 1, #per do
  74.     local pt = peripheral.getType(per[i])
  75.     if pt == "tilejar" or pt == "tilejarvoid" then
  76.       local jar = peripheral.wrap(per[i])
  77.       local asp = jar.getAspects()[1]
  78.       if not asp then
  79.         error("The jar \""..per[i].."\" is unlabeled and empty!")
  80.       end
  81.       local aspect = string.lower(asp.name)
  82.       local count = asp.quantity
  83.      
  84.       if not jarHandles[aspect] then
  85.         jarHandles[aspect] = {jar}
  86.         jarAmount[aspect] = count
  87.         table.insert(aspects, aspect)
  88.       else
  89.         table.insert(jarHandles[aspect], jar)
  90.         jarAmount[aspect] = jarAmount[aspect] + count
  91.       end
  92.     end
  93.   end
  94.  
  95.   table.sort(aspects)
  96. end
  97.  
  98. ----------------------------------------------------------------
  99. function updateJars()
  100.   print("Updating jar values")
  101.   for aspect, handles in pairs(jarHandles) do
  102.     jarAmount[aspect] = 0
  103.     for _, jar in pairs(handles) do
  104.       local asp = jar.getAspects()[1]
  105.       if not asp then
  106.         error("One of the jars that used to hold "..aspect.." is unlabeled and empty!")
  107.       end
  108.       jarAmount[aspect] = jarAmount[aspect] + asp.quantity
  109.     end
  110.   end
  111. end
  112.  
  113. ----------------------------------------------------------------
  114. function warning(...)
  115.   term.setTextColor(colors.orange)
  116.   print("Warning: ", ...)
  117.   term.setTextColor(colors.white)
  118. end
  119.  
  120. ----------------------------------------------------------------
  121. --Returns the aspect of the mana bean referred to by ident
  122. function getAspectFromIdent(ident)
  123.   local nbt = ident.getTagCompound()
  124.   return nbt.value.Aspects.value[1].value.key.value
  125. end
  126.  
  127. ----------------------------------------------------------------
  128. function updateStock()
  129.   print("Updating stock values")
  130.   stockAmount = {}
  131.   items = lp.getAvailableItems()
  132.   for i = 1, #items do
  133.     local ident = items[i].getValue1()
  134.     if ident.getId() == manaBeanItemId then
  135.       local aspect = getAspectFromIdent(ident)
  136.       local count = items[i].getValue2()
  137.      
  138.       itemIdents[aspect] = ident
  139.       stockAmount[aspect] = count
  140.     end
  141.   end
  142. end
  143.  
  144. ----------------------------------------------------------------
  145. function loadFromFile(file)
  146.   local f = fs.open(file, "r")
  147.   if not f then
  148.     return nil
  149.   end
  150.   local ret = textutils.unserialize(f.readAll())
  151.   f.close()
  152.   return ret
  153. end
  154.  
  155. ----------------------------------------------------------------
  156. function storeToFile(val, file)
  157.   local f = fs.open(file, "w")
  158.   if not f then return false end
  159.   f.write(textutils.serialize(val))
  160.   f.close()
  161.   return true
  162. end
  163.  
  164. ----------------------------------------------------------------
  165. --A simple stable sort algorithm
  166. function insertionSort(tbl, cmp)
  167.   cmp = cmp or function(a, b) return a < b end
  168.   for i = 2, #tbl do
  169.     local el = tbl[i]
  170.     local j = i
  171.     while j > 1 and cmp(el, tbl[j-1]) do
  172.       tbl[j] = tbl[j-1]
  173.       j = j-1
  174.     end
  175.     tbl[j] = el
  176.   end
  177. end
  178.  
  179. ----------------------------------------------------------------
  180. function displayJars(colWidth, lines, mode)
  181.   local winAspects = winAspects
  182.   winAspects.setVisible(false)
  183.   winAspects.clear()
  184.  
  185.   local x, y = 1, 1
  186.   for i = 1, #aspects do
  187.     winAspects.setTextColor(aspectColors[aspects[i]] or colors.white)
  188.     winAspects.setCursorPos(x, y)
  189.     winAspects.write(firstToUpper(aspects[i]))
  190.     winAspects.setCursorPos(x+13, y)
  191.    
  192.     local ava = jarAmount[aspects[i]]
  193.     local sto = stockAmount[aspects[i]] or 0
  194.     local stat = totalConsumed[aspects[i]] or 0
  195.     local cap = 64 * #jarHandles[aspects[i]]
  196.    
  197.     local dstr = ""
  198.     if mode == "available" then
  199.       dstr = string.format("%4d", ava)
  200.     elseif mode == "stock" then
  201.       dstr = string.format("%4d", sto)
  202.     elseif mode == "total" then
  203.       dstr = string.format("%4d", ava + sto)
  204.     elseif mode == "statistics" then
  205.       dstr = string.format("%4d", stat)
  206.     elseif mode == "capacity" then
  207.       dstr = string.format("%4d", cap)
  208.     elseif mode == "percentage" then
  209.       dstr = string.format("%3d%%", 100*ava/cap)
  210.     end
  211.     winAspects.write(dstr)
  212.    
  213.     if y < lines then
  214.       y = y+1
  215.     else
  216.       y = 1
  217.       x = x + colWidth
  218.     end
  219.   end
  220.   winAspects.setVisible(true)
  221.   winContr.redraw()
  222. end
  223.  
  224. ----------------------------------------------------------------
  225. function doRequest(aspect, amount)
  226.   if amount == 0 then return true end
  227.   local ident = itemIdents[aspect]
  228.   if not ident then
  229.     warning("No item identifier for ", aspect)
  230.     return false
  231.   end
  232.   local res = lp.makeRequest(ident, amount)
  233.   if res ~= "DONE" then
  234.     warning("Request for ", amount, " x ", aspect, " failed: ", res)
  235.     return false
  236.   end
  237.   print("Successfully requested ", amount, " x ", aspect)
  238.   totalConsumed[aspect] = (totalConsumed[aspect] or 0) + amount
  239.   if stockAmount[aspect] then
  240.     stockAmount[aspect] = stockAmount[aspect] - amount
  241.   end
  242.   storeToFile(totalConsumed, totalConsumedFile)
  243.   return true
  244. end
  245.  
  246. ----------------------------------------------------------------
  247. function firstToUpper(str)
  248.   return str:gsub("^%l", string.upper)
  249. end
  250.  
  251. ----------------------------------------------------------------
  252. function drawModeButton(mode)
  253.   if aspectMode == mode then
  254.     winContr.setBackgroundColor(colors.red)
  255.   else
  256.     winContr.setBackgroundColor(colors.blue)
  257.   end
  258.   if mode == "available" then
  259.     winContr.setCursorPos(2,2)
  260.     winContr.write(" Available ")
  261.   elseif mode == "stock" then
  262.     winContr.setCursorPos(2,3)
  263.     winContr.write(" Stocked   ")
  264.   elseif mode == "total" then
  265.     winContr.setCursorPos(2,4)
  266.     winContr.write(" Total     ")
  267.   elseif mode == "statistics" then
  268.     winContr.setCursorPos(14,2)
  269.     winContr.write(" Statistics ")
  270.   elseif mode == "capacity" then
  271.     winContr.setCursorPos(14,3)
  272.     winContr.write(" Capacity   ")
  273.   elseif mode == "percentage" then
  274.     winContr.setCursorPos(14,4)
  275.     winContr.write(" Percentage ")
  276.   end
  277. end
  278.  
  279. ----------------------------------------------------------------
  280. function drawRefreshButton()
  281.   winContr.setCursorPos(27,2)
  282.   winContr.write("           ")
  283.   winContr.setCursorPos(27,3)
  284.   winContr.write("  Refresh  ")
  285.   winContr.setCursorPos(27,4)
  286.   winContr.write("           ")
  287. end
  288.  
  289. ----------------------------------------------------------------
  290. function drawOptionsButton()
  291.   winContr.setCursorPos(39,2)
  292.   winContr.write("           ")
  293.   winContr.setCursorPos(39,3)
  294.   winContr.write("  Options  ")
  295.   winContr.setCursorPos(39,4)
  296.   winContr.write("           ")
  297. end
  298.  
  299. ----------------------------------------------------------------
  300. function changeAspectMode(mode)
  301.   if aspectMode == mode then return end
  302.   local oldMode = aspectMode
  303.   aspectMode = mode
  304.   drawModeButton(oldMode)
  305.   drawModeButton(mode)
  306.   displayJars(colWidth, lines, mode)
  307. end
  308.  
  309. ----------------------------------------------------------------
  310. function changeState(nst)
  311.   if state == nst then return end
  312.   if state == "aspects" then
  313.     winAspects.setVisible(false)
  314.   elseif state == "refill" then
  315.     winRefill.setVisible(false)
  316.   end
  317.  
  318.   if nst == "aspects" then
  319.     displayJars(colWidth, lines, aspectMode)
  320.     timerRefresh = os.startTimer(refreshTime)
  321.   elseif nst == "refill" then
  322.     refCurrent = jarAmount[refAspect]
  323.     refMaximum = refCurrent + (stockAmount[refAspect] or 0)
  324.     refCapacity = 64*#jarHandles[refAspect]
  325.  
  326.     winRefill.setTextColor(aspectColors[refAspect] or colors.white)
  327.     winRefill.setBackgroundColor(colors.black)
  328.     winRefill.setCursorPos(22, 5)
  329.     winRefill.write(firstToUpper(refAspect).."        ")
  330.     winRefill.setTextColor(colors.white)
  331.     winRefill.setCursorPos(14, 7)
  332.     winRefill.write(string.format("%6d", refCurrent))
  333.     winRefill.setCursorPos(14, 8)
  334.     winRefill.write(string.format("%6d", refMaximum))
  335.     winRefill.setCursorPos(14, 9)
  336.     winRefill.write(string.format("%6d", refCapacity))
  337.     winRefill.setVisible(true)
  338.     changeRefAmount(refCurrent)
  339.   end
  340.   state = nst
  341. end
  342.  
  343. ----------------------------------------------------------------
  344. function changeRefAmount(amount)
  345.   refAmount = math.min(math.max(refCurrent, amount), refMaximum, refCapacity)
  346.   winRefill.setBackgroundColor(colors.gray)
  347.   winRefill.setCursorPos(31, 7)
  348.   winRefill.write(string.format(" %3d ", refAmount-refCurrent))
  349.   winRefill.setCursorPos(31, 8)
  350.   winRefill.write(string.format(" %3d ", refAmount))
  351. end
  352.  
  353. ----------------------------------------------------------------
  354. --Main
  355.  
  356. print("Wrapping request pipe and monitor")
  357. wrapLp()
  358. wrapMonitor()
  359. print("Finding and wrapping all jars")
  360. wrapJars()
  361. print("Searching for mana beans")
  362. updateStock()
  363. print("Loading total consumed file ", totalConsumedFile)
  364. totalConsumed = loadFromFile(totalConsumedFile) or {}
  365.  
  366. print("Creating Windows")
  367. winAspects = window.create(mon, 1, 1, 60, 26, true)
  368.  
  369. winContr = window.create(winAspects, 1, 21, 60, 4, false)
  370. drawModeButton("available")
  371. drawModeButton("stock")
  372. drawModeButton("total")
  373. drawModeButton("statistics")
  374. drawModeButton("capacity")
  375. drawModeButton("percentage")
  376.  
  377. --drawOptionsButton()
  378. drawRefreshButton()
  379. winContr.setVisible(true)
  380.  
  381. displayJars(colWidth, lines, aspectMode)
  382.  
  383. winRefill = window.create(mon, 1, 1, 60, 26, false)
  384. winRefill.setCursorPos(4, 5)
  385. winRefill.write("Aspect to refill:")
  386. winRefill.setCursorPos(4, 7)
  387. winRefill.write("Current:")
  388. winRefill.setCursorPos(4, 8)
  389. winRefill.write("Maximum:")
  390. winRefill.setCursorPos(4, 9)
  391. winRefill.write("Capacity:")
  392. winRefill.setCursorPos(23, 7)
  393. winRefill.write(" Plus:  ")
  394. winRefill.setCursorPos(23, 8)
  395. winRefill.write(" Total: ")
  396. winRefill.setBackgroundColor(colors.blue)
  397. winRefill.setCursorPos(4, 11)
  398. winRefill.write("   +1   ")
  399. winRefill.setCursorPos(13, 11)
  400. winRefill.write("   +5   ")
  401. winRefill.setCursorPos(22, 11)
  402. winRefill.write("  +32   ")
  403. winRefill.setCursorPos(4, 13)
  404. winRefill.write("   -1   ")
  405. winRefill.setCursorPos(13, 13)
  406. winRefill.write("   -5   ")
  407. winRefill.setCursorPos(22, 13)
  408. winRefill.write("  -32   ")
  409. winRefill.setCursorPos(31, 11)
  410. winRefill.write("       ")
  411. winRefill.setCursorPos(31, 12)
  412. winRefill.write("  Max  ")
  413. winRefill.setCursorPos(31, 13)
  414. winRefill.write("       ")
  415. winRefill.setCursorPos(7, 15)
  416. winRefill.write("          ")
  417. winRefill.setCursorPos(7, 16)
  418. winRefill.write("    OK    ")
  419. winRefill.setCursorPos(7, 17)
  420. winRefill.write("          ")
  421. winRefill.setCursorPos(25, 15)
  422. winRefill.write("          ")
  423. winRefill.setCursorPos(25, 16)
  424. winRefill.write("  Cancel  ")
  425. winRefill.setCursorPos(25, 17)
  426. winRefill.write("          ")
  427. print("Initiation successful")
  428.  
  429. local quit = false
  430. local timerFlash
  431. timerRefresh = os.startTimer(refreshTime)
  432. while not quit do
  433.   local event, param1, param2, param3 = os.pullEvent()
  434.   if state == "aspects" then
  435.     if event == "monitor_touch" then
  436.       local x, y = param2, param3
  437.       if y <= lines then
  438.         local asp = y + lines * math.floor(x/colWidth)
  439.         refAspect = aspects[asp]
  440.         if refAspect then changeState("refill") end
  441.       else
  442.         if x >= 2 and x <= 12 then
  443.           if y == 22 then
  444.             changeAspectMode("available")
  445.           elseif y == 23 then
  446.             changeAspectMode("stock")
  447.           elseif y == 24 then
  448.             changeAspectMode("total")
  449.           end
  450.         elseif x >= 14 and x <= 25 then
  451.           if y == 22 then
  452.             changeAspectMode("statistics")
  453.           elseif y == 23 then
  454.             changeAspectMode("capacity")
  455.           elseif y == 24 then
  456.             changeAspectMode("percentage")
  457.           end
  458.         elseif x >= 27 and x <= 37 and y >= 22 and y <= 24 then
  459.           winContr.setBackgroundColor(colors.red)
  460.           drawRefreshButton()
  461.           updateJars()
  462.           updateStock()
  463.           displayJars(colWidth, lines, aspectMode)
  464.           timerRefresh = os.startTimer(refreshTime)
  465.           timerFlash = os.startTimer(0.15)
  466.         elseif x >= 39 and x <= 49 and y >= 22 and y <= 24 then
  467.           quit = true
  468.         end
  469.       end
  470.     elseif event == "timer" then
  471.       if param1 == timerRefresh then
  472.         winContr.setBackgroundColor(colors.red)
  473.         drawRefreshButton()
  474.         updateJars()
  475.         updateStock()
  476.         displayJars(colWidth, lines, aspectMode)
  477.         timerRefresh = os.startTimer(refreshTime)
  478.         timerFlash = os.startTimer(0.15)
  479.       elseif param1 == timerFlash then
  480.         winContr.setBackgroundColor(colors.blue)
  481.         drawRefreshButton()
  482.       end
  483.     end
  484.   elseif state == "refill" then
  485.     if event == "monitor_touch" then
  486.       local x, y = param2, param3
  487.       if y == 11 and x >= 4 and x <= 11 then
  488.         changeRefAmount(refAmount+1)
  489.       elseif y == 13 and x >= 4 and x <= 11 then
  490.         changeRefAmount(refAmount-1)
  491.       elseif y == 11 and x >= 13 and x <= 20 then
  492.         changeRefAmount(refAmount+5)
  493.       elseif y == 13 and x >= 13 and x <= 20 then
  494.         changeRefAmount(refAmount-5)
  495.       elseif y == 11 and x >= 22 and x <= 29 then
  496.         changeRefAmount(refAmount+32)
  497.       elseif y == 13 and x >= 22 and x <= 29 then
  498.         changeRefAmount(refAmount-32)
  499.       elseif y >= 11 and y <= 13 and x >= 31 and x <= 37 then
  500.         changeRefAmount(math.huge)
  501.       elseif y >= 15 and y <= 17 and x >= 7 and x <= 16 then
  502.         doRequest(refAspect, refAmount-refCurrent)
  503.         changeState("aspects")
  504.       elseif y >= 15 and y <= 17 and x >= 25 and x <= 34 then
  505.         changeState("aspects")
  506.       end
  507.     end
  508.   end
  509. end
  510.  
  511. mon.clear()
  512. print("Program successfully ended")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement