Перейти к публикации

Таблица лидеров


Популярные публикации

Отображаются публикации с наибольшей репутацией начиная с 15.03.2019 во всех областях

  1. 3 балла
    Не так давно решил я немного нафармить обсидиана, но прыгать по озерам лавы, тушить её водой, а потом долго и нудно собирать как-то не то. Хотелось автоматизировать этот процесс. Да есть специальные генераторы обсидиана, но там требуются расходники в виде красной пыли или другого горючего материала, что для меня было неприемлимо. Поэтому был собран первый прототип генератора обсидиана. Портатип генератора обсидианта Version 1.0 В комплект к роботу требуется некая емкость для которая будет хранить лаву (я использовал барабан на 256 литров из мода Extra Utilities) и ведро охладителя (обычная вода). В робота необходимо вставить: Системный блок Т-2 Монитор Т-1 Клавиатура Видеокарта Т-1 ЦП Т-1 Память Т-2.5 (2 штуки) EEPROM (Lua BIOS) Жесткий диск Т-1 (OpenOS) Улучшение "Инвентарь" Бак для жидкостей" Улучшение "Контроллер бака" Так же не забываем про бур/молот который может выбирать сразу территорию 3х3. Для работы необходима постройка как на скрине. Ставим как на скрине сундук и зарядку, выдаем роботу в 1 слот охладитель, во второй бочку с лавой. Рекомендую заменить дно этой установки на какой то материал прочнее обсидиана, на крайняк обсидианом, причем в 2 слоя. Дело в том, что иногда происходит сбой в буре (зачастую из за ошибок сервера), из за чего он вскапывает не только по горизонтали но и по вертикали. Вы же не хотите в один прекрасный день обнаружить что от вашего генератора растекается лава по всему домику. Устанавливаем следующую программу: --1 слот ведро воды --2 слот бочка лавы --апгрейды: контроллер бочки, бочка, инвентарь local com = require("component") local r = require("robot") local tc = com.tank_controller local function go() while not r.forward() do os.sleep(0) end end local function goUp() while not r.up() do os.sleep(0) end end local function goDown() while not r.down() do os.sleep(0) end end local function dropFluid(slot) r.select(slot) if tc.drain() then --1000 мл r.fillDown() else if slot == 1 then r.select(2) else r.select(1) end tc.fill() dropFluid(slot) end end goDown() r.swingDown(0) repeat r.fillDown() print('обнуление!') until r.tankLevel() == 0 while true do go() r.turnLeft() dropFluid(2) go() r.turnLeft() dropFluid(2) go() dropFluid(2) go() r.turnLeft() dropFluid(2) go() dropFluid(2) go() r.turnLeft() dropFluid(2) go() dropFluid(2) go() r.turnLeft() dropFluid(2) go() r.turnLeft() go() r.turnAround() dropFluid(2) goUp() os.sleep(1) r.select(1) dropFluid(1) os.sleep(1) r.drainDown() tc.fill() goDown() r.swingDown(0) if r.count(3) == 64 then print('опустошаю инвентарь') goUp() for i=3, r.inventorySize() do if r.count(i) > 0 then r.select(i) r.dropUp(64) end end os.sleep(5) goDown() end if r.durability() < 0.1 then os.exit() end end ВНИМАНИЕ! Для тех кто копирует, внимательно после вставки проглядите код, там могут встретиться такие символы "?" из за этого программа не запустится (тапки кидать в кривой html код) Запускаем программу и наслаждаемся результатом. Прогон на время с разными бурами (Синий бур из Graviation Suite и Бур из Immersive Engineering) показал слабый результат, стак обсидиана за 2 минуты и 30~35 секунд. Меня такой результат вполне устраивал, но потом мне @Romanok2805 показал свою версию похожего генератора. Описывать его я не буду, поясню что смысл работы того генератора, он черпает ведром лаву из бочки, выливает её рядом с источником воды, меняет ведро на бур и разрушает обсидиан. И так по кругу. Генератор обсидианта Version 2.0 Немного подумав и внеся пару раз изменения в программу, добились нереального результата: стак обсидиана за 14~16 секунд! Итак, конфигурация робота: Системный блок Т-1 Монитор Т-1 Клавиатура Видеокарта Т-1 ЦП Т-1 Память Т-1.5 (2 штуки) EEPROM (Lua BIOS) Жесткий диск Т-1 (OpenOS) Улучшение "Инвентарь" Контейнер для улучшения Т-1 (в него устанавливается Бак для жидкостей) Код программы: --обсидиановый майнер с внешней бочкой --скоростной! local r = require("component").robot local slots = r.inventorySize() local function drop() for i=1, slots do if r.count(i) > 0 then r.select(i) r.drop(1) end end r.select(1) end while r.drain(0) do r.fill(3) r.swing(3) if r.count(slots) > 0 then drop() end end drop() Установка: Под роботом разместите бочку, над роботом сундук. Сзади можно установить зарядку. Сбоку рядом с роботом разлить воду, а рядом с местом где будет ставиться лава убрать 1 блок, чтобы вода туда стекала. Роботу вручите самую быструю кирку, желательно с чарами на эффективность. При желании можете напихать в робота прокачанных апгрейдов опыта, чтобы увеличить скорость разрушения блоков, но тут уже конфигурацию робота и как апгрейды прокачать, сами продумаете. Генератор обсидиана Version 2.1 Данная установка красиво выглядит, но довольно большая и бочка бросается в глаза сильно. Можно избавиться от бочки, забирая лаву из неё напрямую из инвентаря робота, но тогда сложность робота повысится и программа изменится. Итак, конфигурация робота точно такая же как у первого генератора. Код программы: --обсидиановый майнер с внутренней бочкой --скоростной! local r = require("component").robot local tc = require("component").tank_controller local slots = r.inventorySize() local function drop() for i=2, slots do if r.count(i) > 0 then r.select(i) r.drop(1) end end r.select(1) end while tc.drain() do r.fill(3) r.swing(3) if r.count(slots) > 0 then drop() end end drop() Установка: Все так же как и в предыдущем варианте, только бочку необходимо в 1 слот положить. Кстати такая структура фермы позволяет одновременно активировать 2 робота. Собственно такие вот получились варианты сборки фермы обсидиана, я конечно хз зачем вам столько его потребуется, но, коль уж есть программа почему бы ею не воспользоваться. Всем удачи, копайте обсидиант быстрее, чем вам сосед P.S. Большое спасибо за демонстрацию и помощь в написании программы @Romanok2805
  2. 2 балла
    Давным-давно делал модный файловый менеджер с графическим интерфейсом для опенкомпов. Переходы по папкам, запуск файлов, распаковака tarball'ов и просмотр картинок в одной программе, к тому же фичи в виде листания свайпами, экранной клавиатуры и горстки настроек. И все это добро занимало меньше килобайта. Но развивать идею не стал, код удалил и осталась только одна картинка тестовой версии. Недавно решил это дело возродить, без зависимостей и лишних свистоплясок. Для начала напишем функции, которые добавят дополнительные возможности для пользователя. Когда игрок тыкает в экран, создаются два события - touch и drop. Когда зажимает и тащит - touch, потом куча drag и в конце drop. Из имеющихся событий, можно развить дополнительные события - клик, двойной клик и свайп. Можно даже добавить сложные жесты, но пока не понятно, как они могут пригодиться. На все нужные события повесим слушателей и будем сохранять результат в переменную. Слушатель для события touch будет проверять, было ли предыдущее событие drop. Затем сравнит с временем от последнего клика, вычислит расстояние между точками, в которых произошло событие. При совпадении координат и заданным временем между кликами пошлет событие double_click. Для события drop надо проверить, было ли предыдущим touch и по тому же параметру скорости проверять время между событиями, чтобы не захватывать долгие нажатия. Если предыдущим событием было drag, то надо определить расстояние между началом и концом действия, вычислить угол и послать это все в виде события swipe. В итоге получится примерно такой код: local computer = require('computer') -- подгрузить обертку для uptime & pushSignal local event = require('event') -- подгрузить библиотеку событий local lastEvent = nil -- последнее действие local lastTouch = nil -- последнее касание local eventTime = nil -- время от последнего события local clickSpeed = 0.5 -- время, за которое совершается клик и дабл-клик event.listen('drag', function(...) lastEvent = {...} -- просто сохранить событие end) event.listen('touch', function(...) local e = {...} -- сохранить событие в таблицу if e[5] == 0 and lastEvent and lastEvent[1] == 'drop' then -- если нажата ЛКМ и предыдущее было drop if eventTime and computer.uptime()-eventTime < clickSpeed then -- если прошло меньше времени, чем задано if lastTouch and lastTouch[3]-e[3]+lastTouch[4]-e[4] == 0 then -- если координаты событий не отличаются computer.pushSignal('double_click', e[2], e[3], e[4], e[6]) -- послать дабл-клик с координатами end end lastTouch = e -- сохранить последнее касание end eventTime = computer.uptime() -- обновить таймштамп события lastEvent = e -- сохранить событие end) event.listen('drop', function(...) local e = {...} -- сохранить событие в таблицу if e[5] == 0 and lastEvent then -- если нажата ЛКМ if lastEvent[1] == 'touch' then -- если предыдущее событие было касанием if eventTime and computer.uptime()-eventTime < clickSpeed then -- если прошло меньше времени, чем задано computer.pushSignal('click', e[2], e[3], e[4], e[6]) -- послать клик с координатами end elseif lastEvent[1] == 'drag' then -- если предыдущее было тасканием local dx, dy = lastTouch[3]-e[3], lastTouch[4]-e[4] -- найти дельту до координат касания computer.pushSignal('swipe', e[2], dx, dy, math.floor(math.deg(math.atan(dx/dy))), e[6]) -- послать свайп с дельтой и углом end end eventTime = computer.uptime() -- обновить таймштамп события lastEvent = e -- сохранить событие end) Пока он ничего не делает, только создает события, когда будет готов функционал отрисовки и взаимодействия с файловой системой, добавим к этим слушателям управляющие функции.
  3. 2 балла
    https://www.youtube.com/watch?v=AQE4V0J47bk
  4. 2 балла
    Компонент crystal, это прозрачный сундук из мода ironchest, подключается модом OpenPeripheral. Нумерация начинается с единицы, cry.getStackInSlot(i) возвращает таблицу с описанием содержимого слота или nil, если слот пустой. Код из стартового поста выглядит работоспособным, и я пока не вижу проблему. @Teen_Romance можешь выложить код не скриношотом, чтобы я его запустил у себя? А ещё нужны версии ironchest и OpenPeripheral.
  5. 2 балла
    Мяу, ну написали же русским языком, что getStackInSlot(номер слота) возвращает таблицу с информацией о предмете, если таковой имеется в слоте - либо nil в том случае, если слот пустой, для чего и нужна проверка на "пустотность". Шаг 1. Получил инфу о предмете в слоте stack = getStackInSlot(i) Шаг 2. Убедился, что в слоте есть предмет if stack then Шаг 3. Обработал информацию о предмете в слоте так, как требуется. НЕ НУЖНО вызывать getStackInSlot() еще раз. Переменная stack уже хранит результат вызова getStackInSlot() if stack.id == 8 then Конкретно в твоем случае ошибка происходит по той причине, что getStackInSlot возвращает nil, а ты пытаешься получить поле от возвращаемых данных по ключу id - вот и получаешь ошибку attempt to index a nil value. Слот пустой, id не существует. Делай проверку разово - и работай с переменной stack. Также я не совсем понимаю, почему ты используешь два цикла for i = 1, 10 / for j = 1, 10, когда число предметов в ME-сети явно может превышать 100. Наверняка там должен иметься метод getInventorySize, или getItemCount, или еще какой-то схожий - используй его. И еще: для сравнения id предметов с таблицей pe4 также придется делать отдельную логику. Что-то наподобие: local pe4 = { [1] = "камушек", [8] = "доски" } ... stack = cry.getStackInSlot(i) if stack and pe4[stack.id] then print("рассматривается валидный предмет") end Кроме того, как заметил @Asior, мы понятия не имеем, что это за компонент такой под названием "crystal". Так что если выяснится, что информация о его stack'ах вообще не содержит никаких id, либо его id является строковым наподобие "minecraft:stone" - то тут уж ты сам виноват. ПоДуМоЙ
  6. 2 балла
    Что такое crystal ? Все перебрал в МЭ так и не нашел этой штуки. И вообще покажи что за установка, чтобы можно было воссаздать и протестировать. А то так долго можно перебирать и предполагать "а если ..."
  7. 2 балла
    Валидной Луа-программой является набор из 0 байт. Компилируется в одну инструкцию VM. Мудрости в орании не вижу. То, что ты по полмиллиону строчек в свои проекты годами коммитишь, никоим образом не запрещает новичку радоваться им написанной программе, которая в 5000 раз лаконичнее. Надо принять, что полезность предельная одной строчки новичка этого от твоей сильно отличается, и не ржать по-лошадиному, соседей тошнее дрели пугая криком звериным, а заняться чем-то более полезным.
  8. 2 балла
    Нет, а что вы хотели от ОС, красиво оформленный скрипт = программа. И вообще как различить скрипт от программы? >100 строк кода = программа или как? Так я могу навесить отладочных функций на 500 строк для одного маленького скриптика в 2 строчки.
  9. 1 балл
    Если задаваться вопросами о смысле, то какой смысл и в функции __index, если наличие элемента в таблице легко проверяется обычным обращением к самому элементу? Чем это удобнее уже обсуждённой конструкции if tbl[idx] then?
  10. 1 балл
    Вот я о чем: local knowns = {"A","B","C"} local indexer = { __index = function(self, key) return "unknown" end } setmetatable(knowns, indexer) for i=1,5 do print(knowns[i]) end результат: A B C unknown unknown т..е. __index стреляет только для тех элементов, которые отсутствуют в таблице knowns.
  11. 1 балл
    Сомнение в том, что __index вызывается только при отсутствии элемента в таблице.
  12. 1 балл
    @FelixBanan Дык это, а папки-то у него в каком виде вообще отображаются? Опеносовский ls? Или он хочет софтину для листинга с нуля написать? НиПаНЯяяТна
  13. 1 балл
    Ну как где? "pe4[stack.id]" - тут и сравнивает. Если таблица pe4 содержит элемент с ключом, эквивалентным значению поля id таблицы stack, то результатом будет значение элемента таблицы pe4 по требуемому ключу. Да, для того, чтобы ветвь if выполнилась, все условные элементы должны отличаться от nil. И нет, первая часть условия далеко не всегда будет истинна: если требуемый слот не содержит предметов, то переменная stack будет иметь значение nil. Для работы программы нужно банально пробежаться по всем слотам сундука, проверить, есть ли что-либо в слоте - и если есть, то проверить, является ли id предмета в слоте валидным (т.е. содержится ли он в таблице pe4). По крайней мере, я именно так понял условие задачи.
  14. 1 балл
    Идеи есть, но я пока не добрался до компа с Майнкрафтом, чтобы проверить. Можешь показать значения cry.getStackInSlot(i) для пустых и заполненных слотов?
  15. 1 балл
    @Teen_Romance, local stack for i = 1, 10 do stack = cry.getStackInSlot(i) if stack then -- Делай чо надобно end end
  16. 1 балл
    Что значит "не может дать индекс"? Как выглядит ошибка? Какая версия OpenComputers?
  17. 1 балл
    Скорее всего, cry.getStackInSlot(j) для пустого слота возвращает пустую таблицу. Избежать исключения можно, проверив наличие поля cry.getStackInSlot(j).id.
  18. 1 балл
    принято. держи в курсе.
  19. 1 балл
    Очень ценная информация. Но с каких пор слова "прога" и "допилил" стали считаться амбициозными?
  20. 1 балл
    И снова доброго времени суток! Написал и недавно допили прогу по упровлению светом с помощью RedLogic! Команда для скачивания: pastebin get -f uZFEL62c light.lua Вот код: component = require("component"); side = require("sides"); color = require("colors"); rs = component.redstone; --funcs------------------------------------------------------------------------------------------------------------- function hlp() os.execute('clear'); check(); print('\n-------------------------------------------------', '\nlight_1_on - to switсh on a light_1;', '\nlight_1_off - to switсh off a light_1;', '\nlight_2_on - to switсh on a light_2;', '\nlight_2_off - to switсh of a light_2;', '\nall_on - switсh on all light;', '\nall_off - to switсh off all light;', '\n-------------------------------------------------\n'); end -- function check() local component = require('component'); local light_1 = component.redstone.getBundledInput(2, 14); local light_2 = component.redstone.getBundledInput(2, 4); if light_1 <= 255 and light_1 > 15 then print('Light_1 \x1b[32m++\x1b[0m '); elseif light_1 >= 0 and light_1 < 15 then print('Light_1 \x1b[31m--\x1b[0m '); end if light_2 <= 255 and light_2 > 15 then print('Light_2 \x1b[32m++\x1b[0m'); elseif light_2 >= 0 and light_2 < 15 then print('Light_2 \x1b[31m--\x1b[0m'); end end -- function _light_1_on() rs.setBundledOutput(2, 14, 255); os.execute('clear'); check(); end -- function _light_1_off() rs.setBundledOutput(2, 14, 0); os.execute('clear'); check(); end -- function _light_2_on() rs.setBundledOutput(2, 4, 255); os.execute('clear'); check(); end -- function _light_2_off() rs.setBundledOutput(2, 4, 0); os.execute('clear'); check(); end -- function _all_off() rs.setBundledOutput(2, 4, 0); rs.setBundledOutput(2, 14, 0); os.execute('clear'); check(); end -- function _all_on() rs.setBundledOutput(2, 4, 255); rs.setBundledOutput(2, 14, 255); os.execute('clear'); check(); end --main-------------------------------------------------------------------------------------------------------------- os.execute('clear'); print('Enter \'help\''); local cmds = { light_1_on = _light_1_on, light_1_off = _light_1_off, light_2_on = _light_2_on, light_2_off = _light_2_off, all_on = _all_on, all_off = _all_off, help = hlp } local term = require("term"); while true do term.write('> '); cmd = term.read(); if cmd == false then print("Exiting!") os.exit() end cmd, _ = cmd:gsub("\n",""); if type(cmds[cmd]) == "function" then cmds[cmd](); else print("No such command: " .. cmd); end end (На лампе №1 нет контакта, но и так понятно что всё работает) Если преодолею лень и перестану тупить то возможно у этой проги появится GUI!
  21. 0 баллов
    @Teen_Romance, замищательно! Держи тяночку. Она тоже искала идшники в таблицах, но что-то пошло не так...
Таблица лидеров находится в часовом поясе Москва/GMT+03:00
  • Рассылка

    Хотите узнавать о наших последних новостях и информации?

    Подписаться
×