Advertisement
Guest User

Doesitall_tppi1.0

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