Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Current plan:
- -- Create somewhere the bot can access the network. (supply)
- -- Give it another inventory it can move things into, and from there suck into the turtle
- -- Have loop using the parallel api.
- -- Make it listen for chat. Format of "crafty <routine> <amount> <return to current>"
- -- "crafty stop" should make the bot immediately cease the program and, if possible, return to base station or wherever it started.
- -- first argument should accept stuff like fleshAuto, sourceGems, essence, etc.
- -- instead of running the actual files, these will set the the information that the computer has to use.
- -- Namely, target (the type of device to use), materials (a table of possible materials), and results
- -- If the last argument is true, then save the current location as tempHome.
- -- teleport to the access point, read through the network until you find the correct item id, move it to the other inventory in slot 1, then suck into turtle
- -- teleport to correct point ("imbuer" for source gems, "basin" for leather, etc), then execute normal program
- -- when done or stopped, check if that last argument was true. If not, return to the access point, deposit the result, send message to me, then either remain there or return to a default
- -- if true, then check how much fuel it takes to return. If it's too expensive, still return to base point and deposit the result
- -- otherwise, if argument is true and if there is enough fuel to return to starting location, do so
- -- Possibly set up "crafty echo"/"crafty say" program so that I can make crafty speak.
- -- preprogrammed responses? "Hey Crafty, say hello" could make crafty send a message to the whole server like "Hello, I'm Crafty! Ivy's autocrafting bot! Pleased to meet you all!"
- -- table of responses to the phrase "Hello Crafty" based on each user.
- local programTable
- programTable = {
- sourceGems={
- target="ars_nouveau:imbuement_chamber",
- materials = {
- --insert valid ingredients here
- ["minecraft:amethyst_shard"]=true,
- ["minecraft:lapis_lazuli"]=true
- },
- results = {
- --Insert desired results here
- ["ars_nouveau:source_gem"] = true
- },
- location="imbuer"
- },
- fleshAuto = {
- target="integrateddynamics:drying_basin",
- materials = {
- --insert valid ingredients here
- ["minecraft:rotten_flesh"]=true
- },
- results = {
- ["minecraft:leather"]=true
- },
- location="basin"
- }
- }
- local storageNames={
- drawers="functionalstorage:storage_controller_0",
- chests="sophisticatedstorage:controller_0"
- }
- local storageModems={}
- local function storageSync() for k,v in storageNames do storageModems[k]=peripheral.wrap(v) end end
- local queue={}
- local stopped=false
- local suck,drop
- local fuelList = {
- ["minecraft:charcoal"]=80,
- ["minecraft:coal"]=80,
- ["modern_industrialization:lignite_coal"]=80
- }
- local chatBox = peripheral.find("chatBox")
- local automata = peripheral.find("endAutomata")
- local sideSearch = {
- front=function()
- suck = turtle.suck()
- drop = turtle.drop()
- return true
- end,
- left=function()
- turtle.turnLeft()
- suck = turtle.suck()
- drop = turtle.drop()
- return true end,
- right=function()
- turtle.turnRight()
- suck = turtle.suck()
- drop = turtle.drop()
- return true end,
- back=function ()
- turtle.turnLeft()
- turtle.turnLeft()
- suck = turtle.suck()
- drop = turtle.drop()
- return true
- end,
- top=function ()
- suck=turtle.suckUp
- drop=turtle.dropUp
- end,
- bottom=function ()
- suck=turtle.suckDown
- drop=turtle.dropDown
- end
- }
- local function warpFuel(location)
- local targetNumber = automata.estimateWarpCost(location) - turtle.getFuelLevel()
- if targetNumber <= 0 then return true end
- local solution={}
- for k,v in pairs(fuelList) do
- if targetNumber <= 0 then break end
- for i=16,1,-1 do
- if turtle.getItemDetail(i) ~= nil and k == turtle.getItemDetail(i).name then
- if turtle.getItemDetail(i).count * v >= targetNumber then
- solution[#solution+1] = {i,math.ceil(targetNumber/v)}
- targetNumber=0
- break
- else
- solution[#solution+1] = {i,turtle.getItemDetail(i).count}
- targetNumber = targetNumber - (turtle.getItemDetail(i).count*v)
- end
- end
- end
- end
- if targetNumber > 0 then return false
- else
- for k,v in pairs(solution) do
- turtle.select(v[1])
- turtle.refuel(v[2])
- end
- return true
- end
- end
- local function refuelFromStorage(targetNum)
- local targetNumber = targetNum - turtle.getFuelLevel()
- local solution={}
- for fuel,fuelVal in pairs(fuelList) do
- if targetNumber <= 0 then break end
- for _,modem in pairs(storageModems) do
- if targetNumber <= 0 then break end
- for slot,item in pairs(modem.list()) do
- if item.name == fuel then
- if item.count*fuelVal >= targetNumber then
- targetNumber=0
- solution[#solution+1] = {modem,slot, math.ceil(targetNumber/fuelVal)}
- break
- else
- targetNumber=targetNumber-(item.count*fuelVal)
- solution[#solution+1] = {modem,slot, item.count}
- end
- end
- end
- end
- end
- if targetNumber<=0 then
- local chest = peripheral.wrap("bottom")
- --move items to chest to be put into turtle
- for _,v in pairs(solution) do
- v[1].pushItems("bottom",v[2],v[3])
- end
- for i=16,1,-1 do
- if turtle.getItemDetail(i) == nil then turtle.select(i) break end
- end
- for k,v in pairs(bottom.list()) do
- bottom.pushItems("bottom",k,nil,1)
- turtle.suck()
- turtle.refuel()
- end
- return true
- else
- return false
- end
- end
- local function warp(location)
- local function tryWarp(destination)
- local success = automata.warpToPoint(destination)
- if not success then
- local nearestPoint
- for _,v in pairs(automata.points()) do
- if nearestPoint == nil or automata.distanceToPoint(v)<automata.distanceToPoint(nearestPoint) then nearestPoint=v end
- end
- chatBox.sendFormattedMessageToPlayer(textutils.serialiseJSON({
- {text="I'm sorry, but something went wrong when trying to warp! I'm closest to "},
- {text=nearestPoint,color="gold"},
- {", though. Please come pick me up!"}
- }), "Gallent_Bristle", "Crafty")
- return false
- else return true
- end
- end
- if automata.estimateWarpCost(location) >= turtle.getFuelLevel() or warpFuel(location) then
- return tryWarp(location)
- elseif automata.estimateWarpCost("supply") >= turtle.getFuelLevel() or warpFuel("supply") then
- chatBox.sendFormattedMessageToPlayer(textutils.serialiseJSON({
- {text="Have to refuel before I can get to "},
- {text=location,color="gold"},
- {text=", but I'll be right there!"}
- }),"Gallent_Bristle", "Crafty")
- if not tryWarp("supply") then
- return false
- end
- if refuelFromStorage(automata.estimateWarpCost(location)) then
- if refuelFromStorage(automata.estimateWarpCost(location)*2)then
- chatBox.sendMessageToPlayer("Alright, all fueled up and ready to go!", "Gallent_Bristle", "Crafty")
- else
- chatBox.sendMessageToPlayer("We don't have enough fuel for a return trip. Should I make the jump?", "Gallent_Bristle", "Crafty")
- local jumping = true
- parallel.waitForAny(
- function()
- while true do
- local _, username, message, uuid, isHidden = os.pullEvent("chat")
- if isHidden and uuid == "58b2110a-ceb4-4781-9359-1a764ac57edc" then
- lowerString = string.lower(message)
- if lowerString:find("deny") == 1 or lowerString:find("crafty deny") == 1
- or lowerString:find("no") == 1 or lowerString:find("crafty no") == 1
- or lowerString:find("cancel") == 1 then
- jumping = false
- chatBox.sendMessageToPlayer("Alright, I'll stay at the base!", "Gallent_Bristle", "Crafty")
- break
- elseif message:find("confirm") or message:find("yes") then
- chatBox.sendMessageToPlayer("Ok, warping now!", "Gallent_Bristle", "Crafty")
- break
- end
- end
- end
- end,
- function ()
- sleep(60)
- chatBox.sendMessageToPlayer("I didn't get a response, should I warp?", "Gallent_Bristle", "Crafty")
- sleep(60)
- chatBox.sendFormattedMessageToPlayer(textutils.serialiseJSON({
- {text="I'm going to warp now, but I'll be over by "},
- {text=location,color="gold"},
- {text=" so you can pick me up there."}
- }), "Gallent_Bristle", "Crafty")
- end
- )
- if jumping then return tryWarp(location) end
- end
- else
- chatBox.sendMessageToPlayer("I'm sorry, we don't have enough fuel to make it to the crafting station! Please bring more and try again.", "Gallent_Bristle", "Crafty")
- return false
- end
- else
- local nearestPoint
- for _,v in pairs(automata.points()) do
- if nearestPoint == nil or automata.distanceToPoint(v)<automata.distanceToPoint(nearestPoint) then nearestPoint=v end
- end
- chatBox.sendFormattedMessageToPlayer(textutils.serialiseJSON({
- {text="I'm sorry, but I can't warp right now! I don't have enough fuel! I'm closest to "},
- {text=nearestPoint,color="gold"},
- {", though. Please come pick me up, or at least refuel me."}
- }), "Gallent_Bristle", "Crafty")
- return false
- end
- end
- local function processMats(args)
- --go to supply area
- if not warp("supply") then return end
- local amount
- if args.amount ~= nil then amount = args.amount else amount = 64 end
- local details = programTable[args.name]
- --Withdraw materials
- local startingMats={}
- for _,modem in pairs(storageModems) do
- for slot,item in pairs(modem.list()) do
- if details.materials[item.name] then
- startingMats[#startingMats+1] = {modem,slot,item.count}
- end
- end
- end
- while amount > 0 and next(startingMats) ~= nil do
- local mostItems=1
- for k,v in pairs(startingMats) do
- if v[3] > startingMats[mostItems][3] then mostItems=k end
- end
- if startingMats[mostItems][3] >= amount then
- startingMats[mostItems][1].pushItems("bottom", startingMats[mostItems][2], amount)
- amount = 0
- break
- else
- startingMats[mostItems][1].pushItems("bottom",startingMats[mostItems][2])
- amount = amount-startingMats[mostItems][3]
- startingMats[mostItems]=nil
- end
- end
- for k,v in pairs(peripheral.wrap("bottom").list()) do
- peripheral.wrap("bottom").pushItems("bottom",k,nil,1)
- for i=1,16 do
- if turtle.getItemDetail(i) == nil or (turtle.getItemDetail(i) ~= nil and turtle.getItemDetail(i).name == v.name) then turtle.select(i) break end
- end
- turtle.suckDown()
- end
- -- go to area
- if not warp(details.location) then return end
- --find device
- local target = peripheral.find(details.target)
- if target== nil then
- turtle.turnLeft()
- target = peripheral.find(details.target)
- if target == nil then
- chatBox.sendFormattedMessageToPlayer(
- textutils.serialiseJSON({
- {text="I'm sorry, I cannot find the block id "},
- {text=details.target, color="red"},
- {text=" at this location. Did you move it, perhaps? Be sure to update the point named "},
- {text=details.location, color="gold"},
- {text=" when you are able!"}
- }), "Gallent_Bristle", "Crafty"
- )
- return
- end
- end
- sideSearch[target]()
- --start creating items
- local input,output
- if details.input ~= nil then input = details.input else input = 1 end
- if details.output ~= nil then output = details.output else output = target.size() end
- local matSlots = {}
- for i=1,16 do
- if turtle.getItemDetail(i) ~= nil and
- (details.materials[turtle.getItemDetail(i).name])
- then
- table.insert(matSlots,i)
- end
- end
- local resultCell=0
- local function emptyCheck()
- for i=1,16 do
- if turtle.getItemDetail(i) == nil then
- if resultCell == 0 then resultCell=i end
- elseif (details.results[turtle.getItemDetail(i).name] and turtle.getItemDetail(i).count < turtle.getItemDetail(i,true).maxCount) then
- resultCell=i
- break
- end
- end
- return resultCell
- end
- local function makeItem(currentSlot)
- turtle.select(currentSlot)
- emptyCheck()
- while true do
- if target.getItemDetail(1) ~= nil and not details.materials[target.getItemDetail(1).name] then
- turtle.select(resultCell)
- suck(1)
- local detail = turtle.getItemDetail(resultCell,true)
- if not details.results[detail.name] or detail.count==detail.maxCount then emptyCheck() end
- turtle.select(currentSlot)
- end
- if target.getItemDetail(1) == nil then
- local check = turtle.getItemDetail(currentSlot)
- if check ~= nil and details.materials[check.name] then drop(1)
- else break
- end
- end
- end
- end
- for _,v in pairs(matSlots) do
- makeItem(v)
- end
- --return and deposit items, or if argument 4 is true, return to tempHome
- if (not args.altReturn) and warp("supply") then
- for i=1,16 do
- if turtle.getItemDetail(i) ~= nil and details.results[turtle.getItemDetail(i)] then
- turtle.select(i)
- turtle.dropUp()
- end
- end
- else
- warp("tempHome")
- end
- end
- parallel.waitForAny(
- function()
- local username, message, uuid, isHidden
- while true do
- _, username, message, uuid, isHidden = os.pullEvent("chat")
- if isHidden and uuid == "58b2110a-ceb4-4781-9359-1a764ac57edc" then
- local args = {}
- for word in message:gmatch("%S+") do args[#args+1] = word end
- if args[1]:lower() == "crafty" then
- if args[2]:lower() == "echo" then
- local sayThis = message:gsub(args[1].." "..args[2].." ","")
- chatBox.sendMessageToPlayer(sayThis, username, "Crafty")
- end
- if args[2]:lower() == "say" then
- local sayThis = message:gsub(args[1].." "..args[2].." ","")
- chatBox.sendMessage(sayThis, "Crafty")
- end
- if args[2]:lower() == "stop" then return end
- end
- elseif select(1, message:lower():gsub("[^%w%s]+", "")):find("crafty say hello") and uuid == "58b2110a-ceb4-4781-9359-1a764ac57edc" then
- chatBox.sendMessage("Hello, I'm Crafty! Ivy's new robot meant to assist with many tasks and automation! It's a huge pleasure to meet you all! ^.^", "Crafty")
- end
- end end,
- function() while true do
- local tasks = {}
- if next(queue) ~= nil then
- tasks=queue
- queue={}
- end
- if next(tasks) ~= nil then
- for k,v in pairs(tasks) do
- if v.args ~= nil then v.func(v.args) else v.func() end
- end
- end
- os.sleep(0)
- end end
- )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement