Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Basalt configurated installer
- local filePath = "basalt.lua" --here you can change the file path default: basalt
- if not(fs.exists(filePath))then
- shell.run("pastebin run ESs1mg7P packed true "..filePath:gsub(".lua", "")) -- this is an alternative to the wget command
- end
- local basalt = require(filePath:gsub(".lua", "")) -- here you can change the variablename in any variablename you want default: basalt
- local maxCoWorker = 3
- local recipeList = {}
- local craftingQueue = {}
- local bridge = peripheral.find("rsBridge")
- local w, h = term.getSize()
- local main = basalt.createFrame()
- local home = main:addFrame():setPosition(1,2):setBackground(colors.lightGray):setSize(w, h-2)
- local recipes = main:addFrame():setPosition(1,2):setBackground(colors.lightGray):hide()
- local log = main:addFrame():setPosition(1,2):setBackground(colors.lightGray):hide()
- local menuBar = main:addMenubar():addItem("Home"):addItem("Recipes"):addItem("Log"):setBackground(colors.gray):setSize(w, 1):setSpace(6):setScrollable():show()
- menuBar:onChange(function(self)
- home:hide()
- recipes:hide()
- log:hide()
- if(self:getValue().text=="Home")then
- home:show()
- elseif(self:getValue().text=="Recipes")then
- recipes:show()
- elseif(self:getValue().text=="Log")then
- log:show()
- end
- end)
- local function buttonVisuals(btn)
- btn:onClick(basalt.schedule(function() btn:setBackground(colors.black) btn:setForeground(colors.lightGray) os.sleep(0.1) btn:setBackground(colors.gray) btn:setForeground(colors.black) end))
- end
- local coworkerCount = home:addLabel():setText(maxCoWorker):setPosition(45,2):show()
- home:addLabel():setText("Co-Worker:"):setPosition(32,2):show()
- buttonVisuals(home:addButton():setText(">"):setSize(1,1):setPosition(47,2):onClick(function() if(maxCoWorker<100)then maxCoWorker = maxCoWorker+1 end coworkerCount:setText(maxCoWorker) end):show())
- buttonVisuals(home:addButton():setText("<"):setSize(1,1):setPosition(43,2):onClick(function() if(maxCoWorker>1)then maxCoWorker = maxCoWorker-1 end coworkerCount:setText(maxCoWorker) end):show())
- local logList = log:addList():setPosition(2,2):setSize(w-2,h-3):setScrollable(false):show()
- local jobList = home:addList():setPosition(20,4):setSize(30,10):show()
- local rList = recipes:addList():setPosition(13,2):setSize(38,16):show()
- local function logging(text)
- logList:addItem(text)
- if(logList:getItemCount()>h-3)then
- logList:removeItem(1)
- end
- end
- logging("Loading autocrafter...")
- function SaveToFile()
- local file = io.open("recipes", "wb")
- local sel = rList:getItemIndex()
- rList:clear()
- for _,v in pairs(recipeList)do
- if(v.useDmg)then
- file:write(v.name.."|"..v.damage.."|"..v.minAmount.."|"..v.maxCraftAmount.."|true|", "\n")
- else
- file:write(v.name.."|"..v.damage.."|"..v.minAmount.."|"..v.maxCraftAmount.."|false|", "\n")
- end
- rList:addItem(v.minAmount.."x "..v.name..":"..v.damage, nil, nil, v)
- end
- rList:selectItem(sel)
- file:close()
- end
- buttonVisuals(recipes:addButton():setPosition(2,2):setText("Remove"):setSize(8,1):onClick(function()
- if(rList:getValue()~=nil)then
- local sel = rList:getValue().args[1]
- for k,v in pairs(recipeList)do
- if(v.name==sel.name)and(tonumber(v.damage)==tonumber(sel.damage))then
- table.remove(recipeList, k)
- logging("Removed recipe: "..v.name..":"..v.damage)
- SaveToFile()
- end
- end
- end
- end))
- local changeAmn = recipes:addInput():setPosition(4,4):setSize(5,1):setInputType("number"):setForeground(colors.black):setDefaultText("32", colors.black):onChange(function(self)
- local val = tonumber(self:getValue()) or 32
- if(val<0)then
- self:setValue(0)
- end
- end)
- buttonVisuals(recipes:addButton():setPosition(2,4):setSize(1,1):setText("-"):onClick(function()
- local val = tonumber(changeAmn:getValue()) or 32
- if(rList:getValue()~=nil)then
- local sel = rList:getValue().args[1]
- if(val>0)and(sel.name~=nil)and(sel.damage~=nil)then
- for k,v in pairs(recipeList)do
- if(v.name==sel.name)and(tonumber(v.damage)==tonumber(sel.damage))then
- v.minAmount = v.minAmount - val
- if(v.minAmount < 0)then v.minAmount = 0 end
- SaveToFile()
- end
- end
- end
- end
- end))
- buttonVisuals(recipes:addButton():setPosition(10,4):setSize(1,1):setText("+"):onClick(function()
- local val = tonumber(changeAmn:getValue()) or 32
- if(rList:getValue()~=nil)then
- local sel = rList:getValue().args[1]
- if(val>0)and(sel.name~=nil)and(sel.damage~=nil)then
- for k,v in pairs(recipeList)do
- if(v.name==sel.name)and(tonumber(v.damage)==tonumber(sel.damage))then
- v.minAmount = v.minAmount + val
- SaveToFile()
- end
- end
- end
- end
- end))
- buttonVisuals(recipes:addButton():setPosition(2,6):setSize(8,1):setText("Set"):onClick(function()
- local val = tonumber(changeAmn:getValue()) or 32
- if(rList:getValue()~=nil)then
- local sel = rList:getValue().args[1]
- if(val>0)and(sel.name~=nil)and(sel.damage~=nil)then
- for k,v in pairs(recipeList)do
- if(v.name==sel.name)and(tonumber(v.damage)==tonumber(sel.damage))then
- v.minAmount = val
- SaveToFile()
- end
- end
- end
- end
- end))
- local rItemFrame = home:addFrame():setPosition(7,3):setBackground(colors.gray):setSize(27,6):setMoveable(true):setBar("Remove Item", colors.black, colors.lightGray):showBar():hide()
- rItemFrame:addButton():setPosition(1,1):setAnchor("topRight"):setSize(1,1):setBackground(colors.black):setForeground(colors.lightGray):setText("x"):onClick(function() rItemFrame:hide() end):show()
- rItemFrame:addLabel():setText("Item ID:"):setPosition(2,3):show()
- local ritemId = rItemFrame:addInput("itemid"):setPosition(12,3):setSize(15,1):setBackground(colors.black):setForeground(colors.lightGray):setDefaultText("minecraft:stick", colors.gray):show()
- rItemFrame:addButton():setPosition(-7,0):setAnchor("bottomRight"):setSize(8,1):setBackground(colors.black):setForeground(colors.lightGray):setText("Remove"):onClick(function()
- local id = ritemId:getValue()
- for k,v in pairs(recipeList)do
- if(v.name==id)then
- table.remove(recipeList, k)
- logging("Removed recipe: "..v.name..":"..v.damage)
- end
- end
- SaveToFile()
- end)
- local aItemFrame = home:addFrame():setPosition(7,3):setBackground(colors.gray):setSize(27,12):setMoveable(true):setBar("Add Item", colors.black, colors.lightGray):showBar():hide()
- aItemFrame:addLabel():setText("Item ID:"):setPosition(2,3)
- aItemFrame:addLabel():setText("Damage:"):setPosition(2,5)
- aItemFrame:addLabel():setText("Count:"):setPosition(2,7)
- aItemFrame:addLabel():setText("Max:"):setPosition(2,9)
- aItemFrame:addLabel():setText("Use Damage:"):setAnchor("bottomLeft"):setPosition(4,0)
- local itemId = aItemFrame:addInput():setPosition(12,3):setSize(15,1):setBackground(colors.black):setForeground(colors.lightGray):setDefaultText("minecraft:stick", colors.gray)
- local itemDamage = aItemFrame:addInput():setPosition(12,5):setSize(15,1):setBackground(colors.black):setForeground(colors.lightGray):setInputType("number"):setDefaultText("0", colors.gray)
- local itemCount = aItemFrame:addInput():setPosition(12,7):setSize(15,1):setBackground(colors.black):setForeground(colors.lightGray):setInputType("number"):setDefaultText("64", colors.gray)
- local itemMaxCount = aItemFrame:addInput():setPosition(12,9):setSize(15,1):setBackground(colors.black):setForeground(colors.lightGray):setInputType("number"):setDefaultText("0", colors.gray)
- local useDamage = aItemFrame:addCheckbox():setAnchor("bottomLeft"):setPosition(2,0):setBackground(colors.black):setForeground(colors.lightGray):setValue(true)
- aItemFrame:addButton():setAnchor("topRight"):setPosition(1,1):setSize(1,1):setBackground(colors.black):setForeground(colors.lightGray):setText("x"):onClick(function() aItemFrame:hide() end)
- aItemFrame:addButton():setAnchor("bottomRight"):setPosition(-4,0):setSize(5,1):setBackground(colors.black):setForeground(colors.lightGray):setText("Add"):onClick(function()
- local id = itemId:getValue()
- local dmg = itemDamage:getValue() == "" and 0 or itemDamage:getValue()
- local count = itemCount:getValue() == "" and 64 or itemCount:getValue()
- local maxCount = itemMaxCount:getValue() == "" and 0 or itemMaxCount:getValue()
- local usedamage = useDamage:getValue() or true
- if(id~="")then
- local itemExist = false
- for k,v in pairs(recipeList)do
- if(v.name==id)then
- if(usedamage)then
- if(v.damage==dmg)then
- itemExist = true
- v.minAmount = count or 64
- v.maxCraftAmount = maxCount or 0
- logging("Edited recipe: "..(count).."x "..id..":"..dmg)
- end
- else
- itemExist = true
- v.minAmount = count or 64
- v.maxCraftAmount = maxCount or 0
- logging("Edited recipe: "..(count).."x "..id..":"..dmg)
- end
- end
- end
- if(itemExist == false)then
- table.insert(recipeList, {name = id, damage = dmg or 0, minAmount = count, maxCraftAmount = maxCount or 0, useDmg = usedamage, fails = 0, timer = 0})
- logging("Added recipe: "..(count).."x "..id..":"..dmg)
- end
- SaveToFile()
- else
- logging("Please set a ID.")
- end
- end)
- buttonVisuals(home:addButton():setText("Add Item"):setSize(12,3):setPosition(2,6):onClick(function() aItemFrame:show() aItemFrame:setFocus() end):show())
- buttonVisuals(home:addButton():setText("Remove Item"):setSize(12,3):setPosition(2,10):onClick(function() rItemFrame:show() rItemFrame:setFocus() end):show())
- local function StringSeperate(str, seperator)
- local words = {}
- local word = ""
- if(string.sub(str, str:len(), str:len())~=seperator)then
- str = str..""..seperator
- end
- for x=1,str:len() do
- local s = string.sub(str,x,x)
- if(s==seperator)then
- table.insert(words, word)
- word = ""
- else
- word = word..s
- end
- end
- return words
- end
- if not(fs.exists("recipes"))then
- fs.open("recipes","w").close()
- end
- local f = fs.open("recipes", "r")
- for line in f.readLine do
- local tab = StringSeperate(line, "|")
- if(tab[1]~=nil)and(tab[2]~=nil)and(tab[3]~=nil)and(tab[4]~=nil)and(tab[5]~=nil)then
- logging("Registered recipe: "..tab[3].."x "..tab[1]..":"..tab[2])
- local recipe = {name=tab[1],damage=tonumber(tab[2]),minAmount=tonumber(tab[3]),maxCraftAmount=tonumber(tab[4]),fails=0,timer=0}
- if(tab[5]=="true")then
- recipe.useDmg=true
- else
- recipe.useDmg=false
- end
- rList:addItem(recipe.minAmount.."x "..recipe.name..":"..recipe.damage, nil, nil, recipe)
- table.insert(recipeList, recipe)
- end
- end
- f.close()
- local function findKeyWithItemName(table, itemname, damage)
- for k,v in pairs(table)do
- if(v.name==itemname)and(v.damage == damage)then
- return k
- end
- end
- return nil
- end
- local scanChestBtn = home:addButton("scanChest"):setText("Scan Chest"):setSize(12,3):setPosition(2,2):show()
- local function checkChestForNewEntrys()
- scanChestBtn:setText("Scanning..")
- local inventory = peripheral.find("minecraft:chest")
- local items = {}
- local itemAmounts = {}
- local somethingChanged = false
- if(inventory~=nil)then
- for x=1,inventory.size(), 1 do
- local item = inventory.getItemDetail(x)
- if(item~=nil)then
- if(item.damage==nil)then item.damage = 0 end
- table.insert(items, item)
- end
- os.sleep(0.1)
- end
- else
- logging("No chest available!")
- end
- if(#items > 0)then
- for _,v in pairs(items)do
- local key = findKeyWithItemName(itemAmounts, v.name, v.damage)
- if(key~=nil)then
- itemAmounts[key].count = itemAmounts[key].count + v.count
- else
- table.insert( itemAmounts, {name=v.name, damage=v.damage, count = v.count})
- end
- end
- end
- if(#itemAmounts > 0)then
- for _,v in pairs(itemAmounts)do
- local key = findKeyWithItemName(recipeList, v.name, v.damage)
- if(key~=nil)then
- if(recipeList[key].minAmount ~= v.count)then
- logging("Edited recipe: "..v.name.. ":"..v.damage.." new count: "..v.count)
- end
- somethingChanged = true
- recipeList[key].minAmount = v.count
- else
- table.insert( recipeList, {name=v.name, damage=v.damage, minAmount = v.count, maxCraftAmount = 0, useDmg = true, fails = 0, timer = 0})
- somethingChanged = true
- logging("Registered recipe: "..v.count.."x "..v.name.. ":"..v.damage)
- end
- end
- if(somethingChanged)then
- SaveToFile()
- end
- end
- scanChestBtn:setText("Scan Chest")
- logging("Scanning chest done.")
- end
- local chestScanThread = main:addThread("chestScanThread")
- buttonVisuals(scanChestBtn:onClick(function() chestScanThread:start(checkChestForNewEntrys) end))
- local function GetAmount(itemAmount, recipe)
- local amount = 0
- if(itemAmount < recipe.minAmount)then
- if(recipe.maxCraftAmount > 0)then
- if(recipe.minAmount-itemAmount > recipe.maxCraftAmount)then
- amount = recipe.maxCraftAmount
- else
- amount = recipe.minAmount-itemAmount
- end
- else
- amount = recipe.minAmount-itemAmount
- end
- end
- return amount
- end
- function GetRecipeKey(pattern)
- for k,v in pairs(recipeList)do
- if(v.name == pattern.name)then
- if(pattern.damage==nil)then return k end
- if(v.useDmg)then
- if(v.damage == pattern.damage)then
- return k
- end
- else
- return k
- end
- end
- end
- return nil
- end
- local function CheckCraftingRecipe(recipe)
- local pattern = bridge.getItem({name=recipe.name})
- local item = {pattern=pattern, amount=0}
- if(pattern~=nil)then
- local storedAmount = pattern.amount
- local neededItemAmount = GetAmount(storedAmount, recipe)
- if(neededItemAmount > 0)then
- item.amount = neededItemAmount
- table.insert(craftingQueue, item)
- return true
- end
- end
- return false
- end
- function RemoveRecipe(item)
- local key = -1
- for k,v in pairs(recipeList)do
- if(v.name == item.name)and(v.damage== item.damage)then
- key = k
- end
- end
- if(key>=0)then
- table.remove(recipeList, key)
- end
- SaveToFile()
- end
- local function FindKeyInTable(table, item)
- for k,v in pairs(table)do
- if(v==item)then
- return k
- end
- end
- return nil
- end
- local function CheckAllRecipes()
- for _,v in pairs(recipeList)do
- if(type(v)=="table")then
- CheckCraftingRecipe(v)
- end
- end
- end
- local function jobCrafting(coworker, item)
- if(jobList:getItem(coworker)~=nil)then
- jobList:editItem(coworker, "Co-Worker "..coworker..": "..item.amountToCraft.."x "..item.item.displayName:gsub(" ", ""))
- else
- jobList:addItem("Co-Worker "..coworker..": "..item.amountToCraft.."x "..item.item.displayName:gsub(" ", ""))
- end
- end
- local function jobDone(coworker)
- if(jobList:getItem(coworker)~=nil)then
- jobList:editItem(coworker, "Co-Worker "..coworker..": waiting...")
- else
- jobList:addItem("Co-Worker "..coworker..": waiting...")
- end
- end
- local coWorkerId = 1
- local function UpdateCraftingQueue()
- while(#craftingQueue > 0)do
- local activeCoWorkers = {}
- local craftingQueuesToRemove = {}
- for _,v in pairs(craftingQueue)do
- if(#activeCoWorkers+1 <= maxCoWorker)then
- local stack = v.pattern
- local recipeKey = GetRecipeKey(stack)
- local waittimer = 0
- local multiplier = 1
- if(recipeList[recipeKey].fails > 0)and(recipeList[recipeKey].fails <=10)then
- multiplier = recipeList[recipeKey].fails
- elseif(recipeList[recipeKey].fails > 10)then
- multiplier = 20
- end
- waittimer = multiplier * 30
- if(os.clock()>=recipeList[recipeKey].timer+waittimer)then
- if not(bridge.isItemCrafting(stack.name))then
- local currentItemState = {item=stack, curAmount = stack.count, amountToCraft = v.amount}
- if(bridge.isItemCraftable({name=stack.name}))then
- local task, errormsg = bridge.craftItem({name=stack.name, count = v.amount})
- if(task)then
- logging("Sheduled Task: "..v.amount.." ("..stack.name..") "..stack.displayName:gsub(" ", ""))
- jobCrafting(coWorkerId, currentItemState)
- currentItemState.coWorker = coWorkerId
- coWorkerId = coWorkerId + 1
- if(coWorkerId > maxCoWorker)then coWorkerId = 1 end
- table.insert(activeCoWorkers, currentItemState)
- recipeList[recipeKey].fails = 0
- else
- logging("Error sheduling task: "..v.amount.."x ("..stack.name..") "..stack.displayName:gsub(" ", ""))
- logging("Not enough materials!")
- recipeList[recipeKey].fails = recipeList[recipeKey].fails + 1
- recipeList[recipeKey].timer = os.clock()
- end
- else
- logging("Error sheduling task: "..v.amount.."x ("..stack.name..") "..stack.displayName:gsub(" ", ""))
- logging("No pattern available!")
- recipeList[recipeKey].fails = recipeList[recipeKey].fails + 1
- recipeList[recipeKey].timer = os.clock()
- end
- end
- end
- table.insert(craftingQueuesToRemove, v)
- end
- end
- if(#craftingQueuesToRemove > 0)then
- for _,v in pairs(craftingQueuesToRemove)do
- local id = FindKeyInTable(craftingQueue, v)
- table.remove(craftingQueue, id)
- end
- end
- while(#activeCoWorkers > 0)do
- local finishedCoworker = {}
- for _,v in pairs(activeCoWorkers)do
- if not(bridge.isItemCrafting(v.item.name))then
- logging("Task done: "..v.amountToCraft.."x ("..v.item.name..") "..v.item.displayName:gsub(" ", ""))
- table.insert(finishedCoworker, v)
- end
- end
- if(#finishedCoworker>0)then
- for _,v in pairs(finishedCoworker)do
- local id = FindKeyInTable(activeCoWorkers, v)
- table.remove(activeCoWorkers, id)
- jobDone(v.coWorker)
- end
- end
- os.sleep(0.75)
- end
- os.sleep(0.75)
- end
- end
- main:addThread("craftingThread"):start(function() while true do CheckAllRecipes() os.sleep(1) UpdateCraftingQueue() os.sleep(1) end end)
- logging("Autocrafter successfully loaded!")
- basalt.autoUpdate()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement