ShinyBird368 Posted June 16, 2024 Share Posted June 16, 2024 Привет! Продолжаю тему автоматизации всего, что только можно придумать. На этот раз будем автоматизировать получение любой пчелы! В общей сложности, этот проект занял у меня чуть больше месяца, так как цель была - сделать лучше, чем аналоги в интернете. На самом деле, я нашел всего 2 похожие программы, но одна работала только для выведения обычной пчелы и ничего более, а для второй нужно было развернуть систему, по сложности как большой адронный коллайдер. В моей же версии присутствует очень простенький графический интерфейс, чтобы влезать в код как можно меньше, а так же сама система крайне компактная. Даже не буду описывать свой путь к финальному варианту, так как он был на столько длинный, что половину я уже забыл, так что приступим сразу к делу! 1. Что нужно для схемы: Спойлер Сам компьютер собирается из следующих компонентов: системный блок 3-го уровня видеокарта 3-го уровня центральный процессор 2-го уровня память 2-го уровня (2 штуки) жесткий диск 2-го уровня EEPROM (Lua BIOS) дискета OpenOS клавиатура монитор 3-го уровня (лучше всего 6 штук) Из обязательного тут только видеокарта 3-го уровня, соответственно и системник. Остальное можете использовать 1-го уровня или как-либо экспериментировать со сборкой. Оперативки лучше не жалейте, так как программа использует рекурсию, а на сложных пчел потребуется много оперативной памяти. Про установку операционной системы и настройку Lua BIOS я уже неоднократно писал в прошлых гайдах, ниже будет ссылка. Для сборки остальной системы нам потребуется: несколько кабелей транспозер 2 обычных сундука алмазный или дракониевый сундук (чем больше будет места, тем лучше) любые предметные трубы (я использую из EnderIO) пасека Подводим энергию к компьютеру и собираем все приблизительно так Тут у нас 3 сундука: хранилище, ввод в пасеку, вывод из пасеки. Все это дело контролируется транспозером, благодаря чему все работает. В хранилище (алмазный сундук) сложите всех ваших пчел. На этом внешняя часть схемы готова. 2. Программная часть Спойлер Программа состоит из двух частей: главная программа и список всех пчел с инструкцией их вывода. Главная программа: Спойлер local component = require("component") local sides = require("sides") local transposer = component.transposer local filesystem = require("filesystem") local shell = require("shell") local term = require("term") local event = require("event") local currentDir = shell.getWorkingDirectory() local beeTreePath = filesystem.concat(currentDir, "bees.lua") local bee_tree = dofile(beeTreePath) --===========ВАЖНО================== --бывают случаи, когда программа находит двух трутней или двух принцесс, из-за чего ломается local bee_storage_side = sides.west -- сторона, на которой находится сундук с пчелами local breeding_side = sides.north -- сторона, на которой находится сундук для вывода пчел local new_bee_side = sides.east -- сторона, на которой находится сундук с новыми пчелами --================================== local TIME_SLEEP = 20 local bee_storage_size = transposer.getInventorySize(bee_storage_side) local bee_storage = { ["drone"] = {}, ["princess"] = {} } function scanBeeStorage() --функция сканирования хранилища с пчелами local function bee_find(name_hight, name_low, bee_name) bee_name = bee_name:gsub(name_hight, "") if not bee_storage[name_low][bee_name] then bee_storage[name_low][bee_name] = 0 end bee_storage[name_low][bee_name] = bee_storage[name_low][bee_name] + 1 end bee_storage["drone"] = {} bee_storage["princess"] = {} for slot = 1, bee_storage_size do local stack = transposer.getStackInSlot(bee_storage_side, slot) if stack then local bee_name = stack.label if bee_name:find("Drone") then bee_find(" Drone", "drone", bee_name) elseif bee_name:find("Princess") then bee_find(" Princess", "princess", bee_name) end end end end function targetBeeExists(target_bee) -- функция проверки на наличие целевой пчелы if bee_storage["drone"][target_bee] and bee_storage["drone"][target_bee] > 0 then return true end if bee_storage["princess"][target_bee] and bee_storage["princess"][target_bee] > 0 then return true end return false end function findBeePair(target_bee) --функция поиска пары пчел для разведения print("Поиск пары для выведения:", target_bee) if not bee_tree[target_bee] then print("Нет информации о выведении:", target_bee) return nil, nil end for parent1, _ in pairs(bee_tree[target_bee]) do for parent2, _ in pairs(bee_tree[target_bee]) do if parent1 ~= parent2 then print("Проверяем наличие пчел:", parent1, parent2) if bee_storage["drone"][parent1] and bee_storage["princess"][parent2] then print("Пара найдена:", parent1, parent2) return parent1, parent2 elseif bee_storage["drone"][parent2] and bee_storage["princess"][parent1] then print("Пара найдена:", parent2, parent1) return parent2, parent1 end end end end print("Не найдена пара для вывода:", target_bee) return nil, nil end function moveBeesForBreeding(parent1, parent2) --функция переноса пары пчел для разведения local function move_bee_from_slot(parent, slot, type_bee1) transposer.transferItem(bee_storage_side, breeding_side, 1, slot) bee_storage[type_bee1][parent] = bee_storage[type_bee1][parent] - 1 if bee_storage[type_bee1][parent] == 0 then bee_storage[type_bee1][parent] = nil end end print("Перенос пчел в пасеку:", parent1, parent2) local drone_moved = false local princess_moved = false for slot = 1, bee_storage_size do if drone_moved and princess_moved then break end local stack = transposer.getStackInSlot(bee_storage_side, slot) if stack then local bee_name = stack.label if bee_name == parent1 .. " Drone" and not drone_moved then print("Переносим ", bee_name, "из слота", slot) move_bee_from_slot(parent1, slot, "drone") drone_moved = true elseif bee_name == parent2 .. " Princess" and not princess_moved then print("Переносим", bee_name, "из слота", slot) move_bee_from_slot(parent2, slot, "princess") princess_moved = true end end end end function collectNewBees() -- функция перемещения новых пчел в хранилище print("Собираем новых пчел") for slot = 1, transposer.getInventorySize(new_bee_side) do local stack = transposer.getStackInSlot(new_bee_side, slot) if stack then local bee_name = stack.label if bee_name:find("Drone") then local name = bee_name:gsub(" Drone", "") if not bee_storage["drone"][name] then bee_storage["drone"][name] = 0 end bee_storage["drone"][name] = bee_storage["drone"][name] + 1 elseif bee_name:find("Princess") then local name = bee_name:gsub(" Princess", "") if not bee_storage["princess"][name] then bee_storage["princess"][name] = 0 end bee_storage["princess"][name] = bee_storage["princess"][name] + 1 end transposer.transferItem(new_bee_side, bee_storage_side, 1, slot) end end end function breedUntilTarget(target_bee) --рекурсивная функция поиска нужной пчелы while true do scanBeeStorage() if targetBeeExists(target_bee) then print("Целевая пчела найдена:", target_bee) return true end local parent1, parent2 = findBeePair(target_bee) if parent1 and parent2 then moveBeesForBreeding(parent1, parent2) repeat local stack = transposer.getSlotStackSize(new_bee_side, 1) os.sleep(TIME_SLEEP) until stack > 0 collectNewBees() else print("Невозможно найти комбинацию для вывода этой пчелы, попытка обхода") local success = false for parent1, _ in pairs(bee_tree[target_bee]) do for parent2, _ in pairs(bee_tree[target_bee]) do if parent1 ~= parent2 then if not targetBeeExists(parent1) or not targetBeeExists(parent2) then if breedUntilTarget(parent1) and breedUntilTarget(parent2) then success = true break end end end end if success then break end end if not success then print("Error: Все попытки обхода провалились.") return false end end end end function main() local success = breedUntilTarget(target_bee) if not success then print("Не удалось вывести целевую пчелу:", target_bee) else print("Целевая пчела успешно выведена:", target_bee) end end local function displayMenu() local bee_list = {} for bee, _ in pairs(bee_tree) do table.insert(bee_list, bee) end local screen_height = 50 local items_per_page = screen_height - 2 local current_page = 1 local total_pages = math.ceil(#bee_list / items_per_page) while true do term.clear() print("Выберите целевую пчелу (Страница " .. current_page .. " из " .. total_pages .. "):") local start_index = (current_page - 1) * items_per_page + 1 local end_index = math.min(current_page * items_per_page, #bee_list) for i = start_index, end_index do print(string.format("%d. %s", i, bee_list[i])) end print("Введите номер пчелы, 'n' для следующей страницы, 'p' для предыдущей страницы:") local input = io.read() if input == "n" and current_page < total_pages then current_page = current_page + 1 elseif input == "p" and current_page > 1 then current_page = current_page - 1 else local choice = tonumber(input) if choice and choice >= 1 and choice <= #bee_list then target_bee = bee_list[choice] print("Вы выбрали: " .. target_bee) main() return end end end end displayMenu() Словарь пчел: Спойлер local bee_tree = { ["Common"] = { ["Forest"] = true, ["Meadows"] = true }, ["Cultivated"] = { ["Common"] = true, ["Meadows"] = true }, ["Noble"] = { ["Common"] = true, ["Cultivated"] = true }, ["Majestic"] = { ["Noble"] = true, ["Cultivated"] = true }, ["Imperial"] = { ["Majestic"] = true, ["Noble"] = true }, ["Diligent"] = { ["Common"] = true, ["Cultivated"] = true }, ["Unweary"] = { ["Diligent"] = true, ["Cultivated"] = true }, ["Industrious"] = { ["Unweary"] = true, ["Diligent"] = true }, ["Steadfast"] = { ["Forest"] = true, ["Common"] = true }, ["Stalwart"] = { ["Steadfast"] = true, ["Cultivated"] = true }, ["Valiant"] = { ["Stalwart"] = true, ["Diligent"] = true }, ["Tropical"] = { ["Forest"] = true, ["Common"] = true }, ["Exotic"] = { ["Tropical"] = true, ["Eldritch"] = true }, ["Monastic"] = { ["Cultivated"] = true, ["Common"] = true }, ["Secluded"] = { ["Monastic"] = true, ["Forest"] = true }, ["Hermit"] = { ["Secluded"] = true, ["Monastic"] = true }, ["Austere"] = { ["Hermit"] = true, ["Secluded"] = true }, ["Frugal"] = { ["Austere"] = true, ["Hermit"] = true }, ["Miserly"] = { ["Frugal"] = true, ["Austere"] = true }, ["Sinister"] = { ["Common"] = true, ["Forest"] = true }, ["Fiendish"] = { ["Sinister"] = true, ["Cultivated"] = true }, ["Demonic"] = { ["Fiendish"] = true, ["Sinister"] = true }, ["Attuned"] = { ["Sinister"] = true, ["Demonic"] = true }, ["Infernal"] = { ["Attuned"] = true, ["Demonic"] = true }, ["Ender"] = { ["Exotic"] = true, ["Esoteric"] = true }, ["Eldritch"] = { ["Monastic"] = true, ["Sinister"] = true }, ["Spectral"] = { ["Ethereal"] = true, ["Ender"] = true }, ["Invisible"] = { ["Spectral"] = true, ["Ethereal"] = true }, ["Spatial"] = { ["Invisible"] = true, ["Spectral"] = true }, ["Abominable"] = { ["Infernal"] = true, ["Demonic"] = true }, ["Ghastly"] = { ["Abominable"] = true, ["Spooky"] = true }, ["Spooky"] = { ["Ghastly"] = true, ["Sinister"] = true }, ["Skulking"] = { ["Spooky"] = true, ["Infernal"] = true }, ["Draconic"] = { ["Eldritch"] = true, ["Dragon"] = true }, ["Dragon"] = { ["Eldritch"] = true, ["Tropical"] = true }, ["Wyvern"] = { ["Dragon"] = true, ["Draconic"] = true }, ["Enchanted"] = { ["Arcane"] = true, ["Eldritch"] = true }, ["Witching"] = { ["Arcane"] = true, ["Esoteric"] = true }, ["Sorcerous"] = { ["Witching"] = true, ["Arcane"] = true }, ["Transmuting"] = { ["Sorcerous"] = true, ["Witching"] = true }, ["Mystical"] = { ["Cultivated"] = true, ["Common"] = true }, ["Arcane"] = { ["Mystical"] = true, ["Unusual"] = true }, ["Ethereal"] = { ["Arcane"] = true, ["Mystical"] = true }, ["Esoteric"] = { ["Ethereal"] = true, ["Arcane"] = true }, ["Unusual"] = { ["Cultivated"] = true, ["Common"] = true }, ["Wheaten"] = { ["Common"] = true, ["Cultivated"] = true }, ["Farmed"] = { ["Wheaten"] = true, ["Diligent"] = true }, ["Miry"] = { ["Water"] = true, ["Tropical"] = true }, ["Boggy"] = { ["Miry"] = true, ["Tropical"] = true }, ["Marshy"] = { ["Boggy"] = true, ["Miry"] = true }, ["Water"] = { ["Marshy"] = true, ["Tropical"] = true }, ["Ocean"] = { ["Water"] = true, ["Cultivated"] = true }, ["Wet"] = { ["Water"] = true, ["Common"] = true }, ["Soggy"] = { ["Wet"] = true, ["Boggy"] = true }, ["Dank"] = { ["Soggy"] = true, ["Wet"] = true }, ["Rocky"] = { ["Common"] = true, ["Forest"] = true }, ["Stony"] = { ["Rocky"] = true, ["Common"] = true }, ["Pupae"] = { ["Cultivated"] = true, ["Common"] = true }, ["Larvae"] = { ["Pupae"] = true, ["Common"] = true }, ["Pupa"] = { ["Larvae"] = true, ["Pupae"] = true }, ["Silky"] = { ["Pupa"] = true, ["Cultivated"] = true }, ["Stringy"] = { ["Silky"] = true, ["Pupa"] = true }, ["Woven"] = { ["Stringy"] = true, ["Silky"] = true }, ["Furry"] = { ["Woven"] = true, ["Stringy"] = true }, ["Fluffy"] = { ["Furry"] = true, ["Woven"] = true }, ["Plush"] = { ["Fluffy"] = true, ["Furry"] = true }, ["Hirsute"] = { ["Plush"] = true, ["Fluffy"] = true }, ["Feathery"] = { ["Hirsute"] = true, ["Plush"] = true }, ["Shaggy"] = { ["Feathery"] = true, ["Hirsute"] = true }, ["Rugged"] = { ["Shaggy"] = true, ["Feathery"] = true }, ["Jagged"] = { ["Rugged"] = true, ["Shaggy"] = true }, ["Fierce"] = { ["Jagged"] = true, ["Rugged"] = true }, ["Savage"] = { ["Fierce"] = true, ["Jagged"] = true }, ["Ferocious"] = { ["Savage"] = true, ["Fierce"] = true }, ["Wild"] = { ["Ferocious"] = true, ["Savage"] = true }, ["Untamed"] = { ["Wild"] = true, ["Ferocious"] = true }, ["Barbaric"] = { ["Untamed"] = true, ["Wild"] = true }, ["Primitive"] = { ["Barbaric"] = true, ["Untamed"] = true }, ["Primeval"] = { ["Primitive"] = true, ["Barbaric"] = true }, ["Ancient"] = { ["Primeval"] = true, ["Primitive"] = true }, ["Primal"] = { ["Ancient"] = true, ["Primeval"] = true }, ["Mythic"] = { ["Primal"] = true, ["Ancient"] = true }, ["Legendary"] = { ["Mythic"] = true, ["Primal"] = true }, ["Fabled"] = { ["Legendary"] = true, ["Mythic"] = true }, ["Mythical"] = { ["Fabled"] = true, ["Legendary"] = true }, ["Fable"] = { ["Mythical"] = true, ["Fabled"] = true }, ["Story"] = { ["Fable"] = true, ["Mythical"] = true }, ["Tale"] = { ["Story"] = true, ["Fable"] = true}, ["Saga"] = { ["Tale"] = true, ["Story"] = true }, ["Epic"] = { ["Saga"] = true, ["Tale"] = true }, ["Heroic"] = { ["Epic"] = true, ["Saga"] = true }, ["Legend"] = { ["Heroic"] = true, ["Epic"] = true }, ["Chronicle"] = { ["Legend"] = true, ["Heroic"] = true }, ["Annals"] = { ["Chronicle"] = true, ["Legend"] = true }, ["Records"] = { ["Annals"] = true, ["Chronicle"] = true }, ["Archives"] = { ["Records"] = true, ["Annals"] = true }, ["Library"] = { ["Archives"] = true, ["Records"] = true }, ["Collection"] = { ["Library"] = true, ["Archives"] = true }, ["Hoard"] = { ["Collection"] = true, ["Library"] = true }, ["Treasure"] = { ["Hoard"] = true, ["Collection"] = true }, ["Riches"] = { ["Treasure"] = true, ["Hoard"] = true }, ["Fortune"] = { ["Riches"] = true, ["Treasure"] = true }, ["Wealth"] = { ["Fortune"] = true, ["Riches"] = true }, ["Prosperity"] = { ["Wealth"] = true, ["Fortune"] = true }, ["Abundance"] = { ["Prosperity"] = true, ["Wealth"] = true }, ["Plenty"] = { ["Abundance"] = true, ["Prosperity"] = true }, ["Bounty"] = { ["Plenty"] = true, ["Abundance"] = true }, ["Gift"] = { ["Bounty"] = true, ["Plenty"] = true }, ["Present"] = { ["Gift"] = true, ["Bounty"] = true }, ["Prize"] = { ["Present"] = true, ["Gift"] = true }, ["Award"] = { ["Prize"] = true, ["Present"] = true }, ["Medal"] = { ["Award"] = true, ["Prize"] = true }, ["Badge"] = { ["Shield"] = true, ["Crest"] = true }, ["Emblem"] = { ["Badge"] = true, ["Shield"] = true }, ["Symbol"] = { ["Emblem"] = true, ["Badge"] = true }, ["Sign"] = { ["Symbol"] = true, ["Emblem"] = true }, ["Mark"] = { ["Sign"] = true, ["Symbol"] = true }, ["Seal"] = { ["Mark"] = true, ["Sign"] = true }, ["Stamp"] = { ["Seal"] = true, ["Mark"] = true }, ["Print"] = { ["Stamp"] = true, ["Seal"] = true }, ["Imprint"] = { ["Print"] = true, ["Stamp"] = true }, ["Insignia"] = { ["Imprint"] = true, ["Print"] = true }, ["Crest"] = { ["Insignia"] = true, ["Imprint"] = true }, ["Shield"] = { ["Crest"] = true, ["Insignia"] = true }, } return bee_tree Для начала нужно создать файл "bees.lua" и в него вставить словарь пчел (второй код). После используем Ctrl + S для сохранения и Ctrl + W для выхода из редактора кода. Обязательно писать именно с .lua. edit bees.lua После чего создаем файл с любым названием (в моем случае - main) и вставляем код главной программы. Тут не обязательно дописывать .lua. edit main Теперь запускаем программу (просто в консоли пишем main) и идем дальше. 3.Управление программой Спойлер После запуска программы, на мониторе выведется первые 48 пчел. Если написать "n", отобразятся следующие 48 пчел, если "p", прошлые 48. Чтоб выбрать пчелу для выведения, нужно написать номер целевой пчелы. Программа начнет рекурсивно искать нужную пару пчел, пока не найдет кратчайший путь выведения. Например, у сундуке есть знатная, развитая и обычная пчела, а нам нужна имперская. Сначала программа ищет комбинацию из знатной и величавой пчелы. Знатная найдена, величавая нет. Теперь программа работает над выводом величавой программы и так же ищет нужную пару. Таким образом программа будет искать, пока не найдет любую пару для выведения. Таким образом, если программа дойдет до самой первой комбинации и не найдет для нее пару, будет ошибка. Еще одна ошибка кроется в том, что вывести новую пчелу из двух трутней или двух принцесс не представится возможным. Я так и не смог пофиксить эту проблему, по этому в таком случае программа так же выведет ошибку. Решением будет вручную найти конфликтных двух трутней и убрать одного из них. Небольшой недочет схемы в том, что она может работать только с одной пасекой одновременно. Главный недочет программы - словарь пчел написан полностью на английском, но у большинства игроков интерфейс русский. Чтоб программа работала, нужно или держать интерфейс на английском или переписать словарь на русские названия пчел. Возможно, когда-нибудь я перепишу словарь на русский, но не сегодня) Если вы все сделаете правильно, у вас будет самый простой способ вывода имперской пчелы (проще - только купить). Надеюсь, мои мучения вам помогут, пишите ваши вопросы и предложения в комментариях, постараюсь ответить как можно скорее! 1 Quote Link to comment Share on other sites More sharing options...
AL523 Posted December 2, 2024 Share Posted December 2, 2024 нужно проверить будет ли русификатор подхватывать программное название пчёл и автоматом переводить их на нужный язык пример как видит мод пчёлы for.bees.species.austere=Суровая for.bees.species.avenging=Мстящая for.bees.species.boggy=Болотистая for.bees.species.common=Обычная for.bees.species.cultivated=Развитая for.bees.species.darkened=Тёмная for.bees.species.demonic=Одержимая for.bees.species.diligent=Прилежная for.bees.species.edenic=Райская for.bees.species.ended=Драконья for.bees.species.exotic=Редкая for.bees.species.fiendish=Жестокая Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.