Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Blood altar automation
- -- (c)2020 SillyBits
- local component = require("component")
- local event = require("event")
- local sides = require("sides")
- local gpu = component.gpu
- local gui = require("gui")
- local thread = require("thread")
- --
- local inv = component.transposer
- local rs = component.redstone
- local chest = sides.south
- local altar = sides.east
- local stone = "minecraft:stone"
- local slate = "bloodmagic:slate"
- local slate_blank = 0
- local slate_reinf = 1
- local slate_imb = 2
- local slate_dem = 3
- local slate_eth = 4
- local slates = { "Blank slate", "Reinforced slate", "Imbued slate", "Demonic slate", "Ethereal slate" }
- local blood = { 1000, 3000, 8000, 23000, 53000 } -- Incl. prev. amounts
- --
- function dumpInv(proxy, side)
- local item
- local slot = 1
- for item in proxy.getAllStacks(side) do
- if ( item.name ) then
- print("#" .. slot .. ": \"" .. item.name .. ":" .. item.damage .. "\", \"" .. item.label .. "\", " .. item.size .. "/" .. item.maxSize)
- else
- print("#" .. slot .. ": empty")
- end
- slot = slot + 1
- end
- end
- --
- function findSlot(proxy, side, name, damage)
- local item
- local slot = 1
- for item in proxy.getAllStacks(side) do
- if ( item.name == name ) then
- if ( ( not damage ) or ( damage and item.damage == damage ) ) then
- return slot
- end
- end
- slot = slot + 1
- end
- return nil
- end
- --
- function countItems(proxy, side, name, damage)
- local count = 0
- local item
- local slot = 1
- for item in proxy.getAllStacks(side) do
- if ( item.name == name and ( ( not damage ) or ( damage and item.damage == damage ) ) ) then
- count = count + item.size
- end
- end
- return math.tointeger(count)
- end
- --
- function findFreeSlot(proxy, side)
- local item
- local slot = 1
- for item in proxy.getAllStacks(side) do
- if ( not item.name ) then
- return slot
- end
- slot = slot + 1
- end
- return nil
- end
- --
- function getBlood()
- return inv.getTankLevel(altar)
- end
- --
- function getMaxBlood()
- return inv.getTankCapacity(altar)
- end
- --
- function moveStone()
- local slot = findSlot(inv, chest, stone)
- if ( not slot ) then
- return false, "No smooth stone found!"
- end
- local count = 1
- if ( not inv.transferItem(chest, altar, count, slot, 1) == count ) then
- return false, "Unable to move smooth stone into altar!"
- end
- return true
- end
- --
- function checkSlate(type)
- local item = inv.getStackInSlot(altar, 1)
- return ( item and item.name == slate and item.damage == type )
- end
- --
- function moveSlate(type)
- -- local item = inv.getStackInSlot(altar, 1)
- -- if not ( item and item.name == slate and item.damage == type ) then
- if ( not checkSlate(type) ) then
- return false, "Expected slate not found!"
- end
- local slot = findSlot(inv, chest, slate, type)
- if ( not slot ) then
- slot = findFreeSlot(inv, chest)
- if ( not slot ) then
- return false, "No more room in crate!"
- end
- end
- local count = 1
- if ( not inv.transferItem(altar, chest, count, 1, slot) == count ) then
- return false, "Unable to move slate into crate!"
- end
- return true
- end
- --
- -- (0=Loot mode, 1=Blood mode)
- local mobfarm_mode = nil
- function switchMobFarm(mode)
- if ( mode == 0 ) then
- -- Deactivate ritual
- rs.setOutput(sides.down, 15)
- -- Place spikes by pulsing 'green' at 3 times
- -- (there might be mobs in the way)
- for l = 1,3 do
- rs.setOutput(sides.south, 15)
- os.sleep(0.2)
- rs.setOutput(sides.south, 0)
- os.sleep(0.2)
- end
- elseif ( mode == 1 ) then
- -- Remove spikes by pulsing 'red' once
- rs.setOutput(sides.north, 15)
- os.sleep(0.2)
- rs.setOutput(sides.north, 0)
- -- Activate ritual
- rs.setOutput(sides.down, 0)
- end
- mobfarm_mode = mode
- end
- --
- local mobfarm_light = true
- function switchMobFarmLight(state)
- if ( state ) then
- rs.setOutput(sides.up, 15)
- else
- rs.setOutput(sides.up, 0)
- end
- mobfarm_light = state
- end
- --
- -- UI creation
- --
- -- (requires a 80x25 resolution)
- --
- local x,y
- -- Crafting progress UI
- local crafting_running = false
- local c_ui = gui.newGui(10,7, 60,10, true, "Crafting status")
- x,y = 5,2
- local c_l_slate = gui.newLabel(c_ui, x,y , "Slate :")
- local c_l_total = gui.newLabel(c_ui, x,y+1, "Total :")
- local c_l_curr = gui.newLabel(c_ui, x,y+2, "Current:")
- local c_l_state = gui.newLabel(c_ui, x,y+4, "State :")
- function g_c_abort(g, ui)
- crafting_running = false
- end
- local c_b_abort = gui.newButton(c_ui, x+40,y+6, "ABORT!", g_c_abort)
- local crafting_type, crafting_slate, crafting_total, crafting_curr, crafting_state, crafting_blood
- function updateState()
- local filler = string.rep(" ", 10)
- gui.setText(c_ui, c_l_slate, "Slate : " .. crafting_slate .. filler)
- gui.setText(c_ui, c_l_total, "Total : " .. crafting_total .. filler)
- gui.setText(c_ui, c_l_curr , "Current: " .. crafting_curr .. filler)
- gui.setText(c_ui, c_l_state, "State : " .. crafting_state .. filler)
- end
- --
- function threadUI()
- while ( crafting_running and crafting_curr < crafting_total ) do
- updateState()
- coroutine.yield()
- gui.runGui(c_ui)
- end
- end
- --
- local craft_states = {
- "Waiting for enough blood",
- "Waiting for slate to be crafted",
- "Preparing for next slate" }
- function doCraft(type, count)
- crafting_type = type
- crafting_slate = slates[type+1]
- crafting_total = count
- crafting_curr = countItems(inv, chest, slate, type)
- crafting_state = "Preparing..."
- crafting_blood = blood[type+1]
- gui.displayGui(c_ui)
- crafting_running = true
- local ui_task = thread.create(threadUI)
- local state = 0
- local errmsg
- while ( crafting_running and crafting_curr < crafting_total ) do
- -- Craft check
- --os.sleep(0.5)
- if ( state == 0 ) then
- if ( getBlood() > crafting_blood ) then
- crafting_running,errmsg = moveStone()
- state = 1
- end
- elseif ( state == 1 ) then
- if ( checkSlate(crafting_type) ) then
- state = 2
- end
- elseif ( state == 2 ) then
- crafting_running,errmsg = moveSlate(crafting_type)
- state = 0
- if ( crafting_running ) then
- crafting_curr = crafting_curr + 1
- end
- end
- if ( errmsg ) then
- crafting_state = "Errored!"
- gui.showMsg("ERROR!", errmsg)
- errmsg = nil
- else
- crafting_state = craft_states[state+1]
- end
- -- Trigger UI updates
- event.push("blubb")
- thread.waitForAny({ui_task}, 0.1)
- end
- ui_task:kill()
- gui.closeGui(c_ui)
- end
- -- Main UI
- local ui = gui.newGui(2,2, 78,23, true)
- function g_exit(g, id)
- gui.exit()
- end
- local b_exit = gui.newButton(ui, "center", 23, "Exit", g_exit)
- x,y = 2,1 -- 36,2
- local f_avail = gui.newFrame(ui, x,y, 40,13, "Available")
- local l_a_stone = gui.newLabel(ui, x+2,y+1, "./.")
- local l_a_sl_blank = gui.newLabel(ui, x+2,y+2, "./.")
- local l_a_sl_reinf = gui.newLabel(ui, x+2,y+3, "./.")
- local l_a_sl_imb = gui.newLabel(ui, x+2,y+4, "./.")
- local l_a_sl_dem = gui.newLabel(ui, x+2,y+5, "./.")
- local l_a_sl_eth = gui.newLabel(ui, x+2,y+6, "./.")
- x,y = 44,1 -- 3,2
- local f_craft = gui.newFrame(ui, x,y, 32,13, "Crafting")
- local l_c_what = gui.newLabel(ui, x+2,y+1, "Target:")
- local r_c_sl_blank, l_c_sl_blank = gui.newRadio(ui, x+2,y+2), gui.newLabel(ui, x+6,y+2, slates[1])
- local r_c_sl_reinf, l_c_sl_reinf = gui.newRadio(ui, x+2,y+3), gui.newLabel(ui, x+6,y+3, slates[2])
- local r_c_sl_imb , l_c_sl_imb = gui.newRadio(ui, x+2,y+4), gui.newLabel(ui, x+6,y+4, slates[3])
- local r_c_sl_dem , l_c_sl_dem = gui.newRadio(ui, x+2,y+5), gui.newLabel(ui, x+6,y+5, slates[4])
- local r_c_sl_eth , l_c_sl_eth = gui.newRadio(ui, x+2,y+6), gui.newLabel(ui, x+6,y+6, slates[5])
- local l_c_amount = gui.newLabel(ui, x+2,y+8, "Amount:")
- local t_c_amount = gui.newText(ui, x+2+4,y+10, 5, "1")
- function g_craft(g, id)
- -- Get type of slate and amount, show this op, call doCraft() and unlock ui afterwards
- local type = gui.getRadio(ui)
- local count = tonumber(gui.getText(ui, t_c_amount))
- if ( type > 0 ) then
- type = ( type - r_c_sl_blank ) / 2
- local avail = countItems(inv, chest, stone)
- local done = countItems(inv, chest, slate, type)
- if ( count - done > avail ) then
- gui.showMsg("No enough smooth stone avail!")
- return
- end
- doCraft(type, count)
- --updateAvail()
- event.push("blubb")
- else
- gui.showMsg("No type selected!")
- end
- end
- function updateAmount(delta)
- local a = tonumber(gui.getText(ui, t_c_amount))
- a = a + delta
- if ( a < 1 ) then
- a = 1
- else
- if ( a > 128 ) then
- a = 128
- end
- end
- gui.setText(ui, t_c_amount, string.format("%d", a), true)
- end
- function g_Minus1 (g, id) updateAmount( -1); end
- function g_Minus10(g, id) updateAmount(-10); end
- function g_Minus64(g, id) updateAmount(-64); end
- function g_Plus1 (g, id) updateAmount( 1); end
- function g_Plus10(g, id) updateAmount(10); end
- function g_Plus64(g, id) updateAmount(64); end
- local b_c_minus_1 = gui.newButton(ui, x+2+0,y+ 9, "-1" , g_Minus1)
- local b_c_minus_10 = gui.newButton(ui, x+2+4,y+ 9, "-10", g_Minus10)
- local b_c_minus_64 = gui.newButton(ui, x+2+9,y+ 9, "-64", g_Minus64)
- local b_c_plus_1 = gui.newButton(ui, x+2+0,y+11, "+1" , g_Plus1)
- local b_c_plus_10 = gui.newButton(ui, x+2+4,y+11, "+10", g_Plus10)
- local b_c_plus_64 = gui.newButton(ui, x+2+9,y+11, "+64", g_Plus64)
- local b_c_craft = gui.newButton(ui, x+2+19,y+10, "Craft", g_craft)
- x,y = 2,14 -- 3,18
- local f_tank = gui.newFrame(ui, x,y, 74,4, "Tank")
- local p_blood = gui.newProgress(ui, x+2,y+2, 70, 100, 50, nil, true)
- x,y = 2,19
- local f_farm = gui.newFrame(ui, x,y, 74,3, "Mob farm control")
- function g_loot(g, id)
- switchMobFarm(0)
- end
- function g_blood(g, id)
- switchMobFarm(1)
- end
- function g_light(g, id)
- switchMobFarmLight( not mobfarm_light )
- end
- local b_f_loot = gui.newButton(ui, x+10,y+1, "Loot", g_loot)
- local l_f_loot = gui.newLabel (ui, x+ 7,y+1, "")
- local b_f_blood = gui.newButton(ui, x+56,y+1, "Blood", g_blood)
- local l_f_blood = gui.newLabel (ui, x+53,y+1, "")
- local b_f_light = gui.newButton(ui, x+33,y+1, "Light", g_light)
- local l_f_light = gui.newLabel (ui, x+30,y+1, "")
- function buildAvailStr(item, dmg, lbl)
- local filler = string.rep(" ", 10)
- if ( not lbl ) then
- lbl = slates[dmg+1]
- end
- local count = countItems(inv, chest, item, dmg)
- if ( count > 0 ) then
- count = string.format("%d", count) .. filler
- else
- count = "<none avail>"
- end
- return string.format("%18s: %s", lbl, count)
- end
- function updateAvail()
- gui.setText(ui, l_a_stone , buildAvailStr(stone, nil, "Smooth stone"))--, false)
- gui.setText(ui, l_a_sl_blank, buildAvailStr(slate, slate_blank))--, false)
- gui.setText(ui, l_a_sl_reinf, buildAvailStr(slate, slate_reinf))--, false)
- gui.setText(ui, l_a_sl_imb , buildAvailStr(slate, slate_imb) )--, false)
- gui.setText(ui, l_a_sl_dem , buildAvailStr(slate, slate_dem) )--, false)
- gui.setText(ui, l_a_sl_eth , buildAvailStr(slate, slate_eth) )--, false)
- end
- function updateTank()
- gui.setMax(ui, p_blood, getMaxBlood())
- gui.setValue(ui, p_blood, getBlood())
- end
- function updateMobfarmState()
- local l1, l2, b1, b2
- if ( mobfarm_mode == 0 ) then
- l1,l2 = ">>","<<"
- b1,b2 = " "," "
- elseif ( mobfarm_mode == 1 ) then
- l1,l2 = " "," "
- b1,b2 = ">>","<<"
- end
- gui.setText(ui, l_f_loot , l1.." [Loot] "..l2)
- gui.setText(ui, l_f_blood, b1.." [Blood] "..b2)
- if ( mobfarm_light ) then
- l1,l2 = ">>","<<"
- else
- l1,l2 = " "," "
- end
- gui.setText(ui, l_f_light, l1.." [Light] "..l2)
- end
- gui.clearScreen()
- gui.setTop("Blood Altar Automation v0.1")
- switchMobFarm(0) -- "Loot" is default
- --switchMobFarm(1) -- "Blood" is default
- switchMobFarmLight(true) -- Lit farm is default
- --
- -- Main loop
- --
- while true do
- updateAvail()
- updateTank()
- updateMobfarmState()
- gui.runGui(ui)
- end
- gpu.setResolution(132,40)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement