Advertisement
Guest User

startup

a guest
Jul 23rd, 2014
224
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 63.03 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 = 58
  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 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.       aspect = aspect[1]
  522.      
  523.       aspectCount = peripheral.call(j, "getAspectCount", aspect)
  524.      
  525.       if (aspectCount > 0) then
  526.         jars[jarID] = {}
  527.         jars[jarID]["aspect"] = aspect
  528.         jars[jarID]["count"] = aspectCount
  529.         jarID = jarID + 1
  530.         myTotalJars = myTotalJars + 1
  531.       elseif (aspectCount == 0) then
  532.         myEmptyJars = myEmptyJars + 1
  533.         myTotalJars = myTotalJars + 1
  534.       end
  535.     end
  536.   end
  537.  
  538.   emptyJars = myEmptyJars
  539.   totalJars = myTotalJars
  540.  
  541.   return jars
  542. end
  543.  
  544. function updateEssentia()
  545.   local myJars
  546.   local myEssentia
  547.   local i, j
  548.  
  549.   myJars = scanJars()
  550.   myEssentia = essentiaList()
  551.  
  552.   for i in pairs(myJars) do
  553.     myEssentia[myJars[i]["aspect"]] = myEssentia[myJars[i]["aspect"]] + myJars[i]["count"]
  554.   end
  555.  
  556.   for i,j in sortEss(myEssentia) do
  557.     if (essentia[i] ~= j) then
  558.       essentia[i] = j
  559.     end
  560.   end
  561. end
  562.  
  563. function printEssentia()
  564.   local inactiveTextColor
  565.   local buttonName
  566.   local x, y
  567.   local i, j
  568.  
  569.   x = essentiaX
  570.   y = essentiaY
  571.  
  572.   for i,j in sortEss(essentia) do
  573.     inactiveTextColor = getEssentiaColor(j)
  574.    
  575.     buttonName = i .. string.sub(padding, 1, essentiaColumnWidth - (string.len(i) + string.len(pad(j)))) .. pad(j)
  576.     button.addButton(buttonName, essentiaButton, buttonName, x, y, essentiaColumnWidth, 0, essentiaInactiveBackColor, essentiaActiveBackColor, inactiveTextColor, essentiaActiveTextColor)
  577.    
  578.     if (y < (essentiaY + essentiaColumnHeight - 1)) then
  579.       y = y + 1
  580.     else
  581.       y = essentiaY
  582.       x = x + essentiaColumnWidth + essentiaColumnSpacing
  583.     end
  584.   end
  585. end
  586.  
  587. function getEssentiaColor(currentEssentiaAmount)
  588.   local myColor
  589.  
  590.   if (currentEssentiaAmount == 0) then
  591.     myColor = essentiaInactiveTextColorEmpty
  592.   elseif (currentEssentiaAmount <= 20) then
  593.     myColor = essentiaInactiveTextColorLow
  594.   elseif (currentEssentiaAmount < 100 and currentEssentiaAmount > 20) then
  595.     myColor = essentiaInactiveTextColorMedium
  596.   else
  597.     myColor = essentiaInactiveTextColorHigh
  598.   end
  599.  
  600.   return myColor
  601. end
  602.  
  603. function printEmptyJars()
  604.   m.setTextColor(emptyJarsTextColor)
  605.   m.setBackgroundColor(emptyJarsBackColor)
  606.  
  607.   m.setCursorPos(emptyJarsX, emptyJarsY)
  608.   m.write("Empty jars:" .. string.sub(padding, 1, essentiaColumnWidth - (string.len("Empty jars:") + string.len(pad(emptyJars))) - 1) .. pad(emptyJars))
  609. end
  610.  
  611. function printTotalJars()
  612.   m.setTextColor(totalJarsTextColor)
  613.   m.setBackgroundColor(totalJarsBackColor)
  614.  
  615.   m.setCursorPos(totalJarsX, totalJarsY)
  616.   m.write("Total jars:" .. string.sub(padding, 1, essentiaColumnWidth - (string.len("Total jars:") + string.len(pad(totalJars))) - 1) .. pad(totalJars))
  617. end
  618.  
  619. function pad(number, amount)
  620.   local myPadding = "000000"
  621.   local paddingRequired = 0
  622.  
  623.   if not (amount) then
  624.     amount = numberPadding
  625.   end
  626.  
  627.   paddingRequired = amount - string.len(tostring(number))
  628.  
  629.   if (paddingRequired ~= 0 and paddingRequired > 0) then
  630.     return string.sub(myPadding, 1, paddingRequired) .. tostring(number)
  631.   end
  632.  
  633.   return tostring(number)
  634. end
  635.  
  636. function getClick()
  637.   local event
  638.   local side
  639.   local x,y
  640.  
  641.   event,side,x,y = os.pullEvent()
  642.  
  643.   if (event == "monitor_touch") then
  644.     button.checkxy(x,y)
  645.   end
  646. end
  647.  
  648. function refresh(buttonToFlash)
  649.   -- Flash the refresh button
  650.   if (buttonToFlash) then
  651.     button.flash(buttonToFlash)
  652.   end
  653.  
  654.   -- Clear the screen and button list
  655.   m.setBackgroundColor(monBackColor)
  656.   m.clear()
  657.   button.clear()
  658.  
  659.   -- Scan and print the essentias
  660.   updateEssentia()
  661.   printEssentia()
  662.  
  663.   -- Print the number of empty jars
  664.   printEmptyJars()
  665.  
  666.   -- Print the number of jars
  667.   printTotalJars()
  668.  
  669.   -- Create the refresh button
  670.   addRefreshButton()
  671.  
  672.   -- Create the top off all jars button
  673.   addTopoffAllJarsButton()
  674.  
  675.   -- Create the fill all to 64 button
  676.   addFillAllTo64Button()
  677.  
  678.   -- Create the fill all to 128 button
  679.   addFillAllTo128Button()
  680.  
  681.   -- Create the other button
  682.   addOtherOptionsButton()
  683.  
  684.   -- Draw all the buttons on the screen
  685.   button.drawButtons()
  686. end
  687.  
  688. function addRefreshButton()
  689.   button.addButton("Refresh", refresh, "Refresh", refreshButtonX, refreshButtonY, refreshButtonWidth, refreshButtonHeight, refreshInactiveBackColor, refreshActiveBackColor, refreshInactiveTextColor, refreshActiveTextColor)
  690. end
  691.  
  692. function addTopoffAllJarsButton()
  693.   button.addButton("Top off all jars", topoffAllJars, "Top off all jars", topoffAllButtonX, topoffAllButtonY, topoffAllButtonWidth, topoffAllButtonHeight, topoffAllJarsInactiveBackColor, topoffAllJarsActiveBackColor, topoffAllJarsInactiveTextColor, topoffAllJarsActiveTextColor)
  694. end
  695.  
  696. function addFillAllTo64Button()
  697.   button.addButton("Fill all to 64", fillAllTo64, "Fill all to 64", fillAllTo64ButtonX, fillAllTo64ButtonY, fillAllTo64ButtonWidth, fillAllTo64ButtonHeight, fillAllTo64InactiveBackColor, fillAllTo64ActiveBackColor, fillAllTo64InactiveTextColor, fillAllTo64ActiveTextColor)
  698. end
  699.  
  700. function addFillAllTo128Button()
  701.   button.addButton("Fill all to 128", fillAllTo128, "Fill all to 128", fillAllTo128ButtonX, fillAllTo128ButtonY, fillAllTo128ButtonWidth, fillAllTo128ButtonHeight, fillAllTo128InactiveBackColor, fillAllTo128ActiveBackColor, fillAllTo128InactiveTextColor, fillAllTo128ActiveTextColor)
  702. end
  703.  
  704. function addOtherOptionsButton()
  705.   button.addButton("Reboot", otherOptions, "Reboot", otherOptionsButtonX, otherOptionsButtonY, otherOptionsButtonWidth, otherOptionsButtonHeight, otherOptionsButtonInactiveBackColor, otherOptionsButtonActiveBackColor, otherOptionsButtonInactiveTextColor, otherOptionsButtonActiveTextColor)
  706. end
  707.  
  708. function otherOptions(buttonName)
  709.   button.flash(buttonName)
  710.   os.reboot()
  711. end
  712.  
  713. function fillAllTo64(buttonName)
  714.   local aspect
  715.   local count
  716.   local essentiaToFill
  717.   local haveEssentiaToFill
  718.   local myEmptyJars
  719.  
  720.   -- The button is erased if jars to top off are found else it's toggled back below.
  721.   button.toggleButton(buttonName, true)
  722.   sleep(.15)
  723.  
  724.   essentiaToFill = essentiaList()
  725.   myEmptyJars = emptyJars
  726.   haveEssentiaToFill = false
  727.  
  728.   -- Update the list of essentias in all jars
  729.   updateEssentia()
  730.  
  731.   -- Checks each jar to see if any of them aren't full.
  732.   for aspect,count in pairs(essentia) do
  733.     if (count < 64) then
  734.       if (count == 0) then
  735.         myEmptyJars = myEmptyJars - 1
  736.       end
  737.      
  738.       essentiaToFill[aspect] = 64 - count
  739.       haveEssentiaToFill = true
  740.     end
  741.   end
  742.  
  743.   if (haveEssentiaToFill == true) then
  744.     -- Not all essentia is at 64 or more, display the found essentias and confirm filling.
  745.     showFillAllTo64(essentiaToFill, myEmptyJars)
  746.   else
  747.     -- 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.
  748.     button.renameButton(buttonName, "All jars at 64", true)
  749.     sleep(2.5)
  750.     button.toggleButton("All jars at 64", false)
  751.     button.renameButton("All jars at 64", buttonName, true)
  752.   end
  753. end
  754.  
  755. function showFillAllTo64(essentiaList, emptyJarsAfterFill)
  756.   local x, y
  757.   local myEssentia
  758.   local amount
  759.   local errorText
  760.  
  761.   fillAllTo64EssentiaList = essentiaList
  762.  
  763.   -- Clear the screen and button list
  764.   m.setBackgroundColor(monBackColor)
  765.   m.clear()
  766.   button.clear()
  767.  
  768.   x = essentiaFillAllTo64X
  769.   y = essentiaFillAllTo64Y
  770.  
  771.   m.setBackgroundColor(fillAllTo64EssentiaLabelBackColor)
  772.   m.setTextColor(fillAllTo64EssentiaLabelTextColor)
  773.  
  774.   m.setCursorPos(essentiaFillAllTo64LabelX, essentiaFillAllTo64LabelY)
  775.   m.write("Fill all jars to 64 request")
  776.  
  777.   m.setBackgroundColor(fillAllTo64EssentiaBackColor)
  778.  
  779.   for myEssentia,amount in sortEss(essentiaList) do
  780.     if (amount == 0) then
  781.       m.setTextColor(fillAllTo64EssentiaTextColorZero)
  782.     else
  783.       m.setTextColor(fillAllTo64EssentiaTextColorNonZero)
  784.     end
  785.    
  786.     m.setCursorPos(x, y)
  787.     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))
  788.    
  789.     if (y < (essentiaFillAllTo64Y + essentiaColumnHeight - 1)) then
  790.       y = y + 1
  791.     else
  792.       y = essentiaFillAllTo64Y
  793.       x = x + essentiaColumnWidth + essentiaColumnSpacing
  794.     end
  795.   end
  796.  
  797.   button.addButton("Cancel filling", cancelFillAllTo64Button, "Cancel filling", cancelFillAllTo64ButtonX, cancelFillAllTo64ButtonY, cancelFillAllTo64ButtonWidth, cancelFillAllTo64ButtonHeight, cancelFillAllTo64ButtonInactiveBackColor, cancelFillAllTo64ButtonActiveBackColor, cancelFillAllTo64ButtonInactiveTextColor, cancelFillAllTo64ButtonActiveTextColor)
  798.   button.addButton("Begin filling", beginFillAllTo64Button, "Begin filling", beginFillAllTo64ButtonX, beginFillAllTo64ButtonY, beginFillAllTo64ButtonWidth, beginFillAllTo64ButtonHeight, beginFillAllTo64ButtonInactiveBackColor, beginFillAllTo64ButtonActiveBackColor, beginFillAllTo64ButtonInactiveTextColor, beginFillAllTo64ButtonActiveTextColor)
  799.  
  800.   if (emptyJarsAfterFill < 0) then
  801.     errorText = "NOT ENOUGH EMPTY JARS; HAVE " .. emptyJars .. " NEED "  .. (emptyJars - emptyJarsAfterFill)
  802.     m.setCursorPos(essentiaFillAllTo64LabelX + math.floor(string.len("Fill all jars to 64 request") / 2) - math.floor(string.len(errorText) / 2), essentiaFillAllTo64LabelY + 1)
  803.     m.setTextColor(colors.red)
  804.     m.write(errorText)
  805.     button.disableButton("Begin filling")
  806.   end
  807.  
  808.   button.drawButtons()
  809. end
  810.  
  811. function fillAllTo128(buttonName)
  812.   local aspect
  813.   local count
  814.   local essentiaToFill
  815.   local haveEssentiaToFill
  816.   local myEmptyJars
  817.   local myJars
  818.   local jar
  819.   local essentiaJarCount
  820.  
  821.   -- The button is erased if jars to top off are found else it's toggled back below.
  822.   button.toggleButton(buttonName, true)
  823.   sleep(.15)
  824.  
  825.   essentiaToFill = essentiaList()
  826.   essentiaJarCount = essentiaList()
  827.   myJars = scanJars()
  828.   myEmptyJars = emptyJars
  829.   haveEssentiaToFill = false
  830.  
  831.   -- Count how many jars of each aspect exist
  832.   for jar in pairs(myJars) do
  833.     essentiaJarCount[myJars[jar]["aspect"]] = essentiaJarCount[myJars[jar]["aspect"]] + 1
  834.   end
  835.  
  836.   -- Update the list of essentias in all jars
  837.   updateEssentia()
  838.  
  839.   -- Checks each jar to see if any of them aren't full.
  840.   for aspect,count in pairs(essentia) do
  841.     if (count < 128) then
  842.       if (count == 0) then
  843.         myEmptyJars = myEmptyJars - 2
  844.       else
  845.         if (essentiaJarCount[aspect] == 1) then
  846.           if (count <= 64) then -- if it's above 64 the jar is probably an advanced thaumaturgy jar that holds 256
  847.             myEmptyJars = myEmptyJars - 1
  848.           end
  849.         end
  850.       end
  851.      
  852.       essentiaToFill[aspect] = 128 - count
  853.       haveEssentiaToFill = true
  854.     end
  855.   end
  856.  
  857.   if (haveEssentiaToFill == true) then
  858.     -- Jars have been found that aren't full, display the found jars and confirm filling.
  859.     showFillAllTo128(essentiaToFill, myEmptyJars)
  860.   else
  861.     -- 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.
  862.     button.renameButton(buttonName, "All jars at 128", true)
  863.     sleep(2.5)
  864.     button.toggleButton("All jars at 128", false)
  865.     button.renameButton("All jars at 128", buttonName, true)
  866.   end
  867. end
  868.  
  869. function showFillAllTo128(essentiaList, emptyJarsAfterFill)
  870.   local x, y
  871.   local myEssentia
  872.   local amount
  873.   local errorText
  874.  
  875.   fillAllTo128EssentiaList = essentiaList
  876.  
  877.   -- Clear the screen and button list
  878.   m.setBackgroundColor(monBackColor)
  879.   m.clear()
  880.   button.clear()
  881.  
  882.   x = essentiaFillAllTo128X
  883.   y = essentiaFillAllTo128Y
  884.  
  885.   m.setBackgroundColor(fillAllTo128EssentiaLabelBackColor)
  886.   m.setTextColor(fillAllTo128EssentiaLabelTextColor)
  887.   m.setCursorPos(essentiaFillAllTo128LabelX, essentiaFillAllTo128LabelY)
  888.   m.write("Fill all jars to 128 request")
  889.  
  890.   m.setBackgroundColor(fillAllTo128EssentiaBackColor)
  891.  
  892.   for myEssentia,amount in sortEss(essentiaList) do
  893.     if (amount == 0) then
  894.       m.setTextColor(fillAllTo128EssentiaTextColorZero)
  895.     else
  896.       m.setTextColor(fillAllTo128EssentiaTextColorNonZero)
  897.     end
  898.    
  899.     m.setCursorPos(x, y)
  900.     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))
  901.    
  902.     if (y < (essentiaFillAllTo128Y + essentiaColumnHeight - 1)) then
  903.       y = y + 1
  904.     else
  905.       y = essentiaFillAllTo128Y
  906.       x = x + essentiaColumnWidth + essentiaColumnSpacing
  907.     end
  908.   end
  909.  
  910.   button.addButton("Cancel filling", cancelFillAllTo128Button, "Cancel filling", cancelFillAllTo128ButtonX, cancelFillAllTo128ButtonY, cancelFillAllTo128ButtonWidth, cancelFillAllTo128ButtonHeight, cancelFillAllTo128ButtonInactiveBackColor, cancelFillAllTo128ButtonActiveBackColor, cancelFillAllTo128ButtonInactiveTextColor, cancelFillAllTo128ButtonActiveTextColor)
  911.   button.addButton("Begin filling", beginFillAllTo128Button, "Begin filling", beginFillAllTo128ButtonX, beginFillAllTo128ButtonY, beginFillAllTo128ButtonWidth, beginFillAllTo128ButtonHeight, beginFillAllTo128ButtonInactiveBackColor, beginFillAllTo128ButtonActiveBackColor, beginFillAllTo128ButtonInactiveTextColor, beginFillAllTo128ButtonActiveTextColor)
  912.  
  913.   if (emptyJarsAfterFill < 0) then
  914.     errorText = "NOT ENOUGH EMPTY JARS; HAVE " .. emptyJars .. " NEED "  .. (emptyJars - emptyJarsAfterFill)
  915.    
  916.     m.setCursorPos(essentiaFillAllTo128LabelX + math.floor(string.len("Fill all jars to 128 request") / 2) - math.floor(string.len(errorText) / 2), essentiaFillAllTo128LabelY + 1)
  917.     m.setTextColor(colors.red)
  918.     m.write(errorText)
  919.     button.disableButton("Begin filling")
  920.   end
  921.  
  922.   button.drawButtons()
  923. end
  924.  
  925. function topoffAllJars(buttonName)
  926.   local myJars
  927.   local jar
  928.   local essentiaToFill
  929.   local haveEssentiaToFill
  930.  
  931.   -- The button is erased if jars to top off are found else it's toggled back below.
  932.   button.toggleButton(buttonName, true)
  933.   sleep(.15)
  934.  
  935.   -- Get a table of all the essentia jars
  936.   myJars = scanJars()
  937.   essentiaToFill = essentiaList()
  938.   haveEssentiaToFill = false
  939.  
  940.   -- Checks each jar to see if any of them aren't full.
  941.   for jar in pairs(myJars) do
  942.     if (myJars[jar]["count"] < 64) then
  943.       essentiaToFill[myJars[jar]["aspect"]] = essentiaToFill[myJars[jar]["aspect"]] + (64 - myJars[jar]["count"])
  944.       haveEssentiaToFill = true
  945.     elseif (myJars[jar]["count"] > 64) then -- Advanced Thaumaturgy jars hold 256
  946.       essentiaToFill[myJars[jar]["aspect"]] = essentiaToFill[myJars[jar]["aspect"]] + (256 - myJars[jar]["count"])
  947.       haveEssentiaToFill = true
  948.     end
  949.   end
  950.  
  951.   if (haveEssentiaToFill == true) then
  952.     -- Jars have been found that aren't full, display the found jars and confirm filling.
  953.     showTopOffAllJars(essentiaToFill)
  954.   else
  955.     -- 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.
  956.     button.renameButton(buttonName, "All jars full", true)
  957.     sleep(2.5)
  958.     button.toggleButton("All jars full", false)
  959.     button.renameButton("All jars full", buttonName, true)
  960.   end
  961. end
  962.  
  963. function showTopOffAllJars(essentiaList)
  964.   local x, y
  965.   local myEssentia
  966.   local essentiaText
  967.   local amount
  968.  
  969.   topOffJarsEssentiaList = essentiaList
  970.  
  971.   -- Clear the screen and button list
  972.   m.setBackgroundColor(monBackColor)
  973.   m.clear()
  974.   button.clear()
  975.  
  976.   x = essentiaTopOffJarsX
  977.   y = essentiaTopOffJarsY
  978.  
  979.   m.setBackgroundColor(topOffAllJarsEssentiaLabelBackColor)
  980.   m.setTextColor(topOffAllJarsEssentiaLabelTextColor)
  981.   m.setCursorPos(essentiaTopOffLabelX, essentiaTopOffLabelY)
  982.   m.write("Top off jars fill request")
  983.  
  984.   m.setBackgroundColor(topOffAllJarsEssentiaBackColor)
  985.  
  986.   for myEssentia,amount in sortEss(essentiaList) do
  987.     if (amount == 0) then
  988.       m.setTextColor(topOffAllJarsEssentiaTextColorZero)
  989.     else
  990.       m.setTextColor(topOffAllJarsEssentiaTextColorNonZero)
  991.     end
  992.    
  993.     m.setCursorPos(x, y)
  994.     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))
  995.    
  996.     if (y < (essentiaTopOffJarsY + essentiaColumnHeight - 1)) then
  997.       y = y + 1
  998.     else
  999.       y = essentiaTopOffJarsY
  1000.       x = x + essentiaColumnWidth + essentiaColumnSpacing
  1001.     end
  1002.   end
  1003.  
  1004.   button.addButton("Cancel filling", cancelTopOffJarsButton, "Cancel filling", cancelTopOffJarsButtonX, cancelTopOffJarsButtonY, cancelTopOffJarsButtonWidth, cancelTopOffJarsButtonHeight, cancelTopOffJarsButtonInactiveBackColor, cancelTopOffJarsButtonActiveBackColor, cancelTopOffJarsButtonInactiveTextColor, cancelTopOffJarsButtonActiveTextColor)
  1005.   button.addButton("Begin filling", beginTopOffJarsFillButton, "Begin filling", beginTopOffJarsFillButtonX, beginTopOffJarsFillButtonY, beginTopOffJarsFillButtonWidth, beginTopOffJarsFillButtonHeight, beginTopOffJarsFillButtonInactiveBackColor, beginTopOffJarsFillButtonActiveBackColor, beginTopOffJarsFillButtonInactiveTextColor, beginTopOffJarsFillButtonActiveTextColor)
  1006.  
  1007.   button.drawButtons()
  1008. end
  1009.  
  1010. function cancelTopOffJarsButton(buttonName)
  1011.   button.flash(buttonName)
  1012.   topOffJarsEssentiaList = nil
  1013.   refresh()
  1014. end
  1015.  
  1016. function beginTopOffJarsFillButton(buttonName)
  1017.   local beanType
  1018.   local amountToBurn
  1019.   local burnCount
  1020.  
  1021.   button.flash(buttonName)
  1022.  
  1023.   drawBurnMainScreen()
  1024.   allBurnResults = {}
  1025.   for beanType,amountToBurn in sortEss(topOffJarsEssentiaList) do
  1026.     if (amountToBurn ~= 0) then
  1027.       updateBurnBeanType(beanType)
  1028.       burnCount = burnBeans(beanType, amountToBurn)
  1029.      
  1030.      
  1031.       print("")
  1032.       print(beanType)
  1033.       print("Burned: " .. burnCount)
  1034.      
  1035.       if (burnCount == -100) then
  1036.         print(translateBurnResultToText(burnCount))
  1037.         break
  1038.       end
  1039.     end
  1040.   end
  1041.  
  1042.   refresh()
  1043. end
  1044.  
  1045. function cancelFillAllTo64Button(buttonName)
  1046.   button.flash(buttonName)
  1047.   fillAllTo64EssentiaList = nil
  1048.   refresh()
  1049. end
  1050.  
  1051. function beginFillAllTo64Button(buttonName)
  1052.   local beanType
  1053.   local amountToBurn
  1054.   local burnCount
  1055.  
  1056.   button.flash(buttonName)
  1057.  
  1058.   drawBurnMainScreen()
  1059.   allBurnResults = {}
  1060.   for beanType,amountToBurn in sortEss(fillAllTo64EssentiaList) do
  1061.     if (amountToBurn ~= 0) then
  1062.       updateBurnBeanType(beanType)
  1063.       burnCount = burnBeans(beanType, amountToBurn)
  1064.      
  1065.      
  1066.       print("")
  1067.       print(beanType)
  1068.       print("Burned: " .. burnCount)
  1069.      
  1070.       if (burnCount == -100) then
  1071.         print(translateBurnResultToText(burnCount))
  1072.         break
  1073.       end
  1074.     end
  1075.   end
  1076.  
  1077.   refresh()
  1078. end
  1079.  
  1080. function cancelFillAllTo128Button(buttonName)
  1081.   button.flash(buttonName)
  1082.   fillAllTo128EssentiaList = nil
  1083.   refresh()
  1084. end
  1085.  
  1086. function beginFillAllTo128Button(buttonName)
  1087.   local beanType
  1088.   local amountToBurn
  1089.   local burnCount
  1090.   local bk, bv
  1091.  
  1092.   button.flash(buttonName)
  1093.  
  1094.   drawBurnMainScreen()
  1095.   for beanType,amountToBurn in sortEss(fillAllTo128EssentiaList) do
  1096.     if (amountToBurn ~= 0) then
  1097.       updateBurnBeanType(beanType)
  1098.       burnCount = burnBeans(beanType, amountToBurn)
  1099.      
  1100.       print("")
  1101.       print(beanType)
  1102.       print("Burned: " .. burnCount)
  1103.      
  1104.       if (burnCount == -100) then
  1105.         print(translateBurnResultToText(burnCount))
  1106.         break
  1107.       end
  1108.     end
  1109.   end
  1110.  
  1111.   refresh()
  1112. end
  1113.  
  1114. function essentiaButton(which)
  1115.   local buttonEssentiaName
  1116.   local availableEssentiaSpace = 0
  1117.   local myJars
  1118.   local essentiaCount = 0
  1119.   local i
  1120.  
  1121.   myJars = scanJars()
  1122.   button.flash(which)
  1123.   buttonEssentiaName = string.sub(which, 1, string.find(which, " ") - 1)
  1124.  
  1125.   for i in pairs(myJars) do
  1126.     if (myJars[i]["aspect"] == buttonEssentiaName) then
  1127.       availableEssentiaSpace = availableEssentiaSpace + (64 - myJars[i]["count"])
  1128.       essentiaCount = essentiaCount + myJars[i]["count"]
  1129.     end
  1130.   end
  1131.  
  1132.   showRefillEssentia(buttonEssentiaName, essentiaCount, availableEssentiaSpace)
  1133. end
  1134.  
  1135. function showRefillEssentia(essentiaName, essentiaCount, availableEssentiaSpace)
  1136.   local fillingText
  1137.  
  1138.   fillEssentia =  essentiaName
  1139.   fillCurrentAmount = essentiaCount
  1140.   fillAmount = 0
  1141.   fillAvailableSpace = availableEssentiaSpace
  1142.  
  1143.   button.clear()
  1144.   m.setBackgroundColor(monBackColor)
  1145.   m.clear()
  1146.  
  1147.   m.setTextColor(refillLabelTextColor)
  1148.   fillingText = "Refilling: " .. string.upper(string.sub(fillEssentia, 1, 1)) .. string.sub(fillEssentia, 2)
  1149.   m.setCursorPos(refillScreenX + math.floor((41 - string.len(fillingText)) / 2), refillScreenY)
  1150.   m.write(fillingText)
  1151.  
  1152.   if (fillAvailableSpace == 0 and emptyJars == 0) then
  1153.     m.setCursorPos(refillScreenX + math.floor((41 - string.len("ALL JARS USED OR FULL")) / 2), refillScreenY + 1)
  1154.     m.setTextColor(colors.red)
  1155.     m.write("ALL JARS USED OR FULL")
  1156.   end
  1157.  
  1158.  
  1159.   m.setTextColor(refillCurrentAmountTextColor)
  1160.   m.setCursorPos(refillScreenX, refillScreenY + 2)
  1161.   m.write("Currently contains:" .. string.sub(padding, 1, 41 - (string.len("Currently contains:") + string.len(pad(fillCurrentAmount)))) .. pad(fillCurrentAmount))
  1162.  
  1163.   m.setTextColor(refillAddingAmountTextColor)
  1164.   m.setCursorPos(refillScreenX, refillScreenY + 3)
  1165.   m.write("Currently adding:" .. string.sub(padding, 1, 41 - (string.len("Currently adding:") + string.len(pad(fillAmount)))) .. pad(fillAmount))
  1166.  
  1167.   m.setTextColor(getEssentiaColor(fillCurrentAmount))
  1168.   m.setCursorPos(refillScreenX, refillScreenY + 4)
  1169.   m.write("Total after filling:" .. string.sub(padding, 1, 41 - (string.len("Total after filling:") + string.len(pad(fillCurrentAmount)))) .. pad(fillCurrentAmount))
  1170.  
  1171.   button.addButton("+1", addEssentia, "+1", refillScreenX, refillScreenY + 6, 10, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1172.   button.addButton("+5", addEssentia, "+5", refillScreenX + 11, refillScreenY + 6, 9, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1173.   button.addButton("+10", addEssentia, "+10", refillScreenX + 21, refillScreenY + 6, 9, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1174.   button.addButton("+64", addEssentia, "+64", refillScreenX + 31, refillScreenY + 6, 10, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1175.  
  1176.   button.addButton("-1", addEssentia, "-1", refillScreenX, refillScreenY + 10, 10, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1177.   button.addButton("-5", addEssentia, "-5", refillScreenX + 11, refillScreenY + 10, 9, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1178.   button.addButton("-10", addEssentia, "-10", refillScreenX + 21, refillScreenY + 10, 9, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1179.   button.addButton("-64", addEssentia, "-64", refillScreenX + 31, refillScreenY + 10, 10, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1180.  
  1181.   button.addButton("Top off jar(s)", addEssentia, "Top off jar(s)", refillScreenX, refillScreenY + 14, 20, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1182.   button.addButton("Max fill", addEssentia, "Max fill", refillScreenX + 21, refillScreenY + 14, 20, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1183.  
  1184.   button.addButton("Cancel filling", refresh, "Cancel filling", refillScreenX, refillScreenY + 18, 41, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1185.  
  1186.   button.addButton("Begin filling", buttonBeginRefill, "Begin filling", refillScreenX, refillScreenY + 22, 41, 2, refillButtonsInactiveBackColor, refillButtonsActiveBackColor, refillButtonsInactiveTextColor, refillButtonsActiveTextColor)
  1187.  
  1188.   button.drawButtons()
  1189. end
  1190.  
  1191. function addEssentia(amount)
  1192.   local myFillAmount
  1193.  
  1194.   myFillAmount = fillAmount
  1195.  
  1196.   --print(fillAmount .. " before")
  1197.  
  1198.   button.flash(amount)
  1199.  
  1200.   if (amount == "Top off jar(s)") then
  1201.     fillAmount = fillAvailableSpace
  1202.   elseif (amount == "Max fill") then
  1203.     fillAmount = fillAvailableSpace + (emptyJars * 64)
  1204.   else
  1205.     fillAmount = fillAmount + tonumber(amount)
  1206.   end
  1207.  
  1208.   if (fillAmount < 0) then
  1209.     --print(fillAmount .. " is less than 0 - setting to 0")
  1210.     fillAmount = 0
  1211.   elseif (fillAmount > fillAvailableSpace) then
  1212.     if (emptyJars > 0) then
  1213.       if (fillAmount > (fillAvailableSpace + (emptyJars * 64))) then
  1214.         fillAmount = fillAvailableSpace + (emptyJars * 64)
  1215.       end
  1216.     else
  1217.       fillAmount = fillAvailableSpace
  1218.     end
  1219.   end
  1220.  
  1221.   if (fillAmount ~= myFillAmount) then
  1222.     m.setBackgroundColor(monBackColor)
  1223.    
  1224.     m.setTextColor(refillAddingAmountTextColor)
  1225.     m.setCursorPos(refillScreenX, refillScreenY + 3)
  1226.     m.write("Currently adding:" .. string.sub(padding, 1, 41 - (string.len("Currently adding:") + string.len(pad(fillAmount)))) .. pad(fillAmount))
  1227.    
  1228.     m.setTextColor(getEssentiaColor(fillCurrentAmount + fillAmount))
  1229.     m.setCursorPos(refillScreenX, refillScreenY + 4)
  1230.     m.write("Total after filling:" .. string.sub(padding, 1, 41 - (string.len("Total after filling:") + string.len(pad(fillCurrentAmount + fillAmount)))) .. pad(fillCurrentAmount + fillAmount))
  1231.   end
  1232. end
  1233.  
  1234. -- Standard refill button
  1235. function buttonBeginRefill(buttonName)
  1236.   local burnCount
  1237.  
  1238.   button.flash(buttonName)
  1239.  
  1240.   if (fillAmount ~= 0) then
  1241.     drawBurnMainScreen()
  1242.     updateBurnBeanType(fillEssentia)
  1243.     burnCount = burnBeans(fillEssentia, fillAmount)
  1244.    
  1245.     print("")
  1246.     print("Burned: " .. burnCount)
  1247.    
  1248.     print(translateBurnResultToText(burnCount))
  1249.   end
  1250.  
  1251.   refresh()
  1252. end
  1253.  
  1254. function translateBurnResultToText(burnResult)
  1255.   if (burnResult == -100) then
  1256.     return "Aborted"
  1257.   end
  1258. end
  1259.  
  1260. maximumLength = 0
  1261.  
  1262. function updateBurnStatus(newStatus)
  1263.   local monWidth, monHeight
  1264.   local pos
  1265.   local writeWidth
  1266.   local y
  1267.  
  1268.   monWidth, monHeight = m.getSize()
  1269.   writeWidth = monWidth - 10
  1270.   pos = 1
  1271.  
  1272.   for y = 0, 3 do
  1273.     m.setCursorPos(burnScreenStatusX, y + burnScreenStatusY + 2)
  1274.     m.write(string.sub(padding, 1, writeWidth))
  1275.     m.setCursorPos(burnScreenStatusX, y + burnScreenStatusY + 2)
  1276.     m.write(string.sub(newStatus, pos, writeWidth + pos - 1))
  1277.     pos = pos + writeWidth
  1278.   end
  1279. end
  1280.  
  1281. function updateBurnBeanType(newBean)
  1282.   m.setCursorPos(burnScreenBeanLabelX + string.len(burnScreenBeanTextLabel) + 1, burnScreenBeanLabelY)
  1283.   m.write(string.upper(string.sub(newBean, 1, 1)) .. string.sub(newBean, 2) .. string.sub(padding, 1, 15 - string.len(newBean)))
  1284. end
  1285.  
  1286. function drawBurnMainScreen()
  1287.   local monWidth
  1288.   local monHeight
  1289.   local x, y
  1290.  
  1291.   -- Clears the screen before creating the information burn screen
  1292.   button.clear()
  1293.   m.setBackgroundColor(monBackColor)
  1294.   m.clear()
  1295.  
  1296.   -- Draws the border on the screen
  1297.   monWidth,monHeight = m.getSize()
  1298.   m.setBackgroundColor(burnScreenBorderColor)
  1299.  
  1300.   m.setCursorPos(1, 1)
  1301.   m.write(string.sub(padding, 1, monWidth))
  1302.   m.setCursorPos(1, monHeight)
  1303.   m.write(string.sub(padding, 1, monWidth))
  1304.  
  1305.   for y = 0, monHeight do
  1306.     m.setCursorPos(1, y)
  1307.     m.write("  ")
  1308.     m.setCursorPos(monWidth - 1, y)
  1309.     m.write("  ")
  1310.   end
  1311.  
  1312.   -- Draws the label text
  1313.   m.setBackgroundColor(burnScreenLabelBackColor)
  1314.   m.setTextColor(burnScreenLabelTextColor)
  1315.   m.setCursorPos(burnScreenLabelX, burnScreenLabelY)
  1316.   m.write("Burn request information")
  1317.  
  1318.   m.setBackgroundColor(burnScreenBeanLabelBackColor)
  1319.   m.setTextColor(burnScreenBeanLabelTextColor)
  1320.   m.setCursorPos(burnScreenBeanLabelX, burnScreenBeanLabelY)
  1321.   m.write(burnScreenBeanTextLabel)
  1322.  
  1323.   m.setBackgroundColor(burnScreenBeanLabelBackColor)
  1324.   m.setTextColor(burnScreenBeanLabelTextColor)
  1325.   m.setCursorPos(burnScreenStatusX, burnScreenStatusY)
  1326.   m.write(burnScreenStatusTextLabel)
  1327. end
  1328.  
  1329.  
  1330.  
  1331.  
  1332.  
  1333.  
  1334.  
  1335.  
  1336.  
  1337.  
  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.   The functions below are used to track mana beans in connected chests and put them in the alchemical furnaces.
  1394.  
  1395. --]]
  1396.  
  1397. function executeBurn(chest, beanType, amount, returnIfStuck)
  1398.   local amountBurned
  1399.   local stack
  1400.   local slot
  1401.   local direction
  1402.   local directions
  1403.   local aspect
  1404.   local count
  1405.   local validBeanCount
  1406.   local waitingForBeans
  1407.   local amountToBurn
  1408.   local waitingForFurnace
  1409.  
  1410.   -- No beans for this type have ever been found.
  1411.   if (chests[chest][beanType] == nil) then
  1412.     return 0
  1413.   end
  1414.  
  1415.   if (returnIfStuck ~= false and returnIfStuck ~= true) then
  1416.     returnIfStuck = false
  1417.   end
  1418.  
  1419.   updateBurnStatus("attempting to burn beans")
  1420.  
  1421.   if (alchemicalFurnaceFromChestDirection == "auto") then
  1422.     directions = validFurnaceDirections()
  1423.   else
  1424.     directions = {[alchemicalFurnaceFromChestDirection] = true}
  1425.   end
  1426.  
  1427.   amountToBurn = amount
  1428.   waitingForBeans = 0
  1429.   waitingForFurnace = 0
  1430.  
  1431.   while (amountToBurn > 0) do
  1432.     amountBurned = 0
  1433.     for slot in pairs(chests[chest][beanType]) do
  1434.       stack = peripheral.call(chests[chest]["peripheral name"], "getStackInSlot", slot)
  1435.      
  1436.       if (stack ~= nil and stack.qty > 2) then
  1437.         count = amountToBurn - amountBurned
  1438.        
  1439.         if (count > (stack.qty - 2)) then
  1440.           count = stack.qty - 2
  1441.           waitingForBeans = 0
  1442.         end
  1443.       else
  1444.         count = 0
  1445.       end
  1446.      
  1447.       if (count ~= 0) then
  1448.         while (count > 0) do
  1449.           for direction in pairs(directions) do
  1450.             if (count > 0) then
  1451.               burned = peripheral.call(chests[chest]["peripheral name"], "pushItemIntoSlot", direction, slot, count, 1)
  1452.               count = count - burned
  1453.               amountBurned = amountBurned + burned
  1454.              
  1455.               if (burned ~= 0) then
  1456.                 waitingForFurnace = 0
  1457.               end
  1458.              
  1459.               sleep(serverFriendly)
  1460.             end
  1461.           end
  1462.          
  1463.           if (count > 0) then
  1464.             -- Failed to put all the beans into the attached furnace(s)
  1465.             if (waitingForFurnace == 1 and returnIfStuck == true) then
  1466.               return amount - (amountToBurn - amountBurned)
  1467.             elseif (waitingForFurnace == 0) then
  1468.               print("Furnace(s) full, waiting for furnace(s) to have room...")
  1469.               updateBurnStatus("furnace(s) full, waiting for them to have room")
  1470.             end
  1471.            
  1472.             waitingForFurnace = 1
  1473.             sleep(1)
  1474.           end
  1475.         end
  1476.       else
  1477.         sleep(serverFriendly)
  1478.       end
  1479.     end
  1480.    
  1481.     if (amountBurned == 0) then
  1482.       -- Out of beans
  1483.       if (waitingForBeans == 1 and returnIfStuck == true) then
  1484.         return amount - (amountToBurn - amountBurned)
  1485.       elseif (waitingForBeans == 0) then
  1486.         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...")
  1487.         updateBurnStatus("out of " .. beanType .. " in chest " .. chests[chest]["peripheral name"] .. " - waiting for refill")
  1488.       end
  1489.      
  1490.       waitingForBeans = 1
  1491.       --enableRefill()
  1492.       sleep(1)
  1493.       --disableRefill()
  1494.     else
  1495.       waitingForBeans = 0
  1496.     end
  1497.    
  1498.     amountToBurn = amountToBurn - amountBurned
  1499.   end
  1500.  
  1501.   -- This should always calculate to amount but just in case it doesn't, it's not set static.
  1502.   return (amount - amountToBurn)
  1503. end
  1504.  
  1505. function validFurnaceDirections()
  1506.   return {["north"] = true, ["south"] = true, ["east"] = true, ["west"] = true}
  1507. end
  1508.  
  1509. function burnBeans(beanType, amount)
  1510.   local remainingAmount
  1511.   local ci
  1512.   local continue
  1513.   local amountBurned
  1514.   local amountToBurn
  1515.   local chestsWithAspect
  1516.  
  1517.   amountBurned = 0
  1518.   remainingAmount = amount
  1519.   chestsWithAspect = {}
  1520.   chestsBurnResult = {}
  1521.  
  1522.   if (chestAspects[beanType] == 0) then
  1523.     -- No chests contain the bean type
  1524.     return 0, nil
  1525.   else
  1526.     for ci in pairs(chests) do
  1527.       if (chests[ci][beanType] ~= nil) then
  1528.         chestsWithAspect[ci] = true
  1529.       end
  1530.     end
  1531.    
  1532.     if (distributeBurnRequests == true) then
  1533.       continue = true
  1534.      
  1535.       while (continue) do
  1536.         for ci in pairs(chestsWithAspect) do
  1537.           if (rs.getInput("left") == true) then
  1538.             return -100
  1539.           end
  1540.           amountToBurn = 64
  1541.          
  1542.           if ((remainingAmount - amountToBurn) < 0) then
  1543.             amountToBurn = remainingAmount
  1544.           end
  1545.          
  1546.           amountBurned = executeBurn(ci, beanType, amountToBurn, true)
  1547.           remainingAmount = remainingAmount - amountBurned
  1548.          
  1549.           if (remainingAmount <= 0) then
  1550.             continue = false
  1551.             break
  1552.           end
  1553.         end
  1554.        
  1555.         if (continue == true) then
  1556.           sleep(5)
  1557.         end
  1558.       end
  1559.     else
  1560.       for ci in pairs(chestsWithAspect) do
  1561.         amountBurned = executeBurn(ci, beanType, remainingAmount)
  1562.        
  1563.         remainingAmount = remainingAmount - amountBurned
  1564.        
  1565.         if (remainingAmount <= 0) then
  1566.           break
  1567.         end
  1568.       end
  1569.     end
  1570.   end
  1571.  
  1572.   return (amount - remainingAmount)
  1573. end
  1574.  
  1575. function getValidChestNames()
  1576.   local chests = {
  1577.     ["container_chest"] = true,
  1578.     ["iron"] = true,
  1579.     ["gold"] = true,
  1580.     ["diamond"] = true,
  1581.     ["crystal"] = true,
  1582.     ["obsidian"] = true,
  1583.     ["copper"] = true,
  1584.     ["silver"] = true
  1585.     }
  1586.  
  1587.   return chests
  1588. end
  1589.  
  1590. function findChestsAndAnalyzers()
  1591.   local i, j
  1592.   local peripheralType
  1593.   local validChestNames
  1594.   local myChestID
  1595.   local myAnalyzerID
  1596.  
  1597.   validChestNames = getValidChestNames()
  1598.   myChestId = 1
  1599.   myAnalyzerID = 1
  1600.  
  1601.   for i,j in ipairs(peripheral.getNames()) do
  1602.     peripheralType = peripheral.getType(j)
  1603.    
  1604.     if (validChestNames[peripheralType] == true) then
  1605.       if (debugOutput > 1) then
  1606.         print("Valid chest found: " .. peripheralType .. " size: " .. peripheral.call(j, "getInventorySize"))
  1607.       end
  1608.      
  1609.       chests[myChestId] = {}
  1610.       chests[myChestId]["peripheral name"] = j
  1611.       myChestId = myChestId + 1
  1612.     elseif (peripheralType == "tt_aspectanalyzer") then
  1613.       if (debugOutput > 1) then
  1614.         print("Aspect analyzer found: " .. j)
  1615.       end
  1616.      
  1617.       aspectAnalyzers[myAnalyzerID] = {}
  1618.       aspectAnalyzers[myAnalyzerID]["peripheral name"] = j
  1619.       myAnalyzerID = myAnalyzerID + 1
  1620.     end
  1621.   end
  1622. end
  1623.  
  1624. function printChestAspects()
  1625.   local ci
  1626.   local e, s, i
  1627.   local myEssentias
  1628.   local chestEssentia
  1629.  
  1630.   myEssentias = essentiaList()
  1631.  
  1632.   for ci in pairs(chests) do
  1633.     chestEssentia = ""
  1634.    
  1635.     for e, i in pairs(chests[ci]) do
  1636.       if not (string.find(e, " ")) then
  1637.         for s in pairs(i) do
  1638.           chestEssentia = chestEssentia .. e .. ":" .. s .. ", "
  1639.         end
  1640.       end
  1641.     end
  1642.    
  1643.     if (chestEssentia ~= nil) then
  1644.       print("Chest " .. ci .. ": " .. string.sub(chestEssentia, 1, string.len(chestEssentia) - 2))
  1645.     end
  1646.    
  1647.     print("")
  1648.   end
  1649.  
  1650.   for ci in pairs(chests) do
  1651.     print("Chest: " .. ci .. " analyze time: " .. chests[ci]["analyze time"])
  1652.   end
  1653. end
  1654.  
  1655. function analyzeChestsContents()
  1656.   local ci
  1657.   local e
  1658.   local slot
  1659.   local chestContents
  1660.   local aspect
  1661.   local count
  1662.   local startTime
  1663.   local endTime
  1664.   local missingAspects
  1665.  
  1666.   chestAspects = essentiaList()
  1667.  
  1668.   for ci in pairs(chests) do
  1669.     if (debugOutput > 1) then
  1670.       print("Analyzing chest contents " .. ci)
  1671.     end
  1672.    
  1673.     chestContents = peripheral.call(chests[ci]["peripheral name"], "getAllStacks")
  1674.     startTime = os.clock()
  1675.     for slot in pairs(chestContents) do
  1676.       if (chestContents[slot].name == "Mana Bean") then
  1677.         aspect,count = scanItemInSlot(chests[ci]["aspect analyzer"], chests[ci]["peripheral name"], slot, chestContents[slot].qty)
  1678.        
  1679.         if (aspect ~= nil) then
  1680.           if (chests[ci][aspect] == nil) then
  1681.             chests[ci][aspect] = {}
  1682.           end
  1683.          
  1684.           chests[ci][aspect][slot] = true
  1685.           chestAspects[aspect] = 1
  1686.          
  1687.           if (debugOutput > 1) then
  1688.             print("Found mana bean in chest " .. ci .. " slot " .. slot .. " of aspect type " .. aspect)
  1689.           end
  1690.         else
  1691.           print("Mana bean in chest " .. ci .. " slot " .. slot .. " needs refilling; only " .. count .. " left.")
  1692.         end
  1693.       end
  1694.     end
  1695.    
  1696.     chests[ci]["analyze time"] = os.clock() - startTime
  1697.    
  1698.     if (debugOutput > 0) then
  1699.       print("Time to analyze chest " .. ci .. " " .. (os.clock() - startTime))
  1700.     end
  1701.   end
  1702.  
  1703.   missingAspects = ""
  1704.   for e in pairs(chestAspects) do
  1705.     if (chestAspects[e] == 0) then
  1706.       if (missingAspects ~= "") then
  1707.         missingAspects = missingAspects .. ", "
  1708.       end
  1709.      
  1710.       missingAspects = missingAspects .. e
  1711.     end
  1712.   end
  1713.  
  1714.   if (missingAspects ~= "") then
  1715.     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).")
  1716.     print("")
  1717.     print("Missing aspects: " .. missingAspects)
  1718.   end
  1719. end
  1720.  
  1721. function scanItemInSlot(aspectAnalyzer, chest, slot, quantity)
  1722.   local aspect
  1723.   local stack
  1724.  
  1725.   if (quantity == nil) then
  1726.     stack = peripheral.call(chest, "getStackInSlot", slot)
  1727.     if (stack ~= nil) then
  1728.       quantity = stack.qty
  1729.     else
  1730.       quantity = 0
  1731.     end
  1732.   end
  1733.  
  1734.   if (quantity <= 2) then
  1735.     return nil, quantity
  1736.   end
  1737.  
  1738.   if (peripheral.call(chest, "pushItemIntoSlot", "down", slot, 1, 1) == 0) then
  1739.     print("Failed to push mana bean from chest " .. chest .. " slot " .. slot .. " into aspect analyzer. Program halted. !!RESTART REQUIRED!!")
  1740.    
  1741.     -- Something went wrong, wait for human intervention.
  1742.     while (true) do
  1743.       sleep(60)
  1744.     end
  1745.   end
  1746.  
  1747.   aspect = peripheral.call(aspectAnalyzer, "getAspects")
  1748.  
  1749.   if (peripheral.call(chest, "pullItemIntoSlot", "down", 1, 1, slot) == 0) then
  1750.     print("Failed to pull mana bean from aspect analyzer " .. aspectAnalyzer .. " back into chest " .. chest .. " slot " .. slot .. ". Program halted. !!RESTART REQUIRED!!")
  1751.    
  1752.     -- Something went wrong, wait for human intervention.
  1753.     while (true) do
  1754.       sleep(60)
  1755.     end
  1756.   end
  1757.  
  1758.   return aspect, quantity
  1759. end
  1760.  
  1761. function matchChestsWithAnalyzer()
  1762.   local ci
  1763.   local ai
  1764.   local hasItem
  1765.   local chestContents
  1766.   local slot
  1767.   local foundSlot
  1768.   local itemStack
  1769.  
  1770.   -- Checks to make sure none of the analyzers have any items in them
  1771.   for ai in pairs (aspectAnalyzers) do
  1772.     hasItem = peripheral.call(aspectAnalyzers[ai]["peripheral name"], "hasItem")
  1773.     if (hasItem) then
  1774.       print("One of the aspect analyzer(s) has an item in it. All aspect analyzer should be empty.")
  1775.      
  1776.       while (hasItem) do
  1777.         sleep(1)
  1778.         hasItem = peripheral.call(aspectAnalyzers[ai]["peripheral name"], "hasItem")
  1779.       end
  1780.     end
  1781.   end
  1782.  
  1783.  
  1784.   for ci in pairs(chests) do
  1785.     chestContents = peripheral.call(chests[ci]["peripheral name"], "getAllStacks")
  1786.     foundSlot = false
  1787.    
  1788.     -- See if the chest contains anything and record the slot of any item if it does.
  1789.     for slot in pairs(chestContents) do
  1790.       if (chestContents[slot].name == "Mana Bean") then
  1791.         foundSlot = slot
  1792.         break
  1793.       end
  1794.     end
  1795.    
  1796.     -- Something went wrong, try to get it fixed.
  1797.     if not (foundSlot) then
  1798.       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.")
  1799.       print("")
  1800.      
  1801.       while not (foundSlot) do
  1802.         sleep(5)
  1803.         chestContents = peripheral.call(chests[ci]["peripheral name"], "getAllStacks")
  1804.        
  1805.         for slot in pairs(chestContents) do
  1806.           if (chestContents[slot].name == "Mana Bean") then
  1807.             foundSlot = slot
  1808.             break
  1809.           end
  1810.         end
  1811.       end
  1812.      
  1813.       print("Found mana bean in chest slot: " .. foundSlot)
  1814.       print("")
  1815.     end
  1816.    
  1817.    
  1818.     -- Put one of the random items from the chest into the aspect analyzer above it.
  1819.     if not (peripheral.call(chests[ci]["peripheral name"], "pushItemIntoSlot", "down", foundSlot, 1, 1)) then
  1820.       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.")
  1821.       print("")
  1822.       sleep(1)
  1823.      
  1824.       while not (peripheral.call(chests[ci]["peripheral name"], "pushItemIntoSlot", "down", foundSlot, 1, 1)) do
  1825.         sleep(1)
  1826.       end
  1827.     end
  1828.    
  1829.    
  1830.     -- Scan through the aspect analyzers and find which one has the item in it.
  1831.     for ai in pairs (aspectAnalyzers) do
  1832.       hasItem = peripheral.call(aspectAnalyzers[ai]["peripheral name"], "hasItem")
  1833.      
  1834.       if (hasItem) then
  1835.         if not (peripheral.call(chests[ci]["peripheral name"], "pullItemIntoSlot", "down", 1, 1, foundSlot)) then
  1836.           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!!")
  1837.          
  1838.           -- This is too difficult to explain how to recover from. Wait for human intervention.
  1839.           while (true) do
  1840.             sleep(60)
  1841.           end
  1842.         end
  1843.        
  1844.         chests[ci]["aspect analyzer"] = aspectAnalyzers[ai]["peripheral name"]
  1845.        
  1846.         if (debugOutput) then
  1847.           print("Matched chest: " .. chests[ci]["peripheral name"] .. " with aspect analyzer: " .. aspectAnalyzers[ai]["peripheral name"])
  1848.           print("")
  1849.         end
  1850.        
  1851.         break
  1852.       end
  1853.     end
  1854.    
  1855.     if not (hasItem) then
  1856.       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!!")
  1857.      
  1858.       -- Some part of the peripheral configuration is wrong and needs to be fixed. Wait for human intervention.
  1859.       while (true) do
  1860.         sleep(60)
  1861.       end
  1862.     end
  1863.   end
  1864. end
  1865.  
  1866. function disableRefill()
  1867.   rs.setOutput(disableFillRedstoneDirection, false)
  1868.   redstone.setBundledOutput(disableFillRedstoneDirection, colors.white)
  1869.   sleep(redstoneWaitTicks * .05)
  1870. end
  1871.  
  1872. function enableRefill(skipSleep)
  1873.   rs.setOutput(disableFillRedstoneDirection, true)
  1874.   redstone.setBundledOutput(disableFillRedstoneDirection, 0)
  1875.  
  1876.   if (skipSleep ~= true) then
  1877.     sleep(redstoneWaitTicks * .05)
  1878.   end
  1879. end
  1880.  
  1881. function essentiaList()
  1882.   local essentias
  1883.  
  1884.   essentias = {
  1885.     ["aer"] = 0,
  1886.     ["alienis"] = 0,
  1887.     ["aqua"] = 0,
  1888.     ["arbor"] = 0,
  1889.     ["auram"] = 0,
  1890.     ["bestia"] = 0,
  1891.     ["cognitio"] = 0,
  1892.     ["corpus"] = 0,
  1893.     ["desidia"] = 0,
  1894.     ["exanimis"] = 0,
  1895.     ["fabrico"] = 0,
  1896.     ["fames"] = 0,
  1897.     ["gelum"] = 0,
  1898.     ["granum"] = 0,
  1899.     ["gula"] = 0,
  1900.     ["herba"] = 0,
  1901.     ["humanus"] = 0,
  1902.     ["ignis"] = 0,
  1903.     ["infernus"] = 0,
  1904.     ["instrumentum"] = 0,
  1905.     ["invidia"] = 0,
  1906.     ["ira"] = 0,
  1907.     ["iter"] = 0,
  1908.     ["limus"] = 0,
  1909.     ["lucrum"] = 0,
  1910.     ["lux"] = 0,
  1911.     ["luxuria"] = 0,
  1912.     ["machina"] = 0,
  1913.     ["messis"] = 0,
  1914.     ["metallum"] = 0,
  1915.     ["meto"] = 0,
  1916.     ["mortuus"] = 0,
  1917.     ["motus"] = 0,
  1918.     ["ordo"] = 0,
  1919.     ["pannus"] = 0,
  1920.     ["perditio"] = 0,
  1921.     ["perfodio"] = 0,
  1922.     ["permutatio"] = 0,
  1923.     ["potentia"] = 0,
  1924.     ["praecantatio"] = 0,
  1925.     ["sano"] = 0,
  1926.     ["saxum"] = 0,
  1927.     ["sensus"] = 0,
  1928.     ["spiritus"] = 0,
  1929.     ["superbia"] = 0,
  1930.     ["telum"] = 0,
  1931.     ["tempus"] = 0,
  1932.     ["tempestas"] = 0,
  1933.     ["tenebrae"] = 0,
  1934.     ["terra"] = 0,
  1935.     ["tutamen"] = 0,
  1936.     ["vacuos"] = 0,
  1937.     ["venenum"] = 0,
  1938.     ["victus"] = 0,
  1939.     ["vinculum"] = 0,
  1940.     ["vitium"] = 0,
  1941.     ["vitreus"] = 0,
  1942.     ["volatus"] = 0
  1943.   }
  1944.  
  1945.   return essentias
  1946. end
  1947.  
  1948.  
  1949. m.clear()
  1950. m.setCursorPos(1, 1)
  1951. term.redirect(m)
  1952. print("Analyzing chests, watch the computer for more information.")
  1953. print("")
  1954. print("The monitor will refresh once chest analysis is finished.")
  1955. term.restore()
  1956. essentia = essentiaList()
  1957. setAutoDetectVariables()
  1958.  
  1959. disableRefill()
  1960. findChestsAndAnalyzers()
  1961. matchChestsWithAnalyzer()
  1962. analyzeChestsContents()
  1963. enableRefill()
  1964.  
  1965. print("")
  1966. print("Chest analysis finished. Showing interface.")
  1967. sleep(1)
  1968.  
  1969.  
  1970. refresh()
  1971.  
  1972. while (run) do
  1973.   -- uses os.pullevent so this isn't triggered constantly
  1974.   getClick()
  1975. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement