Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Computercraft program that auto mutates bees from forestrycraft
- -- Configs:
- species1 = "meadows"
- species2 = "forest"
- targetSpecies = "common"
- alwaysPreferTarget = false -- If true, will always use a bee if it has the target species in active or inactive
- -- How to use:
- -- Place turtle down with a big chest, an analyzer and an apiary touching it.
- -- Edit the configs above to match the species it is working with, and the target species.
- -- You can also run program with params: <species1> <species2> <targetSpecies>
- -- Edit the configs below to match your setup from where stuff is relative to the turtle.
- -- The apiary must be untouched during the program.
- -- Turtle slot 1 must be empty.
- -- Start the program, wait for the turtle to do it's job.
- -- All caps
- turtleFacing = "EAST"
- storageDirection = "SOUTH"
- analyzerDirection = "NORTH"
- apiaryDirection = "EAST"
- -- DO NOT EDIT BELOW
- dirs = {[1] = "NORTH", ["NORTH"] = 1,
- [2] = "EAST", ["EAST"] = 2,
- [3] = "SOUTH", ["SOUTH"] = 3,
- [4] = "WEST", ["WEST"] = 4}
- local Args = {...}
- if Args[1] == "update" then
- local running = shell.getRunningProgram()
- print("Updating " .. running .. ".")
- fs.delete(running)
- shell.run("pastebin", "get", "F6LPTxQ6", running)
- print("Finished updating.")
- return
- end
- function analyzeAll()
- print("Analyzing all bees in storage..")
- for slot, e in pairs(storage.p.getAllStacks()) do
- if not isBeeAnalyzed(storage.p.getStackInSlot(slot)) then
- while not moveStack(storage, analyzer, slot) do
- if not moveAllAnalyzedToStorage() then
- sleep(1)
- end
- end
- end
- end
- sleep(1)
- if analyzer.p.hasWork() then print("Waiting for analyzing done..") end
- while analyzer.p.hasWork() do
- moveAllAnalyzedToStorage()
- sleep(1)
- end
- moveAllAnalyzedToStorage()
- print("Analyzing done..")
- end
- function moveAllAnalyzedToStorage()
- for i = 9, 12 do
- moveStack(analyzer, storage, i)
- end
- end
- function moveAllApiaryToStorage()
- print("Moving apiary products to storage..")
- for i = 1, 9 do
- if apiary.p.getStackInSlot(i) ~= nil and not moveStack(apiary, storage, i) then
- print("Could not move apiary products to storage?")
- return
- end
- end
- end
- function analyzerHasHoney()
- local c = analyzer.getTankInfo()[1].contents
- return compareString(c.name, "honey") and c.amount >= 100
- end
- function isBee(item)
- return item.individual ~= nil
- end
- function isBeeAnalyzed(item)
- if item.individual == nil then return true end -- Not a bee
- return item.individual.isAnalyzed;
- end
- function getBeeData(item)
- if item.individual == nil then return nil end -- Not a bee
- local data = {}
- data.isAnalyzed = item.individual.isAnalyzed
- data.type = getBeeType(item)
- if data.isAnalyzed then
- data.active = item.individual.active.species.name
- data.inactive = item.individual.inactive.species.name
- end
- return data
- end
- function getBeeString(item)
- if item.individual == nil then return "nil" end -- Not a bee
- local data = getBeeData(item)
- return data.active .. ":" .. data.inactive
- end
- function getBeeType(item)
- local name = item.name
- if compareString(name, "drone") then return "d" end
- if compareString(name, "princess") then return "p" end
- if compareString(name, "queen") then return "q" end
- return "nil"
- end
- function getItem(inventory, slot)
- return inventory.p.getStackInSlot(slot)
- end
- function getFirstQueen()
- for slot, i in pairs(storage.p.getAllStacks()) do
- local item = getItem(storage, slot)
- if getBeeType(item) == "q" then
- return slot
- end
- end
- return 0
- end
- function getBestPrincessSlot()
- local bestValue = 0
- local bestSlot = 0
- for slot, i in pairs(storage.p.getAllStacks()) do
- if isBee(getItem(storage, slot)) and isBeeAnalyzed(getItem(storage, slot)) then
- if getBeeType(getItem(storage, slot)) == "p" then
- local nextValue = getBeeValue(getItem(storage, slot))
- if nextValue > bestValue then
- bestValue = nextValue
- bestSlot = slot
- end
- end
- end
- end
- -- if bestSlot == 0 then
- -- print("Could not find a propper queen to use.")
- -- else
- -- print("Found best princess in slot " .. bestSlot .. ": " .. getBeeString(getItem(storage, bestSlot)))
- -- end
- return bestSlot
- end
- function getBestDroneSlot(queen)
- local bestValue = 0
- local bestSlot = 0
- for slot, i in pairs(storage.p.getAllStacks()) do
- if isBee(getItem(storage, slot)) and isBeeAnalyzed(getItem(storage, slot)) then
- if getBeeType(getItem(storage, slot)) == "d" then
- local nextValue = getMatchValue(getItem(storage, slot), queen)
- if nextValue > bestValue then
- bestValue = nextValue
- bestSlot = slot
- end
- end
- end
- end
- -- if bestSlot == 0 then
- -- print("Could not find a propper drone to use.")
- -- else
- -- print("Found drone in slot " .. bestSlot .. ": " .. getBeeString(getItem(storage, bestSlot)))
- -- end
- return bestSlot
- end
- function getBeeValue(bee)
- local beeData = getBeeData(bee)
- local value = 0
- if compareString(beeData.active, species1) or compareString(beeData.active, species2) then
- value = value + 1
- end
- if compareString(beeData.inactive, species1) or compareString(beeData.inactive, species2) then
- value = value + 1
- end
- if compareString(beeData.inactive, targetSpecies) then -- Needs to run 2 times, if both inactive and active is, it is good
- if alwaysPreferTarget then value = value + 100
- else value = value + 2 end
- end
- if compareString(beeData.active, targetSpecies) then
- if alwaysPreferTarget then value = value + 100
- else value = value + 2 end
- end
- return value
- end
- function getMatchValue(drone, queen)
- local queenData = getBeeData(queen)
- local lookfor = nil
- if compareString(queenData.active, species1) and compareString(queenData.inactive, species1) then
- lookfor = species2
- elseif compareString(queenData.active, species2) and compareString(queenData.inactive, species2) then
- lookfor = species1
- end
- if lookfor == nil then
- return getBeeValue(drone)
- end
- local beeData = getBeeData(drone)
- local value = 0
- if compareString(beeData.active, lookfor) then
- value = value + 1
- end
- if compareString(beeData.inactive, lookfor) then
- value = value + 1
- end
- if compareString(beeData.active, targetSpecies) then -- Needs to run 2 times, if both inactive and active is, it is good
- if alwaysPreferTarget then value = value + 100
- else value = value + 2 end
- end
- if compareString(beeData.inactive, targetSpecies) then
- if alwaysPreferTarget then value = value + 100
- else value = value + 2 end
- end
- return value
- end
- function isDone()
- local droneDone = false
- local princessDone = false
- for slot, i in pairs(storage.p.getAllStacks()) do
- local item = getItem(storage, slot)
- if isBee(item) and isBeeAnalyzed(item) then
- local beeData = getBeeData(item)
- if compareString(beeData.active, targetSpecies) and compareString(beeData.inactive, targetSpecies) then
- if getBeeType(item) == "d" then
- droneDone = true
- elseif getBeeType(item) == "p" then
- princessDone = true
- end
- if droneDone and princessDone then return true end
- end
- end
- end
- return false
- end
- function moveItems(invFrom, invTo, slotFrom, slotTo, totalItems)
- local found = invFrom.p.pushItem(getOppositeDir(invFrom.d), slotFrom, totalItems, 1)
- if found == 0 then return false end
- local total = invTo.p.pullItem(getOppositeDir(invTo.d), 1, totalItems, slotTo)
- if total == 0 then
- invFrom.p.pullItem(getOppositeDir(invFrom.d), 1, totalItems, slotFrom)
- return false
- end
- return true
- end
- function moveStack(invFrom, invTo, slotFrom, slotTo)
- return moveItems(invFrom, invTo, slotFrom, slotTo, 1000)
- end
- function moveStack(invFrom, invTo, slotFrom)
- local found = invFrom.p.pushItem(getOppositeDir(invFrom.d), slotFrom, 100, 1)
- if found == 0 then return false end
- local total = invTo.p.pullItem(getOppositeDir(invTo.d), 1)
- if total == 0 then
- invFrom.p.pullItem(getOppositeDir(invFrom.d), 1, 100, slotFrom)
- return false
- end
- return true
- end
- function compareString(master, match)
- return string.match(master:lower(), match:lower()) ~= nil
- end
- function getIntDir(dir)
- if type(dir) == "string" then
- return dirs[dir]
- end
- return dir
- end
- function getOppositeDir(dir)
- local finalDir = getIntDir(dir)
- return dirs[((finalDir - 1 + 2) % 4) + 1] -- Stupid lua index offset ;)
- end
- function convertDir(dir)
- local periDir = getIntDir(dir)
- local facingDir = dirs[turtleFacing]
- local cDir = facingDir - periDir
- if cDir == 0 then return "front" end
- if cDir == 1 then return "left" end
- if cDir == -1 then return "right" end
- if cDir == 2 then return "back" end
- if cDir == -2 then return "back" end
- end
- function log(msg)
- local path = shell.getRunningProgram() .. "log"
- local file = fs.open(path, "a")
- file.writeLine(msg)
- file.close()
- end
- function clearLog()
- local path = shell.getRunningProgram() .. "log"
- fs.delete(path)
- end
- apiary = {p = peripheral.wrap(convertDir(apiaryDirection)), d = apiaryDirection}
- storage = {p = peripheral.wrap(convertDir(storageDirection)), d = storageDirection}
- analyzer = {p = peripheral.wrap(convertDir(analyzerDirection)), d = analyzerDirection}
- totalCycles = 0
- firstCouple = nil
- function saveData()
- local path = shell.getRunningProgram() .. "save"
- fs.delete(path)
- local file = fs.open(path, "a")
- local data = {}
- data.species1 = species1
- data.species2 = species2
- data.targetSpecies = targetSpecies
- data.cycle = totalCycles
- data.firstCouple = firstCouple
- file.writeLine(textutils.serialize(data))
- file.close()
- end
- function loadData()
- local path = shell.getRunningProgram() .. "save"
- if not fs.exists(path) then
- return false
- end
- local file = fs.open(path, "r")
- local readAll = file.readAll()
- file.close()
- local data = textutils.unserialize(readAll)
- if data.species1 ~= species1 or data.species2 ~= species2 or data.targetSpecies ~= targetSpecies then
- return false
- end
- totalCycles = data.cycle
- firstCouple = data.firstCouple
- return true
- end
- if Args[1] == "test" then
- if not loadData() then
- print("Saved data did not match config, starting new mutaton..")
- clearLog()
- saveData()
- end
- print("Done testing")
- return
- end
- if #Args >= 3 then
- species1 = Args[1]
- species2 = Args[2]
- targetSpecies = Args[3]
- print("Got input: " .. species1 .. ":" .. species2 .. " > " .. targetSpecies)
- end
- if not loadData() then
- print("Saved data did not match config, starting new mutaton..")
- clearLog()
- saveData()
- totalCycles = 0
- firstCouple = nil
- end
- while true do
- local printStatus = true
- local currentQueen = getItem(apiary, 1)
- if currentQueen ~= nil and getBeeType(currentQueen) == "q" then
- print("Waiting for apiary to finish..")
- while getItem(apiary, 1) ~= nil do
- sleep(5)
- end
- end
- moveAllApiaryToStorage()
- local foundQueen = getFirstQueen()
- if foundQueen ~= 0 then
- print("Found queen in storage, breeding her first.")
- moveItems(storage, apiary, foundQueen, 1, 1)
- sleep(1)
- else
- analyzeAll()
- if isDone() then
- log("Successfully purebred " .. targetSpecies .. "!")
- print("Successfully purebred " .. targetSpecies .. " in " .. totalCycles .. " cycles!")
- print("First couple used was: " .. tostring(firstCouple))
- return
- end
- local bestPrincess = getBestPrincessSlot()
- if bestPrincess == 0 then
- print("Could not find useable princess, sorry!")
- return
- end
- local bestMatch = getBestDroneSlot(getItem(storage, bestPrincess))
- if bestMatch == 0 then
- exit("Could not find useable drone, sorry!")
- return
- end
- print("Found usable couple:")
- local coupleString = getBeeString(getItem(storage, bestPrincess)) .. " and " .. getBeeString(getItem(storage, bestMatch))
- if firstCouple == nil then firstCouple = coupleString end
- log("#" .. totalCycles .. ": " .. coupleString)
- print(coupleString)
- moveItems(storage, apiary, bestPrincess, 1, 1)
- moveItems(storage, apiary, bestMatch, 2, 1)
- totalCycles = totalCycles + 1
- saveData()
- sleep(5)
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment