Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[TODO LIST
- 1. make prompts blink to make them stand out to the user
- 2. modify FindHome() to prevent turtle from running away
- 3. modify RunMenu() so that the printing code is more compact
- 4. modify menu routine to have +duration/+effect/splash sub menus for each of the primary potions
- 5. allow for 'n' dispensers to be used ( n > 2 )
- 6. modify menu to indicate what potions were selected for inactive shelves
- ]]
- function Main() --Control center for the program DONE
- --construction
- if DoYouWantTheBuilder() == true then
- WaitForInventory()
- SurveySite()
- AutoBuilder()
- end
- --potion selection
- if DoesOldSaveExist() == true then
- if ChooseANewSet() == true then
- potionList = RunMenu()
- SaveFile(potionList)
- else
- potionList = LoadFile()
- end
- else
- potionList = RunMenu()
- SaveFile(potionList)
- end
- inventory, reservedSlots = DefineInventory(potionList)
- --potion brewing
- FindHome()
- CleanUp(reservedSlots)
- shelfNo = 1
- while true do
- if IsShelfFull(shelfNo,reservedSlots) == true then
- --Do nothing
- else
- if IsEnoughIngredients(potionList[shelfNo],inventory) == true then
- FillBottles(reservedSlots)
- BrewPotion(potionList[shelfNo],inventory)
- RestockShelf(shelfNo)
- else
- RestockTurtle(reservedSlots)
- end
- end
- if shelfNo == 4 then
- Rest(10,"sleep","Cycle complete.")
- shelfNo = 1
- else
- shelfNo = shelfNo + 1
- end
- end
- end
- function DoYouWantTheBuilder() --Ask the user if they require instructions DONE
- term.clear() term.setCursorPos(1,1)
- print("Would you like to use the builder program? (Y/N)")
- local timer = os.startTimer(10) --#The interval that you would like to wait
- while true do
- local event, result = os.pullEvent()
- if event=="timer" then --#If a timer event is pulled and its ID matches the one returned by startTimer
- return false
- elseif event == "key" then
- if result == keys.enter or result == keys.y then return true
- elseif result == keys.n then return false
- end
- end
- end
- end
- function WaitForInventory() --Waits for the required building materials DONE
- repeat
- term.clear() term.setCursorPos(1,1)
- local inventory = "good"
- turtle.select(1) --building material
- if turtle.getItemCount(1) < 23 then
- print(" - Put exactly 23 blocks of a building material in slot 1")
- inventory = "bad"
- end
- turtle.select(2) --dispensers
- if turtle.getItemCount(2) < 4 then
- print(" - Put exactly 4 dispensers or droppers in slot 2")
- inventory = "bad"
- end
- turtle.select(3) --chest
- if turtle.getItemCount(3) < 2 then
- print(" - Put exactly 2 chests in slot 3")
- inventory = "bad"
- end
- turtle.select(4) --brewing stand
- if turtle.getItemCount(4) < 1 then
- print(" - Put exactly one brewing stand in slot 4")
- inventory = "bad"
- end
- turtle.select(5) --fuel
- turtle.refuel()
- if turtle.getFuelLevel() < 90 then
- print(" - Put at least 2 coal worth of fuel in slot 5")
- inventory = "bad"
- end
- sleep(3)
- until inventory == "good"
- end
- function SurveySite() --Ensures the area is ready for construction DONE
- term.clear() term.setCursorPos(1,1)
- print("Surveying site. Stand well back.")
- for layer = 1,2 do
- for section = 1,6 do
- while turtle.detect() == true do
- print("Remove this block. TimeStamp = " ..os.clock())
- sleep(5)
- end
- turtle.turnLeft()
- while turtle.detect() == true do
- print("Remove this block. TimeStamp = " ..os.clock())
- sleep(5)
- end
- TurnAround()
- while turtle.detect() == true do
- print("Remove this block. TimeStamp = " ..os.clock())
- sleep(5)
- end
- turtle.turnLeft()
- turtle.forward()
- end
- if layer == 1 then
- while turtle.detectUp() == true do
- print("Remove this block. TimeStamp = " ..os.clock())
- sleep(5)
- end
- turtle.up()
- end
- TurnAround()
- turtle.forward()
- end
- turtle.down()
- for i = 1,3 do turtle.forward() end
- while turtle.detectDown() == true do
- print("Remove the block below and fill it with water. TimeStamp = " ..os.clock())
- sleep(5)
- end
- for i = 1,3 do turtle.back() end
- print("Survey complete. Area is clear.")
- end
- function AutoBuilder() --Constructs the setup DONE
- print("Laying first layer")
- turtle.select(1)
- for i = 1,6 do --build the left and right sides
- turtle.turnLeft()
- turtle.place()
- TurnAround()
- turtle.place()
- turtle.turnLeft()
- turtle.forward()
- end
- turtle.back() --place the end block
- turtle.back()
- turtle.place()
- turtle.select(4) --place the brewing stand
- turtle.back()
- turtle.place()
- turtle.select(3) --place the chest
- for i = 1,3 do turtle.back() end
- turtle.place()
- turtle.select(1) --place the last block
- turtle.back()
- turtle.place()
- --turtle is now outside the apothecary facing the righthand end
- print("Laying top layer")
- turtle.up()
- turtle.forward()
- turtle.select(1) --BM
- turtle.turnLeft()
- turtle.place()
- TurnAround()
- turtle.place()
- turtle.turnRight()
- turtle.back()
- turtle.select(3) --chests
- turtle.place()
- TurnAround()
- for i = 1,4 do --laying the 'shelves'
- turtle.turnLeft()
- turtle.select(2) --dispensers
- turtle.place()
- TurnAround()
- turtle.select(1) --Building material
- turtle.place()
- turtle.turnLeft()
- turtle.forward()
- end
- turtle.turnLeft() --place the blocks around 'home'
- turtle.place()
- TurnAround()
- turtle.place()
- turtle.turnLeft()
- turtle.back()
- turtle.select(1) --BM
- turtle.place()
- --turtle is now in home position
- end
- function DoesOldSaveExist() --Is there an old save file existing? DONE
- print("Searching for existing save file..")
- local fileName = os.getComputerID()..".potions" --computer ID with the extension .potions
- local file = io.open(fileName,"r")
- if file == nil then
- return false
- else
- --[[if file:readLine() == nil then
- file:close()
- return false
- else
- file:close()
- return true
- end]]
- return true
- end
- end
- function ChooseANewSet() --do you need to choose a new potion set? DONE
- term.clear() term.setCursorPos(1,1)
- print("Would you like to select a new set of potions?? (Y/N)")
- local timer = os.startTimer(20) --#The interval that you would like to wait
- while true do
- local event, result = os.pullEvent()
- if event=="timer" then --#If a timer event is pulled and its ID matches the one returned by startTimer
- return false
- elseif event == "key" then
- if result == keys.enter or result == keys.y then return true
- elseif result == keys.n then return false
- end
- end
- end
- end
- function RunMenu() --run the menu program to read a users selection DONE
- local potion = {}
- potion[01] = {"N.V. 3:00","g.carrot "} --Night Vision
- potion[02] = {"N.V. 8:00","g.carrot ","redstone "} --Night Vision
- potion[03] = {"Inv. 3:00","g.carrot ","f.s.eye "} --Invisibility
- potion[04] = {"Inv. 8:00","g.carrot ","f.s.eye ","redstone "} --Invisibility
- potion[05] = {"F.R. 3:00","m. cream "} --Fire Resist
- potion[06] = {"F.R. 8:00","m. cream ","redstone "} --Fire Resist
- potion[07] = {"Sl(s) 1:30","m. cream ","f.s.eye ","gunpowder"} --Slowness
- potion[08] = {"Sl(s) 4:00","m. cream ","f.s.eye ","redstone ","gunpowder"} --Slowness
- potion[09] = {"Sw I 3:00","sugar "} --Swiftness
- potion[10] = {"Sw I 8:00","sugar ","redstone "} --Swiftness
- potion[11] = {"Sw II 1:30","sugar ","gl.stone "} --Swiftness
- potion[12] = {"Hp I +6 ","gl.melon "} --Healing
- potion[13] = {"Hp II +12 ","gl.melon ","gl.stone "} --Healing
- potion[14] = {"Hm1(s)-6 ","spidereye","f.s.eye ","gunpowder"} --Harming
- potion[15] = {"Hm2(s)-12 ","spidereye","f.s.eye ","glowstone","gunpowder"} --Harming
- potion[16] = {"Ps1(s)0:45","spidereye","redstone ","gunpowder"} --Poison
- potion[17] = {"Ps1(s)2:00","spidereye","glowstone","gunpowder"} --Poison
- potion[18] = {"Ps2(s)0:22","spidereye","glowstone","f.s.eye ","gunpowder"}
- potion[19] = {"RgnI 0:45","ghastTear"}
- potion[20] = {"RgnI 2:00","ghastTear","redstone "}
- potion[21] = {"RgnII 0.22","ghastTear","glowstone"}
- potion[22] = {"Weak 1:30","f.s.eye ","gunpowder"}
- potion[23] = {"Weak 4:00","f.s.eye ","redstone ","gunpowder"}
- potion[24] = {"St I 3:00","blz.pwdr "}
- potion[25] = {"St I 8:00","blz.pwdr ","glowstone"}
- potion[26] = {"St II 1:30","blz.pwdr ","redstone "}
- local choice={1,1,1,1}
- local itemspp = 9
- local column = 1
- local pagestart = 4
- repeat
- term.clear() term.setCursorPos(1,1)
- --Print the headings
- print("Select potions from the choice: (UDLR)")
- print(" <<< Shelf "..column.." of 4 >>> ")
- --Print the potions
- --todo - rebuild this section much shorter
- for ID = 1,itemspp do
- term.setCursorPos(1,pagestart + ID - 1)
- if choice[column] == ID then
- print(">>"..potion[ID][1])
- else
- print(" "..potion[ID][1])
- end
- end
- for ID = itemspp+1,itemspp*2 do
- term.setCursorPos(14,pagestart + ID - itemspp - 1)
- if choice[column] == ID then
- print(">>"..potion[ID][1])
- else
- print(" "..potion[ID][1])
- end
- end
- for ID = itemspp*2+1,#potion do
- term.setCursorPos(27,pagestart + ID - itemspp*2 - 1)
- if choice[column] == ID then
- print(">>"..potion[ID][1])
- else
- print(" "..potion[ID][1])
- end
- end
- --Recieve and process keyboard input
- local eventtype, key = os.pullEvent() --get keyboard input
- if key == 200 and choice[column] == 1 then choice[column] = #potion --up
- elseif key == 200 then choice[column] = choice[column] - 1 --up
- elseif key == 208 and choice[column] == #potion then choice[column] = 1 --down
- elseif key == 208 then choice[column] = choice[column] + 1 --down
- elseif key == 205 and column == 4 then column = 1 --right
- elseif key == 205 then column = column + 1 --right
- elseif key == 203 and column == 1 then column = 4 --left
- elseif key == 203 then column = column - 1 --left
- end
- until key == 28 --if keypress = 'enter' then continue the program
- --print the user choice
- term.clear() term.setCursorPos(1,1)
- print("You have selected:\n") --print the user choice
- print("Shelf 1 Shelf 2")
- print(potion[choice[1]][1].." "..potion[choice[2]][1].."\n")
- print(" Shelf 3 Shelf 4")
- print(" "..potion[choice[3]][1].." "..potion[choice[4]][1].."\n")
- print("Are you happy with this selection? (Y/N)")
- local input = read()
- if input == "n" then
- return RunMenu()
- else
- --reduce the potionlist to just the 4 choices stored in a 2D array
- local potionShortList = {}
- for i = 1,4 do
- potionShortList[i] = potion[choice[i]]
- end
- term.clear() term.setCursorPos(1,1)
- return potionShortList
- end
- end
- function SaveFile(potionShortList) --saves the potion list as an 8 bit number in a file DONE
- print("Saving potion set to file..")
- local fileName = os.getComputerID()..".potions" --computer ID with the extension .potions
- local file = fs.open(fileName,"w")
- for potionNo = 1,4 do
- local potionString = ""
- for potionItem = 1,#potionShortList[potionNo],1 do
- potionString = potionString..potionShortList[potionNo][potionItem]
- end
- file.writeLine(potionString)
- end
- file:close()
- end
- function LoadFile() --loads the data from file and returns the potion list DONE
- print("Loading potions set from existing file..")
- local fileName = os.getComputerID()..".potions" --computer ID with the extension .potions
- local file = fs.open(fileName,"r")
- local potionShortList = {}
- potionShortList[1] = {"",""} --possibly unnecessary code
- potionShortList[2] = {"",""}
- potionShortList[3] = {"",""}
- potionShortList[4] = {"",""}
- for potionNo = 1,4,1 do
- local potionString = file.readLine()
- potionShortList[potionNo][1] = potionString:sub(1,10) --record the potion name
- for potionItem = 1,(potionString:len()-10)/9 do
- local startChar = (potionItem-1)*9 + 1 + 10
- local endChar = (potionItem) * 9 + 10
- --local ingredient = potionString:sub(startChar,endChar)
- --potionShortList[potionNo][potionItem] = ingredient
- potionShortList[potionNo][potionItem+1] = potionString:sub(startChar,endChar)
- end
- end
- file:close()
- return potionShortList
- end
- function DefineInventory(potionShortList) --gives instruction on inventory layout and returns the inventory array DONE
- local inventory = {"bottles ","n. wart "} --establish the inventory
- for potID = 1,4 do --loop through all 4 potions
- for ingredient = 2,#potionShortList[potID] do --loop through all the ingredients
- local listed = false --assume the current ingredient not in the inventory array
- for slot = 1,#inventory do
- if inventory[slot] == potionShortList[potID][ingredient] then
- listed = true
- end
- end
- if listed == false then
- inventory[#inventory+1] = potionShortList[potID][ingredient] --append the array
- end
- end
- end
- local resSlotNum = #inventory --calculates the number of reserved slots
- for slot = resSlotNum+1,16 do inventory[slot] = "[empty] " end --mark the empty slots
- --prints the inventory and scans the inventory ensuring it is at least minimally stocked
- local stocked
- repeat
- term.clear() term.setCursorPos(1,1)
- print("Stock the inventory to continue. \n\n")
- for x = 0,3 do
- print(inventory[x*4+1].." "..inventory[x*4+2].." "..inventory[x*4+3].." "..inventory[x*4+4].."")
- end
- sleep(1)
- stocked = true
- for slot = 1,resSlotNum do
- turtle.select(slot)
- if turtle.getItemCount(slot) == 0 then
- stocked = false
- end
- end
- until stocked
- term.clear() term.setCursorPos(1,1)
- return inventory, resSlotNum
- end
- function FindHome() --Navigates to home base DONE (needs to prevent breakouts)
- print("\nGetting my bearings...")
- repeat
- turtle.forward()
- turtle.turnLeft()
- until (turtle.detect() == false) and (turtle.detectDown() == false) --nothing forwards or down (narrows it down to 3 blocks, 5 orientations)
- if turtle.back() == true then
- turtle.forward()
- turtle.down()
- repeat
- turtle.forward()
- turtle.turnLeft()
- until (turtle.detect() == false) and (turtle.detectDown() == false) --nothing forwards or down
- end
- turtle.turnLeft()
- turtle.turnLeft()
- turtle.up()
- turtle.forward()
- end
- function CleanUp(reservedSlotCount) --Clears away any leftovers from the previous run DONE
- print("Cleaning up from last time")
- turtle.suckDown()
- turtle.back()
- turtle.down()
- for i = 1,3 do turtle.suck() end
- TurnAround()
- turtle.forward()
- for slot = reservedSlotCount+1,16 do
- turtle.select(slot)
- turtle.drop(64)
- end
- TurnAround()
- turtle.up()
- turtle.forward() turtle.forward() turtle.forward()
- term.clear() term.setCursorPos(1,1)
- end
- function IsShelfFull(shelfID,reservedSlotCount) --counts the contents of a shelf and returns true or false DONE
- print("Inspecting shelf #"..shelfID.."..")
- --move into position and face the shelf
- while shelfID > 1 do
- turtle.back()
- shelfID = shelfID - 1
- end
- turtle.turnLeft()
- --attempt to withdraw as many potions as possible
- turtle.select(reservedSlotCount+1)
- for slot = reservedSlotCount+1,16 do
- turtle.suck()
- end
- --count the potions and put them back
- local potionCount = 0
- for slot = reservedSlotCount+1,16 do
- turtle.select(slot)
- if turtle.getItemCount(slot) == 1 then
- potionCount = potionCount + 1
- elseif turtle.getItemCount(slot) == 0 then
- break
- end
- turtle.drop()
- end
- --go home
- turtle.turnRight()
- while turtle.forward() == true do
- turtle.forward()
- end
- --return a result
- if potionCount < 16-reservedSlotCount then
- if potionCount > 6 then
- return true
- else
- return false
- end
- else
- return true
- end
- end
- function IsEnoughIngredients(potionRecipe, inventoryList) --ensures engough supply of raw materials for brewing DONE
- print("Checking internal storage..")
- turtle.select(1) --contains bottles
- if turtle.getItemCount(1) <= 3 then return false end
- turtle.select(2)
- if turtle.getItemCount(2) <= 1 then return false end
- for slot = 3,16 do
- turtle.select(slot)
- if turtle.getItemCount(slot) <= 1 then --check item count first. more likely to be false. saves time
- for ingredient = 2,#potionRecipe do
- if inventoryList[slot] == potionRecipe[ingredient] then
- return false
- end
- end
- end
- end
- return true
- end
- function FillBottles(reservedSlotCount) --DONE
- print("Filling bottles..")
- turtle.back()
- turtle.down()
- for i = 1,3 do
- turtle.select(1) --slot 1 contains empty bottles
- turtle.placeDown()
- turtle.select(reservedSlotCount + 1)
- turtle.drop()
- end
- turtle.up()
- turtle.forward()
- end
- function BrewPotion(potionRecipe, inventoryList) --brews the potion corresponding to the shelfID DONE
- local potionSize = #potionRecipe
- turtle.select(2) --this slot contains netherwart
- turtle.dropDown(1)
- term.clear() term.setCursorPos(1,1)
- Rest(20,"brew","Brewing step 1 of "..potionSize)
- --find the next ingredient in the recipe in the inventory and put it in the stand
- for ingredient = 2,potionSize do
- for slot = 1,16 do
- if inventoryList[slot] == potionRecipe[ingredient] then
- turtle.select(slot)
- turtle.dropDown(1)
- term.clear() term.setCursorPos(1,1)
- Rest(20,"brew","Brewing step "..ingredient.." of "..potionSize)
- end
- end
- end
- end
- function RestockShelf(shelfID) --puts freshly brewed potions on the shelf DONE
- print("Restocking Shelves...")
- --move to the brewing stand
- turtle.back()
- turtle.down()
- --extract potions
- for i = 1,3 do
- turtle.suck()
- end
- --move to home
- turtle.up()
- turtle.forward()
- --move to shelf
- while shelfID > 1 do
- turtle.back()
- shelfID = shelfID - 1
- end
- turtle.turnLeft()
- --identify which slots the potions are stored in
- local slot = 16
- turtle.select(slot)
- while turtle.getItemCount(slot) == 0 do
- slot = slot - 1
- turtle.select(slot)
- end
- --put the potions away
- for i = 1,3 do
- turtle.drop()
- slot = slot - 1
- turtle.select(slot)
- end
- --move to home
- turtle.turnRight()
- while turtle.forward() == true do
- turtle.forward()
- end
- end
- function RestockTurtle(reservedSlotCount) --restocks the turtle from the storage chests DONE
- print("Restocking turtle...")
- TurnAround()
- while turtle.forward() == true do turtle.forward() end --go to the chests
- turtle.select(reservedSlotCount+1)
- while turtle.suck() == true do --get a stack of items
- for slot = 1,reservedSlotCount do turtle.transferTo(slot) end --shove it in the working inventory
- turtle.refuel() --attempt to refuel with the item
- turtle.dropDown() --dump the item in the temp chest
- end
- while turtle.suckDown() == true do --move items from temp to perm chest
- turtle.drop()
- end
- TurnAround()
- while turtle.forward() == true do turtle.forward() end --go home
- if turtle.getFuelLevel() < 50 then
- Rest(300,"sleep","Low on fuel. Slowing down work rate..")
- elseif turtle.getFuelLevel() < 100 then
- Rest(100,"sleep","Low on fuel. Slowing down work rate..")
- end
- end
- function Rest(restTime, restType, heading) --makes the turtle sleep for a time with animations DONE
- term.clear() term.setCursorPos(1,1)
- print(heading)
- local restStep
- while restTime > 0 do
- term.setCursorPos(1,2)
- if restType == "brew" then
- restStep = 1 --must be an odd number
- print("Brewing for "..restTime.."s \n")
- if math.fmod(restTime,2) == 0 then
- print[[
- \
- } \ {
- |O \o |
- | o \ |
- \_____/
- ]]
- else
- print[[
- /
- } / {
- | o / O |
- | / o |
- \_____/
- ]]
- end
- elseif restType == "sleep" then
- restStep = 1 --must be an odd number
- print("Sleeping for "..restTime.."s \n")
- if math.fmod(restTime,2) == 0 then
- print[[
- ==== ====
- // // === ===
- // // // //
- ==== ==== === ===
- ]]
- else
- print[[
- ==== ==== === ===
- // // // //
- // // === ===
- ==== ====
- ]]
- end
- end
- restTime = restTime - restStep
- sleep(restStep)
- end
- term.clear() term.setCursorPos(1,1)
- end
- function TurnAround() --turtle performs a 180 leftwise DONE
- turtle.turnLeft() turtle.turnLeft()
- end
- term.clear() term.setCursorPos(1,1)
- print("\nStarting program 'Potion Robot v1.2' by YardKing42 aka YK7942")
- Main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement