Guest User

blood.lua

a guest
Apr 8th, 2020
466
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Blood altar automation
  2. -- (c)2020 SillyBits
  3.  
  4. local component = require("component")
  5. local event     = require("event")
  6. local sides     = require("sides")
  7. local gpu       = component.gpu
  8. local gui       = require("gui")
  9. local thread    = require("thread")
  10.  
  11.  
  12. --
  13. local inv = component.transposer
  14. local rs  = component.redstone
  15.  
  16. local chest  = sides.south
  17. local altar  = sides.east
  18.  
  19. local stone  = "minecraft:stone"
  20.  
  21. local slate  = "bloodmagic:slate"
  22. local slate_blank = 0
  23. local slate_reinf = 1
  24. local slate_imb   = 2
  25. local slate_dem   = 3
  26. local slate_eth   = 4
  27. local slates = { "Blank slate", "Reinforced slate", "Imbued slate", "Demonic slate", "Ethereal slate" }
  28. local blood  = { 1000, 3000, 8000, 23000, 53000 } -- Incl. prev. amounts
  29.  
  30.  
  31. --
  32. function dumpInv(proxy, side)
  33.   local item
  34.   local slot = 1
  35.   for item in proxy.getAllStacks(side) do
  36.     if ( item.name ) then
  37.       print("#" .. slot .. ": \"" .. item.name .. ":" .. item.damage .. "\", \"" .. item.label .. "\", " .. item.size .. "/" .. item.maxSize)
  38.     else
  39.       print("#" .. slot .. ": empty")
  40.     end
  41.     slot = slot + 1
  42.   end
  43. end
  44.  
  45.  
  46. --
  47. function findSlot(proxy, side, name, damage)
  48.   local item
  49.   local slot = 1
  50.   for item in proxy.getAllStacks(side) do
  51.     if ( item.name == name ) then
  52.       if ( ( not damage ) or ( damage and item.damage == damage ) ) then
  53.         return slot
  54.       end
  55.     end
  56.     slot = slot + 1
  57.   end
  58.   return nil
  59. end
  60.  
  61. --
  62. function countItems(proxy, side, name, damage)
  63.   local count = 0
  64.   local item
  65.   local slot = 1
  66.   for item in proxy.getAllStacks(side) do
  67.     if ( item.name == name and ( ( not damage ) or ( damage and item.damage == damage ) ) ) then
  68.       count = count + item.size
  69.     end
  70.   end
  71.   return math.tointeger(count)
  72. end
  73.  
  74. --
  75. function findFreeSlot(proxy, side)
  76.   local item
  77.   local slot = 1
  78.   for item in proxy.getAllStacks(side) do
  79.     if ( not item.name ) then
  80.       return slot
  81.     end
  82.     slot = slot + 1
  83.   end
  84.   return nil
  85. end
  86.  
  87. --
  88. function getBlood()
  89.   return inv.getTankLevel(altar)
  90. end
  91.  
  92. --
  93. function getMaxBlood()
  94.   return inv.getTankCapacity(altar)
  95. end
  96.  
  97. --
  98. function moveStone()
  99.   local slot = findSlot(inv, chest, stone)
  100.   if ( not slot ) then
  101.     return false, "No smooth stone found!"
  102.   end
  103.   local count = 1
  104.   if ( not inv.transferItem(chest, altar, count, slot, 1) == count ) then
  105.     return false, "Unable to move smooth stone into altar!"
  106.   end
  107.   return true
  108. end
  109.  
  110. --
  111. function checkSlate(type)
  112.   local item = inv.getStackInSlot(altar, 1)
  113.   return ( item and item.name == slate and item.damage == type )
  114. end
  115.  
  116. --
  117. function moveSlate(type)
  118. --  local item = inv.getStackInSlot(altar, 1)
  119. --  if not ( item and item.name == slate and item.damage == type ) then
  120.   if ( not checkSlate(type) ) then
  121.     return false, "Expected slate not found!"
  122.   end
  123.   local slot = findSlot(inv, chest, slate, type)
  124.   if ( not slot ) then
  125.     slot = findFreeSlot(inv, chest)
  126.     if ( not slot ) then
  127.       return false, "No more room in crate!"
  128.     end
  129.   end
  130.   local count = 1
  131.   if ( not inv.transferItem(altar, chest, count, 1, slot) == count ) then
  132.     return false, "Unable to move slate into crate!"
  133.   end
  134.   return true
  135. end
  136.  
  137. --
  138. -- (0=Loot mode, 1=Blood mode)
  139. local mobfarm_mode = nil
  140. function switchMobFarm(mode)
  141.   if ( mode == 0 ) then
  142.     -- Deactivate ritual
  143.     rs.setOutput(sides.down, 15)
  144.     -- Place spikes by pulsing 'green' at 3 times
  145.     -- (there might be mobs in the way)
  146.     for l = 1,3 do
  147.       rs.setOutput(sides.south, 15)
  148.       os.sleep(0.2)
  149.       rs.setOutput(sides.south, 0)
  150.       os.sleep(0.2)
  151.     end
  152.   elseif ( mode == 1 ) then
  153.     -- Remove spikes by pulsing 'red' once
  154.     rs.setOutput(sides.north, 15)
  155.     os.sleep(0.2)
  156.     rs.setOutput(sides.north, 0)
  157.     -- Activate ritual
  158.     rs.setOutput(sides.down, 0)
  159.   end
  160.   mobfarm_mode = mode
  161. end
  162.  
  163. --
  164. local mobfarm_light = true
  165. function switchMobFarmLight(state)
  166.   if ( state ) then
  167.     rs.setOutput(sides.up, 15)
  168.   else
  169.     rs.setOutput(sides.up, 0)
  170.   end
  171.   mobfarm_light = state
  172. end
  173.  
  174.  
  175. --
  176. -- UI creation
  177. --
  178. -- (requires a 80x25 resolution)
  179. --
  180.  
  181.  
  182. local x,y
  183.  
  184.  
  185. -- Crafting progress UI
  186.  
  187. local crafting_running = false
  188.  
  189. local c_ui = gui.newGui(10,7, 60,10, true, "Crafting status")
  190.  
  191. x,y = 5,2
  192. local c_l_slate = gui.newLabel(c_ui, x,y  , "Slate  :")
  193. local c_l_total = gui.newLabel(c_ui, x,y+1, "Total  :")
  194. local c_l_curr  = gui.newLabel(c_ui, x,y+2, "Current:")
  195. local c_l_state = gui.newLabel(c_ui, x,y+4, "State  :")
  196.  
  197. function g_c_abort(g, ui)
  198.   crafting_running = false
  199. end
  200. local c_b_abort = gui.newButton(c_ui, x+40,y+6, "ABORT!", g_c_abort)
  201.  
  202. local crafting_type, crafting_slate, crafting_total, crafting_curr, crafting_state, crafting_blood
  203. function updateState()
  204.   local filler = string.rep(" ", 10)
  205.   gui.setText(c_ui, c_l_slate, "Slate  : " .. crafting_slate .. filler)
  206.   gui.setText(c_ui, c_l_total, "Total  : " .. crafting_total .. filler)
  207.   gui.setText(c_ui, c_l_curr , "Current: " .. crafting_curr .. filler)
  208.   gui.setText(c_ui, c_l_state, "State  : " .. crafting_state .. filler)
  209. end
  210.  
  211. --
  212. function threadUI()
  213.   while ( crafting_running and crafting_curr < crafting_total ) do
  214.     updateState()
  215.     coroutine.yield()
  216.     gui.runGui(c_ui)
  217.   end
  218. end
  219.  
  220. --
  221. local craft_states = {
  222.   "Waiting for enough blood",
  223.   "Waiting for slate to be crafted",
  224.   "Preparing for next slate" }
  225.  
  226. function doCraft(type, count)
  227.   crafting_type  = type
  228.   crafting_slate = slates[type+1]
  229.   crafting_total = count
  230.   crafting_curr  = countItems(inv, chest, slate, type)
  231.   crafting_state = "Preparing..."
  232.   crafting_blood = blood[type+1]
  233.  
  234.   gui.displayGui(c_ui)
  235.  
  236.   crafting_running = true
  237.   local ui_task = thread.create(threadUI)
  238.  
  239.   local state = 0
  240.   local errmsg
  241.  
  242.   while ( crafting_running and crafting_curr < crafting_total ) do
  243.     -- Craft check
  244.     --os.sleep(0.5)
  245.     if ( state == 0 ) then
  246.       if ( getBlood() > crafting_blood ) then
  247.         crafting_running,errmsg = moveStone()
  248.         state = 1
  249.       end
  250.     elseif ( state == 1 ) then
  251.       if ( checkSlate(crafting_type) ) then
  252.         state = 2
  253.       end
  254.     elseif ( state == 2 ) then
  255.       crafting_running,errmsg = moveSlate(crafting_type)
  256.       state = 0
  257.       if ( crafting_running ) then
  258.         crafting_curr = crafting_curr + 1
  259.       end
  260.     end
  261.  
  262.     if ( errmsg ) then
  263.       crafting_state = "Errored!"
  264.       gui.showMsg("ERROR!", errmsg)
  265.       errmsg = nil
  266.     else
  267.       crafting_state = craft_states[state+1]
  268.     end
  269.  
  270.     -- Trigger UI updates
  271.     event.push("blubb")
  272.     thread.waitForAny({ui_task}, 0.1)
  273.   end
  274.  
  275.   ui_task:kill()
  276.  
  277.   gui.closeGui(c_ui)
  278. end
  279.  
  280.  
  281.  
  282. -- Main UI
  283.  
  284. local ui = gui.newGui(2,2, 78,23, true)
  285.  
  286. function g_exit(g, id)
  287.   gui.exit()
  288. end
  289. local b_exit = gui.newButton(ui, "center", 23, "Exit", g_exit)
  290.  
  291. x,y = 2,1 -- 36,2
  292. local f_avail = gui.newFrame(ui, x,y, 40,13, "Available")
  293. local l_a_stone    = gui.newLabel(ui, x+2,y+1, "./.")
  294. local l_a_sl_blank = gui.newLabel(ui, x+2,y+2, "./.")
  295. local l_a_sl_reinf = gui.newLabel(ui, x+2,y+3, "./.")
  296. local l_a_sl_imb   = gui.newLabel(ui, x+2,y+4, "./.")
  297. local l_a_sl_dem   = gui.newLabel(ui, x+2,y+5, "./.")
  298. local l_a_sl_eth   = gui.newLabel(ui, x+2,y+6, "./.")
  299.  
  300. x,y = 44,1 -- 3,2
  301. local f_craft = gui.newFrame(ui, x,y, 32,13, "Crafting")
  302. local l_c_what = gui.newLabel(ui, x+2,y+1, "Target:")
  303. 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])
  304. 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])
  305. 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])
  306. 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])
  307. 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])
  308. local l_c_amount = gui.newLabel(ui, x+2,y+8, "Amount:")
  309. local t_c_amount = gui.newText(ui, x+2+4,y+10, 5, "1")
  310. function g_craft(g, id)
  311.   -- Get type of slate and amount, show this op, call doCraft() and unlock ui afterwards
  312.   local type = gui.getRadio(ui)
  313.   local count = tonumber(gui.getText(ui, t_c_amount))
  314.   if ( type > 0 ) then
  315.     type = ( type - r_c_sl_blank ) / 2
  316.     local avail = countItems(inv, chest, stone)
  317.     local done  = countItems(inv, chest, slate, type)
  318.     if ( count - done > avail ) then
  319.       gui.showMsg("No enough smooth stone avail!")
  320.       return
  321.     end
  322.     doCraft(type, count)
  323.     --updateAvail()
  324.     event.push("blubb")
  325.   else
  326.     gui.showMsg("No type selected!")
  327.   end
  328. end
  329. function updateAmount(delta)
  330.   local a = tonumber(gui.getText(ui, t_c_amount))
  331.   a = a + delta
  332.   if ( a < 1 ) then
  333.     a = 1
  334.   else
  335.     if ( a > 128 ) then
  336.       a = 128
  337.     end
  338.   end
  339.   gui.setText(ui, t_c_amount, string.format("%d", a), true)
  340. end
  341. function g_Minus1 (g, id) updateAmount( -1); end
  342. function g_Minus10(g, id) updateAmount(-10); end
  343. function g_Minus64(g, id) updateAmount(-64); end
  344. function g_Plus1 (g, id) updateAmount( 1); end
  345. function g_Plus10(g, id) updateAmount(10); end
  346. function g_Plus64(g, id) updateAmount(64); end
  347. local b_c_minus_1  = gui.newButton(ui, x+2+0,y+ 9, "-1" , g_Minus1)
  348. local b_c_minus_10 = gui.newButton(ui, x+2+4,y+ 9, "-10", g_Minus10)
  349. local b_c_minus_64 = gui.newButton(ui, x+2+9,y+ 9, "-64", g_Minus64)
  350. local b_c_plus_1   = gui.newButton(ui, x+2+0,y+11, "+1" , g_Plus1)
  351. local b_c_plus_10  = gui.newButton(ui, x+2+4,y+11, "+10", g_Plus10)
  352. local b_c_plus_64  = gui.newButton(ui, x+2+9,y+11, "+64", g_Plus64)
  353. local b_c_craft = gui.newButton(ui, x+2+19,y+10, "Craft", g_craft)
  354.  
  355. x,y = 2,14 -- 3,18
  356. local f_tank = gui.newFrame(ui, x,y, 74,4, "Tank")
  357. local p_blood = gui.newProgress(ui, x+2,y+2, 70, 100, 50, nil, true)
  358.  
  359. x,y = 2,19
  360. local f_farm = gui.newFrame(ui, x,y, 74,3, "Mob farm control")
  361. function g_loot(g, id)
  362.   switchMobFarm(0)
  363. end
  364. function g_blood(g, id)
  365.   switchMobFarm(1)
  366. end
  367. function g_light(g, id)
  368.   switchMobFarmLight( not mobfarm_light )
  369. end
  370. local b_f_loot  = gui.newButton(ui, x+10,y+1, "Loot", g_loot)
  371. local l_f_loot  = gui.newLabel (ui, x+ 7,y+1, "")
  372. local b_f_blood = gui.newButton(ui, x+56,y+1, "Blood", g_blood)
  373. local l_f_blood = gui.newLabel (ui, x+53,y+1, "")
  374. local b_f_light = gui.newButton(ui, x+33,y+1, "Light", g_light)
  375. local l_f_light = gui.newLabel (ui, x+30,y+1, "")
  376.  
  377.  
  378. function buildAvailStr(item, dmg, lbl)
  379.   local filler = string.rep(" ", 10)
  380.   if ( not lbl ) then
  381.     lbl = slates[dmg+1]
  382.   end
  383.   local count = countItems(inv, chest, item, dmg)
  384.   if ( count > 0 ) then
  385.     count = string.format("%d", count) .. filler
  386.   else
  387.     count = "<none avail>"
  388.   end
  389.   return string.format("%18s: %s", lbl, count)
  390. end
  391. function updateAvail()
  392.   gui.setText(ui, l_a_stone   , buildAvailStr(stone, nil, "Smooth stone"))--, false)
  393.   gui.setText(ui, l_a_sl_blank, buildAvailStr(slate, slate_blank))--, false)
  394.   gui.setText(ui, l_a_sl_reinf, buildAvailStr(slate, slate_reinf))--, false)
  395.   gui.setText(ui, l_a_sl_imb  , buildAvailStr(slate, slate_imb)  )--, false)
  396.   gui.setText(ui, l_a_sl_dem  , buildAvailStr(slate, slate_dem)  )--, false)
  397.   gui.setText(ui, l_a_sl_eth  , buildAvailStr(slate, slate_eth)  )--, false)
  398. end
  399.  
  400. function updateTank()
  401.   gui.setMax(ui, p_blood, getMaxBlood())
  402.   gui.setValue(ui, p_blood, getBlood())
  403. end
  404.  
  405. function updateMobfarmState()
  406.   local l1, l2, b1, b2
  407.   if ( mobfarm_mode == 0 ) then
  408.     l1,l2 = ">>","<<"
  409.     b1,b2 = "  ","  "
  410.   elseif ( mobfarm_mode == 1 ) then
  411.     l1,l2 = "  ","  "
  412.     b1,b2 = ">>","<<"
  413.   end
  414.   gui.setText(ui, l_f_loot , l1.." [Loot] "..l2)
  415.   gui.setText(ui, l_f_blood, b1.." [Blood] "..b2)
  416.  
  417.   if ( mobfarm_light ) then
  418.     l1,l2 = ">>","<<"
  419.   else
  420.     l1,l2 = "  ","  "
  421.   end
  422.   gui.setText(ui, l_f_light, l1.." [Light] "..l2)
  423. end
  424.  
  425.  
  426. gui.clearScreen()
  427. gui.setTop("Blood Altar Automation v0.1")
  428.  
  429. switchMobFarm(0) -- "Loot" is default
  430. --switchMobFarm(1) -- "Blood" is default
  431. switchMobFarmLight(true) -- Lit farm is default
  432.  
  433. --
  434. -- Main loop
  435. --
  436.  
  437. while true do
  438.   updateAvail()
  439.   updateTank()
  440.   updateMobfarmState()
  441.   gui.runGui(ui)
  442. end
  443.  
  444. gpu.setResolution(132,40)
RAW Paste Data