JereTheJuggler

potions.lua

Nov 13th, 2021 (edited)
550
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 26.99 KB | None | 0 0
  1. filenames = {}
  2. filenames.configFolder = "config"
  3. filenames.tankContents = filenames.configFolder.."/tank_contents.json"
  4. filenames.potionTypes = filenames.configFolder.."/potion_types.json"
  5.  
  6. itemNames = {
  7.     redstone = "minecraft:redstone",
  8.     glowstone = "minecraft:glowstone_dust",
  9.     gunpowder = "minecraft:gunpowder",
  10.     dragonBreath = "minecraft:dragon_breath",
  11.     netherwart = "minecraft:nether_wart"
  12. }
  13.  
  14. term.clear()
  15. term.setCursorPos(1,1)
  16. term.setTextColor(colors.white)
  17. if json == nil then
  18.     json = {}
  19. end
  20. if not fs.exists("apis/json") then
  21.     print("Downloading json api...")
  22.     shell.run("pastebin","get","4nRg9CHU","apis/json")
  23. end
  24. if not fs.exists(filenames.potionTypes) then
  25.     print("Downloading potion types config...")
  26.     shell.run("pastebin","get","YBSC0sGp",filenames.potionTypes)
  27. end
  28.  
  29. UNKNOWN = "unknown"
  30.  
  31. potionTypes = {}
  32. potionDisplayNames = {}
  33. potionModifiers = {
  34.     normal="Normal",
  35.     extended="Extended",
  36.     levelTwo="Level II",
  37.     getList=function()
  38.         return {
  39.             potionModifiers.normal,
  40.             potionModifiers.extended,
  41.             potionModifiers.levelTwo
  42.         }
  43.     end,
  44.     isValid=function(value)
  45.         if value == potionModifiers.normal then return true end
  46.         if value == potionModifiers.extended then return true end
  47.         if value == potionModifiers.levelTwo then return true end
  48.     end
  49. }
  50. potionStyles = {
  51.     normal="Normal",
  52.     splash="Splash",
  53.     lingering="Lingering",
  54.     getList=function()
  55.         return {
  56.             potionStyles.normal,
  57.             potionStyles.splash,
  58.             potionStyles.lingering
  59.         }
  60.     end,
  61.     isValid=function(value)
  62.         if value == potionStyles.normal then return true end
  63.         if value == potionStyles.splash then return true end
  64.         if value == potionStyles.lingering then return true end
  65.     end
  66. }
  67.  
  68. waterTank = nil
  69. storageTanks = {}
  70. basinName = nil
  71. inventories = {}
  72. inventoryIndex = {}
  73. monitors = {}
  74. spout = nil
  75. depot = nil
  76.  
  77. string.startsWith = function(self,str)
  78.     return self:find("^"..str)
  79. end
  80. string.split = function(self,sep)
  81.     if sep == nil then
  82.         sep = "%s"
  83.     end
  84.     local t = {}
  85.     for str in self:gmatch("([^"..sep.."]+)") do
  86.         table.insert(t,str)
  87.     end
  88.     return t
  89. end
  90. table.contains = function(self,value)
  91.     for _, v in ipairs(self) do
  92.         if v == value then
  93.             return true
  94.         end
  95.     end
  96.     return false
  97. end
  98. container={
  99.     contents={
  100.         name=UNKNOWN,
  101.         modifier=potionModifiers.normal,
  102.         style=potionStyles.normal
  103.     },
  104.     contentsMatch=function(self,value)
  105.         if self.contents == nil then
  106.             return value == nil
  107.         elseif value == nil then
  108.             return false
  109.         end
  110.         if self.contents.name ~= value.name then
  111.             return false
  112.         end
  113.         if self.contents.name == UNKNOWN then
  114.             return true
  115.         end
  116.         return self.contents.modifier == value.modifier and self.contents.style == value.style
  117.     end
  118. }
  119. function createContainer(t)
  120.     t.contents = {
  121.         name=UNKNOWN,
  122.         modifier=potionModifiers.normal,
  123.         style=potionStyles.normal
  124.     }
  125.     t.contentsMatch = container.contentsMatch
  126.     return t
  127. end
  128. function createList(t)
  129.     if t == nil then
  130.         t = {}
  131.     end
  132.     t.insert = table.insert
  133.     t.contains = table.contains
  134.     t.remove = table.remove
  135.     return t
  136. end
  137.  
  138. function clearMonitor(mon)
  139.     if mon ~= nil then
  140.         mon.clear()
  141.         mon.setCursorPos(1,1)
  142.     elseif #monitors > 0 then
  143.         for _,v in ipairs(monitors) do
  144.             v.clear()
  145.             v.setCursorPos(1,1)
  146.         end
  147.     end
  148. end
  149. function writeMonitor(text)
  150.     if #monitors > 0 then
  151.         for k,v in ipairs(monitors) do
  152.             clearMonitor(v)
  153.             v.setTextColor(colors.white)
  154.             v.write(text)
  155.         end
  156.     end
  157. end
  158. function writeMonitorError(text)
  159.     if #monitors > 0 then
  160.         for k,v in ipairs(monitors) do
  161.             clearMonitor(v)
  162.             v.setTextColor(colors.red)
  163.             v.write(text)
  164.         end
  165.     end
  166. end
  167. function clearTerm()
  168.     term.clear()
  169.     term.setCursorPos(1,1)
  170. end
  171. function printError(text)
  172.     term.setTextColor(colors.red)
  173.     print(text)
  174.     term.setTextColor(colors.white)
  175. end
  176. function printInstruction(text)
  177.     term.setTextColor(colors.lightBlue)
  178.     print(text)
  179.     term.setTextColor(colors.white)
  180. end
  181. function printLine()
  182.     print()
  183. end
  184. function waitForKey()
  185.     return os.pullEvent("key")
  186. end
  187.  
  188. function wrapPeripherals()
  189.     while true do
  190.         waterTank = nil
  191.         storageTanks = createList()
  192.         basin = nil
  193.         inventories = createList()
  194.         monitors = createList()
  195.         for _,v in ipairs(peripheral.getNames()) do
  196.             if v:startsWith("create:fluid_tank") then
  197.                 local t = peripheral.wrap(v)
  198.                 local tanks = t.tanks()
  199.                 if #tanks > 0 and tanks[1].name == "minecraft:water" then
  200.                     waterTank = t
  201.                     waterTank.name = v
  202.                 else
  203.                     t.name = v
  204.                     t = createContainer(t)
  205.                     if #tanks == 0 then
  206.                         t.contents = nil
  207.                     end
  208.                     storageTanks:insert(t)
  209.                 end
  210.             elseif v:startsWith("create:basin") then
  211.                 basin = peripheral.wrap(v)
  212.                 basin.name = v
  213.             elseif v:startsWith("monitor") then
  214.                 monitors:insert(peripheral.wrap(v))
  215.             elseif v:startsWith("create:spout") then
  216.                 spout = peripheral.wrap(v)
  217.                 spout.name = v
  218.             elseif v:startsWith("create:depot") then
  219.                 depot = peripheral.wrap(v)
  220.                 depot.name = v
  221.             else
  222.                 local sideNames = createList({"top","front","left","right","back","bottom"})
  223.                 if not sideNames:contains(v) then
  224.                     local p = peripheral.wrap(v)
  225.                     if p.pullItems ~= nil then
  226.                         p.name = v
  227.                         inventories:insert(p)
  228.                     end
  229.                 end
  230.             end
  231.         end
  232.         local messages = createList()
  233.         if waterTank == nil then
  234.             messages:insert("No water tank found")
  235.         end
  236.         if #storageTanks == 0 then
  237.             messages:insert("No storage tanks found")
  238.         end
  239.         if basin == nil then
  240.             messages:insert("No basin found")
  241.         end
  242.         if spout == nil then
  243.             messages:insert("No spout found")
  244.         end
  245.         if depot == nil then
  246.             messages:insert("No depot found")
  247.         end
  248.         if #inventories == 0 then
  249.             messages:insert("No item inventories found")
  250.         end
  251.         if #messages > 0 then
  252.             writeMonitorError("Could not find necessary peripherals")
  253.             clearTerm()
  254.             printError("Could not find necessary peripherals")
  255.             for _,msg in ipairs(messages) do
  256.                 printError("- "..msg)
  257.             end
  258.             printLine()
  259.             print("Press X to quit. Press any other key to retry.")
  260.             local _, key = waitForKey()
  261.             if key == keys.x then
  262.                 return false
  263.             end
  264.         else
  265.             return true
  266.         end
  267.     end
  268. end
  269. function initializePotionTypes()
  270.     potionTypes = {}
  271.     if not pcall(function()
  272.         potionTypes = json.decodeFromFile(filenames.potionTypes)
  273.     end) then
  274.         --failed to decode file and load potion types
  275.         clearTerm()
  276.         printError("An error occurred while reading potion types config")
  277.         return false
  278.     end
  279.     for typeName,typeData in pairs(potionTypes) do
  280.         for i=1, #typeData.names do
  281.             potionDisplayNames[typeData.names[i]] = typeName
  282.         end
  283.     end
  284.     return true
  285. end
  286. function getPotionTypeByName(name)
  287.     if potionTypes[name] ~= nil then
  288.         return name
  289.     end
  290.     if potionDisplayNames[name] == nil then
  291.         return nil
  292.     end
  293.     return potionDisplayNames[name]
  294. end
  295. function initializeTankContents()
  296.     if fs.exists(filenames.tankContents) then
  297.         local contents = nil
  298.         if not pcall(function()
  299.             contents = json.decodeFromFile(filenames.tankContents)
  300.             for _,tank in ipairs(storageTanks) do
  301.                 if tank.contents ~= nil then
  302.                     if contents[tank.name] ~= nil then
  303.                         tank.contents = contents[tank.name]
  304.                     end
  305.                 end
  306.             end
  307.         end) then
  308.             --failed to decode file and set tank contents
  309.             clearTerm()
  310.             printError("An error occurred while reading previous tank contents")
  311.             waitForKey()
  312.         end
  313.         writeTankContents()
  314.     end
  315. end
  316. function writeTankContents()
  317.     local contents = {}
  318.     for _,tank in ipairs(storageTanks) do
  319.         if tank.contents ~= nil and tank.contents.name ~= UNKNOWN then
  320.             contents[tank.name] = tank.contents
  321.         end
  322.     end
  323.     if not pcall(function()
  324.         local h = fs.open(filenames.tankContents,"w")
  325.         h.write(json.encode(contents))
  326.         h.close()
  327.     end) then
  328.         printError("Error writing tank contents file")
  329.         waitForKey()
  330.     end
  331. end
  332. function setTankContents(tank,potionType,modifier,style)
  333.     local contents = {}
  334.     if #tank.tanks() == 0 then
  335.         contents = nil
  336.     elseif potionType == nil then
  337.         contents = {
  338.             name=UNKNOWN,
  339.             modifier=potionModifiers.normal,
  340.             style=potionStyles.normal
  341.         }
  342.     else
  343.         if modifier == nil then
  344.             modifier = potionModifiers.normal
  345.         end
  346.         if style == nil then
  347.             style = potionStyles.normal
  348.         end
  349.         contents = {
  350.             name=potionType,
  351.             modifier=modifier,
  352.             style=style
  353.         }
  354.     end
  355.     for i,t in ipairs(storageTanks) do
  356.         if t.name == tank.name then
  357.             storageTanks[i].contents = contents
  358.             if contents == nil then
  359.                 print("setting contents of "..tank.name.." to nil")
  360.             else
  361.                 print("setting contents of "..tank.name.." to...")
  362.                 print(json.encode(storageTanks[i].contents))
  363.             end
  364.         end
  365.     end
  366.     writeTankContents()
  367. end
  368.  
  369. function findStorage(potionName,modifier,style)
  370.     local matchingTanks = createList()
  371.     local unknownTanks = createList()
  372.     local emptyTanks = createList()
  373.     local search = {
  374.         name=potionName,
  375.         modifier=modifier,
  376.         style=style
  377.     }
  378.     for i,v in ipairs(storageTanks) do
  379.         print("checking storage tank "..i)
  380.         if #v.tanks() ~= 0 then
  381.             print("tank has fluids")
  382.             if v:contentsMatch(search) then
  383.                 print("tank is a match")
  384.                 print(json.encode(v.contents))
  385.                 matchingTanks:insert(v)
  386.             elseif v.contents.name == UNKNOWN then
  387.                 print("tank is unknown")
  388.                 unknownTanks:insert(v)
  389.             end
  390.         else
  391.             print("tank is empty")
  392.             emptyTanks:insert(v)
  393.         end
  394.     end
  395.     return matchingTanks, unknownTanks, emptyTanks
  396. end
  397.  
  398. function getItemForModifier(modifier)
  399.     if modifier == potionModifiers.extended then
  400.         return itemNames.redstone
  401.     elseif modifier == potionModifiers.levelTwo then
  402.         return itemNames.glowstone
  403.     end
  404.     return nil
  405. end
  406. function getItemForStyle(style)
  407.     if style == potionStyles.splash then
  408.         return itemNames.gunpowder
  409.     elseif style == potionStyles.lingering then
  410.         return itemNames.dragonBreath
  411.     end
  412.     return nil
  413. end
  414.  
  415. function refillWater()
  416.     basin.pullFluid(waterTank.name)
  417. end
  418.  
  419. function indexInventories()
  420.     local totalSlots = 0
  421.     for _,inv in ipairs(inventories) do
  422.         totalSlots = totalSlots + inv.size()
  423.     end
  424.     inventoryIndex = {}
  425.     local currentSlot = 1
  426.     for _,inv in ipairs(inventories) do
  427.         local inventorySize = inv.size()
  428.         clearTerm()
  429.         for slot=1, inventorySize do
  430.             term.setCursorPos(1,1)
  431.             term.write("Indexing Inventories... Slot "..currentSlot.." of "..totalSlots)
  432.             local item = inv.getItemDetail(slot)
  433.             if item ~= nil then
  434.                 if inventoryIndex[item.name] == nil then
  435.                     inventoryIndex[item.name] = {
  436.                         total=0,
  437.                         locations=createList()
  438.                     }
  439.                 end
  440.                 inventoryIndex[item.name].total = inventoryIndex[item.name].total + item.count
  441.                 inventoryIndex[item.name].locations:insert({
  442.                     inv,
  443.                     slot,
  444.                     item.count
  445.                 })
  446.             end
  447.             currentSlot = currentSlot + 1
  448.         end
  449.     end
  450.     clearTerm()
  451. end
  452.  
  453. function checkPotionStorage(potionType,modifier,style,bottleCount)
  454.     if modifier == nil then
  455.         modifier = potionModifiers.normal
  456.     end
  457.     if style == nil then
  458.         style = potionStyles.normal
  459.     end
  460.     if bottleCount == nil then
  461.         bottleCount = 1
  462.     end
  463.  
  464.     potionType = getPotionTypeByName(potionType)
  465.     if potionType == nil then
  466.         writeMonitorError("canCraftPotion: Unknown potion type provided. "..potionType)
  467.         return false
  468.     end
  469.     if potionModifiers[modifier] == nil then
  470.         writeMonitorError("canCraftPotion: Unknown modifier provided. "..modifier)
  471.     end
  472.     if potionStyles[style] == nil then
  473.         writeMonitorError("canCraftPotion: Unknown style provided. "..style)
  474.     end
  475.  
  476.     local mbNeeded = bottleCount*250
  477.  
  478.     local saveContents = false
  479.     local locations = createList()
  480.     for i,tank in ipairs(storageTanks) do
  481.         if tank:contentsMatch({
  482.             name=potionType,
  483.             modifier=modifier,
  484.             style=style
  485.         }) then
  486.             local tanks = tank.tanks()
  487.             if #tanks == 0 then
  488.                 --tank contents is out of date
  489.                 tank.contents = nil
  490.                 saveContents = true
  491.             else
  492.                 if tanks[1].amount >= mbNeeded then
  493.                     locations:insert({i,mbNeeded})
  494.                     break
  495.                 elseif tanks[1].amount > 0 then
  496.                     locations:insert({i,tanks[1].amount})
  497.                     mbNeeded = mbNeeded - tanks[1].amount
  498.                 end
  499.             end
  500.         end
  501.     end
  502.     if saveContents then
  503.         writeTankContents()
  504.     end
  505.     if mbNeeded > 0 then
  506.         return false, mbNeeded / 250
  507.     end
  508.     return true, locations
  509. end
  510. function canCraftPotion(potionName,modifier,style,recipeCount)
  511.     if modifier == nil then
  512.         modifier = potionModifiers.normal
  513.     end
  514.     if style == nil then
  515.         style = potionStyles.normal
  516.     end
  517.     if recipeCount == nil then
  518.         recipeCount = 1
  519.     end
  520.  
  521.     potionType = getPotionTypeByName(potionName)
  522.  
  523.     local missing = createList()
  524.  
  525.     checkMissingItem(itemNames.netherwart,recipeCount,checkMissingItem)
  526.  
  527.     if modifier ~= potionModifiers.normal then
  528.         print("checking item for modifier")
  529.         local i = getItemForModifier(modifier)
  530.         print("modifier item:")
  531.         print(i)
  532.         checkMissingItem(i,recipeCount,missing)
  533.     end
  534.     if style ~= potionStyles.normal then
  535.         print("checking item for style")
  536.         local i = getItemForStyle(style)
  537.         print("style item:")
  538.         print(i)
  539.         checkMissingItem(i,recipeCount,missing)
  540.     end
  541.  
  542.     local recipes = createList()
  543.     local remainingCrafts = recipeCount
  544.     print("checking recipe specific items")
  545.     for r,items in ipairs(potionTypes[potionType].recipes) do
  546.         local crafts = getPossibleCrafts(items,remainingCrafts)
  547.         if crafts > 0 then
  548.             remainingCrafts = remainingCrafts - crafts
  549.             recipes:insert({crafts,r})
  550.             if remainingCrafts == 0 then
  551.                 break
  552.             end
  553.         end
  554.     end
  555.     if remainingCrafts > 0 then
  556.         print("remaining crafts > 0")
  557.         for _,item in ipairs(potionTypes[potionType].recipes[1]) do
  558.             print(item)
  559.             checkMissingItem(item,recipeCount,missing)
  560.         end
  561.     end
  562.  
  563.     if #missing > 0 then
  564.         return false, missing, nil
  565.     end
  566.     return true, nil, recipes
  567. end
  568. function checkMissingItem(name,qty,missing)
  569.     print("checking for {"..qty.."} {"..name.."}")
  570.     local count = 0
  571.     if inventoryIndex[name] ~= nil then
  572.         count = inventoryIndex[name].total
  573.     end
  574.     if count < qty then
  575.         print("item not found")
  576.         missing:insert({name,qty - count})
  577.     end
  578. end
  579. function getPossibleCrafts(items,remainingCrafts)
  580.     local maxPossible = remainingCrafts
  581.     for _,item in ipairs(items) do
  582.         if inventoryIndex[item] == nil then
  583.             return 0
  584.         else
  585.             if inventoryIndex[item].total < maxPossible then
  586.                 maxPossible = inventoryIndex[item].total
  587.             end
  588.         end
  589.     end
  590.     return maxPossible
  591. end
  592.  
  593. function promptPotionType()
  594.     while true do
  595.         printInstruction("Which potion type do you want? (Enter \"cancel\" to quit)")
  596.         local i = tostring(read())
  597.         if i == "cancel" then
  598.             return nil
  599.         end
  600.         local t = getPotionTypeByName(i)
  601.         if t == nil then
  602.             printError("Invalid type provided")
  603.         else
  604.             return t
  605.         end
  606.     end
  607. end
  608. function promptModifier()
  609.     local mods = potionModifiers.getList()
  610.     while true do
  611.         printInstruction("Which modifier do you want?")
  612.         for m=1, #mods do
  613.             printInstruction(" "..m..") "..mods[m])
  614.         end
  615.         printInstruction(" "..(#mods+1)..") Cancel")
  616.         local i = tonumber(read())
  617.         if i == nil or i < 1 or i > #mods+1 then
  618.             printError("Invalid value provided")
  619.         elseif i == #mods+1 then
  620.             return nil
  621.         else
  622.             return mods[i]
  623.         end
  624.     end
  625. end
  626. function promptStyle()
  627.     local mods = potionStyles.getList()
  628.     while true do
  629.         printInstruction("Which style do you want?")
  630.         for m=1, #mods do
  631.             printInstruction(" "..m..") "..mods[m])
  632.         end
  633.         printInstruction(" "..(#mods+1)..") Cancel")
  634.         local i = tonumber(read())
  635.         if i == nil or i < 1 or i > #mods+1 then
  636.             printError("Invalid value provided")
  637.         elseif i == #mods+1 then
  638.             return nil
  639.         else
  640.             return mods[i]
  641.         end
  642.     end
  643. end
  644. function promptQty(qtyType)
  645.     while true do
  646.         printInstruction("How many "..qtyType.." do you want? (Enter \"cancel\" to quit)")
  647.         local i = read()
  648.         if i == "cancel" then
  649.             return nil
  650.         else
  651.             i = tonumber(i)
  652.             if i == nil or i <= 0 then
  653.                 printError("Invalid value provided")
  654.             else
  655.                 return i
  656.             end
  657.         end
  658.     end
  659. end
  660.  
  661. function getFullPotionName(potionType,modifier,style)
  662.     local fullPotionName = "Potion of "..potionTypes[potionType].names[1]
  663.     if style ~= potionStyles.normal then
  664.         fullPotionName = style.." "..fullPotionName
  665.     end
  666.     if modifier == potionModifiers.extended then
  667.         fullPotionName = potionModifiers.extended.." "..fullPotionName
  668.     elseif modifier == potionModifiers.levelTwo then
  669.         fullPotionName = fullPotionName.." II"
  670.     end
  671.     return fullPotionName
  672. end
  673.  
  674. function isBasinEmpty()
  675.     if #basin.tanks() > 0 then
  676.         return false
  677.     end
  678.     if basin.tanks()[3] ~= nil then
  679.         return false
  680.     end
  681.     return true
  682. end
  683.  
  684. function itemStuckInBasin()
  685.     writeMonitorError("Item stuck in basin!")
  686.     while true do
  687.         sleep(10)
  688.         if basin.getItemDetail(1) == nil then
  689.             return
  690.         end
  691.     end
  692. end
  693. function itemMissingInInventory(itemName)
  694.     writeMonitorError("Item could not be found in inventory! "..itemName)
  695.     waitForKey()
  696. end
  697. function cannotStorePotion()
  698.     writeMonitorError("Potion in basin could not be stored!")
  699.     waitForKey()
  700. end
  701.  
  702. function craft(com)
  703.     local potionType, modifier, style, qty = nil, nil, nil, nil
  704.     if #com >= 2 then
  705.         potionType = getPotionTypeByName(com[2])
  706.         if potionType == nil then
  707.             printError("Invalid value provided for potion type")
  708.             return
  709.         end
  710.     else
  711.         potionType = promptPotionType()
  712.         if potionType == nil then return end
  713.     end
  714.     if #com >= 3 then
  715.         modifier = com[3]
  716.         if tonumber(modifier) ~= nil then
  717.             modifier = tonumber(modifier)
  718.             if modifier > 0 and modifier <= #potionModifiers.getList() then
  719.                 modifier = potionModifiers.getList()[modifier]
  720.             else
  721.                 modifier = nil
  722.             end
  723.         else
  724.             if not potionModifiers.isValid(modifier) then
  725.                 modifier = nil
  726.             end
  727.         end
  728.         if modifier == nil then
  729.             printError("Invalid value provided for potion modifier")
  730.             return
  731.         end
  732.     else
  733.         modifier = promptModifier()
  734.         if modifier == nil then return end
  735.     end
  736.     if #com >= 4 then
  737.         style = com[4]
  738.         if tonumber(style) ~= nil then
  739.             style = tonumber(style)
  740.             if style > 0 and style <= #potionStyles.getList() then
  741.                 style = potionStyles.getList()[style]
  742.             else
  743.                 style = nil
  744.             end
  745.         else
  746.             if not potionStyles.isValid(style) then
  747.                 style = nil
  748.             end
  749.         end
  750.         if style == nil then
  751.             printError("Invalid value provided for potion style")
  752.             return
  753.         end
  754.     else
  755.         style = promptStyle()
  756.         if style == nil then return end
  757.     end
  758.     if #com == 5 then
  759.         qty = tonumber(com[5])
  760.         if qty == nil then
  761.             printError("Invalid value provided for number of buckets")
  762.             return
  763.         end
  764.     else
  765.         qty = promptQty("buckets")
  766.         if qty == nil then return end
  767.     end
  768.  
  769.     local result, missing, recipes = canCraftPotion(potionType,modifier,style,qty)
  770.     if not result then
  771.         printError("Cannot craft specified potion. Missing items:")
  772.         for _,m in ipairs(missing) do
  773.             print(" - "..m[1].." x "..m[2])
  774.             return
  775.         end
  776.     end
  777.    
  778.     clearTerm()
  779.  
  780.     local remainingQty = qty
  781.     local fullPotionName = getFullPotionName(potionType,modifier,style)
  782.  
  783.     for _,recipe in ipairs(recipes) do
  784.         local recipeCount = recipe[1]
  785.         local recipeIndex = recipe[2]
  786.         for i=1, recipeCount do
  787.             writeMonitor("Crafting "..(qty-remainingQty+1).." of "..qty..": "..fullPotionName)
  788.             refillWater()
  789.             mix(itemNames.netherwart)
  790.             for _,itemName in ipairs(potionTypes[potionType].recipes[recipeIndex]) do
  791.                 mix(itemName)
  792.             end
  793.             if modifier ~= potionModifiers.normal then
  794.                 mix(getItemForModifier(modifier))
  795.             end
  796.             if style ~= potionStyles.normal then
  797.                 mix(getItemForStyle(style))
  798.             end
  799.             while true do
  800.                 if storePotion(potionType,modifier,style) then
  801.                     break
  802.                 else
  803.                     cannotStorePotion()
  804.                 end
  805.             end
  806.             remainingQty = remainingQty - 1
  807.         end
  808.     end
  809.     clearMonitor()
  810.     clearTerm()
  811. end
  812.  
  813. function mix(itemName)
  814.     if basin.getItemDetail(1) ~= nil then
  815.         itemStuckInBasin()
  816.     end
  817.     if putItemInBasin(itemName) then
  818.         while true do
  819.             sleep(1)
  820.             if basin.getItemDetail(1) == nil then
  821.                 break
  822.             end
  823.         end
  824.     else
  825.         return false
  826.     end
  827.     return true
  828. end
  829. function putItemInBasin(itemName)
  830.     while true do
  831.         local itemLocation = inventoryIndex[itemName].locations[1]
  832.         local pullCount = basin.pullItems(itemLocation[1].name,itemLocation[2],1)
  833.         if pullCount == 0 then
  834.             if itemLocation[1].getItemDetail(itemLocation[2]).count == 0 then
  835.                 inventoryIndex[itemName].total = inventoryIndex[itemName].total - itemLocation[3]
  836.                 inventoryIndex[itemName].locations:remove(1)
  837.                 if #inventoryIndex[itemName].locations == 0 then
  838.                     if not itemMissingInInventory(itemName) then
  839.                         return false
  840.                     end
  841.                 end
  842.             end
  843.         else
  844.             inventoryIndex[itemName].total = inventoryIndex[itemName].total - 1
  845.             inventoryIndex[itemName].locations[1][3] = inventoryIndex[itemName].locations[1][3]-1
  846.             if inventoryIndex[itemName].locations[1][3] == 0 then
  847.                 inventoryIndex[itemName].locations:remove(1)
  848.             end
  849.             return true
  850.         end
  851.     end
  852. end
  853.  
  854. function storePotion(potionType,modifier,style)
  855.     local matchingTanks, unknownTanks, emptyTanks = findStorage(potionType,modifier,style)
  856.     if #matchingTanks > 0 then
  857.         for _,t in ipairs(matchingTanks) do
  858.             if t.pullFluid(basin.name) > 0 then
  859.                 if isBasinEmpty() then
  860.                     return true
  861.                 end
  862.             end
  863.         end
  864.     end
  865.     if #unknownTanks > 0 then
  866.         for _,t in ipairs(unknownTanks) do
  867.             if t.pullFluid(basin.name) > 0 then
  868.                 setTankContents(t,potionType,modifier,style)
  869.                 if isBasinEmpty() then
  870.                     break
  871.                 end
  872.             end
  873.         end
  874.     end
  875.     if not isBasinEmpty() and #emptyTanks > 0 then
  876.         for _,t in ipairs(emptyTanks) do
  877.             if t.pullFluid(basin.name) > 0 then
  878.                 setTankContents(t,potionType,modifier,style)
  879.                 if isBasinEmpty() then
  880.                     break
  881.                 end
  882.             end
  883.         end
  884.     end
  885.     return isBasinEmpty()
  886. end
  887.  
  888. function run()
  889.     if not wrapPeripherals() then
  890.         return
  891.     end
  892.  
  893.     clearMonitor()
  894.     clearTerm()
  895.  
  896.     if not os.loadAPI("apis/json") then
  897.         writeMonitorError("Could not load json api")
  898.         printError("Could not load json api")
  899.         return
  900.     end
  901.  
  902.     initializeTankContents()
  903.     if not initializePotionTypes() then
  904.         return
  905.     end
  906.  
  907.     indexInventories()
  908.  
  909.     while true do
  910.         printInstruction("Please enter a command")
  911.         writeMonitor("Waiting for input!")
  912.         local com = tostring(read()):split(",")
  913.         if #com > 0 then
  914.             if com[1] == "craft" then
  915.                 craft(com)
  916.             elseif com[1] == "bottle" then
  917.            
  918.             elseif com[1] == "index" then
  919.                 indexInventories()
  920.             elseif com[1] == "exit" then
  921.                 return
  922.             end
  923.         end
  924.     end
  925. end
  926.  
  927. run()
Add Comment
Please, Sign In to add comment