Advertisement
Kaerius

Untitled

Apr 21st, 2024 (edited)
697
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.51 KB | None | 0 0
  1. local component = require('component')
  2. local thread = require('thread')
  3. local event = require('event')
  4. local sides = require('sides')
  5. local gpu = component.gpu
  6.  
  7. -----------------------------------------
  8. --  Прога для автоматизации крафтов в блад меджик алтаре.
  9. --  Для функционирования системы нужено иметь:
  10. --  т1 компьютер кейс, т1 графическую карту, т1 ЖД, т1 цпу
  11. --  и две т1 оперативы. Для взаимодействия с аларём
  12. --  используется transposer. Ставим транспосер вплотную к алтарю
  13. --  и к транспозеру 2 инвенторя входной и выходной. Указываем название
  14. --  инвенторей ниже, если все инвентори имею разные имена, либо
  15. --  указываем стороны света относительно транспосера (input_side/output_side/altar_side)
  16. --  Подключаем транспозез к компьютер кейсу при помощи кабелей из ОК.
  17. --  Запускаем программу, кидаем итем в инпут чест, ждём результат.
  18. --
  19. --  Для заливки программы можно использовать простое копирование
  20. --  через колёсико мыши (но придётся копировать за 2 раза, по 200 строк),
  21. --  либо крафтить т2 кейс и интернет карту.
  22. --
  23. --  В конфиге программы прописаны почти все рецепты GTNH и сколько LP нужно на крафты.
  24. --  Поэтому перед стартом крафта проверяется текущий уровень эссенции и, если
  25. --  он больше или равен требуемому в рецепте, предмет будет помещён в алтарь для крафта.
  26. --  После окончания крафта предмет перемещается в отпут чест. Переменная CheckInterval
  27. --  определяет, насколько часто проверять алтарь.
  28. --
  29. --  Программа умеет работать с орбами. Если в алтаре лежит блад орб,
  30. --  программа переложит его в оутпут чест и будет выполнять крафты.
  31. --  После выполнения всех крафтов, программа пытается вернуть орб в алтарь.
  32. --  Поэтому позаботьтесь о том, чтоб из оутпут честа орба никуда не пропадала.
  33. --
  34. --  Доп фича: программа выводит текущий уровень крови в алтаре и его вместимомсть.
  35. -----------------------------------------
  36.  
  37.  
  38. local CheckInterval = 1                                         -- loop cooldown (sec)
  39. local updateGuiInterval = 1
  40. local altar_side = nil                                          -- if nil -> autodetect
  41. local input_side = nil                                          -- if nil -> autodetect
  42. local output_side = nil                                         -- if nil -> autodetect
  43. local altar_name = "tile.bloodAltar"                            -- if altar_side == nil required altar name
  44. local input_name = "tile.extrautils:chestFull"                  -- if input_side == nil required input chest name
  45. local output_name = "tile.appliedenergistics2.BlockInterface"   -- if output_side == nil required output chest name
  46.  
  47. local bm_recipe_config = {
  48.     ["minecraft:bucket:0"]                              = 1,
  49.     ["minecraft:tnt"]                                   = 10,
  50.     ["minecraft:cake"]                                  = 10,
  51.     ["minecraft:iron_ingot:0"]                          = 6,
  52.     ["minecraft:dye:14"]                                = 0.2,
  53.     ["minecraft:cookie"]                                = 2,
  54.     ["minecraft:paper"]                                 = 10,
  55.     ["MagicBees:frameMagic"]                            = 5,
  56.     ["Botania:flower"]                                  = 15,
  57.     ["minecraft:log:0"]                                 = 5,
  58.     ["minecraft:log:1"]                                 = 5,
  59.     ["minecraft:log:2"]                                 = 5,
  60.     ["minecraft:log:3"]                                 = 5,
  61.     ["minecraft:log2:0"]                                = 5,
  62.     ["minecraft:log2:1"]                                = 5,
  63.     ["minecraft:glass:0"]                               = 0.2,
  64.     ["minecraft:ice"]                                   = 0.4,
  65.     ["minecraft:packed_ice"]                            = 0.6,
  66.     ["minecraft:iron_block:0"]                          = 64,
  67.     ["minecraft:glowstone:0"]                           = 28,
  68.     ["BloodArsenal:blood_infused_diamond_unactive:0"]   = 120,
  69.     ["gregtech:gt.metaitem.02:30500"]                   = 12,
  70.     ["minecraft:glowstone_dust:0"]                      = 7,
  71.     ["witchery:ingredient:102"]                         = 5,
  72.     ["BloodArsenal:heart:0"]                            = 100,
  73.     ["dreamcraft:item.WeakOrb:0"]                       = 5,
  74.     ["dreamcraft:item.ApprenticeOrb:0"]                 = 10,
  75.     ["dreamcraft:item.MagicianOrb:0"]                   = 30,
  76.     ["dreamcraft:item.MasterOrb:0"]                     = 60,
  77.     ["dreamcraft:item.ArchmageOrb:0"]                   = 120,
  78.     ["dreamcraft:item.TranscendentOrb:0"]               = 300,
  79.     ["dreamcraft:item.ArcaneSlate:0"]                   = 1,
  80.     ["AWWayofTime:blankSlate:0"]                        = 2.5,
  81.     ["AWWayofTime:reinforcedSlate:0"]                   = 7.5,
  82.     ["AWWayofTime:imbuedSlate:0"]                       = 20,
  83.     ["AWWayofTime:demonicSlate:0"]                      = 60,
  84.     ["IC2:itemFluidCell:0"]                             = 1,
  85.     ["Thaumcraft:ItemEssence:0"]                        = 4,
  86.     ["IC2:itemBatCrystal:1"]                            = 5,
  87.     ["AWWayofTime:sacrificialKnife:0"]                  = 10,
  88.     ["AWWayofTime:blankSpell:0"]                        = 20,
  89.     ["AWWayofTime:emptySocket:0"]                       = 40,
  90.     ["Thaumcraft:blockCrystal:0"]                       = 5,
  91.     ["Thaumcraft:blockCrystal:1"]                       = 5,
  92.     ["Thaumcraft:blockCrystal:2"]                       = 5,
  93.     ["Thaumcraft:blockCrystal:3"]                       = 5,
  94.     ["Thaumcraft:blockCrystal:5"]                       = 10,
  95.     ["Thaumcraft:blockCrystal:6"]                       = 100,
  96.     ["EnderZoo:enderFragment:0"]                        = 5,
  97.     ["AWWayofTime:telepositionFocus:0"]                 = 20,
  98.     ["Thaumcraft:blockCosmeticSolid:4"]                 = 5,
  99.     ["thaumicbases:voidBlock:0"]                        = 10,
  100.     ["gregtech:gt.blockmetal8:13"]                      = 50,
  101.     ["BloodArsenal:blood_infused_diamond_active"]       = 10,
  102.     ["minecraft:sandstone"]                             = 3.5,
  103.     ["ForbiddenMagic:WandCores:6"]                      = 50,
  104. }
  105.  
  106. local bm_orb_config = {
  107.     ["AWWayofTime:weakBloodOrb"] = true,
  108.     ["AWWayofTime:apprenticeBloodOrb"] = true,
  109.     ["AWWayofTime:magicianBloodOrb"] = true,
  110.     ["AWWayofTime:masterBloodOrb"] = true,
  111.     ["AWWayofTime:archmageBloodOrb"] = true,
  112.     ["AWWayofTime:transcendentBloodOrb"] = true,
  113.     ["ForbiddenMagic:EldritchOrb"] = true,
  114.     ["Avaritia:Orb_Armok"] = true
  115. }
  116.  
  117. local tr = nil
  118. local d_limit = 5                   -- debud recursion limit
  119. local cur_item_name = nil
  120. local saved_orb_name = nil
  121.  
  122. function main()
  123.     init()
  124.     init_gui()
  125.  
  126.     local resetBColor, resetFColor = gpu.getBackground(), gpu.getForeground()
  127.     local background = {}
  128.  
  129.     table.insert(background, event.listen("key_up", function (key, address, char)
  130.         if char == string.byte('q') then
  131.             event.push('exit')
  132.         end
  133.     end))
  134.     table.insert(background, event.timer(CheckInterval, failFast(check_craft), math.huge))
  135.     table.insert(background, event.timer(updateGuiInterval, failFast(update_gui), math.huge))
  136.  
  137.     local _, err = event.pull("exit")
  138.  
  139.     for _, b in ipairs(background) do
  140.         if type(b) == 'table' and b.kill then
  141.             b:kill()
  142.         else
  143.             event.cancel(b)
  144.         end
  145.     end
  146.  
  147.     gpu.setBackground(resetBColor)
  148.     gpu.setForeground(resetFColor)
  149.  
  150.     if err then
  151.         io.stderr:write(err)
  152.         os.exit(1)
  153.     else
  154.         os.exit(0)
  155.     end
  156. end
  157.  
  158. function failFast(fn)
  159.     return function(...)
  160.         local res = table.pack(xpcall(fn, debug.traceback, ...))
  161.         if not res[1] then
  162.             event.push('exit', res[2])
  163.         end
  164.         return table.unpack(res, 2)
  165.     end
  166. end
  167.  
  168. function errorExit(...)
  169.     out(...)
  170.     event.push('exit')
  171. end
  172.  
  173. ----------------------- DEBUG ---------------------------
  174.  
  175. function object_to_string(level, object)
  176.     local function get_tabs(num)
  177.         local msg = ""
  178.         for i = 0, num do  msg = msg .. "  " end
  179.         return msg
  180.     end
  181.  
  182.     if level == nil then level = 0 end
  183.  
  184.     local message = " "
  185.  
  186.     if object == nil then
  187.         message = message .. "nil"
  188.     elseif type(object) == "boolean" or type(object) == "number" then
  189.         message = message .. tostring(object) end
  190.     if type(object) == "string" then
  191.         message = message..object end
  192.     if type(object) == "function" then
  193.         message = message.."\"__function\"" end
  194.     if type(object) == "table" then
  195.       if level <= d_limit then
  196.         message = message .. "\n" .. get_tabs(level) .. "{\n"
  197.         for key, next_object in pairs(object) do
  198.             message = message .. get_tabs(level + 1) .. "\"" .. key .. "\"" .. ":" .. object_to_string(level + 1, next_object) .. ",\n";
  199.         end
  200.         message = message .. get_tabs(level) .. "}"
  201.       else
  202.         message = message .. "\"" .. "__table" .. "\""
  203.       end
  204.     end
  205.     return message
  206. end
  207.  
  208. function rec_obj_to_string(object, ...)
  209.     arg = {...}
  210.     if #arg > 0 then
  211.         return object_to_string(0, object) .. rec_obj_to_string(...)
  212.     else
  213.         return object_to_string(0, object)
  214.     end
  215. end
  216.  
  217. function out(...)
  218.     local message = rec_obj_to_string(...)
  219.     print(message)
  220. end
  221.  
  222. ----------------------- LOOP ---------------------------
  223.  
  224. function check_craft()
  225.     if cur_item_name then
  226.         local item_in_altar = tr.getStackInSlot(altar_side, 1)
  227.  
  228.         if item_in_altar == nil then
  229.             cur_item_name = nil
  230.         elseif item_in_altar.name .. ":" .. math.floor(item_in_altar.damage) ~= cur_item_name then
  231.             transfer_item(altar_side, output_side, 1, 1)
  232.         end
  233.     else
  234.         local in_item_slot, item = get_first_item(input_side, bm_recipe_config)
  235.         if item then
  236.             local item_in_altar = tr.getStackInSlot(altar_side, 1)
  237.  
  238.             if item_in_altar then
  239.                 if bm_orb_config[item_in_altar.name] then
  240.                     transfer_item(altar_side, output_side, 1, 1)
  241.                     saved_orb_name = item_in_altar.name
  242.                 end
  243.             else
  244.                 local fluid = tr.getFluidInTank(altar_side, 1)
  245.                 if fluid and fluid.amount >= bm_recipe_config[item] * 1000 then
  246.                     tr.transferItem(input_side, altar_side, 1, in_item_slot, 1)
  247.                     cur_item_name = item
  248.                 end
  249.             end
  250.         elseif saved_orb_name then
  251.             local out_chest_size = tr.getInventorySize(output_side)
  252.             local selected_slot = nil
  253.  
  254.             for i = 1, out_chest_size do --find orb
  255.                 local item_in_outchest = tr.getStackInSlot(output_side, i)
  256.                 if item_in_outchest and item_in_outchest.name == saved_orb_name then
  257.                     selected_slot = i
  258.                     break
  259.                 end
  260.             end
  261.  
  262.             if selected_slot then
  263.                 if tr.getStackInSlot(altar_side, 1) == nil then
  264.                     tr.transferItem(output_side, altar_side, 1, selected_slot, 1)
  265.                     saved_orb_name = nil
  266.                 end
  267.             else
  268.                 saved_orb_name = nil
  269.             end
  270.         end
  271.     end
  272. end
  273.  
  274. -------------------- SUPPORTED FUNCTION -----------------------
  275.  
  276. function transfer_item(in_side, out_side, item_cnt, in_slot)
  277.     local out_chest_size = tr.getInventorySize(out_side)
  278.     local item_in_inchest = tr.getStackInSlot(in_side, in_slot)
  279.     local selected_slot = nil
  280.  
  281.     -- find slot in output chest
  282.     for i = 1, out_chest_size do
  283.         local item_in_outchest = tr.getStackInSlot(out_side, i)
  284.         if item_in_outchest == nil then
  285.             if not selected_slot then
  286.                 selected_slot = i
  287.             end
  288.         elseif item_in_outchest.name == item_in_inchest.name and
  289.                item_in_outchest.maxSize - item_in_outchest.size > 0 then
  290.             selected_slot = i
  291.             break
  292.         end    
  293.     end
  294.    
  295.     if (selected_slot) then
  296.         tr.transferItem(in_side, out_side, item_cnt, in_slot, selected_slot)
  297.     end
  298. end
  299.  
  300. function get_first_item(side, filter)
  301.     local inv_size = tr.getInventorySize(side)
  302.  
  303.     for i = 1, inv_size do
  304.         item = tr.getStackInSlot(side, i)
  305.         if item then
  306.             if not filter or filter[item.name .. ":" .. math.floor(item.damage)] then
  307.                 return i, item.name .. ":" .. math.floor(item.damage)
  308.             end
  309.         end
  310.     end
  311. end
  312.  
  313. function init()
  314.     tr = link_component("transposer")
  315.  
  316.     if tr == nil then
  317.         errorExit("Transposer not found")
  318.         return
  319.     end
  320.  
  321.     if altar_side == nil then
  322.         altar_side = detect_named_side(altar_name)
  323.         if altar_side == nil then
  324.             errorExit("Altar: ", altar_name, " not found or not located next to the Transposer")
  325.             return
  326.         end
  327.     end
  328.  
  329.     if input_side == nil then
  330.         input_side = detect_named_side(input_name)
  331.         if input_side == nil then
  332.             errorExit("Input: ", input_name, " not found or not located next to the Transposer")
  333.             return
  334.         end
  335.     end
  336.  
  337.     if output_side == nil then
  338.         output_side = detect_named_side(output_name)
  339.         if output_side == nil then
  340.             errorExit("Output: ", output_name, " not found or not located next to the Transposer")
  341.             return
  342.         end
  343.     end
  344.  
  345.     print("altar_side", altar_side)
  346.     print("input_side", input_side)
  347.     print("output_side", output_side)
  348. end
  349.  
  350. function link_component(comp_name)
  351.     components = component.list(comp_name)
  352.     ret_comp = nil
  353.     for addr, name in pairs(components) do
  354.         if ret_comp == nil then
  355.             ret_comp = component.proxy(addr)
  356.             print("Link component " .. name .. " to address " .. ret_comp.address)
  357.         else
  358.             print("Warning: More then one component " .. name .. " found. Used: " .. ret_comp.address)
  359.         end
  360.     end
  361.     return ret_comp
  362. end
  363.  
  364. function detect_named_side(name)
  365.     for i = 0,5 do
  366.         local loc_name = tr.getInventoryName(i)
  367.         if loc_name == name then
  368.             return i
  369.         end
  370.     end
  371. end
  372.  
  373. -------------------- GUI FUNCTION -----------------------
  374.  
  375. function clear_screen()
  376.     local x, y = gpu.getResolution()
  377.     gpu.fill(1, 1, x, y, " ")
  378. end
  379.  
  380. function update_gui()
  381.     local fluid = tr.getFluidInTank(altar_side)
  382.     if fluid and fluid[1] and fluid[1].name == "lifeessence" then
  383.         gpu.set(1, 2, math.floor(fluid[1].amount) .. "/" .. math.floor(fluid[1].capacity) .. "          ")
  384.     end
  385. end
  386.  
  387. function init_gui()
  388.     gpu.setResolution(14, 2)
  389.     clear_screen()
  390.     gpu.set(1, 1, "Altar Essense:")
  391.     update_gui()
  392. end
  393.  
  394. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement