Перейти к публикации
Форум - ComputerCraft
  • записей
    9
  • комментариев
    116
  • просмотров
    80 859

О блоге

Сложно о простом

Записи в этом блоге

 

Zn: строим простой ретранслятор

Иногда случается такое, что ваши компьютеры расположены на расстоянии большем,
чем стандартные 400 блоков. Wi-Fi отказал, а вам надо связать компьютеры по сети.   Какие тут есть варианты?   1) Повысить лимит в конфиге.
Это просто, но не всегда возможно.   2) Использовать linked карту.
С её помощью можно пробить любое расстояние, да.
Но тут есть несколько своих проблем. Она связывает компьютеры только попарно.
Для связи нескольких компьютеров надо уже делать сложную систему проброса сообщений.
Она занимает дополнительный слот. И т.п.   3) Использовать цепочку Wi-Fi карт
Казалось бы, чем это проще второго варианта?
А проще оно тем, что тут есть уже готовые библиотеки. =)   Интермедия   Когда-то в стародавние времена, когда трава была зеленее и птички пели громче,
собралась на нашем сервере компания крутых парней и написала OpenNet.
Это была полноценная компьютерная сеть. Этакий местный интернет. Она обладала
своей строгой и надёжной топологией. Каждый узел - своим местом и адресом в сети.
Никакой анархии. Хочешь - в чатике общайся. Хочешь - сайты строй.   К сожалению, исходники и гайды до сих пор разбросаны по частям по всему форуму.
Чтобы собрать это снова вместе, потребуется немало усилий.
Да и зачем нам поднимать полноценный "интернет", если всё, чего мы хотим - это
пробросить парочку сообщений туда-сюда?   Поэтому в более новые и не такие добрые времена (птички потише, трава потускнее),
некто Totoro и fingercomp придумали систему попроще и погибче.
И назвали её Zn.   Приступаем к решению   Итак, как нам связать Васю и Олю, которые живут на противоположных краях Земного Блина?   1) Через микроконтроллёр
Самое дешёвое в плане ресурсов решение - собрать микроконтроллёр, прошить его
и закопать где-нибудь в лесу на полпути между Васей и Олей.   Сначала нам потребуется код прошивки. Он идёт в комплекте с Zn библиотекой.
Как цивилизованные современные люди, мы скачаем её с Hel-репозитория: hpm install zn
Теперь в папке /usr/share/zn/ у нас есть файлик eeprom.lua. Который мы и прошиваем
на чистый EEPROM: flash -q /usr/share/zn/eeprom.lua "Zn node"
Всё. Осталось вставить чип в контроллер, включить его и закопать.
Сеть создана!  
2) Через компьютер
Более солидное и основательное решение. Строим в лесу будку. В будке ставим
компьютер. На компьютер устанавливаем OpenOS и HPM (если он не идёт в комплекте).
Снова качаем библиотеку: hpm install zn
Создаём мини скрипт: edit node.lua
Пишем в нём такой код: (require ('zn')).connect()
Сохраняем, выходим, запускаем его: node
Всё! Скрипт выполнится и завершится, а в фоновом режиме останется работать
демон Zn-сети, который будет пробрасывать сообщения.
По желанию можно сделать скрипт более сложным - например выводить на экран
сетевой трафик и другую полезную инфу.
Также можно добавить скрипт в автозапуск компьютера, чтобы даже неожиданные
сбои питания (белка залезла в трансформатор) не смогли повалить сеть.  
Эти два варианта обладают некоторыми недостатком, конечно.
Чтобы ретранслятор работал автономно, надо ставить чанклодер и источник энергии.
Однако, в силу своей гибкости, Zn сеть можно организовать и по другому.
Поднять, так сказать, "лайт версию" ретранслятора.   3) Через планшет
Устанавливаем на планшет OpenOS и ставим библиотеку и скрипт по методике #2.
Далее, вручаем планшет соседу Пете и забиваем ему стрелку в том самом лесу.
На протяжении X минут (где X зависит от терпения Пети) у вас будет полноценная сеть!
Игрок будет служить чанклодером, а батарея планшета источником питания.   4) Через робота
Строим робота, устанавливаем скрипт по методике #2. Затем ставим робота где-нибудь
в незаметном месте (можно спрятать в кроне дерева, так чтобы свет солнца падал
на солнечную батарею). Всё, мобильный ретранслятор готов.
Если чанклодеры к роботам разрешены, он может существовать автономно долгое время,
питаясь солнечной энергией.   5) Через дрон
Прошиваете EEPROM как для микроконтроллёра, заряжаете в дрона. Дрона запускаете
в свободный полёт над лесом. Готово! Хотя чанклодер всё равно нужен. Так что вам
наверное придётся пастись где-то рядом.
Этот вариант самый сложный, потому что если вы хотите управлять дроном (например,
с планшета) то вам потребуется модифицировать прошивку и добавить блок управления.
Зато запустив 1000 дронов, вы можете почувствовать себя Илоном Маском,
или Цукербергом, раздающим Интернет папуасам.   А как теперь этой сетью пользоваться?   Все просто. Это делается почти как с обычным модемом.
Только вместо модема вы используете библиотеку Zn.   Если вы знаете адрес модема адресата - можете послать сообщение прямо на него.
И не важно, через сколько промежуточных узлов оно должно будет пройти. До тех
пор пока адресат в радиусе досягаемости хотя бы одного узла вашей сети - он ваше
сообщение получит. -- подключаем библиотекуlocal zn = require('zn')-- коннектимся к сетиzn.connect()-- посылаем Оле сообщениеzn.send("адрес модема Оли", "сообщение для Оли")-- при завершении программы не забываем закрыть коннект-- (можно и не закрывать, но зачем тратить ресурсы компа зазря)zn.disconnect()
Ну а если адресат неизвестен, можно кинуть сообщение бродкастом. Тогда его получат все,
кто подключен к сети. И адресат, конечно тоже. local zn = require('zn')zn.connect()-- посылаем сообщение всем, кто подключён к сети (Оле в том числе)zn.broadcast("сообщение для Оли")zn.disconnect()
Удачи в построении своих сетей.
Enjoy Zn!

Totoro

Totoro

 

Hel Repository: Если не хватает Pastebin

Итак, вы написали крутую программу. Всё работает отлично, не глючит, и вы горите желанием поделиться своим творением с общественностью.   Какие есть варианты?  
1) Pastebin
Это самое популярное, простое и идеальное решение для программ из одного файла.
Заливаете файлик, даёте юзерам ссылку или код файла - и дело в шляпе.
Консольная утилитка для скачивания программ с Pastebin доступна прямо в составе OpenOS.   2) Wget
Здесь тоже всё достаточно просто. Кидаете файл куда угодно в интернете, лишь бы прямую ссылку можно было получить.
Юзер пишет:
wget <url>
и получает ваш файл.   3) Копи-паст
Просто, но геморно. Сначала надо создать файл, потом скопировать в него код (откуда-нибудь). Потом сохранить.
Причём длинный листинг за одни раз скопировать не выйдет. Размер буфера обмена в ОС - 256 строк.  
Ну, тут вроде всё ясно.
Но как быть если программа состоит из нескольких файлов?
Или если она использует какую-нибудь прикольную библиотечку?
Залить десятью файлами и заставлять пользователя скачать всё?  
4) OPPM
Многие наверное слышали, но мало кто использует.
Это клиент к репозиторию OpenPrograms на GitHub. Он предназначен специально для программ под OpenComputers.   Однако, тут тоже не всё безоблачно.
Во первых надо владеть Git'ом. Во вторых - получить личный репозиторий в OpenPrograms.
В третьих, надо будет заполнить специальный конфиг для своей программы. Если в нём будет хоть одна ошибка - всё сломается.   5) Pastebin с самописным инсталлятором
Многие в итоге приходят к этому.
Вы делаете небольшой скрипт и заливаете его на Pastebin, как обычно. Когда пользователь запустит скрипт, тот уже самостоятельно докачает остальные файлы, раскидает их по нужным папкам и настроит конфиги как надо.   Это гибкий способ. Но хлопотный. Надо морочиться с инсталлятором. Надо постоянно обновлять его код под новые версии программы или библиотек. Надо объяснять юзерам, как именно установить программу.
А если у пользователя две программы, которые используют одну библиотеку, то на жёстком окажется две копии этой библиотеки = лишние затраты места.  
Было бы здорово этот процесс как-то облегчить или даже автоматизировать, не правда ли?
И тут на помощь приходит репозиторий Hel.  
6) Hel Repository
Репозиторий - это сайт, которых хранит инфу о программах, и облегчает их поиск и установку.
Общая идея такова. Вы пишете программу как обычно. Там, где вам удобно. Вы можете заливать её на Pastebin, GitHub, C9, файлохранилище или вообще на свой личный сайт.
Главное - чтобы была прямая ссылка на файлы.   Когда пришла пора релизиться, вы заходите на сайт репозитория и создаёте там новый пакет с простым и понятным именем, которое легко запомнят ваши пользователи. Интерфейс создания пакета несложен. Но позволяет многое.     Вы можете указать лицензию, под которой распространяется код.     Добавить короткое описание для каталога (не более 120 символов).
Плюс длинное описание для странички пакета. Тут можно описать подробно ньюансы использования программы. Приложить примеры кода, если это библиотека. Длинное описание поддерживает форматирование кодом Markdown и подсветку синтаксиса 20 с лишним языков программирования (включая Lua и MoonScript).  
  Далее можно приаттачить несколько скриншотов (они потом будут показаны в слайдере наверху странички пакета).     Тегами указываются авторы проекта, а также пользователи Hel, которые имеют доступ к редактированию пакета (обычно это вы сами, но можно "допустить" к рулю кого-то ещё).
Плюс контент теги. Это обычные теги, которыми можно потом пользоваться, чтобы найти вашу программу по ключевым словам.     И наконец главное. Версии программы.
Обычно, ваша первая программа имеет версию вида 0.1.0 или 1.0.0.
Но потом вы решаете добавить немного функциональности, пару фич и печенек. Появляется версия 0.1.1. Потом 0.2.0. А то и 2.0.0.
Но не всем юзерам нравятся нововведения. Какие-то ретрограды остались сидеть на версии 0.1.0, "потому что раньше лучше было". Можно сказать им, что они дураки. Но они ведь обидятся, и свалят к конкурентам.   Однако, есть решение получше. Репозиторий Hel позволяет каждому пакету иметь одновременно несколько версий. Каждая будет доступна для скачивания и установки. И все юзеры останутся довольны.     На вкладке версии вы указываете ссылки на все нужные файлы, на все части программы.
Тут тоже есть дополнительная плюшка. Если нужная вам библиотека уже есть в репозитории, в виде пакета, можно не морочиться с её файлами, а просто указать её название как "зависимость". Тогда репозиторий будет автоматически устанавливать эту библиотеку всем, кто захочет воспользоваться вашей программой.     Когда настройка завершена - просто сохраняете пакет и всё. Теперь любой пользователь может найти его в каталоге на главной странице репозитория и установить себе.    
Установить любой пакет (любой версии) с репозитория крайне легко. И не имеет значения, сколько в нём файлов, сколько библиотек и зависимостей.
Просто пишете:
hpm install mypackage@version
И пакет будет скачан, все нужные файлы распиханы по нужным папкам, а программа полностью готова к запуску.
Удалить пакет, если он вам вдруг больше не нужен, тоже очень просто:
hpm remove mypackage
А если вы вдруг прознали, что доступна свежая версия пакета, можно сделать:
hpm upgrade
И все пакеты будут обновлены.   Сам клиент hpm - это по сути универсальный установщик. Типа того, который могли бы написать вы сами. Но он уже написан за вас. =)
Ставится всего одной командой. Умеет обновляться сам, при помощи апгрейда с репозитория Hel (он там тоже в виде пакета есть).
Плюс он тоже обладает несколькими интересными плюшками. Например его можно расширять дополнительными модулями. В базовой комплектации он как раз имеет один дополнительный модуль, который позволяет ему работать c OPPM. Так что
оригинальный oppm можно в принципе и не ставить, если у вас уже стоит hpm.
Вы можете написать свой собственный модуль, и научить hpm работать не только с Hel и OPPM, но и Pastebin (Hastebin, Asiebin), С9, Яндекс.Диск или вообще своей системой пакетов.  
Подробности я раскрою в одном из следующих гайдов (в относительно недалёком будущем). А пока заходите на
репозиторий по ссылке:   https://hel.fomalhaut.me/
(Эта же ссылка есть в шапке форума, в разделе Lua.)   Клиент HPM можно установить командой:
pastebin run vf6upeAN   P.S. Репозиторий сейчас находится в статусе Beta. Поэтому пишите каких фич ему
не хватает по вашему мнению, или какие баги вам особенно досаждают.
Будем постепенно допиливать.   Enjoy!

Totoro

Totoro

 

Поговорим о Луне! #0. Угадываем числа.

На днях я рассказывал об интересном языке для OpenComputers (и не только).
MoonScript   Но одно дело - прочитать об языке где-то. А совсем другое - попробовать язык самому.
Именно этим я и предлагаю заняться.   Для разогрева, начнем с чего-нибудь несложного. Например "Угадай число".
Думаю все знают эту игру. Компьютер загадывает число, мы пытаемся угадать. На каждую нашу попытку, компьютер злорадно сообщает - "больше!", "меньше!" или "у вас закончились попытки!" и "вы проиграли!".
Немного модифицируем исходную идею, и перенесем ее на 2d поле. Просто, чтобы не было скучно.   ТЗ
Что нам потребуется?
1) Отрисовать сетку
Тут мы просто возьмем текущий размер дисплея, и разметим его на клеточки.
2) Загадать число
3) Слушать команды пользователя
Юзер будет тыкать на клеточки. Нам надо будет слушать эвент touch.
4) Обновлять игровое поле в ответ
Собственно после тыка, будем открывать клетку. Если это не та клетка - рисовать на ней стрелочку. Если та - рисовать победный баннер. Если закончились ходы - рисовать что-нибудь обидное.  
За дело
Первым делом надо подключить все, что мы будем использовать.
В Lua обычно мы при помощи команды require пишем все в локальные переменные.
В MoonScript все переменные по дефолту локальны. Поэтому использовать ключевое слово local нет необходимости.
Для подключения же, используется ключевое слово import:   import getResolution setForeground setBackground set fill from require('component').gpuimport pull from require 'event'import ceil, random from mathimport rep from string
Мы вытащили из нужных библиотек нужные функции. Ничего лишнего.   Теперь объявим переменные, которые будут использоваться в коде. - Размеры экранаwidth, height = getResolution()width /= 2 -- потому что по горизонтали наши клетки займут 2 символаheight -= 1 -- потому что внизу будет статус-- Цветаwhite = 0xFFFFFFblack = 0x000000gray = 0x222222green = 0x00BB33yellow = 0xFFC04Cred = 0xFF0000pink = 0xFF0074violet = 0xD600FFblue = 0x4E5AFFcyan = 0x4ED7FFteal = 0x00CC99-- Заготовка для сетки - один ряд клетокgrid_line = rep("▒▒ ", ceil(width / 2))-- Наша цельtarget = { x: 0, y: 0 }-- Количество попытокmaxAttemts = ceil(width * height / 150) -- 150 - магический коэффициент сложности, больше - сложнее, меньше - легчеattempts = maxAttemts
Тут тоже присутствует несколько новых фич MoonScript.
Во-первых - это сдвоенные операции. Конструкции a /= b или a -= b означают тоже самое, что a = a / b и a = a - b.
Во-вторых это новый синтаксис создания таблиц. Названия полей и их значения отделены двоеточиями. (Такое обозначение будет знакомо тем, кто владеет JavaScript).  
Для реализации геймплея и отрисовки всякой всячины, потребуется определить несколько функций.
Тут мы столкнемся еще с несколькими новшествами, по сравнению с Луа.
Первое, в MoonScript нету ключевого слова end. Блоки кода обозначаются отступом разной величины.
Так что вам придется тщательно следить за тем, на каком уровне вы пишете команды. (Это чертовски полезно, и вырабатывает красивый стиль написания кода =), а не эти кошмарные простыни, где нельзя разобрать начал и хвостов.)
Второе, функции объявляются конструкцией вида (a, b, c) -> .... Тут слева - набор аргументов, потом стрелочка - разделитель и блок кода, который собственно является телом функции. -- Очищаем экранclear = () -> setForeground white setBackground black fill 1, 1, width * 2, height + 1, ' '-- Рисуем сеткуgrid = -> setForeground gray setBackground black for y = 1, height set (if y % 2 == 0 then 1 else 3), y, grid_line
Пустой набор аргументов можно опустить, как в функции grid.
Кроме того, как несложно заметить, MoonScript позволяет вызывать функции, не используя скобочки.   Продолжим. -- Открываем одну клеткуsign = (x, y) -> if x == target.x and y == target.y then black, white, "[]" elseif x == target.x and y < target.y then white, green, "▼▼" -- по неведомой мне причине, стрелки вниз в новом шрифте ОС 1.6 нету =) elseif x == target.x and y > target.y then white, violet, "↑↑" elseif x < target.x and y < target.y then white, teal, "↘↘" elseif x < target.x and y == target.y then white, cyan, "→→" elseif x < target.x and y > target.y then white, blue, "↗↗" elseif x > target.x and y < target.y then white, yellow, "↙↙" elseif x > target.x and y == target.y then white, red, "←←" elseif x > target.x and y > target.y then white, pink, "↖↖"cell = (x, y) -> fore, back, text = sign x, y setForeground fore setBackground back set x * 2 - 1, y, text
Здесь функция sign сконструирована так, чтобы отдавать три переменных разом.
Следует заметить, что в MoonScript можно не пользоваться оператором return.
Функция автоматически вернет значение последнего оператора в теле.
Кроме функций, значения умеют возвращать и условия. Поэтому в данном случае, функция возвращает значение условия, а условие возвращает три значения из той ветки, которая выполнится.   Функция cell просто берет эти значения и отрисовывает в нужном месте клетку.   Далее. -- Рисуем статусstatus = (state) -> setForeground white setBackground black fill 1, height + 1, width * 2, height + 1, ' ' set 2, height + 1, "[Угадай, где клад!]" switch state when 'win' setForeground green set 24, height + 1, "Вы победили!" when 'lose' setForeground red set 24, height + 1, "Вы проиграли!" else set 24, height + 1, "Попыток осталось: #{attempts}" set width * 2 - 10, height + 1, "[R] [Q]"
Здесь тоже используются две новые конструкции.
Первая - это switch. Наверняка многие уже знакомы с ним. По сути, это просто удобный вариант длинных условий, со множеством elseif. Свитч получает значение, а потом сравнивает с ним все ветки when. Какая совпадет - та и выполнится.   Вторая - это интерполяция строк. В строку в двойных кавычках можно встраивать значения перменных (или даже кусочки кода), используя диез и фигурные скобки, как в функции выше.   Последние приготовления: -- Генерируем цельsetTarget = -> target = { x: random(1, width), y: random(1, height) }-- Инициализируем игруnewGame = -> attempts = maxAttemts setTarget! clear! grid! status!
Функция newGame использует специальный синтаксис для вызова функции, которой не нужны аргументы.
Вместо того, чтобы писать setTarget(), MoonScript советует использовать восклицательный знак. setTarget!.
Это довольно весело смотрится в коде. =)  
Ну чтож, все готово.
Давайте соберем все написанное, и запилим немного игровой логики!   -- Поехали!newGame!while true -- Ждем события event, _, x, y = pull! -- Обрабатываем его switch event when 'touch' -- Если был клик -- Открываем клетку, если остались попытки if attempts > 0 x = ceil(x / 2) cell x, y attempts -= 1 -- Обновляем инфу if x == target.x and y == target.y attempts = 0 status('win') elseif attempts == 0 status('lose') else status! when 'key_down' switch x when 113 -- Q: выход из игры break when 114 -- R: перезапуск newGame!clear!
Вуаля! Оно работает. И даже можно поиграть. И даже победить =)  
 
Круто, правда?
Не надо делать такое выражение лица, я знаю что на самом деле, вы со мной согласны. =)
А вы, да-да, вы! - на задних рядах, хватит кидаться тапками!  
Полный код игрушки доступен тут:
http://pastebin.com/M0sxk1QH   Enjoy!

Totoro

Totoro

 

Как включить компьютер если заняты руки?

0. Вступление Итак, представим себе, что вы, после бурного вечера с друзьями, идете к себе домой. Уже добрались почти до входных дверей - у тут на тебе! Компьютер который работает дверным замком, бессовестно взял отгул и отключился. Что делать? Как попасть домой? Как добраться до железного гада, чтобы объяснить всю глубину его заблуждений?   К счастью, красная плата и сетевая карта имеют некоторые недокументированные на gamepedia (я забыл обновить статьи =)) возможности. Вы можете включить компьютер при помощи сигнала редстоуна, или кодового слова отправленного по сети.       1. Wake-On-Redstone component.redstone.setWakeThreshold(threshold:number):number Эта команда позволяет установить в компьютер "будильник", который сработает, если входящий сигнал редстоуна (поданный на корпус компьютера (если вы используете красную плату) или на блок красного контроллера) превысит порог значения threshold. И если компьютер был выключен - он включится.   Т.е. для включения компьютера вы можете воспользоваться рычагом или нажимной пластиной.     2. Wake-On-LAN component.modem.setWakeMessage(message: string):string Если компьютер получит по сети (проводной или без), сообщение message, то он включится. При этом не имеет значения, по какому порту получено сообщение.     Обе функции возвращают в качестве результата старое значение "будильника". Чтобы снять "будильник", установите значение 0 (для редстоуна) или nil (для модема). Ну, а для того, чтобы включенный компьютер тут же принялся за работу, пропишите нужные команды в файле autorun.lua в корне загрузочного диска.

Totoro

Totoro

 

3D-Принтер

Трехмерная печать в Minecraft (инструкции для самых маленьких) Начиная с версии 1.5.4, в OpenComputers появляется интересный девайс - трехмерный принтер. Он дает возможность печатать декоративные блоки любой формы и цвета. Причем не только статичные блоки, но и двери/люки, кнопки и рычаги! Давайте рассмотрим, для чего он может пригодиться, и как именно с ним работать.     1. Цель Как и в предыдущих гайдах, первым делом поставим себе цель. Мы будем создавать стенную плитку со сквозным орнаментом, в виде морды крипера.   Я не буду приводить в этом гайде рецепты предметов, так как их легко найти в NEI, или в статьях на gamepedia.   2. Обзор принтера 3D-принтер - это периферическое устройство, которое должно быть подключено к работающему компьютеру. Оно представляет собой блок, с двумя внутренними слотами:     Верхний слот предназначен для специальной печатной массы (изготовляется из редстоуна, гравия, древесного угля и воды). Принтер вмещает два стека печатной массы (256 000 ед). Нижний слот занимает картридж с красителями. Объем внутреннего хранилища - два картриджа краски (100 000 ед).   По команде от компьютера, принтер берет немного печатной массы и краски и "распечатывает" в крайний правый слот запрограммированную модель. На модель из этого гайда, состоящую из 21 фигуры, принтер потратил 424 единицы массы и 314 единиц краски.   3. Отпечатанный блок Модель для печати задается в виде списка "фигур" - параллелепипедов. Каждая фигура отмечена координатами противоположных углов. Она имеет свою текстуру, цвет оттенка (если необходимо) а также состояние (true/false). Максимальное количество фигур в модели - 24, по умолчанию.   Координаты блока тремя числами (X, Y, Z) в пределах от 0 до 16.     Блок может переключать свое состояние, когда игрок кликает по нему правой кнопкой мыши, или на блок подается сигнал редстоуна. По умолчанию блок имеет форму, заданную блоками с состоянием false, и сменяет ее на форму из блоков с состоянием true, при активации.   Кроме того блок имеет несколько дополнительных общих флагов, которые определяют его название, описание и некоторые другие параметры.   4. Программирование принтера Есть два способа распечатать свою модель. Через компонент принтера и прямое управление, либо при помощи стардартной программки print3d от Сангара.   4.1 Компонент принтера Подключение принтера ничем не отличается от подключения любого другого устройства: local com = require('component')local printer = com.printer3d Компонент предоставляет набор функций для управления: reset() - сброс настроек и остановка печати
setLabel(value:string) - задаем название будущего блока
getLabel():string - получаем текущее название
setTooltip(value:string) - задаем описание блока
getTooltip():string - получаем описание
setRedstoneEmitter(value:boolean) - определяет, излучает ли блок сигнал редстоуна в активированном состоянии
isRedstoneEmitter():boolean - возвращает true, если блок излучает сигнал в активном состоянии
setButtonMode(value:boolean) - определяем поведение блока при активации. Если true, то блок автоматически возвращается в неактивное состояние через несколько секунд после активации (как кнопка)
isButtonMode():boolean - возвращает true, если блок находится в режиме "кнопки"
addShape(minX:number, minY:number, minZ:number, maxX:number, maxY:number, maxZ:number, texture:string[, state:boolean=false][,tint:number]) - добавляет новую "фигуру" к форме блока. Фигура задана координатами. texture - название текстуры, state - для какого состояния фигура предназначена, tint - цвет оттенка фигуры
getShapeCount():number - возвращает количество фигур в модели
getMaxShapeCount():number - возвращает максимально возможное количество фигур
commit([count:number]) - посылает принтеру текущую конфигурацию и начинает печать (count - количество копий, если не задано - равно 1)
status(): string, number or boolean - возвращает состояние принтера - "buzy" и процент готовности, или "idle" и готовность предмета (true/false).
4.2 Программа print3d Код программы не включен в мод по умолчанию, поэтому его надо скачать из интернета. Последнюю версию можно найти на ГитХабе автора: https://github.com/OpenPrograms/Sangar-Programs/blob/master/print3d.lua Либо скачать с Pastebin: http://pastebin.com/b5rD8KcY (поставьте интернет-плату, и наберите в консоли компьютера команду pastebin get b5rD8KcY print3d)   Эта программа по сути, читает параметры модели из текстового файла и передает принтеру. Формат вызова программы: print3d FILE [count] Где FILE - название файла с моделью, а необязательный параметр count - количество копий модели.   Модели имеют простой формат - все параметры записываются в таблицу, по аналогии с Луа. Вот образец файла с моделью. { -- Это - название модели. Т.е. название будущего блока, которое будет видно -- в инвентаре и подсказке Waila. Название по умолчанию - "3D Print" label = "Example Model", -- Это описание предмета, такое, как будет видно в инвентаре. Если не задано, -- предмет не будет иметь описания tooltip = "Это демонстрационная модель, показывающая все возможности", emitRedstone = false, --[[ Если этот параметр равен false, блок работает как дверь, сменяя свое состояние при сигнале редстоуна. Если параметр равен true, блок работает как кнопка или рычаг - излучая сигнал при смене состояния. При этом блок не реагирует на сторонний сигнал. По умолчанию параметр равен false. ]] buttonMode = false, --[[ Если этот параметр равен false, модель работает как дверь или рычаг - то есть остается в том состоянии, в которое установлен игроком. Если параметр равен true, модель автоматически возвращается в неактивное состояние через несколько секунд после активации. По умолчанию параметр равен false. ]] -- Это список фигур модели, которые определяют, как она выглядит. -- Модель должна содержать как минимум одну фигуру (параллелепипед) -- в неактивном состоянии. -- Фигуры не могут быть "плоскими" т.е. не иметь объема. -- Каждая фигура задана шестью числами: minX, minY, minZ, maxX, maxY, maxZ. -- (Координаты двух противоположных углов.) -- Если смотреть спереди, ось X направлена вправо, ось Y - вверх и ось Z - вглубь. -- Дополнительно, каждая фигура длолжна обладать текстурой. Для того чтобы -- определить название текстуры, вы можете воспользоваться Определителем Текстуры -- (Texture Picker), кликнув им по нужному блоку. -- -- Модель имеет два состояния - неактивное (false, состояние по-умолчанию) -- и активное (true, состояние после активации блока). shapes = { -- Фигура идет от точки <0, 0, 0> (левый нижний угол) до <8, 8, 8> (середина), -- и имеет текстуру блока лазурита. { 0, 0, 0, 8, 8, 8, texture = "lapis_block" }, -- Фигура идет из точки <8, 8, 8> (середина) в <16, 16, 16> (правый верхний угол), -- и закрашена текстурой дубовой листвы. Фигура принадлежит активному состоянию -- модели и имеет светло-зеленый оттенок. { 8, 8, 8, 16, 16, 16, texture = "leaves_oak", state = true, tint = 0x48B518 } }} Т.е. описание модели просто содержит перечень всех тех параметров, которые задаются при помощи компонента, и список фигур из которых модель состоит.     Набор тестовых моделей для изучения, можно найти здесь: https://github.com/OpenPrograms/Sangar-Programs/tree/master/models   5. Проектирование модели Разобьем мысленно рисунок запланированной модели на параллелепипеды. Она будет представлять собой тонкую плитку посередине блока, наподобие стекла или решетки.   Руководствуясь сеткой координат и образцом выше, составим описание модели для текстового файла: { label = "Плитка 'Морда крипера'", emitRedstone = true, buttonMode = false, tooltip = "Секретный рычаг в виде головы крипера" shapes={ {0,14,7, 16,16,9, texture="quartz_block_side", tint=0x8eb200}, {0,2,7, 2,14,9, texture="quartz_block_side", tint=0x8eb200}, {6,10,7, 10,14,9, texture="quartz_block_side", tint=0x8eb200}, {14,2,7, 16,14,9, texture="quartz_block_side", tint=0x8eb200}, {2,2,7, 4,10,9, texture="quartz_block_side", tint=0x8eb200}, {4,8,7, 6,10,9, texture="quartz_block_side", tint=0x8eb200}, {10,8,7, 12,10,9, texture="quartz_block_side", tint=0x8eb200}, {12,2,7, 14,10,9, texture="quartz_block_side", tint=0x8eb200}, {6,2,7, 10,4,9, texture="quartz_block_side", tint=0x8eb200}, {0,0,7, 16,2,9, texture="quartz_block_side", tint=0x8eb200}, {0,14,7, 16,16,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {0,2,7, 2,14,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {6,10,7, 10,14,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {14,2,7, 16,14,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {2,2,7, 4,10,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {4,8,7, 6,10,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {10,8,7, 12,10,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {12,2,7, 14,10,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {6,2,7, 10,4,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {0,0,7, 16,2,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {2,2,8, 14,14,9, texture="quartz_block_side", tint=0xe0301e, state=true}}} Итак, наша плитка имеет двойной набор фигур - для двух состояний, окрашенных в текстуру кварца с зеленым оттенком. Кнопка будет работать как рычаг, испуская сигнал в активном состоянии.   Откройте файл командой open creeper. Скопируйте код плитки выше и вставьте в файл кнопкой [insert]. Затем сохраните ([Ctrl]+) и покиньте редактор ([Ctrl]+[W]).   6. Печать Все готово, принтер заправлен, модель спроектирована. Отправляем ее на печать! print3d creeper 7. Итоги         Enjoy!

Totoro

Totoro

 

Цвета алмазного экрана

Нашел эту табличку на англоязычном форуме по OpenComputers. Картинка за авторством Eunomiac показывает весь 8-битный диапазон цветов, доступный для отображения на алмазном дисплее.     Пользуясь схемой, легко подобрать цвета для вашего интерфейса, и тут же составить к ним шестнадцатеричный код.

Totoro

Totoro

 

Как собрать шахтерского робота

Как собрать робота в 5 шагов (инструкция для самых маленьких) Абстрактное описание сборки робота я уже писал много раз, поэтому это будет короткое руководство на конкретном примере. Соберем и запустим Totoro Recursive Miner.     Шаг 1. Подготовка Для создания робота нам потребуется сборщик (assembler). Чтобы он работал - подведите питание. Сборка робота потребует некоторого времени (примерно 5 минут) и энергозатрат.     Шаг 2. Подбор железа Запчасти делятся на обязательные и необязательные.   Детали обязательные: 1) Корпус Основа робота. Без него никуда. Для TRMiner нужен корпус 2+ уровня, потому что он должен содержать апгрейд-генератор. 2) Процессор Мощность процессора определяет количество выполняемых роботом операций в такт. Т.е. проще говоря - скорость его работы. Однако перемещаться быстрее робот не станет. Этот параметр можно улучшить "прокачав" робота (см. апгрейд-опыт). 3) Память Практика показала, что одной планки 1 уровня для нормальной работы на компьютере недостаточно. TRMiner хранит в памяти данные о жилах руды, поэтому требует как минимум две планки уровня 1.5. При меньшем количестве корректную работу не гарантирую. (Хотя возможно он будет работать.) 4) Монитор Достаточно 1 уровня. Робот не поддерживает цветные экраны. (Можно собрать робота и без экрана. Но это - для любителей хардкора.) 5) Видеокарта Также достаточно 1-го уровня. Требуется для вывода изображения на монитор. Без нее монитор будет просто черным. 6) Клавиатура Чтобы иметь возможность набрать что-то в консоли. 7) Дисковод Для установки OpenOS и копирования программы TRMiner. (Любители хардкора могут попробовать запустить робота без дисковода. Это возможно. Но я не скажу как :P ) 8) Жесткий диск Для хранения ОСи и программы. Первоэтапный диск в 1Мб хватит с головой. Это даже много. Будет занято ~20%. 9) Lua BIOS Этот чип нужен для корректной работы OpenOS. Крафтится из пустого EERPOM и книги.   Детали обязательные для Totoro Recursive Miner: 10) Апгрейд-инвентарь. Робот хранит в нем добытую руду. Рекомендуется установить 2 или 3 апгрейда (т.е. 32 или 48 слотов). Больше можно не ставить, ибо обычный сундук, в который робот сбрасывает добычу имеет размер в 27 слотов. 11) Апгрейд-генератор. Нужен роботу для непрерывной работы. Робот будет сам заряжаться с его помощью, сжигая часть добытого угля. (Любители хардкора могу не ставить генератор. Программа будет работать. Вы можете заряжать робот таская за ним заряжающее устройство, или приделав пару солнечных панелей и выкопав вертикальный колодец до поверхности. )   Детали необязательные: 12) Апгрейд-опыт Позволит роботу прокачиваться во время добычи. Со временем он станет быстрее двигаться, меньше тратить энергию и медленнее ломать свой инструмент. Требует Корпуса 3-его уровня. 13) Апгрейд-батарея Ну тут все понятно. Увеличивает емкость аккумулятора. Полезная штука.   Детали вредные (эксклюзив для IT 1.7.10): 14) Апгрейд-чанклоадер После включения робота, в момент опустошит его аккумулятор. На том все и закончится.   Вот две рабочие конфигурации:   Минимальная Рекомендуемая   (UPD.: Тут уважаемый Krutoy любезно предоставил картинку, которая иллюстрирует, сколько всего ресурсов у вас уйдет на сборку рекомендуемой конфигурации робота: За что ему большое спасибо.)   Уложите выбранные детали в сборщик и запускайте процесс.     Шаг 3. Софт Раздобудьте дискету с OpenOS (крафтится из чистой дискеты и книги).   Скачайте программу Totoro Recursive Miner на другую, чистую дискету. http://pastebin.com/L21VMm7S Для этого этапа нам потребуется компьютер. Свой или соседа, все равно. Он должен иметь выход в интернет (интернет-плата) и дисковод для дискет.   Как скачать программу на новую дискету: 1) Вставить дискету 2) Посмотреть в инвентаре ее адрес. Запомнить первые его буквы-цифры. 3) Написать в консоли команду: label -a xxxx floppy Где xxxx - первые буквы-цифры ее адреса, а floppy - это будущее название (этикетка). В результате ваша дискета получит короткое и ясное название. 4) Написать команды: mount floppy fcd /f В результате вы окажетесь в корневом каталоге дискеты. 5) Скачать программу TRMiner: pastebin get L21VMm7S mine Для этого нужна интернет-плата. Программа будет сохранена на дискету под именем mine. 6) Извлеките дискету.   (Также можно поискать игрока с ником Totoro и подоставать его, чтобы дал дискету с программой нахаляву. Тогда и компьютер не нужен.)   Шаг 4. Установка Поставьте робота. Можно прямо на месте предполагаемой добычи руды. Чтоб два раза не ходить. Включите его и установите OpenOS (это надо сделать только один раз).   Как установить OpenOS: 1) Вставить в робота зеленую дискету. 2) Включить его. 3) Написать в консоли: install 4) Он спросит на какой жесткий диск устанавливать. Напишите 1. 5) Согласитесь на рестарт (y).   Теперь сбросьте программу TRMiner с дискеты на жесткий диск робота. (Можно каждый раз вставлять дискету и запускать программу прямо с нее, но это лишние действия. Зачем оно нам?)   Как сбросить программу с дискеты: 1) Вставить дискету с программой в робота. 2) Убедиться, что он включен. 3) Написать в консоли робота: mount floppy fcp f/mine mine 4) Достать дискету.   Все! Софт установлен. Дискеты больше в принципе не нужны. Но сохраните их на всякий случай.     Шаг 4A. Настройка программы (необязательно) Для настройки программы Totoro Recursive Miner, введите в консоль команду: edit mine В двадцатой строке вы увидите константы набранные заглавными буквами: TECH_SLOTS = 6VANILLA_CHEST = truePATHWAYS = trueDROP_TRASH = false TECH_SLOTS - количество слотов с образцами "пустой породы" и сундуками. То есть тех слотов, которые не будут заняты добычей. VANILLA_CHEST - режим для работы с обычными сундуками. Есть возможность работать с сундуком Эндера. Для этого, установите константу в значение false и дайте роботу инструмент с зачарованием "Шелковое касание". В слот с сундуками положите один сундук Эндера. PATHWAYS - если true, робот проделает в шахте дорожки, для удобства хождения игрока DROP_TRASH - если true, робот будет выбрасывать булыжник и другую "пустую породу".   После изменения констант, нажмите клавиши Ctrl+S (сохранение) и Ctrl+W (выход).     Шаг 5. Добыча полезных ископаемых Принесите робота на место предполагаемой шахты. Поставьте робота в ее воображаемый правый передний угол, передней стороной вперед. Вот так:   В инвентаре робота разложите образцы пустой породы (5 штук по дефолту). Причем (лайфхак для ускорения работы робота), кладите в порядке убывания распространенности. У меня это камень-земля-гравий-булыжник-камень Бездны (abyssal stone из RailCraft). В последний из технических слотов (6-ой по дефолту) положите сундуки (или сундук Эндера, если вы перенастроили программу).   Роботу в "руку" положите кирку или бур. Чем прочнее и острее - тем лучше.   Теперь включите. Введите в консоль команду такого формата: mine <длина> [ширина] [возвращаться_в_начало] Первые два параметра - числовые. Последний - true/false (Если не указать, равен false).   Ура! Наконец все ездит, копает и складывает без нашего участия. Остается только иногда менять кирку. И уносить добычу.     Enjoy!

Totoro

Totoro

 

Запускаем дронов!

Дроны - как керосин. Они есть везде. Еще года два назад это было просто еще одно интересное видео на Ютубе. Год назад они вдруг оказались в интернет магазинах. Затем просочились в рекламу на ТВ, и вот теперь - они есть и в OpenComputers! Пришла пора с ними разобраться.   1. Матчасть Дрон, в данном случае - квадрокоптер, это беспилотный летающий аппарат, приводимый в движение двумя парами горизонтальных винтов. Приостановливая вращение винтов с одного боку, дрон двигается в сторону (стрейф). Эти винты вращаются в разном направлении (два - по часовой срелке и два - против), за счет чего дрон не нуждается в стабилизирующем хвостовом пропеллере (как вертолет). За счет этого же он и разворачивается в воздухе, замедлив вращение однонаправленной пары винтов. Дрон обладает небольшой массой, для экономии энергии, которой у него не много (на 10-30 минут полета в среднем). (с) Википедия   2. Дроны и OpenComputers Приблизительное изображение дрона в OpenComputers =): В мире Майнкрафта дрон представляет из себя "сущность" (Entity). Это значит, что он обладает возможностями мобов Майнкрафта. (В то время как робот - это блок.) Его можно сдвинуть с места толкая. Он умеет пролетать сквозь двери и калитки (в отличии от робота). Он движется не последовательно, из блока в блок, а из точки в точку. Причем маршрут может лежать по диагонали.   Конечно, движется он по кратчайшей линии, и если на пути окажется стена - дрон столкнется с нею.   Программирование дрона как две капли воды похоже на программирование микроконтроллера. Вы точно так же записываете программу на EEPROM, и при необходимости меняете ее на верстаке. Только в отличии от контроллера, вам становится доступен новый компонент: drone.   Подробнее об командах дрона можно узнать здесь: OpenComputers/Дрон. (Или здесь: ocdoc.wiki (англ.))   3. План Нужна какая-нибудь несложная задача, для целей эксперимента. Используем программку send из предыдущего поста, для удаленного управления. Зальем ее на планшет. А дрон пусть... носит свиней. Будем оригинальными и непоследовательными.     1. Команда 'add X Y Z Name From'. Добавляем точку Name к маршруту, цепляя ее к точке From. Зададим дрону последовательность точек, которые образуют граф - безопасные маршруты. 2. Команда 'catch' - дрон ловит свинью. 3. Команда 'drop' - дрон выпускает свинью. 4. Команда 'to X' - дрон летит в точку Х.   Для начала не будем особо заморачиваться с графом маршрутов. Это будет простое неориентированное дерево. Примерно такое:   4. Строим полигон Построим что-нибудь подходящее для тестов. Отметим ключевые точки будущего графа красными блоками. А синий блок - будет стартовой площадкой дрона.           Поскольку я играю без модов на энергию, мой планшет и дрон будут работать вечно. И я не заморачиваюсь станцией подзарядки.   Иначе, к схеме выше было бы необходимо добавить станцию, где дрон мог бы зарядить аккумулятор.     5. Пишем программу Скрипт для удаленного управления скопипастим из прошлого поста, подправим, чтобы умела отправлять несколько переменных и зальем на планшетик, для удобства. (Для этого, соберите планшет - не забудьте клавиатуру и видеокарту! - положите его в зарядник и запустите с подключенного компа команду install. Укажите адрес винчестера планшета - и все, что было у вас на компе автоматически загрузится в планшет, включая даже ваши собственные программы.) local com = require('component')local modem = com.modemlocal args = {...}modem.broadcast(27, table.unpack(args))io.write("Message: ")print(table.unpack(args)) Далее - более сложная часть. Программа дрона. Программа предназначена для EEPROM. Значит соблюдаем те же правила: используем computer, component и API имеющихся у дрона компонентов. Включая его родной компонент drone. В нашем случае, дрон вооружен апргейдом-лассо (leash) и беспроводной сетевой картой (modem) для связи.   Стоит отметить, что процесс отладки программы (по крайней мере в текущем билде мода) достаточно неудобен. В случае ошибки дрон отказывается включиться, издав тонкий писк, и не выводя никакой информации. Получить отчет об ошибке при помощи анализатора не выйдет - ведь Shift+ПКМ просто снимает дрона. Автор обещал в скором времени это исправить. Ну а пока - помучаемся.   Отредактировать чип в стороннем редакторе, не вынимая его из дрона тоже не выйдет. В отличии от файловых систем, которые имеют удобную папку вида /saves/World/opencomputers/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/, чипы EEPROM хранят свой код в NBT тегах предмета. Этим же обусловлено и ограничение размера кода в 4 килобайта.   5.1. Основная часть Это цикл который ждет указаний, а затем запускает соответствующую функцию. drone = component.proxy(component.list("drone")())modem = component.proxy(component.list("modem")())leash = component.proxy(component.list("leash")())modem.open(27)route = {}path = {}current = ""while true do name, _, sender, _, _, message, x, y, z, point, from = computer.pullSignal(1) if name == "modem_message" then if message == 'add' then add(tonumber(x), tonumber(y), tonumber(z), point, from) if current == "" then current = point end elseif message == 'to' then to(x) elseif message == 'catch' then catch() elseif message == 'drop' then drop() end end if #path > 0 and drone.getOffset() < 1 then drone.move(route[path[#path]].x-route[current].x, route[path[#path]].y-route[current].y, route[path[#path]].z-route[current].z) current = path[#path] path[#path] = nil endendmodem.close() Чтобы облегчить себе жизнь (и тестирование bios), вы можете сделать так: напишите заглушку для компонента drone (и других, если надо), вроде этой: http://pastebin.com/EVYzN5Bj Просто скопируйте в папку на компьютере, где вы пишете программу для дрона. Затем измените первые строки программы следующим образом: component = require('component')computer = require('computer')drone = require('drone')modem = component.modem-- leash = component.proxy(component.list("leash")()) Затем добавьте в цикл условие выхода по нажатию кнопки: if name == 'key_down' then break end И вы можете просто запустить вашу программу для дрона на компьютере. Разумеется полноценной эмуляцией дрона тут и не пахнет, зато очень удобно отслеживать глупые синтаксические и логические ошибки.     Как устроен код основного цикла? Переменная route - хранит таблицу "вейпоинтов" (waypoints). Это вершины графа и информация о связях между ними. Переменная path - хранит путь от текущей вершины до цели. Переменная current - отмечает текущее местоположение дрона в графе.   В цикле мы читаем получаемые сообщения и вызываем соответствующие функции. Первая переданная вершина считается дроном текущей.   Во второй части цикла происходит проверка. Если путь до цели - не пуст (это значит, что дрону надо куда-то лететь) и дрон уже долетел до текущей вершины (getOffset()), то программа берет следующую вершину из path, отправляет дрона к ней и объявляет ее текущей.   5.2. Функции-команды Теперь последовательно добавим функции для каждой команды. function add(x, y, z, name, from) route[name] = {x=x, y=y, z=z, link = {}} if from ~= nil then if route[name] == nil or route[from] == nil then drone.setStatusText("Error!") else table.insert(route[name].link, from) table.insert(route[from].link, name) end endend Тут все просто. Пишем вершину в список. Если он связана с другой вершиной (from ~= nil), то в специальную табличку link заносим две связи: из name в from, и из from в name. function search(target, point, prev) for key, name in pairs(route[point].link) do if name == target then table.insert(path, point) return true end end for key, name in pairs(route[point].link) do if name ~= prev then if search(target, name, point) then table.insert(path, point) return true end end end return falseendfunction to(name) path = {} table.insert(path, name) search(name, current)end Функция to обнуляет старый путь (на всякий случай), затем вставляет в него цель пути (name) и запускает функцию search, которая рекурсивно ищет и записывает остальные промежуточные вершины на маршруте от name до current (текущей локации). Функция search сделана достаточно примитивно (возможно вы предложите более эффективный способ?). Поскольку мы договорились, в целях упрощения использовать граф-дерево (не содержаший петель), от любой точки к другой существует один и только один маршрут, который функция и находит перебором связанных вершин. function catch() for c = 2, 5 do if leash.leash(c) then return true end end return falseendfunction drop() leash.unleash()end Тут все элементарно.   6. Подготовка Пишем программу на дрона, заряжаем планшет и выдвигаемся в зону действий. Дрона ставим на синий куб (стартовая площадка) и включаем.     После уточнения на местности, составляем карту вейпоинтов и строим на бумажке будущий граф:   Для каждого загона добавлены две точки - name и name_up. Основные "трассы" дрона лежат на высоте в 6 блоков. А в каждом загоне спускаются к земле. (Чтобы заарканить животное, выстреливая лассо вбок, дрону желательно находиться на одном уровне с жертвой).   С планшета вносим координаты в память дрона. Примерно так:     Главное - не ошибиться. Т.к. в код не была добавлена защита "от дурака" =) Алгоритм позволяет добавлять вершину "на лету". В любой момент вы можете добавить еще одну ветку к схеме.   Теперь все готово к тесту.   7. Запуск Все готово. Проверим, как он двигается. Введем send to sheeps в консоль планшета. Дрон уверенно поднимается в воздух и опускается в загоне в овцами.   Теперь введем send to pigs. Функция search снова вычислит путь и робот переместится в указанную вершину:     Функции catch и drop тоже работают штатно =)     Хотя и не лишены некоторых глюков (ведь физика веревки не просчитывается):     8. Итоги а) Дрон - любопытная штуковина. б) Полный код прошивки. использованный в этом посте - здесь: http://pastebin.com/Cy1UR6vy в) Навигация по вейпоинтам - интересный и очень распространенный способ организации сложного движения. Схему можно усложнить - опционально добавлять только одну связь в таблицу link - тогда получатся ребра с односторонним движением. Добавить петли, оптимизировать поиск кратчайшего пути. Еще можно облегчить правление дроном - хранить все команды для конкретной задачи в виде файла-скрипта, который запускать одной командой и т.д.   Enjoy!

Totoro

Totoro

 

А что такое EEPROM и где оно живет?

В последних версиях OpenComputers обрастает всякими загадочными вещами. Игроки, которые только только освоились с предыдущей версией вдруг понимают, что надо изучать все заново. "А пошло оно все!" - думают игроки, и уходят на версию 1.3.6, или переучиваются на ComputerCraft, который проще, и не требует непонятного.   А одна из самых загадочных - неведомый EEPROM. Это такая мелкая хрень, без которой не работает ни один компьютер, или даже робот. Хорошо еще, что есть стандартный EEPROM который называется Lua BIOS. Он легко крафтится и заставляет работать компьютеры как и раньше.   Но найдем задачку посложнее, где Lua BIOS не поможет. Попробуем собрать микроконтроллер, который будет управлять входными дверями.   1. План Представим, как оно должно работать.   Слева от двери (если входить) - микроконтроллер. Ради понтов, возьмем Микроконтроллер 2-ого уровня и поставим в него беспроводную сетевую плату. Кроме того добавим красную плату, чтобы управлять дверью.   1. Если контроллер принимает сигнал "open" - он открывает дверь. 2. Если примет сигнал "close" - он закрывает дверь. 3. Если примет посторонний сигнал - взрывает динамит. Дабы сокровища не достались хакерам.   Для управления задействуем любой комп, у которого тоже будет беспроводная плата (или точка доступа).     2. Крафтим контроллер С этим проблем не возникнет. Потому, что я играю в креативе :P . Открываем NEI и берем нужные детали. В последний слот положим пока пустой EEPROM. Потом поставим на него прошивку, а пока - не важно.     Нажимаем кнопку "Старт" и достаем готовый блок.   3. Готовим прошивку Теперь, когда все готово, мы построили сокровищницу и скрафтили контроллер - осталось самое главное.   Программирование EEPROM'а отличается от программирования обычной программы. Потому, что обычно, наши программы выполняются в OpenOS, которая заботливо загружает нужные библиотеки, предоставляет всякие удобные фичи и прочее.   Тем не менее писать мы будем именно в OpenOS. Запустим компьютер, напишем edit bios и введем следующие строки: red = component.proxy(component.list("redstone")())while true do red.setOutput(5, 0) computer.pullSignal(1) red.setOutput(5, 15) computer.pullSignal(1)end Дело в том, что большая часть библиотек, которые мы использовали - это библиотеки OpenOS. А значит мы не можем ими пользоваться в BIOS. Однако кое-что нам доступно. Это библиотеки computer и component, и соответственно все установленные в целевом агрегате (микроконтроллер) компоненты. Более чем достаточно для наших задач.   Вышеприведенный код делает следующее: * ищет компонент с названием "redstone" и возвращает его прокси * в вечном цикле посылает нулевой редстоун-импульс направо (side = 5), т.е. гасит сигнал * ждет секунду (на самом деле - ожидает эвентов, то есть сигналов) * посылает редстоун сигнал с силой 15 направо * опять ждет секунду   Преследуем двоякую цель: во-первых проверить, что EEPROM вообще работает так про него написано на Вики. Кто его знает? А во-вторых: убедиться, что сторона 5 это именно та сторона, где дверь. А не какая-нибудь другая.   Нажмем Ctrl+S, чтобы сохраниться и Ctrl+W, чтобы закрыть редактор. Вставим пустой EEPROM (еще один) в слот нашего компьютера, вместо лежащего там Lua BIOS. И напишем в консоль такую команду: flash -q bios MCBios Программа flash предназначена для прошивки чипов. Флаг -q говорит ей, чтобы не задавала лишних вопросов, затем идет имя файла с нашим кодом (bios) и метка, которую программа шлепнет на чип (MCBios).   Все. Доставайте. Lua BIOS на место класть не обязательно, ибо этот слот нам еще потребуется. (Но не забудьте его вернуть, если будете перезагружать компьютер)   Чтобы заменить пустой EEPROM в контроллере на наш MCBios, надо положить контроллер и MCBios на верстак. При этом пустой чип вылетит, а новый встанет на его место.   Поставим контроллер на пол и протестируем. После клика ПКМ на контроллере - замигала правая лампа. Значит все работает как нужно.       4. Теперь - серьезно Извлеките чип с MCBios обратно (так же как и вставляли, только наоборот). Или приготовьте новый пустой чип. Главное - не запутайтесь в них.   Пишем клиент для контроллера. У меня он выглядит примерно так: red = component.proxy(component.list("redstone")())modem = component.proxy(component.list('modem')())modem.open(27)red.setOutput(5, 0)red.setOutput(2, 0) -- no explosions yet =)while true do name, _, sender, _, _, message = computer.pullSignal(2) if name == 'modem_message' then if message == 'open' then red.setOutput(5, 15) elseif message == 'close' then red.setOutput(5, 0) else -- hacker tries to get? red.setOutput(2, 15) -- fire in the hole!!! end endendmodem.close() Все согласно плану. Прошиваем чип, вставляем в контроллер, а контроллер ставим слева от дверей. Сзади к контроллеру осторожно прилаживаем запал. ПКМ!     Теперь открываем новый файл на компьютере: edit send И пишем в него такой код: local com = require('component')local modem = com.modemlocal args = {...}modem.broadcast(27, args[1])print("Message '"..args[1].."' sent!") Сохраняем, и закрываем. Это будет программка для тестирования контроллера.     5. Тест! Пишем в консоль send open. Дверь открылась! Пишем send close. Дверь закрылась! Пишем send opeh Упс! Опечатка.     О_О

Totoro

Totoro

×