Advertisement
_Domi

adz

Apr 6th, 2019
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 60.65 KB | None | 0 0
  1. os.loadAPI("button")
  2. local m = peripheral.wrap("top")
  3. button.startup("top")
  4. local run = true
  5. local disableFillRedstoneDirection = "bottom"
  6. local redstoneWaitTicks = 3
  7. local alchemicalFurnaceFromChestDirection = "auto"
  8. local essentia
  9. local essentiasCount = 51
  10. local emptyJars
  11. local totalJars
  12. local fillAmount
  13. local fillEssentia
  14. local fillAvailableSpace
  15. local topOffJarsEssentiaList
  16. local fillAllTo64EssentiaList
  17. local fillAllTo128EssentiaList
  18. local chests = {}
  19. local aspectAnalyzers = {}
  20. local chestAspects
  21. local distributeBurnRequests = true
  22.  
  23.  
  24.  
  25. -- Print debug output during startup: 0 = off, 1 = summary debug, 2 = everything
  26. -- Errors are still shown regardless of the debug output level.
  27. local debugOutput = 1
  28. local padding = "                                                                                                    "
  29. local numberPadding = 3
  30.  
  31. -- If true, the more intensive portions of this script sleep between each action
  32. -- If false, the script runs at maximum speed
  33. local serverFriendly = true
  34.  
  35. --[[
  36.  
  37.     --Locations and colors of different visuals displayed on the monitor.--
  38.    
  39.     * Auto positioning is done per-item depending on where it normally sits in relation
  40.     to the other items. For the final position of a control see the setAutoDetectVariables() function below.
  41.    
  42.     ** Virtually every "auto" set location for the main display is relative to the essentiaX/Y locations. essentiaX = "auto" will
  43.     center the display on the monitor or if it can't be centered due to being too small it will be left-aligned.
  44.    
  45.     ** Virtually every "auto" set location for the refill essentia display is relative to the refillScreenX/Y locations.
  46.     refillScreenX = "auto" will center the display on the monitor or if it can't be centered due to being too small it will be left-aligned.
  47.    
  48.     ** If a location isn't default to "auto" it does not currently support auto positioning.
  49.    
  50.     * Any location or color that defaults to "auto" can be manually specified if that's desired. However, no error
  51.     checking is done to make sure the manual positions are valid.
  52.    
  53.     * Button height is calculated as 1 characters height. A button with the height of 1 will be the height of the button text.
  54.    
  55.     * The inactive colors are the colors used during normal display. Active colors are during button presses.
  56. --]]
  57.  
  58. local essentiaColumnWidth = 19
  59. local essentiaColumnHeight = 17
  60. local essentiaColumnSpacing = 2
  61. local essentiaX = "auto"
  62. local essentiaY = 1
  63.  
  64. local refreshButtonX = "auto"
  65. local refreshButtonY = "auto"
  66. local refreshButtonWidth = 19
  67. local refreshButtonHeight = 2
  68.  
  69. local topoffAllButtonX = "auto"
  70. local topoffAllButtonY = "auto"
  71. local topoffAllButtonWidth = 19
  72. local topoffAllButtonHeight = 2
  73.  
  74. local emptyJarsX = "auto"
  75. local emptyJarsY = "auto"
  76.  
  77. local totalJarsX = "auto"
  78. local totalJarsY = "auto"
  79.  
  80. local refillScreenX = "auto"
  81. local refillScreenY = 1
  82.  
  83. local fillAllTo64ButtonX = "auto"
  84. local fillAllTo64ButtonY = "auto"
  85. local fillAllTo64ButtonWidth = 18
  86. local fillAllTo64ButtonHeight = 2
  87.  
  88. local fillAllTo128ButtonX = "auto"
  89. local fillAllTo128ButtonY = "auto"
  90. local fillAllTo128ButtonWidth = 18
  91. local fillAllTo128ButtonHeight = 2
  92.  
  93. local otherOptionsButtonX = "auto"
  94. local otherOptionsButtonY = "auto"
  95. local otherOptionsButtonWidth = 18
  96. local otherOptionsButtonHeight = 2
  97.  
  98. local essentiaTopOffJarsX = "auto"
  99. local essentiaTopOffJarsY = 5
  100.  
  101. local essentiaTopOffLabelX = "auto"
  102. local essentiaTopOffLabelY = 2
  103.  
  104. local essentiaFillAllTo64X = "auto"
  105. local essentiaFillAllTo64Y = 5
  106.  
  107. local essentiaFillAllTo64LabelX = "auto"
  108. local essentiaFillAllTo64LabelY = 2
  109.  
  110. local essentiaFillAllTo128X = "auto"
  111. local essentiaFillAllTo128Y = 5
  112.  
  113. local essentiaFillAllTo128LabelX = "auto"
  114. local essentiaFillAllTo128LabelY = 2
  115.  
  116. local cancelTopOffJarsButtonX = "auto"
  117. local cancelTopOffJarsButtonY = "auto"
  118. local cancelTopOffJarsButtonWidth = 19
  119. local cancelTopOffJarsButtonHeight = 2
  120.  
  121. local beginTopOffJarsFillButtonX = "auto"
  122. local beginTopOffJarsFillButtonY = "auto"
  123. local beginTopOffJarsFillButtonWidth = 19
  124. local beginTopOffJarsFillButtonHeight = 2
  125.  
  126. local cancelFillAllTo64ButtonX = "auto"
  127. local cancelFillAllTo64ButtonY = "auto"
  128. local cancelFillAllTo64ButtonWidth = 19
  129. local cancelFillAllTo64ButtonHeight = 2
  130.  
  131. local beginFillAllTo64ButtonX = "auto"
  132. local beginFillAllTo64ButtonY = "auto"
  133. local beginFillAllTo64ButtonWidth = 19
  134. local beginFillAllTo64ButtonHeight = 2
  135.  
  136. local cancelFillAllTo128ButtonX = "auto"
  137. local cancelFillAllTo128ButtonY = "auto"
  138. local cancelFillAllTo128ButtonWidth = 19
  139. local cancelFillAllTo128ButtonHeight = 2
  140.  
  141. local beginFillAllTo128ButtonX = "auto"
  142. local beginFillAllTo128ButtonY = "auto"
  143. local beginFillAllTo128ButtonWidth = 19
  144. local beginFillAllTo128ButtonHeight = 2
  145.  
  146. local burnScreenLabelX = "auto"
  147. local burnScreenLabelY = 3
  148.  
  149. local burnScreenBeanLabelX = 6
  150. local burnScreenBeanLabelY = 10
  151.  
  152. local burnScreenStatusX = 6
  153. local burnScreenStatusY = 13
  154.  
  155. local burnScreenBeanTextLabel = "Currently filling bean type: "
  156. local burnScreenStatusTextLabel = "Current status: "
  157.  
  158.  
  159. local monBackColor = colors.black
  160.  
  161. local essentiaInactiveTextColorEmpty = colors.gray
  162. local essentiaInactiveTextColorLow = colors.red
  163. local essentiaInactiveTextColorMedium = colors.yellow
  164. local essentiaInactiveTextColorHigh = colors.green
  165. local essentiaInactiveBackColor = monBackColor
  166. local essentiaActiveTextColor = colors.white
  167. local essentiaActiveBackColor = colors.lime
  168.  
  169. local refreshActiveBackColor = colors.lime
  170. local refreshInactiveBackColor = colors.blue
  171. local refreshActiveTextColor = colors.white
  172. local refreshInactiveTextColor = colors.white
  173.  
  174. local topoffAllJarsActiveTextColor = colors.white
  175. local topoffAllJarsInactiveTextColor = colors.white
  176. local topoffAllJarsActiveBackColor = colors.lime
  177. local topoffAllJarsInactiveBackColor = colors.blue
  178.  
  179. local fillAllTo64InactiveTextColor = colors.white
  180. local fillAllTo64ActiveTextColor = colors.white
  181. local fillAllTo64InactiveBackColor = colors.blue
  182. local fillAllTo64ActiveBackColor = colors.lime
  183.  
  184. local fillAllTo128InactiveTextColor = colors.white
  185. local fillAllTo128ActiveTextColor = colors.white
  186. local fillAllTo128InactiveBackColor = colors.blue
  187. local fillAllTo128ActiveBackColor = colors.lime
  188.  
  189. local refillButtonsInactiveBackColor = colors.blue
  190. local refillButtonsActiveBackColor = colors.lime
  191. local refillButtonsInactiveTextColor = colors.white
  192. local refillButtonsActiveTextColor = colors.white
  193.  
  194. local otherOptionsButtonInactiveBackColor = colors.blue
  195. local otherOptionsButtonActiveBackColor = colors.lime
  196. local otherOptionsButtonInactiveTextColor = colors.white
  197. local otherOptionsButtonActiveTextColor = colors.white
  198.  
  199. local cancelTopOffJarsButtonInactiveBackColor = colors.blue
  200. local cancelTopOffJarsButtonActiveBackColor = colors.lime
  201. local cancelTopOffJarsButtonInactiveTextColor = colors.white
  202. local cancelTopOffJarsButtonActiveTextColor = colors.white
  203.  
  204. local beginTopOffJarsFillButtonInactiveBackColor = colors.blue
  205. local beginTopOffJarsFillButtonActiveBackColor = colors.lime
  206. local beginTopOffJarsFillButtonInactiveTextColor = colors.white
  207. local beginTopOffJarsFillButtonActiveTextColor = colors.white
  208.  
  209. local cancelFillAllTo64ButtonInactiveBackColor = colors.blue
  210. local cancelFillAllTo64ButtonActiveBackColor = colors.lime
  211. local cancelFillAllTo64ButtonInactiveTextColor = colors.white
  212. local cancelFillAllTo64ButtonActiveTextColor = colors.white
  213.  
  214. local beginFillAllTo64ButtonInactiveBackColor = colors.blue
  215. local beginFillAllTo64ButtonActiveBackColor = colors.lime
  216. local beginFillAllTo64ButtonInactiveTextColor = colors.white
  217. local beginFillAllTo64ButtonActiveTextColor = colors.white
  218.  
  219. local cancelFillAllTo128ButtonInactiveBackColor = colors.blue
  220. local cancelFillAllTo128ButtonActiveBackColor = colors.lime
  221. local cancelFillAllTo128ButtonInactiveTextColor = colors.white
  222. local cancelFillAllTo128ButtonActiveTextColor = colors.white
  223.  
  224. local beginFillAllTo128ButtonInactiveBackColor = colors.blue
  225. local beginFillAllTo128ButtonActiveBackColor = colors.lime
  226. local beginFillAllTo128ButtonInactiveTextColor = colors.white
  227. local beginFillAllTo128ButtonActiveTextColor = colors.white
  228.  
  229.  
  230. local emptyJarsTextColor = colors.white
  231. local emptyJarsBackColor = monBackColor
  232.  
  233. local totalJarsTextColor = colors.white
  234. local totalJarsBackColor = monBackColor
  235.  
  236. local refillLabelTextColor = colors.white
  237. local refillCurrentAmountTextColor = colors.white
  238. local refillAddingAmountTextColor = colors.green
  239.  
  240. local topOffAllJarsEssentiaBackColor = monBackColor
  241. local topOffAllJarsEssentiaTextColorZero = essentiaInactiveTextColorEmpty
  242. local topOffAllJarsEssentiaTextColorNonZero = colors.white
  243.  
  244. local topOffAllJarsEssentiaLabelBackColor = monBackColor
  245. local topOffAllJarsEssentiaLabelTextColor = colors.white
  246.  
  247. local fillAllTo64EssentiaBackColor = monBackColor
  248. local fillAllTo64EssentiaTextColorZero = essentiaInactiveTextColorEmpty
  249. local fillAllTo64EssentiaTextColorNonZero = essentiaInactiveTextColorMedium
  250.  
  251. local fillAllTo64EssentiaLabelBackColor = monBackColor
  252. local fillAllTo64EssentiaLabelTextColor = colors.white
  253.  
  254. local fillAllTo128EssentiaBackColor = monBackColor
  255. local fillAllTo128EssentiaTextColorZero = essentiaInactiveTextColorEmpty
  256. local fillAllTo128EssentiaTextColorNonZero = essentiaInactiveTextColorHigh
  257.  
  258. local fillAllTo128EssentiaLabelBackColor = monBackColor
  259. local fillAllTo128EssentiaLabelTextColor = colors.white
  260.  
  261.  
  262. local burnScreenStatusBackColor = monBackColor
  263. local burnScreenStatusTextColor = colors.white
  264. local burnScreenBeanLabelBackColor = monBackColor
  265. local burnScreenBeanLabelTextColor = colors.white
  266. local burnScreenLabelBackColor = monBackColor
  267. local burnScreenLabelTextColor = colors.white
  268. local burnScreenBorderColor = colors.blue
  269.  
  270.  
  271.  
  272.  
  273. function setAutoDetectVariables()
  274.     local monWidth
  275.     local monHeight
  276.    
  277.     monWidth,monHeight = m.getSize()
  278.    
  279.     if (alchemicalFurnaceFromChestDirection ~= "auto") then
  280.         if (alchemicalFurnaceFromChestDirection ~= "north"
  281.             and alchemicalFurnaceFromChestDirection ~= "south"
  282.             and alchemicalFurnaceFromChestDirection ~= "east"
  283.             and alchemicalFurnaceFromChestDirection ~= "west") then
  284.            
  285.             print("Invalid alchemical furnace from chest direction. !!RESTART REQUIRED!!")
  286.             while (true) do
  287.                 sleep(60)
  288.             end
  289.         end
  290.     end
  291.    
  292.     if (essentiaX == "auto") then
  293.         -- Centers the essentia display on the monitor horizontally
  294.         essentiaX = math.floor((monWidth - ((math.ceil(essentiasCount / essentiaColumnHeight) * (essentiaColumnWidth + essentiaColumnSpacing)) - essentiaColumnSpacing)) / 2) + 1
  295.        
  296.         -- The monitor is too small
  297.         if (essentiaX < 1) then
  298.             print("The monitor is too small width wise to display all the needed main screen information correctly.")
  299.            
  300.             essentiaX = 1
  301.         end
  302.     end
  303.    
  304.     if (refreshButtonX == "auto") then
  305.         -- Centers the refresh button on the monitor horizontally
  306.         refreshButtonX = essentiaX + math.floor(((math.ceil(essentiasCount / essentiaColumnHeight) * (essentiaColumnWidth + essentiaColumnSpacing)) - essentiaColumnSpacing) / 2) -  math.ceil(refreshButtonWidth / 2) + 1
  307.     end
  308.    
  309.     if (refreshButtonY == "auto") then
  310.         -- Puts the refresh button directly below the essentia list
  311.         refreshButtonY = essentiaY + essentiaColumnHeight + 1
  312.     end
  313.    
  314.     if (topoffAllButtonX == "auto") then
  315.         -- Puts the top off all button in line with the refresh button
  316.         topoffAllButtonX = essentiaX + math.floor(((math.ceil(essentiasCount / essentiaColumnHeight) * (essentiaColumnWidth + essentiaColumnSpacing)) - essentiaColumnSpacing) / 2) -  math.ceil(topoffAllButtonWidth / 2) + 1
  317.     end
  318.    
  319.     if (topoffAllButtonY == "auto") then
  320.         -- Puts the top off all button directly below the refresh button
  321.         topoffAllButtonY = refreshButtonY + refreshButtonHeight + 2
  322.     end
  323.    
  324.     if (fillAllTo64ButtonX == "auto") then
  325.         -- Puts the fill all to 64 button directly to the right of the refresh button
  326.         fillAllTo64ButtonX = refreshButtonX + refreshButtonWidth + 2
  327.     end
  328.    
  329.     if (fillAllTo64ButtonY == "auto") then
  330.         -- Puts the fill all to 64 button in line with the refresh button
  331.         fillAllTo64ButtonY = refreshButtonY
  332.     end
  333.    
  334.     if (fillAllTo128ButtonX == "auto") then
  335.         -- Puts the fill all to 64 button directly to the right of the fill all to 64 button
  336.         fillAllTo128ButtonX = fillAllTo64ButtonX
  337.     end
  338.    
  339.     if (fillAllTo128ButtonY == "auto") then
  340.         -- Puts the fill all to 64 button directly below the fill all to 64 button
  341.         fillAllTo128ButtonY = fillAllTo64ButtonY + fillAllTo64ButtonHeight + 2
  342.     end
  343.    
  344.     if (otherOptionsButtonX == "auto") then
  345.         -- Puts the other button directly to the left of the top off all jars button
  346.         otherOptionsButtonX = topoffAllButtonX - otherOptionsButtonWidth - 2
  347.     end
  348.    
  349.     if (otherOptionsButtonY == "auto") then
  350.         -- Puts the other button at the same level as the top off all button
  351.         otherOptionsButtonY = topoffAllButtonY
  352.     end
  353.    
  354.     if (emptyJarsX == "auto") then
  355.         emptyJarsX = essentiaX + 1
  356.     end
  357.  
  358.     if (emptyJarsY == "auto") then
  359.         emptyJarsY = essentiaY + essentiaColumnHeight + 1
  360.     end
  361.    
  362.     if (totalJarsX == "auto") then
  363.         totalJarsX = emptyJarsX
  364.     end
  365.    
  366.     if (totalJarsY == "auto") then
  367.         totalJarsY = emptyJarsY + 1
  368.     end
  369.    
  370.     if (refillScreenX == "auto") then
  371.         -- Centers the refill screen on the monitor - the refill screen is 41 pixels wide hard coded
  372.         refillScreenX = math.floor((monWidth - 41) / 2) + 1
  373.        
  374.         -- The monitor is too small
  375.         if (refillScreenX < 1) then
  376.             print("The monitor is too small width wise to display all the needed refill screen information correctly.")
  377.            
  378.             refillScreenX = 1
  379.         end
  380.     end
  381.    
  382.     if (essentiaTopOffJarsX == "auto") then
  383.         -- Centers the top off all essentia display on the monitor horizontally
  384.         essentiaTopOffJarsX = math.floor((monWidth - ((math.ceil(essentiasCount / essentiaColumnHeight) * (essentiaColumnWidth + essentiaColumnSpacing)) - essentiaColumnSpacing)) / 2) + 1
  385.        
  386.         -- The monitor is too small
  387.         if (essentiaTopOffJarsX < 1) then
  388.             print("The monitor is too small width wise to display all the needed top off all screen information correctly.")
  389.            
  390.             essentiaTopOffJarsX = 1
  391.         end
  392.     end
  393.    
  394.     if (essentiaTopOffLabelX == "auto") then
  395.         essentiaTopOffLabelX = essentiaTopOffJarsX + math.floor(((math.ceil(essentiasCount / essentiaColumnHeight) * (essentiaColumnWidth + essentiaColumnSpacing)) - essentiaColumnSpacing) / 2) -  math.ceil(string.len("Top off jars fill request") / 2)
  396.     end
  397.    
  398.     if (cancelTopOffJarsButtonX == "auto") then
  399.         cancelTopOffJarsButtonX = math.floor((monWidth / 2) - cancelTopOffJarsButtonWidth) + 1
  400.     end
  401.    
  402.     if (cancelTopOffJarsButtonY == "auto") then
  403.         cancelTopOffJarsButtonY = essentiaTopOffJarsY + essentiaColumnHeight + 1
  404.     end
  405.    
  406.     if (beginTopOffJarsFillButtonX == "auto") then
  407.         beginTopOffJarsFillButtonX = math.floor((monWidth / 2)) + 2
  408.     end
  409.    
  410.     if (beginTopOffJarsFillButtonY == "auto") then
  411.         beginTopOffJarsFillButtonY = essentiaTopOffJarsY + essentiaColumnHeight + 1
  412.     end
  413.    
  414.    
  415.     if (essentiaFillAllTo64X == "auto") then
  416.         -- Centers the top off all essentia display on the monitor horizontally
  417.         essentiaFillAllTo64X = math.floor((monWidth - ((math.ceil(essentiasCount / essentiaColumnHeight) * (essentiaColumnWidth + essentiaColumnSpacing)) - essentiaColumnSpacing)) / 2) + 1
  418.        
  419.         -- The monitor is too small
  420.         if (essentiaFillAllTo64X < 1) then
  421.             print("The monitor is too small width wise to display all the needed fill all to 64 screen information correctly.")
  422.            
  423.             essentiaFillAllTo64X = 1
  424.         end
  425.     end
  426.    
  427.     if (essentiaFillAllTo64LabelX == "auto") then
  428.         essentiaFillAllTo64LabelX = essentiaFillAllTo64X + math.floor(((math.ceil(essentiasCount / essentiaColumnHeight) * (essentiaColumnWidth + essentiaColumnSpacing)) - essentiaColumnSpacing) / 2) -  math.ceil(string.len("Fill all jars to 64 request") / 2) + 1
  429.     end
  430.    
  431.     if (cancelFillAllTo64ButtonX == "auto") then
  432.         cancelFillAllTo64ButtonX = math.floor((monWidth / 2) - cancelFillAllTo64ButtonWidth) + 1
  433.     end
  434.    
  435.     if (cancelFillAllTo64ButtonY == "auto") then
  436.         cancelFillAllTo64ButtonY = essentiaFillAllTo64Y + essentiaColumnHeight + 1
  437.     end
  438.    
  439.     if (beginFillAllTo64ButtonX == "auto") then
  440.         beginFillAllTo64ButtonX = math.floor((monWidth / 2)) + 2
  441.     end
  442.    
  443.     if (beginFillAllTo64ButtonY == "auto") then
  444.         beginFillAllTo64ButtonY = essentiaFillAllTo64Y + essentiaColumnHeight + 1
  445.     end
  446.    
  447.    
  448.     if (essentiaFillAllTo128X == "auto") then
  449.         -- Centers the top off all essentia display on the monitor horizontally
  450.         essentiaFillAllTo128X = math.floor((monWidth - ((math.ceil(essentiasCount / essentiaColumnHeight) * (essentiaColumnWidth + essentiaColumnSpacing)) - essentiaColumnSpacing)) / 2) + 1
  451.        
  452.         -- The monitor is too small
  453.         if (essentiaFillAllTo128X < 1) then
  454.             print("The monitor is too small width wise to display all the needed fill all to 128 screen information correctly.")
  455.            
  456.             essentiaFillAllTo128X = 1
  457.         end
  458.     end
  459.    
  460.     if (essentiaFillAllTo128LabelX == "auto") then
  461.         essentiaFillAllTo128LabelX = essentiaFillAllTo128X + math.floor(((math.ceil(essentiasCount / essentiaColumnHeight) * (essentiaColumnWidth + essentiaColumnSpacing)) - essentiaColumnSpacing) / 2) -  math.ceil(string.len("Fill all jars to 128 request") / 2) + 1
  462.     end
  463.    
  464.     if (cancelFillAllTo128ButtonX == "auto") then
  465.         cancelFillAllTo128ButtonX = math.floor((monWidth / 2) - cancelFillAllTo128ButtonWidth) + 1
  466.     end
  467.    
  468.     if (cancelFillAllTo128ButtonY == "auto") then
  469.         cancelFillAllTo128ButtonY = essentiaFillAllTo128Y + essentiaColumnHeight + 1
  470.     end
  471.    
  472.     if (beginFillAllTo128ButtonX == "auto") then
  473.         beginFillAllTo128ButtonX = math.floor((monWidth / 2)) + 2
  474.     end
  475.    
  476.     if (beginFillAllTo128ButtonY == "auto") then
  477.         beginFillAllTo128ButtonY = essentiaFillAllTo128Y + essentiaColumnHeight + 1
  478.     end
  479.    
  480.     if (burnScreenLabelX == "auto") then
  481.         burnScreenLabelX = math.floor((monWidth / 2) - (string.len("Burn request information") / 2)) + 1
  482.     end
  483.    
  484.     if (serverFriendly == true) then
  485.         serverFriendly = .05
  486.     else
  487.         serverFriendly = 0
  488.     end
  489. end
  490.  
  491. function sortEss(t)
  492.     local keys = {}
  493.     local k, i
  494.  
  495.     for k in pairs(t) do
  496.         keys[#keys+1] = k
  497.     end
  498.     table.sort(keys)
  499.  
  500.     i = 0
  501.     return function()
  502.         i = i + 1
  503.         if keys[i] then
  504.             return keys[i], t[keys[i]]
  505.         end
  506.     end
  507. end
  508.  
  509. function scanJars()
  510.     local myEmptyJars = 0
  511.     local myTotalJars = 0
  512.     local jars = {}
  513.     local jarID = 1
  514.     local aspect
  515.     local aspectCount
  516.     local i, j
  517.    
  518.     for i,j in ipairs(peripheral.getNames()) do
  519.         if (peripheral.getType(j) == "tt_aspectContainer") then
  520.             aspect = peripheral.call(j, "getAspects")
  521.             local aspectJar
  522.            
  523.             if (type(aspect) == "table") then
  524.                 if (aspect ~= nil) then
  525.                     aspectJar = string.lower(aspect[1]["name"])
  526.                 end
  527.             else
  528.                 aspectJar = string.lower(aspect)
  529.             end
  530.            
  531.             aspect = aspectJar
  532.            
  533.             aspectCount = peripheral.call(v, "getAspectCount", aspect)
  534.  
  535.             if (aspectCount > 0) then
  536.                 jars[jarID] = {}
  537.                 jars[jarID]["aspect"] = aspect
  538.                 jars[jarID]["count"] = aspectCount
  539.                 jarID = jarID + 1
  540.                 myTotalJars = myTotalJars + 1
  541.             elseif (aspectCount == 0) then
  542.                 myEmptyJars = myEmptyJars + 1
  543.                 myTotalJars = myTotalJars + 1
  544.             end
  545.         end
  546.     end
  547.    
  548.     emptyJars = myEmptyJars
  549.     totalJars = myTotalJars
  550.    
  551.     return jars
  552. end
  553.  
  554. function updateEssentia()
  555.     local myJars
  556.     local myEssentia
  557.     local i, j
  558.    
  559.     myJars = scanJars()
  560.     myEssentia = essentiaList()
  561.    
  562.     for i in pairs(myJars) do
  563.         myEssentia[myJars[i]["aspect"]] = myEssentia[myJars[i]["aspect"]] + myJars[i]["count"]
  564.     end
  565.    
  566.     for i,j in sortEss(myEssentia) do
  567.         if (essentia[i] ~= j) then
  568.             essentia[i] = j
  569.         end
  570.     end
  571. end
  572.  
  573. function printEssentia()
  574.     local inactiveTextColor
  575.     local buttonName
  576.     local x, y
  577.     local i, j
  578.    
  579.     x = essentiaX
  580.     y = essentiaY
  581.    
  582.     for i,j in sortEss(essentia) do
  583.         inactiveTextColor = getEssentiaColor(j)
  584.        
  585.         buttonName = i .. string.sub(padding, 1, essentiaColumnWidth - (string.len(i) + string.len(pad(j)))) .. pad(j)
  586.         button.addButton(buttonName, essentiaButton, buttonName, x, y, essentiaColumnWidth, 0, essentiaInactiveBackColor, essentiaActiveBackColor, inactiveTextColor, essentiaActiveTextColor)
  587.        
  588.         if (y < (essentiaY + essentiaColumnHeight - 1)) then
  589.             y = y + 1
  590.         else
  591.             y = essentiaY
  592.             x = x + essentiaColumnWidth + essentiaColumnSpacing
  593.         end
  594.     end
  595. end
  596.  
  597. function getEssentiaColor(currentEssentiaAmount)
  598.     local myColor
  599.    
  600.     if (currentEssentiaAmount == 0) then
  601.         myColor = essentiaInactiveTextColorEmpty
  602.     elseif (currentEssentiaAmount <= 20) then
  603.         myColor = essentiaInactiveTextColorLow
  604.     elseif (currentEssentiaAmount < 100 and currentEssentiaAmount > 20) then
  605.         myColor = essentiaInactiveTextColorMedium
  606.     else
  607.         myColor = essentiaInactiveTextColorHigh
  608.     end
  609.    
  610.     return myColor
  611. end
  612.  
  613. function printEmptyJars()
  614.     m.setTextColor(emptyJarsTextColor)
  615.     m.setBackgroundColor(emptyJarsBackColor)
  616.    
  617.     m.setCursorPos(emptyJarsX, emptyJarsY)
  618.     m.write("Empty jars:" .. string.sub(padding, 1, essentiaColumnWidth - (string.len("Empty jars:") + string.len(pad(emptyJars))) - 1) .. pad(emptyJars))
  619. end
  620.  
  621. function printTotalJars()
  622.     m.setTextColor(totalJarsTextColor)
  623.     m.setBackgroundColor(totalJarsBackColor)
  624.    
  625.     m.setCursorPos(totalJarsX, totalJarsY)
  626.     m.write("Total jars:" .. string.sub(padding, 1, essentiaColumnWidth - (string.len("Total jars:") + string.len(pad(totalJars))) - 1) .. pad(totalJars))
  627. end
  628.  
  629. function pad(number, amount)
  630.     local myPadding = "000000"
  631.     local paddingRequired = 0
  632.    
  633.     if not (amount) then
  634.         amount = numberPadding
  635.     end
  636.    
  637.     paddingRequired = amount - string.len(tostring(number))
  638.  
  639.     if (paddingRequired ~= 0 and paddingRequired > 0) then
  640.         return string.sub(myPadding, 1, paddingRequired) .. tostring(number)
  641.     end
  642.    
  643.     return tostring(number)
  644. end
  645.  
  646. function getClick()
  647.     local event
  648.     local side
  649.     local x,y
  650.    
  651.     event,side,x,y = os.pullEvent()
  652.    
  653.     if (event == "monitor_touch") then
  654.         button.checkxy(x,y)
  655.     end
  656. end
  657.  
  658. function refresh(buttonToFlash)
  659.     -- Flash the refresh button
  660.     if (buttonToFlash) then
  661.         button.flash(buttonToFlash)
  662.     end
  663.    
  664.     -- Clear the screen and button list
  665.     m.setBackgroundColor(monBackColor)
  666.     m.clear()
  667.     button.clear()
  668.    
  669.     -- Scan and print the essentias
  670.     updateEssentia()
  671.     printEssentia()
  672.    
  673.     -- Print the number of empty jars
  674.     printEmptyJars()
  675.    
  676.     -- Print the number of jars
  677.     printTotalJars()
  678.    
  679.     -- Create the refresh button
  680.     addRefreshButton()
  681.    
  682.     -- Create the top off all jars button
  683.     addTopoffAllJarsButton()
  684.    
  685.     -- Create the fill all to 64 button
  686.     addFillAllTo64Button()
  687.    
  688.     -- Create the fill all to 128 button
  689.     addFillAllTo128Button()
  690.    
  691.     -- Create the other button
  692.     addOtherOptionsButton()
  693.    
  694.     -- Draw all the buttons on the screen
  695.     button.drawButtons()
  696. end
  697.  
  698. function addRefreshButton()
  699.     button.addButton("Refresh", refresh, "Refresh", refreshButtonX, refreshButtonY, refreshButtonWidth, refreshButtonHeight, refreshInactiveBackColor, refreshActiveBackColor, refreshInactiveTextColor, refreshActiveTextColor)
  700. end
  701.  
  702. function addTopoffAllJarsButton()
  703.     button.addButton("Top off all jars", topoffAllJars, "Top off all jars", topoffAllButtonX, topoffAllButtonY, topoffAllButtonWidth, topoffAllButtonHeight, topoffAllJarsInactiveBackColor, topoffAllJarsActiveBackColor, topoffAllJarsInactiveTextColor, topoffAllJarsActiveTextColor)
  704. end
  705.  
  706. function addFillAllTo64Button()
  707.     button.addButton("Fill all to 64", fillAllTo64, "Fill all to 64", fillAllTo64ButtonX, fillAllTo64ButtonY, fillAllTo64ButtonWidth, fillAllTo64ButtonHeight, fillAllTo64InactiveBackColor, fillAllTo64ActiveBackColor, fillAllTo64InactiveTextColor, fillAllTo64ActiveTextColor)
  708. end
  709.  
  710. function addFillAllTo128Button()
  711.     button.addButton("Fill all to 128", fillAllTo128, "Fill all to 128", fillAllTo128ButtonX, fillAllTo128ButtonY, fillAllTo128ButtonWidth, fillAllTo128ButtonHeight, fillAllTo128InactiveBackColor, fillAllTo128ActiveBackColor, fillAllTo128InactiveTextColor, fillAllTo128ActiveTextColor)
  712. end
  713.  
  714. function addOtherOptionsButton()
  715.     button.addButton("Reboot", otherOptions, "Reboot", otherOptionsButtonX, otherOptionsButtonY, otherOptionsButtonWidth, otherOptionsButtonHeight, otherOptionsButtonInactiveBackColor, otherOptionsButtonActiveBackColor, otherOptionsButtonInactiveTextColor, otherOptionsButtonActiveTextColor)
  716. end
  717.  
  718. function otherOptions(buttonName)
  719.     button.flash(buttonName)
  720.     os.reboot()
  721. end
  722.  
  723. function fillAllTo64(buttonName)
  724.     local aspect
  725.     local count
  726.     local essentiaToFill
  727.     local haveEssentiaToFill
  728.     local myEmptyJars
  729.    
  730.     -- The button is erased if jars to top off are found else it's toggled back below.
  731.     button.toggleButton(buttonName, true)
  732.     sleep(.15)
  733.    
  734.     essentiaToFill = essentiaList()
  735.     myEmptyJars = emptyJars
  736.     haveEssentiaToFill = false
  737.    
  738.     -- Update the list of essentias in all jars
  739.     updateEssentia()
  740.    
  741.     -- Checks each jar to see if any of them aren't full.
  742.     for aspect,count in pairs(essentia) do
  743.         if (count < 64) then
  744.             if (count == 0) then
  745.                 myEmptyJars = myEmptyJars - 1
  746.             end
  747.            
  748.             essentiaToFill[aspect] = 64 - count
  749.             haveEssentiaToFill = true
  750.         end
  751.     end
  752.    
  753.     if (haveEssentiaToFill == true) then
  754.         -- Not all essentia is at 64 or more, display the found essentias and confirm filling.
  755.         showFillAllTo64(essentiaToFill, myEmptyJars)
  756.     else
  757.         -- All essentia are above 64, rename the button and hold the text for a second so it can be read before reverting to the normal text and color.
  758.         button.renameButton(buttonName, "All jars at 64", true)
  759.         sleep(2.5)
  760.         button.toggleButton("All jars at 64", false)
  761.         button.renameButton("All jars at 64", buttonName, true)
  762.     end
  763. end
  764.  
  765. function showFillAllTo64(essentiaList, emptyJarsAfterFill)
  766.     local x, y
  767.     local myEssentia
  768.     local amount
  769.     local errorText
  770.    
  771.     fillAllTo64EssentiaList = essentiaList
  772.    
  773.     -- Clear the screen and button list
  774.     m.setBackgroundColor(monBackColor)
  775.     m.clear()
  776.     button.clear()
  777.    
  778.     x = essentiaFillAllTo64X
  779.     y = essentiaFillAllTo64Y
  780.    
  781.     m.setBackgroundColor(fillAllTo64EssentiaLabelBackColor)
  782.     m.setTextColor(fillAllTo64EssentiaLabelTextColor)
  783.    
  784.     m.setCursorPos(essentiaFillAllTo64LabelX, essentiaFillAllTo64LabelY)
  785.     m.write("Fill all jars to 64 request")
  786.    
  787.     m.setBackgroundColor(fillAllTo64EssentiaBackColor)
  788.    
  789.     for myEssentia,amount in sortEss(essentiaList) do
  790.         if (amount == 0) then
  791.             m.setTextColor(fillAllTo64EssentiaTextColorZero)
  792.         else
  793.             m.setTextColor(fillAllTo64EssentiaTextColorNonZero)
  794.         end
  795.        
  796.         m.setCursorPos(x, y)
  797.         m.write(string.upper(string.sub(myEssentia, 1, 1)) .. string.sub(myEssentia, 2) .. string.sub(padding, 1, essentiaColumnWidth - (string.len(myEssentia) + string.len(pad(amount)))) .. pad(amount))
  798.        
  799.         if (y < (essentiaFillAllTo64Y + essentiaColumnHeight - 1)) then
  800.             y = y + 1
  801.         else
  802.             y = essentiaFillAllTo64Y
  803.             x = x + essentiaColumnWidth + essentiaColumnSpacing
  804.         end
  805.     end
  806.    
  807.     button.addButton("Cancel filling", cancelFillAllTo64Button, "Cancel filling", cancelFillAllTo64ButtonX, cancelFillAllTo64ButtonY, cancelFillAllTo64ButtonWidth, cancelFillAllTo64ButtonHeight, cancelFillAllTo64ButtonInactiveBackColor, cancelFillAllTo64ButtonActiveBackColor, cancelFillAllTo64ButtonInactiveTextColor, cancelFillAllTo64ButtonActiveTextColor)
  808.     button.addButton("Begin filling", beginFillAllTo64Button, "Begin filling", beginFillAllTo64ButtonX, beginFillAllTo64ButtonY, beginFillAllTo64ButtonWidth, beginFillAllTo64ButtonHeight, beginFillAllTo64ButtonInactiveBackColor, beginFillAllTo64ButtonActiveBackColor, beginFillAllTo64ButtonInactiveTextColor, beginFillAllTo64ButtonActiveTextColor)
  809.    
  810.     if (emptyJarsAfterFill < 0) then
  811.         errorText = "NOT ENOUGH EMPTY JARS; HAVE " .. emptyJars .. " NEED "  .. (emptyJars - emptyJarsAfterFill)
  812.         m.setCursorPos(essentiaFillAllTo64LabelX + math.floor(string.len("Fill all jars to 64 request") / 2) - math.floor(string.len(errorText) / 2), essentiaFillAllTo64LabelY + 1)
  813.         m.setTextColor(colors.red)
  814.         m.write(errorText)
  815.         button.disableButton("Begin filling")
  816.     end
  817.    
  818.     button.drawButtons()
  819. end
  820.  
  821. function fillAllTo128(buttonName)
  822.     local aspect
  823.     local count
  824.     local essentiaToFill
  825.     local haveEssentiaToFill
  826.     local myEmptyJars
  827.     local myJars
  828.     local jar
  829.     local essentiaJarCount
  830.    
  831.     -- The button is erased if jars to top off are found else it's toggled back below.
  832.     button.toggleButton(buttonName, true)
  833.     sleep(.15)
  834.    
  835.     essentiaToFill = essentiaList()
  836.     essentiaJarCount = essentiaList()
  837.     myJars = scanJars()
  838.     myEmptyJars = emptyJars
  839.     haveEssentiaToFill = false
  840.    
  841.     -- Count how many jars of each aspect exist
  842.     for jar in pairs(myJars) do
  843.         essentiaJarCount[myJars[jar]["aspect"]] = essentiaJarCount[myJars[jar]["aspect"]] + 1
  844.     end
  845.    
  846.     -- Update the list of essentias in all jars
  847.     updateEssentia()
  848.    
  849.     -- Checks each jar to see if any of them aren't full.
  850.     for aspect,count in pairs(essentia) do
  851.         if (count < 128) then
  852.             if (count == 0) then
  853.                 myEmptyJars = myEmptyJars - 2
  854.             else
  855.                 if (essentiaJarCount[aspect] == 1) then
  856.                     if (count <= 64) then -- if it's above 64 the jar is probably an advanced thaumaturgy jar that holds 256
  857.                         myEmptyJars = myEmptyJars - 1
  858.                     end
  859.                 end
  860.             end
  861.            
  862.             essentiaToFill[aspect] = 128 - count
  863.             haveEssentiaToFill = true
  864.         end
  865.     end
  866.    
  867.     if (haveEssentiaToFill == true) then
  868.         -- Jars have been found that aren't full, display the found jars and confirm filling.
  869.         showFillAllTo128(essentiaToFill, myEmptyJars)
  870.     else
  871.         -- All essentia are above 128, rename the button and hold the text for a second so it can be read before reverting to the normal text and color.
  872.         button.renameButton(buttonName, "All jars at 128", true)
  873.         sleep(2.5)
  874.         button.toggleButton("All jars at 128", false)
  875.         button.renameButton("All jars at 128", buttonName, true)
  876.     end
  877. end
  878.  
  879. function showFillAllTo128(essentiaList, emptyJarsAfterFill)
  880.     local x, y
  881.     local myEssentia
  882.     local amount
  883.     local errorText
  884.    
  885.     fillAllTo128EssentiaList = essentiaList
  886.    
  887.     -- Clear the screen and button list
  888.     m.setBackgroundColor(monBackColor)
  889.     m.clear()
  890.     button.clear()
  891.    
  892.     x = essentiaFillAllTo128X
  893.     y = essentiaFillAllTo128Y
  894.    
  895.     m.setBackgroundColor(fillAllTo128EssentiaLabelBackColor)
  896.     m.setTextColor(fillAllTo128EssentiaLabelTextColor)
  897.     m.setCursorPos(essentiaFillAllTo128LabelX, essentiaFillAllTo128LabelY)
  898.     m.write("Fill all jars to 128 request")
  899.    
  900.     m.setBackgroundColor(fillAllTo128EssentiaBackColor)
  901.    
  902.     for myEssentia,amount in sortEss(essentiaList) do
  903.         if (amount == 0) then
  904.             m.setTextColor(fillAllTo128EssentiaTextColorZero)
  905.         else
  906.             m.setTextColor(fillAllTo128EssentiaTextColorNonZero)
  907.         end
  908.        
  909.         m.setCursorPos(x, y)
  910.         m.write(string.upper(string.sub(myEssentia, 1, 1)) .. string.sub(myEssentia, 2) .. string.sub(padding, 1, essentiaColumnWidth - (string.len(myEssentia) + string.len(pad(amount)))) .. pad(amount))
  911.        
  912.         if (y < (essentiaFillAllTo128Y + essentiaColumnHeight - 1)) then
  913.             y = y + 1
  914.         else
  915.             y = essentiaFillAllTo128Y
  916.             x = x + essentiaColumnWidth + essentiaColumnSpacing
  917.         end
  918.     end
  919.    
  920.     button.addButton("Cancel filling", cancelFillAllTo128Button, "Cancel filling", cancelFillAllTo128ButtonX, cancelFillAllTo128ButtonY, cancelFillAllTo128ButtonWidth, cancelFillAllTo128ButtonHeight, cancelFillAllTo128ButtonInactiveBackColor, cancelFillAllTo128ButtonActiveBackColor, cancelFillAllTo128ButtonInactiveTextColor, cancelFillAllTo128ButtonActiveTextColor)
  921.     button.addButton("Begin filling", beginFillAllTo128Button, "Begin filling", beginFillAllTo128ButtonX, beginFillAllTo128ButtonY, beginFillAllTo128ButtonWidth, beginFillAllTo128ButtonHeight, beginFillAllTo128ButtonInactiveBackColor, beginFillAllTo128ButtonActiveBackColor, beginFillAllTo128ButtonInactiveTextColor, beginFillAllTo128ButtonActiveTextColor)
  922.    
  923.     if (emptyJarsAfterFill < 0) then
  924.         errorText = "NOT ENOUGH EMPTY JARS; HAVE " .. emptyJars .. " NEED "  .. (emptyJars - emptyJarsAfterFill)
  925.        
  926.         m.setCursorPos(essentiaFillAllTo128LabelX + math.floor(string.len("Fill all jars to 128 request") / 2) - math.floor(string.len(errorText) / 2), essentiaFillAllTo128LabelY + 1)
  927.         m.setTextColor(colors.red)
  928.         m.write(errorText)
  929.         button.disableButton("Begin filling")
  930.     end
  931.    
  932.     button.drawButtons()
  933. end
  934.  
  935. function topoffAllJars(buttonName)
  936.     local myJars
  937.     local jar
  938.     local essentiaToFill
  939.     local haveEssentiaToFill
  940.    
  941.     -- The button is erased if jars to top off are found else it's toggled back below.
  942.     button.toggleButton(buttonName, true)
  943.     sleep(.15)
  944.    
  945.     -- Get a table of all the essentia jars
  946.     myJars = scanJars()
  947.     essentiaToFill = essentiaList()
  948.     haveEssentiaToFill = false
  949.    
  950.     -- Checks each jar to see if any of them aren't full.
  951.     for jar in pairs(myJars) do
  952.         if (myJars[jar]["count"] < 64) then
  953.             essentiaToFill[myJars[jar]["aspect"]] = essentiaToFill[myJars[jar]["aspect"]] + (64 - myJars[jar]["count"])
  954.             haveEssentiaToFill = true
  955.         elseif (myJars[jar]["count"] > 64) then -- Advanced Thaumaturgy jars hold 256
  956.             essentiaToFill[myJars[jar]["aspect"]] = essentiaToFill[myJars[jar]["aspect"]] + (256 - myJars[jar]["count"])
  957.             haveEssentiaToFill = true
  958.         end
  959.     end
  960.    
  961.     if (haveEssentiaToFill == true) then
  962.         -- Jars have been found that aren't full, display the found jars and confirm filling.
  963.         showTopOffAllJars(essentiaToFill)
  964.     else
  965.         -- No jars are found, rename the button and hold the text for a second so it can be read before reverting to the normal text and color.
  966.         button.renameButton(buttonName, "All jars full", true)
  967.         sleep(2.5)
  968.         button.toggleButton("All jars full", false)
  969.         button.renameButton("All jars full", buttonName, true)
  970.     end
  971. end
  972.  
  973. function showTopOffAllJars(essentiaList)
  974.     local x, y
  975.     local myEssentia
  976.     local essentiaText
  977.     local amount
  978.    
  979.     topOffJarsEssentiaList = essentiaList
  980.    
  981.     -- Clear the screen and button list
  982.     m.setBackgroundColor(monBackColor)
  983.     m.clear()
  984.     button.clear()
  985.    
  986.     x = essentiaTopOffJarsX
  987.     y = essentiaTopOffJarsY
  988.    
  989.     m.setBackgroundColor(topOffAllJarsEssentiaLabelBackColor)
  990.     m.setTextColor(topOffAllJarsEssentiaLabelTextColor)
  991.     m.setCursorPos(essentiaTopOffLabelX, essentiaTopOffLabelY)
  992.     m.write("Top off jars fill request")
  993.    
  994.     m.setBackgroundColor(topOffAllJarsEssentiaBackColor)
  995.    
  996.     for myEssentia,amount in sortEss(essentiaList) do
  997.         if (amount == 0) then
  998.             m.setTextColor(topOffAllJarsEssentiaTextColorZero)
  999.         else
  1000.             m.setTextColor(topOffAllJarsEssentiaTextColorNonZero)
  1001.         end
  1002.        
  1003.         m.setCursorPos(x, y)
  1004.         m.write(string.upper(string.sub(myEssentia, 1, 1)) .. string.sub(myEssentia, 2) .. string.sub(padding, 1, essentiaColumnWidth - (string.len(myEssentia) + string.len(pad(amount)))) .. pad(amount))
  1005.        
  1006.         if (y < (essentiaTopOffJarsY + essentiaColumnHeight - 1)) then
  1007.             y = y + 1
  1008.         else
  1009.             y = essentiaTopOffJarsY
  1010.             x = x + essentiaColumnWidth + essentiaColumnSpacing
  1011.         end
  1012.     end
  1013.    
  1014.     button.addButton("Cancel filling", cancelTopOffJarsButton, "Cancel filling", cancelTopOffJarsButtonX, cancelTopOffJarsButtonY, cancelTopOffJarsButtonWidth, cancelTopOffJarsButtonHeight, cancelTopOffJarsButtonInactiveBackColor, cancelTopOffJarsButtonActiveBackColor, cancelTopOffJarsButtonInactiveTextColor, cancelTopOffJarsButtonActiveTextColor)
  1015.     button.addButton("Begin filling", beginTopOffJarsFillButton, "Begin filling", beginTopOffJarsFillButtonX, beginTopOffJarsFillButtonY, beginTopOffJarsFillButtonWidth, beginTopOffJarsFillButtonHeight, beginTopOffJarsFillButtonInactiveBackColor, beginTopOffJarsFillButtonActiveBackColor, beginTopOffJarsFillButtonInactiveTextColor, beginTopOffJarsFillButtonActiveTextColor)
  1016.    
  1017.     button.drawButtons()
  1018. end
  1019.  
  1020. function cancelTopOffJarsButton(buttonName)
  1021.     button.flash(buttonName)
  1022.     topOffJarsEssentiaList = nil
  1023.     refresh()
  1024. end
  1025.  
  1026. function beginTopOffJarsFillButton(buttonName)
  1027.     local beanType
  1028.     local amountToBurn
  1029.     local burnCount
  1030.    
  1031.     button.flash(buttonName)
  1032.    
  1033.     drawBurnMainScreen()
  1034.     allBurnResults = {}
  1035.     for beanType,amountToBurn in sortEss(topOffJarsEssentiaList) do
  1036.         if (amountToBurn ~= 0) then
  1037.             updateBurnBeanType(beanType)
  1038.             burnCount = burnBeans(beanType, amountToBurn)
  1039.            
  1040.            
  1041.             print("")
  1042.             print(beanType)
  1043.             print("Burned: " .. burnCount)
  1044.            
  1045.             if (burnCount == -100) then
  1046.                 print(translateBurnResultToText(burnCount))
  1047.                 break
  1048.             end
  1049.         end
  1050.     end
  1051.    
  1052.     refresh()
  1053. end
  1054.  
  1055. function cancelFillAllTo64Button(buttonName)
  1056.     button.flash(buttonName)
  1057.     fillAllTo64EssentiaList = nil
  1058.     refresh()
  1059. end
  1060.  
  1061. function beginFillAllTo64Button(buttonName)
  1062.     local beanType
  1063.     local amountToBurn
  1064.     local burnCount
  1065.    
  1066.     button.flash(buttonName)
  1067.    
  1068.     drawBurnMainScreen()
  1069.     allBurnResults = {}
  1070.     for beanType,amountToBurn in sortEss(fillAllTo64EssentiaList) do
  1071.         if (amountToBurn ~= 0) then
  1072.             updateBurnBeanType(beanType)
  1073.             burnCount = burnBeans(beanType, amountToBurn)
  1074.            
  1075.            
  1076.             print("")
  1077.             print(beanType)
  1078.             print("Burned: " .. burnCount)
  1079.            
  1080.             if (burnCount == -100) then
  1081.                 print(translateBurnResultToText(burnCount))
  1082.                 break
  1083.             end
  1084.         end
  1085.     end
  1086.    
  1087.     refresh()
  1088. end
  1089.  
  1090. function cancelFillAllTo128Button(buttonName)
  1091.     button.flash(buttonName)
  1092.     fillAllTo128EssentiaList = nil
  1093.     refresh()
  1094. end
  1095.  
  1096. function beginFillAllTo128Button(buttonName)
  1097.     local beanType
  1098.     local amountToBurn
  1099.     local burnCount
  1100.     local bk, bv
  1101.    
  1102.     button.flash(buttonName)
  1103.    
  1104.     drawBurnMainScreen()
  1105.     for beanType,amountToBurn in sortEss(fillAllTo128EssentiaList) do
  1106.         if (amountToBurn ~= 0) then
  1107.             updateBurnBeanType(beanType)
  1108.             burnCount = burnBeans(beanType, amountToBurn)
  1109.            
  1110.             print("")
  1111.             print(beanType)
  1112.             print("Burned: " .. burnCount)
  1113.            
  1114.             if (burnCount == -100) then
  1115.                 print(translateBurnResultToText(burnCount))
  1116.                 break
  1117.             end
  1118.         end
  1119.     end
  1120.    
  1121.     refresh()
  1122. end
  1123.  
  1124. function essentiaButton(which)
  1125.     local buttonEssentiaName
  1126.     local availableEssentiaSpace = 0
  1127.     local myJars
  1128.     local essentiaCount = 0
  1129.     local i
  1130.    
  1131.     myJars = scanJars()
  1132.     button.flash(which)
  1133.     buttonEssentiaName = string.sub(which, 1, string.find(which, " ") - 1)
  1134.    
  1135.     for i in pairs(myJars) do
  1136.         if (myJars[i]["aspect"] == buttonEssentiaName) then
  1137.             availableEssentiaSpace = availableEssentiaSpace + (64 - myJars[i]["count"])
  1138.             essentiaCount = essentiaCount + myJars[i]["count"]
  1139.         end
  1140.     end
  1141.    
  1142.     showRefillEssentia(buttonEssentiaName, essentiaCount, availableEssentiaSpace)
  1143. end
  1144.  
  1145. function showRefillEssentia(essentiaName, essentiaCount, availableEssentiaSpace)
  1146.     local fillingText
  1147.    
  1148.     fillEssentia =  essentiaName
  1149.     fillCurrentAmount = essentiaCount
  1150.     fillAmount = 0
  1151.     fillAvailableSpace = availableEssentiaSpace
  1152.    
  1153.     button.clear()
  1154.     m.setBackgroundColor(monBackColor)
  1155.     m.clear()
  1156.    
  1157.     m.setTextColor(refillLabelTextColor)
  1158.     fillingText = "Refilling: " .. string.upper(string.sub(fillEssentia, 1, 1)) .. string.sub(fillEssentia, 2)
  1159.     m.setCursorPos(refillScreenX + math.floor((41 - string.len(fillingText)) / 2), refillScreenY)
  1160.     m.write(fillingText)
  1161.    
  1162.     if (fillAvailableSpace == 0 and emptyJars == 0) then
  1163.         m.setCursorPos(refillScreenX + math.floor((41 - string.len("ALL JARS USED OR FULL")) / 2), refillScreenY + 1)
  1164.         m.setTextColor(colors.red)
  1165.         m.write("ALL JARS USED OR FULL")
  1166.     end
  1167.    
  1168.    
  1169.     m.setTextColor(refillCurrentAmountTextColor)
  1170.     m.setCursorPos(refillScreenX, refillScreenY + 2)
  1171.     m.write("Currently contains:" .. string.sub(padding, 1, 41 - (string.len("Currently contains:") + string.len(pad(fillCurrentAmount)))) .. pad(fillCurrentAmount))
  1172.    
  1173.     m.setTextColor(refillAddingAmountTextColor)
  1174.     m.setCursorPos(refillScreenX, refillScreenY + 3)
  1175.     m.write("Currently adding:" .. string.sub(padding, 1, 41 - (string.len("Currently adding:") + string.len(pad(fillAmount)))) .. pad(fillAmount))
  1176.    
  1177.     m.setTextColor(getEssentiaColor(fillCurrentAmount))
  1178.     m.setCursorPos(refillScreenX, refillScreenY + 4)
  1179.     m.write("Total after filling:" .. string.sub(padding, 1, 41 - (string.len("Total after filling:") + string.len(pad(fillCurrentAmount)))) .. pad(fillCurrentAmount))
  1180.    
  1181.     button.addButton("+1", addEssentia, "+1", refillScreenX, refillScreenY + 6, 10, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1182.     button.addButton("+5", addEssentia, "+5", refillScreenX + 11, refillScreenY + 6, 9, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1183.     button.addButton("+10", addEssentia, "+10", refillScreenX + 21, refillScreenY + 6, 9, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1184.     button.addButton("+64", addEssentia, "+64", refillScreenX + 31, refillScreenY + 6, 10, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1185.    
  1186.     button.addButton("-1", addEssentia, "-1", refillScreenX, refillScreenY + 10, 10, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1187.     button.addButton("-5", addEssentia, "-5", refillScreenX + 11, refillScreenY + 10, 9, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1188.     button.addButton("-10", addEssentia, "-10", refillScreenX + 21, refillScreenY + 10, 9, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1189.     button.addButton("-64", addEssentia, "-64", refillScreenX + 31, refillScreenY + 10, 10, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1190.    
  1191.     button.addButton("Top off jar(s)", addEssentia, "Top off jar(s)", refillScreenX, refillScreenY + 14, 20, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1192.     button.addButton("Max fill", addEssentia, "Max fill", refillScreenX + 21, refillScreenY + 14, 20, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1193.    
  1194.     button.addButton("Cancel filling", refresh, "Cancel filling", refillScreenX, refillScreenY + 18, 41, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1195.    
  1196.     button.addButton("Begin filling", buttonBeginRefill, "Begin filling", refillScreenX, refillScreenY + 22, 41, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1197.    
  1198.     button.drawButtons()
  1199. end
  1200.  
  1201. function addEssentia(amount)
  1202.     local myFillAmount
  1203.    
  1204.     myFillAmount = fillAmount
  1205.    
  1206.     --print(fillAmount .. " before")
  1207.    
  1208.     button.flash(amount)
  1209.    
  1210.     if (amount == "Top off jar(s)") then
  1211.         fillAmount = fillAvailableSpace
  1212.     elseif (amount == "Max fill") then
  1213.         fillAmount = fillAvailableSpace + (emptyJars * 64)
  1214.     else
  1215.         fillAmount = fillAmount + tonumber(amount)
  1216.     end
  1217.    
  1218.     if (fillAmount < 0) then
  1219.         --print(fillAmount .. " is less than 0 - setting to 0")
  1220.         fillAmount = 0
  1221.     elseif (fillAmount > fillAvailableSpace) then
  1222.         if (emptyJars > 0) then
  1223.             if (fillAmount > (fillAvailableSpace + (emptyJars * 64))) then
  1224.                 fillAmount = fillAvailableSpace + (emptyJars * 64)
  1225.             end
  1226.         else
  1227.             fillAmount = fillAvailableSpace
  1228.         end
  1229.     end
  1230.    
  1231.     if (fillAmount ~= myFillAmount) then
  1232.         m.setBackgroundColor(monBackColor)
  1233.        
  1234.         m.setTextColor(refillAddingAmountTextColor)
  1235.         m.setCursorPos(refillScreenX, refillScreenY + 3)
  1236.         m.write("Currently adding:" .. string.sub(padding, 1, 41 - (string.len("Currently adding:") + string.len(pad(fillAmount)))) .. pad(fillAmount))
  1237.        
  1238.         m.setTextColor(getEssentiaColor(fillCurrentAmount + fillAmount))
  1239.         m.setCursorPos(refillScreenX, refillScreenY + 4)
  1240.         m.write("Total after filling:" .. string.sub(padding, 1, 41 - (string.len("Total after filling:") + string.len(pad(fillCurrentAmount + fillAmount)))) .. pad(fillCurrentAmount + fillAmount))
  1241.     end
  1242. end
  1243.  
  1244. -- Standard refill button
  1245. function buttonBeginRefill(buttonName)
  1246.     local burnCount
  1247.    
  1248.     button.flash(buttonName)
  1249.    
  1250.     if (fillAmount ~= 0) then
  1251.         drawBurnMainScreen()
  1252.         updateBurnBeanType(fillEssentia)
  1253.         burnCount = burnBeans(fillEssentia, fillAmount)
  1254.        
  1255.         print("")
  1256.         print("Burned: " .. burnCount)
  1257.        
  1258.         print(translateBurnResultToText(burnCount))
  1259.     end
  1260.    
  1261.     refresh()
  1262. end
  1263.  
  1264. function translateBurnResultToText(burnResult)
  1265.     if (burnResult == -100) then
  1266.         return "Aborted"
  1267.     end
  1268. end
  1269.  
  1270. maximumLength = 0
  1271.  
  1272. function updateBurnStatus(newStatus)
  1273.     local monWidth, monHeight
  1274.     local pos
  1275.     local writeWidth
  1276.     local y
  1277.    
  1278.     monWidth, monHeight = m.getSize()
  1279.     writeWidth = monWidth - 10
  1280.     pos = 1
  1281.    
  1282.     for y = 0, 3 do
  1283.         m.setCursorPos(burnScreenStatusX, y + burnScreenStatusY + 2)
  1284.         m.write(string.sub(padding, 1, writeWidth))
  1285.         m.setCursorPos(burnScreenStatusX, y + burnScreenStatusY + 2)
  1286.         m.write(string.sub(newStatus, pos, writeWidth + pos - 1))
  1287.         pos = pos + writeWidth
  1288.     end
  1289. end
  1290.  
  1291. function updateBurnBeanType(newBean)
  1292.     m.setCursorPos(burnScreenBeanLabelX + string.len(burnScreenBeanTextLabel) + 1, burnScreenBeanLabelY)
  1293.     m.write(string.upper(string.sub(newBean, 1, 1)) .. string.sub(newBean, 2) .. string.sub(padding, 1, 15 - string.len(newBean)))
  1294. end
  1295.  
  1296. function drawBurnMainScreen()
  1297.     local monWidth
  1298.     local monHeight
  1299.     local x, y
  1300.    
  1301.     -- Clears the screen before creating the information burn screen
  1302.     button.clear()
  1303.     m.setBackgroundColor(monBackColor)
  1304.     m.clear()
  1305.    
  1306.     -- Draws the border on the screen
  1307.     monWidth,monHeight = m.getSize()
  1308.     m.setBackgroundColor(burnScreenBorderColor)
  1309.    
  1310.     m.setCursorPos(1, 1)
  1311.     m.write(string.sub(padding, 1, monWidth))
  1312.     m.setCursorPos(1, monHeight)
  1313.     m.write(string.sub(padding, 1, monWidth))
  1314.    
  1315.     for y = 0, monHeight do
  1316.         m.setCursorPos(1, y)
  1317.         m.write("  ")
  1318.         m.setCursorPos(monWidth - 1, y)
  1319.         m.write("  ")
  1320.     end
  1321.    
  1322.     -- Draws the label text
  1323.     m.setBackgroundColor(burnScreenLabelBackColor)
  1324.     m.setTextColor(burnScreenLabelTextColor)
  1325.     m.setCursorPos(burnScreenLabelX, burnScreenLabelY)
  1326.     m.write("Burn request information")
  1327.    
  1328.     m.setBackgroundColor(burnScreenBeanLabelBackColor)
  1329.     m.setTextColor(burnScreenBeanLabelTextColor)
  1330.     m.setCursorPos(burnScreenBeanLabelX, burnScreenBeanLabelY)
  1331.     m.write(burnScreenBeanTextLabel)
  1332.    
  1333.     m.setBackgroundColor(burnScreenBeanLabelBackColor)
  1334.     m.setTextColor(burnScreenBeanLabelTextColor)
  1335.     m.setCursorPos(burnScreenStatusX, burnScreenStatusY)
  1336.     m.write(burnScreenStatusTextLabel)
  1337. end
  1338.  
  1339.  
  1340.  
  1341.  
  1342.  
  1343.  
  1344.  
  1345.  
  1346.  
  1347.  
  1348.  
  1349.  
  1350.  
  1351.  
  1352.  
  1353.  
  1354.  
  1355.  
  1356.  
  1357.  
  1358.  
  1359.  
  1360.  
  1361.  
  1362.  
  1363.  
  1364.  
  1365.  
  1366.  
  1367.  
  1368.  
  1369.  
  1370.  
  1371.  
  1372.  
  1373.  
  1374.  
  1375.  
  1376.  
  1377.  
  1378.  
  1379.  
  1380.  
  1381.  
  1382.  
  1383.  
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391.  
  1392.  
  1393.  
  1394.  
  1395.  
  1396.  
  1397.  
  1398.  
  1399.  
  1400.  
  1401. --[[
  1402.  
  1403.     The functions below are used to track mana beans in connected chests and put them in the alchemical furnaces.
  1404.  
  1405. --]]
  1406.  
  1407. function executeBurn(chest, beanType, amount, returnIfStuck)
  1408.     local amountBurned
  1409.     local stack
  1410.     local slot
  1411.     local direction
  1412.     local directions
  1413.     local aspect
  1414.     local count
  1415.     local validBeanCount
  1416.     local waitingForBeans
  1417.     local amountToBurn
  1418.     local waitingForFurnace
  1419.    
  1420.     -- No beans for this type have ever been found.
  1421.     if (chests[chest][beanType] == nil) then
  1422.         return 0
  1423.     end
  1424.    
  1425.     if (returnIfStuck ~= false and returnIfStuck ~= true) then
  1426.         returnIfStuck = false
  1427.     end
  1428.    
  1429.     updateBurnStatus("attempting to burn beans")
  1430.    
  1431.     if (alchemicalFurnaceFromChestDirection == "auto") then
  1432.         directions = validFurnaceDirections()
  1433.     else
  1434.         directions = {[alchemicalFurnaceFromChestDirection] = true}
  1435.     end
  1436.    
  1437.     amountToBurn = amount
  1438.     waitingForBeans = 0
  1439.     waitingForFurnace = 0
  1440.    
  1441.     while (amountToBurn > 0) do
  1442.         amountBurned = 0
  1443.         for slot in pairs(chests[chest][beanType]) do
  1444.             stack = peripheral.call(chests[chest]["peripheral name"], "getStackInSlot", slot)
  1445.            
  1446.             if (stack ~= nil and stack.qty > 2) then
  1447.                 count = amountToBurn - amountBurned
  1448.                
  1449.                 if (count > (stack.qty - 2)) then
  1450.                     count = stack.qty - 2
  1451.                     waitingForBeans = 0
  1452.                 end
  1453.             else
  1454.                 count = 0
  1455.             end
  1456.            
  1457.             if (count ~= 0) then
  1458.                 while (count > 0) do
  1459.                     for direction in pairs(directions) do
  1460.                         if (count > 0) then
  1461.                             burned = peripheral.call(chests[chest]["peripheral name"], "pushItemIntoSlot", direction, slot, count, 1)
  1462.                             count = count - burned
  1463.                             amountBurned = amountBurned + burned
  1464.                            
  1465.                             if (burned ~= 0) then
  1466.                                 waitingForFurnace = 0
  1467.                             end
  1468.                            
  1469.                             sleep(serverFriendly)
  1470.                         end
  1471.                     end
  1472.                    
  1473.                     if (count > 0) then
  1474.                         -- Failed to put all the beans into the attached furnace(s)
  1475.                         if (waitingForFurnace == 1 and returnIfStuck == true) then
  1476.                             return amount - (amountToBurn - amountBurned)
  1477.                         elseif (waitingForFurnace == 0) then
  1478.                             print("Furnace(s) full, waiting for furnace(s) to have room...")
  1479.                             updateBurnStatus("furnace(s) full, waiting for them to have room")
  1480.                         end
  1481.                        
  1482.                         waitingForFurnace = 1
  1483.                         sleep(1)
  1484.                     end
  1485.                 end
  1486.             else
  1487.                 sleep(serverFriendly)
  1488.             end
  1489.         end
  1490.        
  1491.         if (amountBurned == 0) then
  1492.             -- Out of beans
  1493.             if (waitingForBeans == 1 and returnIfStuck == true) then
  1494.                 return amount - (amountToBurn - amountBurned)
  1495.             elseif (waitingForBeans == 0) then
  1496.                 print("Out of bean type " .. beanType .. " in chest " .. chests[chest]["peripheral name"] .. ". There needs to be more than 2 beans (in a given stack) to burn them...")
  1497.                 updateBurnStatus("out of " .. beanType .. " in chest " .. chests[chest]["peripheral name"] .. " - waiting for refill")
  1498.             end
  1499.            
  1500.             waitingForBeans = 1
  1501.             --enableRefill()
  1502.             sleep(1)
  1503.             --disableRefill()
  1504.         else
  1505.             waitingForBeans = 0
  1506.         end
  1507.        
  1508.         amountToBurn = amountToBurn - amountBurned
  1509.     end
  1510.    
  1511.     -- This should always calculate to amount but just in case it doesn't, it's not set static.
  1512.     return (amount - amountToBurn)
  1513. end
  1514.  
  1515. function validFurnaceDirections()
  1516.     return {["north"] = true, ["south"] = true, ["east"] = true, ["west"] = true}
  1517. end
  1518.  
  1519. function burnBeans(beanType, amount)
  1520.     local remainingAmount
  1521.     local ci
  1522.     local continue
  1523.     local amountBurned
  1524.     local amountToBurn
  1525.     local chestsWithAspect
  1526.    
  1527.     amountBurned = 0
  1528.     remainingAmount = amount
  1529.     chestsWithAspect = {}
  1530.     chestsBurnResult = {}
  1531.    
  1532.     if (chestAspects[beanType] == 0) then
  1533.         -- No chests contain the bean type
  1534.         return 0, nil
  1535.     else
  1536.         for ci in pairs(chests) do
  1537.             if (chests[ci][beanType] ~= nil) then
  1538.                 chestsWithAspect[ci] = true
  1539.             end
  1540.         end
  1541.        
  1542.         if (distributeBurnRequests == true) then
  1543.             continue = true
  1544.            
  1545.             while (continue) do
  1546.                 for ci in pairs(chestsWithAspect) do
  1547.                     if (rs.getInput("left") == true) then
  1548.                         return -100
  1549.                     end
  1550.                     amountToBurn = 64
  1551.                    
  1552.                     if ((remainingAmount - amountToBurn) < 0) then
  1553.                         amountToBurn = remainingAmount
  1554.                     end
  1555.                    
  1556.                     amountBurned = executeBurn(ci, beanType, amountToBurn, true)
  1557.                     remainingAmount = remainingAmount - amountBurned
  1558.                    
  1559.                     if (remainingAmount <= 0) then
  1560.                         continue = false
  1561.                         break
  1562.                     end
  1563.                 end
  1564.                
  1565.                 if (continue == true) then
  1566.                     sleep(5)
  1567.                 end
  1568.             end
  1569.         else
  1570.             for ci in pairs(chestsWithAspect) do
  1571.                 amountBurned = executeBurn(ci, beanType, remainingAmount)
  1572.                
  1573.                 remainingAmount = remainingAmount - amountBurned
  1574.                
  1575.                 if (remainingAmount <= 0) then
  1576.                     break
  1577.                 end
  1578.             end
  1579.         end
  1580.     end
  1581.    
  1582.     return (amount - remainingAmount)
  1583. end
  1584.  
  1585. function getValidChestNames()
  1586.     local chests = {
  1587.         ["container_chest"] = true,
  1588.         ["iron"] = true,
  1589.         ["gold"] = true,
  1590.         ["diamond"] = true,
  1591.         ["crystal"] = true,
  1592.         ["obsidian"] = true,
  1593.         ["copper"] = true,
  1594.         ["silver"] = true
  1595.         }
  1596.    
  1597.     return chests
  1598. end
  1599.  
  1600. function findChestsAndAnalyzers()
  1601.     local i, j
  1602.     local peripheralType
  1603.     local validChestNames
  1604.     local myChestID
  1605.     local myAnalyzerID
  1606.    
  1607.     validChestNames = getValidChestNames()
  1608.     myChestId = 1
  1609.     myAnalyzerID = 1
  1610.    
  1611.     for i,j in ipairs(peripheral.getNames()) do
  1612.         peripheralType = peripheral.getType(j)
  1613.        
  1614.         if (validChestNames[peripheralType] == true) then
  1615.             if (debugOutput > 1) then
  1616.                 print("Valid chest found: " .. peripheralType .. " size: " .. peripheral.call(j, "getInventorySize"))
  1617.             end
  1618.            
  1619.             chests[myChestId] = {}
  1620.             chests[myChestId]["peripheral name"] = j
  1621.             myChestId = myChestId + 1
  1622.         elseif (peripheralType == "tt_aspectanalyzer") then
  1623.             if (debugOutput > 1) then
  1624.                 print("Aspect analyzer found: " .. j)
  1625.             end
  1626.            
  1627.             aspectAnalyzers[myAnalyzerID] = {}
  1628.             aspectAnalyzers[myAnalyzerID]["peripheral name"] = j
  1629.             myAnalyzerID = myAnalyzerID + 1
  1630.         end
  1631.     end
  1632. end
  1633.  
  1634. function printChestAspects()
  1635.     local ci
  1636.     local e, s, i
  1637.     local myEssentias
  1638.     local chestEssentia
  1639.    
  1640.     myEssentias = essentiaList()
  1641.    
  1642.     for ci in pairs(chests) do
  1643.         chestEssentia = ""
  1644.        
  1645.         for e, i in pairs(chests[ci]) do
  1646.             if not (string.find(e, " ")) then
  1647.                 for s in pairs(i) do
  1648.                     chestEssentia = chestEssentia .. e .. ":" .. s .. ", "
  1649.                 end
  1650.             end
  1651.         end
  1652.        
  1653.         if (chestEssentia ~= nil) then
  1654.             print("Chest " .. ci .. ": " .. string.sub(chestEssentia, 1, string.len(chestEssentia) - 2))
  1655.         end
  1656.        
  1657.         print("")
  1658.     end
  1659.    
  1660.     for ci in pairs(chests) do
  1661.         print("Chest: " .. ci .. " analyze time: " .. chests[ci]["analyze time"])
  1662.     end
  1663. end
  1664.  
  1665. function analyzeChestsContents()
  1666.     local ci
  1667.     local e
  1668.     local slot
  1669.     local chestContents
  1670.     local aspect
  1671.     local count
  1672.     local startTime
  1673.     local endTime
  1674.     local missingAspects
  1675.    
  1676.     chestAspects = essentiaList()
  1677.    
  1678.     for ci in pairs(chests) do
  1679.         if (debugOutput > 1) then
  1680.             print("Analyzing chest contents " .. ci)
  1681.         end
  1682.        
  1683.         chestContents = peripheral.call(chests[ci]["peripheral name"], "getAllStacks")
  1684.         startTime = os.clock()
  1685.         for slot in pairs(chestContents) do
  1686.             if (chestContents[slot].name == "Mana Bean") then
  1687.                 aspect,count = scanItemInSlot(chests[ci]["aspect analyzer"], chests[ci]["peripheral name"], slot, chestContents[slot].qty)
  1688.                
  1689.                 if (aspect ~= nil) then
  1690.                     if (chests[ci][aspect] == nil) then
  1691.                         chests[ci][aspect] = {}
  1692.                     end
  1693.                    
  1694.                     chests[ci][aspect][slot] = true
  1695.                     chestAspects[aspect] = 1
  1696.                    
  1697.                     if (debugOutput > 1) then
  1698.                         print("Found mana bean in chest " .. ci .. " slot " .. slot .. " of aspect type " .. aspect)
  1699.                     end
  1700.                 else
  1701.                     print("Mana bean in chest " .. ci .. " slot " .. slot .. " needs refilling; only " .. count .. " left.")
  1702.                 end
  1703.             end
  1704.         end
  1705.        
  1706.         chests[ci]["analyze time"] = os.clock() - startTime
  1707.        
  1708.         if (debugOutput > 0) then
  1709.             print("Time to analyze chest " .. ci .. " " .. (os.clock() - startTime))
  1710.         end
  1711.     end
  1712.    
  1713.     missingAspects = ""
  1714.     for e in pairs(chestAspects) do
  1715.         if (chestAspects[e] == 0) then
  1716.             if (missingAspects ~= "") then
  1717.                 missingAspects = missingAspects .. ", "
  1718.             end
  1719.            
  1720.             missingAspects = missingAspects .. e
  1721.         end
  1722.     end
  1723.    
  1724.     if (missingAspects ~= "") then
  1725.         print("WARNING: Not every aspect was found in the connected chests. You won't be able to refill them unless they're added to the chest(s).")
  1726.         print("")
  1727.         print("Missing aspects: " .. missingAspects)
  1728.     end
  1729. end
  1730.  
  1731. function scanItemInSlot(aspectAnalyzer, chest, slot, quantity)
  1732.     local aspect
  1733.     local stack
  1734.    
  1735.     if (quantity == nil) then
  1736.         stack = peripheral.call(chest, "getStackInSlot", slot)
  1737.         if (stack ~= nil) then
  1738.             quantity = stack.qty
  1739.         else
  1740.             quantity = 0
  1741.         end
  1742.     end
  1743.    
  1744.     if (quantity <= 2) then
  1745.         return nil, quantity
  1746.     end
  1747.    
  1748.     if (peripheral.call(chest, "pushItemIntoSlot", "down", slot, 1, 1) == 0) then
  1749.         print("Failed to push mana bean from chest " .. chest .. " slot " .. slot .. " into aspect analyzer. Program halted. !!RESTART REQUIRED!!")
  1750.        
  1751.         -- Something went wrong, wait for human intervention.
  1752.         while (true) do
  1753.             sleep(60)
  1754.         end
  1755.     end
  1756.    
  1757.     aspect = peripheral.call(aspectAnalyzer, "getAspects")
  1758.    
  1759.     if (peripheral.call(chest, "pullItemIntoSlot", "down", 1, 1, slot) == 0) then
  1760.         print("Failed to pull mana bean from aspect analyzer " .. aspectAnalyzer .. " back into chest " .. chest .. " slot " .. slot .. ". Program halted. !!RESTART REQUIRED!!")
  1761.        
  1762.         -- Something went wrong, wait for human intervention.
  1763.         while (true) do
  1764.             sleep(60)
  1765.         end
  1766.     end
  1767.    
  1768.     return aspect, quantity
  1769. end
  1770.  
  1771. function matchChestsWithAnalyzer()
  1772.     local ci
  1773.     local ai
  1774.     local hasItem
  1775.     local chestContents
  1776.     local slot
  1777.     local foundSlot
  1778.     local itemStack
  1779.    
  1780.     -- Checks to make sure none of the analyzers have any items in them
  1781.     for ai in pairs (aspectAnalyzers) do
  1782.         hasItem = peripheral.call(aspectAnalyzers[ai]["peripheral name"], "hasItem")
  1783.         if (hasItem) then
  1784.             print("One of the aspect analyzer(s) has an item in it. All aspect analyzer should be empty.")
  1785.            
  1786.             while (hasItem) do
  1787.                 sleep(1)
  1788.                 hasItem = peripheral.call(aspectAnalyzers[ai]["peripheral name"], "hasItem")
  1789.             end
  1790.         end
  1791.     end
  1792.    
  1793.    
  1794.     for ci in pairs(chests) do
  1795.         chestContents = peripheral.call(chests[ci]["peripheral name"], "getAllStacks")
  1796.         foundSlot = false
  1797.        
  1798.         -- See if the chest contains anything and record the slot of any item if it does.
  1799.         for slot in pairs(chestContents) do
  1800.             if (chestContents[slot].name == "Mana Bean") then
  1801.                 foundSlot = slot
  1802.                 break
  1803.             end
  1804.         end
  1805.        
  1806.         -- Something went wrong, try to get it fixed.
  1807.         if not (foundSlot) then
  1808.             print("No beans found in chest: " .. chests[ci]["peripheral name"] .. " at least one bean type needs to be present during startup. Please put some beans in the chest.")
  1809.             print("")
  1810.            
  1811.             while not (foundSlot) do
  1812.                 sleep(5)
  1813.                 chestContents = peripheral.call(chests[ci]["peripheral name"], "getAllStacks")
  1814.                
  1815.                 for slot in pairs(chestContents) do
  1816.                     if (chestContents[slot].name == "Mana Bean") then
  1817.                         foundSlot = slot
  1818.                         break
  1819.                     end
  1820.                 end
  1821.             end
  1822.            
  1823.             print("Found mana bean in chest slot: " .. foundSlot)
  1824.             print("")
  1825.         end
  1826.        
  1827.        
  1828.         -- Put one of the random items from the chest into the aspect analyzer above it.
  1829.         if not (peripheral.call(chests[ci]["peripheral name"], "pushItemIntoSlot", "down", foundSlot, 1, 1)) then
  1830.             print("Failed to put item from chest " .. chests[ci]["peripheral name"] .. " slot " .. foundSlot .. " into aspect analyzer. Make sure everything in the chest is a mana bean.")
  1831.             print("")
  1832.             sleep(1)
  1833.            
  1834.             while not (peripheral.call(chests[ci]["peripheral name"], "pushItemIntoSlot", "down", foundSlot, 1, 1)) do
  1835.                 sleep(1)
  1836.             end
  1837.         end
  1838.        
  1839.        
  1840.         -- Scan through the aspect analyzers and find which one has the item in it.
  1841.         for ai in pairs (aspectAnalyzers) do
  1842.             hasItem = peripheral.call(aspectAnalyzers[ai]["peripheral name"], "hasItem")
  1843.            
  1844.             if (hasItem) then
  1845.                 if not (peripheral.call(chests[ci]["peripheral name"], "pullItemIntoSlot", "down", 1, 1, foundSlot)) then
  1846.                     print("Failed to pull the item back out of the aspect analyzer. Make sure the redstone signal from the computer is disabling refilling of the chests during startup. !!RESTART REQUIRED!!")
  1847.                    
  1848.                     -- This is too difficult to explain how to recover from. Wait for human intervention.
  1849.                     while (true) do
  1850.                         sleep(60)
  1851.                     end
  1852.                 end
  1853.                
  1854.                 chests[ci]["aspect analyzer"] = aspectAnalyzers[ai]["peripheral name"]
  1855.                
  1856.                 if (debugOutput) then
  1857.                     print("Matched chest: " .. chests[ci]["peripheral name"] .. " with aspect analyzer: " .. aspectAnalyzers[ai]["peripheral name"])
  1858.                     print("")
  1859.                 end
  1860.                
  1861.                 break
  1862.             end
  1863.         end
  1864.        
  1865.         if not (hasItem) then
  1866.             print("Failed to match chest " .. chests[ci]["peripheral name"] .. " with any connected aspect analyzer. Make sure all chests have aspect analyzers below them and all chests and aspect analyzers have peripherals/proxies connected and enabled. !!RESTART REQUIRED!!")
  1867.            
  1868.             -- Some part of the peripheral configuration is wrong and needs to be fixed. Wait for human intervention.
  1869.             while (true) do
  1870.                 sleep(60)
  1871.             end
  1872.         end
  1873.     end
  1874. end
  1875.  
  1876. function disableRefill()
  1877.     rs.setOutput(disableFillRedstoneDirection, true)
  1878.     redstone.setBundledOutput(disableFillRedstoneDirection, colors.white)
  1879.     sleep(redstoneWaitTicks * .05)
  1880. end
  1881.  
  1882. function enableRefill(skipSleep)
  1883.     rs.setOutput(disableFillRedstoneDirection, false)
  1884.     redstone.setBundledOutput(disableFillRedstoneDirection, 0)
  1885.    
  1886.     if (skipSleep ~= true) then
  1887.         sleep(redstoneWaitTicks * .05)
  1888.     end
  1889. end
  1890.  
  1891. function essentiaList()
  1892.     local essentias
  1893.    
  1894.     essentias = {
  1895.         ["aer"] = 0,
  1896.         ["alienis"] = 0,
  1897.         ["aqua"] = 0,
  1898.         ["arbor"] = 0,
  1899.         ["auram"] = 0,
  1900.         ["bestia"] = 0,
  1901.         ["cognitio"] = 0,
  1902.         ["corpus"] = 0,
  1903.         ["exanimis"] = 0,
  1904.         ["fabrico"] = 0,
  1905.         ["fames"] = 0,
  1906.         ["gelum"] = 0,
  1907.         ["granum"] = 0,
  1908.         ["herba"] = 0,
  1909.         ["humanus"] = 0,
  1910.         ["ignis"] = 0,
  1911.         ["instrumentum"] = 0,
  1912.         ["iter"] = 0,
  1913.         ["limus"] = 0,
  1914.         ["lucrum"] = 0,
  1915.         ["lux"] = 0,
  1916.         ["machina"] = 0,
  1917.         ["messis"] = 0,
  1918.         ["metallum"] = 0,
  1919.         ["meto"] = 0,
  1920.         ["mortuus"] = 0,
  1921.         ["motus"] = 0,
  1922.         ["ordo"] = 0,
  1923.         ["pannus"] = 0,
  1924.         ["perditio"] = 0,
  1925.         ["perfodio"] = 0,
  1926.         ["permutatio"] = 0,
  1927.         ["potentia"] = 0,
  1928.         ["praecantatio"] = 0,
  1929.         ["sano"] = 0,
  1930.         ["saxum"] = 0,
  1931.         ["sensus"] = 0,
  1932.         ["spiritus"] = 0,
  1933.         ["telum"] = 0,
  1934.         ["tempus"] = 0,
  1935.         ["tempestas"] = 0,
  1936.         ["tenebrae"] = 0,
  1937.         ["terra"] = 0,
  1938.         ["tutamen"] = 0,
  1939.         ["vacuos"] = 0,
  1940.         ["venenum"] = 0,
  1941.         ["victus"] = 0,
  1942.         ["vinculum"] = 0,
  1943.         ["vitium"] = 0,
  1944.         ["vitreus"] = 0,
  1945.         ["volatus"] = 0
  1946.     }
  1947.    
  1948.     return essentias
  1949. end
  1950.  
  1951.  
  1952. m.clear()
  1953. m.setCursorPos(1, 1)
  1954. term.redirect(m)
  1955. print("Analyzing chests, watch the computer for more information.")
  1956. print("")
  1957. print("The monitor will refresh once chest analysis is finished.")
  1958. if not term.restore then m.restoreTo = term.current() end
  1959.  
  1960. -- Redirect the terminal to the attached monitor:
  1961. term.redirect(m)
  1962.  
  1963. -- Restore back:
  1964. if term.restore then
  1965.     term.restore()
  1966. else
  1967.     term.redirect(m.restoreTo)
  1968. end
  1969. essentia = essentiaList()
  1970. setAutoDetectVariables()
  1971.  
  1972. disableRefill()
  1973. findChestsAndAnalyzers()
  1974. matchChestsWithAnalyzer()
  1975. analyzeChestsContents()
  1976. enableRefill()
  1977.  
  1978. print("")
  1979. print("Chest analysis finished. Showing interface.")
  1980. sleep(1)
  1981.  
  1982.  
  1983. refresh()
  1984.  
  1985. while (run) do
  1986.     -- uses os.pullevent so this isn't triggered constantly
  1987.     getClick()
  1988. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement