Как создать lua файл

Обновлено: 03.07.2024

Библиотека ввода-вывода Lua используется для чтения и обработки файлов. Разделены на простой режим (такой же, как C) и полный режим.

  • Простая модель имеет текущий входной файл и текущий выходной файл и предоставляет операции, связанные с этими файлами.
  • Полная модель реализована с использованием внешнего дескриптора файла. Он определяет все файловые операции как методы обработки файлов в объектно-ориентированной форме.

Простой режим больше подходит для выполнения простых файловых операций. Но при выполнении некоторых расширенных операций с файлами простой режим оказывается неадекватным. Например, для таких операций, как одновременное чтение нескольких файлов, больше подходит полный режим.

Оператор операции с открытым файлом выглядит следующим образом:

Режим описание
r Чтобы открыть файл только для чтения, файл должен существовать.
w Откройте файл только для записи.Если файл существует, длина файла сбрасывается до 0, то есть содержимое файла исчезает. Если файл не существует, создайте файл.
a Откройте файл только для записи в режиме добавления. Если файл не существует, он будет создан.Если файл существует, записанные данные будут добавлены в конец файла, то есть исходное содержимое файла будет сохранено. (Символ EOF зарезервирован)
r+ Чтобы открыть файл в режиме чтения-записи, файл должен существовать.
w+ Откройте файл, доступный для чтения и записи.Если файл существует, длина файла сбрасывается до нуля, то есть содержимое файла исчезает. Если файл не существует, создайте файл.
a+ Подобен a, но этот файл доступен для чтения и записи.
b Двоичный режим, если файл является двоичным файлом, вы можете добавить b
+ Знак указывает, что файл можно читать или писать

Простой режим

В простом режиме используется стандартный ввод-вывод или текущий входной файл и текущий выходной файл.

Ниже приведен код файла file.lua, файл, с которым нужно работать, - test.lua (если у вас его нет, вам нужно создать файл), код выглядит следующим образом:

Выполнив приведенный выше код, вы обнаружите, что первая строка информации в файле test.ua выводится, а комментарий lua добавляется к последней строке файла. Например, вот что я вывожу:

В приведенном выше примере мы использовали метод io. "X", где мы не брали параметры в io.read (), и параметр может быть одним из следующих:

Режим описание
"*n" Прочтите число и верните его. Пример: file.read ("* n")
"*a" Прочитать весь файл с текущей позиции. Пример: file.read ("* a")
«* l» (по умолчанию) Прочтите следующую строку и верните ноль в конце файла (EOF). Пример: file.read ("* l")
number Возвращает строку с указанным количеством символов или возвращает ноль, если EOF. Пример: file.read (5)

Другие методы io:

  • io.tmpfile():Возвращает временный дескриптор файла, файл открывается в режиме обновления и автоматически удаляется при завершении программы.
  • io.type(file): Проверьте, является ли obj пригодным для использования дескриптором файла
  • io.flush(): Записать все данные из буфера в файл
  • io.lines(optional file name): Верните итеративную функцию, каждый вызов получит строку содержимого в файле, когда он достигнет конца файла, он вернет ноль, но файл не будет закрыт

Полный режим

Обычно нам нужно обрабатывать несколько файлов одновременно. Нам нужно использовать file: function_name вместо метода io.function_name. В следующем примере показано, как обрабатывать один и тот же файл одновременно:

Выполнив приведенный выше код, вы обнаружите, что первая строка информации в файле test.ua выводится, а комментарий lua добавляется к последней строке файла. Например, вот что я вывожу:

Параметры чтения соответствуют простому режиму.

  • "set": начать с начала файла
  • "cur": начать с текущей позиции [по умолчанию]
  • "конец": начать с конца файла
  • смещение: по умолчанию 0

Без параметров file: seek () возвращает текущую позицию, file: seek ("set") указывает на начало файла, file: seek ("end") находит до конца файла и возвращает размер файла.

file:flush(): Записать все данные из буфера в файл

io.lines(optional file name): Откройте указанное имя файла в режиме чтения и верните итеративную функцию. Каждый вызов будет получать строку содержимого в файле. Когда он достигнет конца файла, он вернет nil и автоматически закроет файл.
Если параметр отсутствует, io.lines () <=> io.input (): lines (); считывает содержимое устройства ввода по умолчанию, но не закрывает файл при конец, например

В следующем примере метод seek используется для поиска 25-й позиции снизу файла и используется параметр * a метода чтения для чтения всего файла с текущей позиции (25-я позиция снизу).


Это руководство призвано исполнить две цели: обучить разработке скриптов с нуля и восполнить все пробелы в знаниях о Lua скриптинге под MoonLoader. В нём освещены все аспекты разработки - от самого простого до продвинутых возможностей и приемов, то есть оно подходит как и для начинающих скриптеров, так и для программистов с опытом. Предварительное прочтение старого руководства не требуется, здесь есть вся необходимая и более актуальная информация.
А если вы всё ещё не знакомы с MoonLoader, то сейчас самое время ознакомиться.
Ну что, приступим?

Перед продолжением необходимо установить сам MoonLoader, желательно через программу установки и с дополнительными инструментами:
1. Скачайте установщик MoonLoader последней версии и запустите, следуйте шагам программы установки
2. На странице выбора компонентов отметьте нужные скрипты (рекомендуется выбрать все)

3. Если вы намерены делать скрипты для SA:MP, выберите SAMP.Lua и отдельно установите SAMPFUNCS
4. Это не обязательно, но не помешает установить и MoonAdditions - эту библиотеку используют некоторые скрипты и она неплохо расширяет стандартные возможности скриптинга
5. Выберите установку расширения для Notepad++, если вы будете использовать программу Notepad++ для редактирования Lua скриптов

Для лёгкой и удобной работы с кодом Lua скриптов вам понадобится настроить для себя среду разработки. Для работы с Lua достаточно любого текстового редактора, но какой-нибудь блокнот Windows для этого подходит совсем плохо, поэтому лучше использовать специализированные программы. На текущий момент полная поддержка MoonLoader есть в Atom и Notepad++, помимо этого есть пользовательские дополнения для Visual Studio Code и Sublime Text.

После установки этого пакета вам будет предложено установить дополнительные пакеты, соглашаемся и забываем про это.

Проект по-умолчанию.
В меню File выбираем пункт Open Folder. и указываем путь до папки moonloader, после этого она откроется как проект.

Кодировка по-умолчанию.
Для установки кодировки по-умолчанию при создании нового скрипта переходим в настройки всё тем же сочетанием Ctrl + , и выбираем пункт Core. В поле File Encoding выбираем Cyrillic (Windows-1251).

Проект по-умолчанию.
Как и в Atom, здесь есть возможность показа меню проекта, а точнее "Папка как Проект". В меню "Файл" выбираем пункт "Открыть Папку как Проект" и указываем путь к папке "moonloader".

Кодировка по-умолчанию.
Над лентой выбираем пункт Опции и переходим в Настройки. В меню слева выбираем пункт Новый документ и в разделе кодировки ставим флажок на список, в котором выбираем кодировку Windows-1251

MoonLoader основан на языке программирования Lua, знание хотя бы основ которого обязательно для дальнейшей работы. Поскольку Lua очень популярен в среде разработки игр и других сферах, по нему полно учебных материалов. Ниже приведено несколько ресурсов, позволяющих изучить Lua от корки до корки. Не стоит пренебрегать этими уроками даже более опытным разработчикам, зачастую можно найти для себя много нового. Имейте в виду, что в MoonLoader используется LuaJIT - Lua 5.1 с некоторыми фичами Lua 5.2 и своими дополнениями, поэтому некоторые мелочи из этих материалов будет неприменимы в MoonLoader.

После установки среды разработки, изучения основ Lua и ознакомления с документацией MoonLoader, можно приступать от теории к практике. Давайте сначала рассмотрим самое основное, на всякий случай.


Глобальная область
Глобальная область - это основное тело скрипта, т.е. всё, что находится вне функций. В основном глобальная область используется для указания директив, подключения модулей, объявления каких-либо глобальных переменных и функций. Она выступает первым этапом загрузки скрипта, код из неё выполняется один раз после загрузки скрипта (а скрипты загружаются почти сразу же после запуска игры) и не может быть приостановлен. Основная работа со скриптом производится в потоке main.
Пример: Загружаем библиотеку VKEYS, записываем моё имя в переменную myName, объявляем функцию main.



Задержки и потоки
Задержка в скрипте позволяет приостанавливать исполнение кода на указанное количество миллисекунд или на один кадр. В ML для осуществления задержек используется функция wait(int time), её аргумент time принимает следующие значения:
-1 - устанавливает непрерывное ожидание, использование допустимо только в main
0 - задержка на один кадр
остальные значения указывают задержку в миллисекундах
Пример: Запущенный скрипт будет в вечном ожидании
Использование задержек недопустимо в callback-функциях. Для создания задержки в такой функции используйте создание потока:

Потоки - это сопрограммы, которые могут быть созданы в процессе работы скрипта для параллельного выполнения задач. Потоки в MoonLoader служат для выноса определенных действий за рамки основного потока, а так же для создания задержек выполняемого кода там, где это невозможно реализовать стандартными методами.
Для запуска потока используются функции lua_thread.create и lua_thread.create_suspended.
Пример: создаётся два потока для параллельного вывода текста в лог


Директивы
Скрипты для MoonLoader могут содержать о себе некоторую информацию и иметь определённые свойства исполнения - и то, и другое задаётся с помощью директив. Директивы - это обычные функции, предназначенные для указания информации о скрипте и изменения его поведения. Их принято обозначать в самом начале скрипта.
Все параметры, задающиеся директивами, можно получить из любого скрипта, обратившись к соответствующим полям класса LuaScript.
Пример:

В этом примере показаны не все директивы, за полным списком обращайтесь к соответствующей странице на вики.

Колбэки (функции обратного вызова) выступают реакцией на действие и по концепции очень похожи на события, но у них есть два отличия: первое - колбэк всегда регистрируется явно, чаще путём вызова функции с передачей функции-колбэка в качестве аргумента, второе - он всегда связан с какой-либо сущностью (командой, идентификатором и т.п.), т.е. будет вызван только если возникшее событие касается связанной сущности (например, колбэк команды будет вызван при вводе только одной команды, а не каждой, как это было бы с событием). Примером функции с колбэком является downloadUrlToFile, принимающая последним аргументом callback-функцию.
В колбэках, как и в событиях, нельзя использовать задержки.
Пример:



Использование библиотек
Библиотеки, либо модули всячески дополняют стандартный набор возможностей новыми и позволяют использовать в скриптах готовые инструменты для разработчиков. Модули делятся на стандартные и сторонние. Стандартные включены в дистрибутив MoonLoader и не требуют отдельной установки.
Все модули располагаются в директории moonloader/lib/ и устанавливаются туда же. Подключение библиотек осуществляется при помощи функции require, которая в качестве аргумента принимает название файла. Чаще всего подключение модулей производится в начале скрипта, но может быть выполнено в любом месте. Каждый модуль загружается отдельно для каждого скрипта.
Пример: Подключим модуль "vkeys", позволяющий работать с виртуальными клавишами.

Работа с модулями не ограничивается стандартным набором, часто приходится иметь дело со сторонними модулями - такие модули не поставляются вместе с MoonLoader и требуют ручную установку. Примерами таких модулей являются Dear ImGui и SAMP.Lua.
Вы можете создать собственный модуль и использовать его в своих скриптах. Благодаря этому вам будет легче оказывать им поддержку, скрипты станут чище и компактнее, а повторяющегося кода будет намного меньше.
Помимо этой возможности в MoonLoader присутствует система импорта, позволяющая использовать работающий скрипт как модуль с общим доступом - об этом и о создании модулей будет сказано позже.
Настоятельная рекомендация: никогда не публикуйте свои работы вместе со стандартными библиотеками или с изменениями в сторонних библиотеках - это может привести к проблемам у пользователей.

Несмотря на обилие информации в теме, знать всё невозможно, поэтому чаще заглядывайте на Wiki, а также не забывайте о теме Вопросы на Lua скриптингу, где вам смогут помочь при возникновении сложностей.
Больше информации именно по Lua лучше искать в поисковиках, язык довольно простой и если эта тема вам никак не помогла - стоит поискать более углубленные уроки.

  • Добавляйте информацию о скрипте при помощи директив
  • Соблюдайте единый стиль кода
  • Соблюдайте табуляцию (отступы)
  • Отделяйте блоки кода логически: пустые строки между функциями и блоками переменных, пробелы между блоками кода, осуществляющими логически завершённое действие и т.д.
  • Называйте переменные и функции внятными именами
  • Комментируйте неочевидные участки кода


Современные решения
С момента релиза ML прошло уже довольно много времени и, конечно, многое поменялось, так, например, вместо предопределенных переменных playerPed и playerHandle стоит использовать PLAYER_PED и PLAYER_HANDLE соответственно.
Помимо стандартного рендеринга, для создания сложных меню можно использовать фреймворк Dear ImGui. Для удобной обработки сетевого трафика SA:MP есть библиотека SAMP.Lua. Библиотека SA Memory для прямого взаимодействия со структурами игры. И MoonAdditions, добавляющая множество интересных функций.
vkeys - стандартный модуль, хранящий все ID и имена виртуальных клавиш. Так уж вышло, что этот модуль изначально не входил в состав MoonLoader и вместо него все константы загружались из модуля moonloader глобально, но со временем выяснилось, что это было плохим решением и поэтому коды клавиш были перенесены в отдельный модуль с немного другой реализацией. Но константы в старом модуле пришлось оставить для совместимости со старыми скриптами и теперь их использование оттуда считается устаревшим. Библиотека vkeys тут приведена в качестве примера, кроме неё были и другие нововведения, приведшие к устареванию старых решений.
Поэтому, если вы занимаетесь активной разработкой, всегда обращайте внимание на список изменений в обновлениях и пользуйтесь новейшими инструментами.


Упрощение процесса установки скриптов
"Да закинь вот эти файлы в папку CORE в папке SOURCE та что в папке с либами где под папкой IT хранится SCORE" - Бррр, чтобы подобное не случалось и ваш собеседник не впадал в ступор, старайтесь упростить установку до максимума - чтобы можно было просто скопировать все составляющие мода в одну папку. То есть соберите один архив так, чтобы неопытный пользователь мог свободно его установить или приложите инструкцию, если процесс установки сложнее стандартного. Чем установка проще, тем лучше и для вас, и для пользователя.

Компиляция скриптов
Во многих других языках программирования выполнение компиляции необходимо для запуска приложения на целевой машине, но в Lua компиляция не требуется - скрипты загружаются из исходного кода без дополнительных манипуляций. Однако, компиляция Lua скриптов возможна и чаще всего применяется для сокрытия исходного кода от любопытных глаз. Чаще всего это применяют для продаваемых скриптов, где защита этого самого скрипта - дело первостепенной важности. Не стоит злоупотреблять этой возможностью и прятать каждый свой скрипт под замок.
Для компиляции Lua скриптов под MoonLoader v.026 и выше скачайте интерпретатор LuaJIT v2.1.0-beta3, распакуйте архив в любое место и перетаскивайте lua-файл на compile.bat, рядом создастся luac-файл - это и есть скомпилированный скрипт. Для компиляции скриптов под более старые версии MoonLoader, вам понадобится LuaJIT 2.0.4.

С основными принципами разработки вы теперь знакомы и при этих знаниях сможете выполнить большинство задач, однако некоторые задачи требуют применения специальных техник. Давайте рассмотрим некоторые из них.


Создание модулей
Модули делятся на два типа: Lua и DLL. Lua-модули пишутся, как вы уже могли догадаться, на языке Lua и в результате представляют из себя привычные Lua-скрипты, только с некоторыми особенностями.
Давайте рассмотрим пример простого модуля, назовём его example:

-- Cortex Command Lua Scripting Tutorial --
___________________________________________

Автор - Ken "CaveCricket48" Do
Переводчик - Программист/ximximik

Владельцем всех прав на перевод является ximximik, поэтому любое копирование, распространение и изменение перевода без согласия владельца (ximximik) запрещено.

Вступление
Этот учебник научит вас, как использовать Lua в Cortex Command. Он написан для людей, которые не встречилались раньше с программированием совсем, и поэтому в нем не будут использованы сложные слова, которые есть в других учебниках. Лучше будет, если вы уже будете знать как работать с ini-кодом, прежде чем приступите к изучению программирования.

1.0 - Начало
-> 1.1 Создание Lua файла
-> 1.2 Прикрепление скрипта к объекту

2.0 - Основы Lua
-> 2.1 Комментарии
-> 2.2 Типы данных
-> 2.3 Переменные
-> 2.4 Операторы
-> 2.5 Таблицы
-> 2.6 Оператор "For"

3.0 - Cortex Command Lua stuff
-> 3.1 Этапы скрипта
-> 3.2 Функции
-> 3.3 Указатели

4.0 - Функции и свойства в Вики

5.0 - Пример скрипта
-> 5.1 Мина

----- 1.0 - Начало -----
________________________

В Cortex Command, Lua позволяет объектам делать то, что они обычно не были бы в состоянии сделать или создать особенные эффекты.

- 1.1 Создание Lua файла-

Принцип работы скриптов Lua в Cortex Command состоит в том, что скрипты присоединены к объектам, созданным с помощью ini. Чтобы сделать файл Lua в простом блокноте в Windows, просто создайте новый текстовый файл, перейдити в меню "Файл", "Сохранить Как. ", измените "Тип файла:" на "Все файлы" , и измените ".txt" в имени файла на ".lua". Если нет никакого расширения, просто добавьте ".lua" в конце имени файла. Потом нажмите "Сохранить". Вы создали файл Lua.

Совет от переводчика: Используйте Notepad++ вместо стандартного блокнота, так как в нем показывается весь синтаксис Lua, и вообще в нем легче работать.

- 1.2 Прикрепление скрипта к объекту -

Чтобы прикрепить Lua скрипт к объекту, созданному в ini файле, просто поместите "ScriptPath = " в блоке кода объекта с соответствующим табулированием.

----- 2.0 - Основы программирования Lua -----
________________________

--- 2.1 Комментарии ---

Комментарии в скрипте Lua - строки текста, которые не читаются игрой/программой, и в основном используются, чтобы аннотировать скрипт. Чтобы аннотировать, сделайте 2 дефиса, и что-нибудь после них на той же самой строке - комментарий.

--- 2.2 Типы данных ---

Типы данных - типы данных, которые используются для переменных и свойств. В CC есть 5 основных типов данных: числа, текст, boolean (логическая переменная), вектор, и ноль (nil). Первые 2 - понятно из названия то это. boolean - логическая переменная, т.е. её значения это истина (true) или ложь (false). Вектор в CC - координаты (X, Y). Числовые данные используются, печатая только числа. Текст используется при наличии пары кавычек ("") с текстом между ними. Вектор используется, следуя за словом "Vector " 2 числами разделенными запятой в двух круглых скобках. Ноль - обозначается как "nil" (чтобы не быть перепутанным с числом ноль).

--Логическая переменная
true
false

--- 2.3 Переменные ---

Переменные - это то в Lua, чему Вы можете дать значение. Они используются для того, чтобы хранить информацию, чтобы Вы могли снова вызвать это позже. Переменная состоит из своего имени, одного знака " bbCodeBlock">

Чтобы изменить переменную, просто напечатайте ту же самую переменную снова с новым значением:

Вы можете также заставить переменную иметь то же самое значение что и другая переменная, устанавливая ее значение как имя другой переменной:

В результате X будет равен 5.

Есть 2 типа переменных в CC: глобальная переменная и локальная. Глобальные переменные могут быть изменены скриптом любого объекта, вновь меняющие значение, и только одна переменная с таким именем может существовать. Глобальные переменные похожи на те выше в примерах.

Локальные переменные - переменные, у которых могут быть множественные копии, каждая из них привязана к объекту со скриптом, который создал их. Чтобы создать локальную переменную, напечатайте "local" перед именем переменной, разделив их пробелом. Установка значения локальной переменной равного значению другой локальной переменной работает подобным способом как и у глобальных переменных.

Это действие сделало переменную "varB" равной 5. Заметьте, что слово "local" не использовалось, когда мы выбирали переменную "varA".

Другое полезное свойство переменных - то, что Вы можете использовать переменные, чтобы установить определенное свойство в объект, и хранить объект в переменной. Храня объект в переменной, с ним легче взаимодействовать и легче вызывать указателем. Чтобы использовать переменные, для изменения свойства объекта, Вы нуждаетесь в переменной, которая является определенным указателем на объект (мы разберем это позже), сопровождающаяся точкой, названием свойства, знаком " bbCodeBlock">

"thing" это указатель на объект, "GetsHitByMOs" это свойство объекта в ini, и "false" это значение.

Обычно используют указатель, который уже определен как "self". Указатель всегда обращается к объекту, к которому присоединен скрипт.

--- 2.4 Операторы ---

Принцип работы Lua (и программирования вообще), это проверка операторов, чтобы увидеть, являются ли их значение истинным (true) и делающим что-либо если это так (или если не так). Давайте посмотрим на код ниже.

Этот код проверяет, если переменная "X" равна "1", то совершает "содержимое" (" " не фактическое действие, только указатель места заполнения для других команд, до которых мы доберемся позже), если оператор будет истиной. Обратите внимание на "end" внизу блока кода, который говорит, что " ", часть этого оператора, закончено. Если Вы не напечатаете "end" после оператора (конец оператора после тоже), то Вы получите ошибку. Также заметьте, что есть 2 знака "=" в "строке "if". "==" нужно для того, чтобы проверить равенство, и " bbCodeBlock">

Внутри операторов "if", могут находится операторы "else". Эти операторы проверяют, выполняется ли условие оператора "if", и если оно не истинно (не выполняется), то
тогда совершаются действия в их содержимом.

Условие "Elseif" похоже на второй "if" оператор и работает также:


if X == 1 then
<содержимое>
elseif X == 2 then
<содержимое>
end

В операторе могут быть много условий "elseif", но только одно "else".

Списки (также называемые как таблицы и массивы) похожи на переменные, у которых могут быть множество значений. Чтобы создать список, напечатайте название списка сопровождаемое знаком " bbCodeBlock">

Добавление значения к списку подобно присвоению/изменению значения переменной. Вы должны напечатать имя списка, сопровождаемое парой квадратных скобок с заданным номером в списке, знаком " bbCodeBlock">

Числовой символ с именем списка перед этим, говорит число элементов в списке.

Тот же самый список как в вышеупомянутых примерах, имеет значение переменной "numbercheck" равное 2.

Чтобы очистить все значения списка, напечатайте имя списка, знак " bbCodeBlock">

-- Очистка всего списка
thelist = <>

Списки могут быть глобальными и локальными, как переменные.

--- 2.6 Оператор For ---

Поскольку операторы используются, чтобы сделать множество повторяющихся действий в одном коротком участке памяти скрипта. Формат написания оператора "For" ниже.

Пример использования оператора "for".

Давайте рассмотрим каждую часть подробно:

for
- Стартовое ключевое слово

i = 1
- "i" - временная переменная, которая используется оператором "for", для сохранения, сколько раз он совершил действия (включая 1). "i" может быть изменен на любое имя как переменная. "1" это начальное значение для отсчета.

5
- Кол-во повторений " ".

Чтобы прервать оператор "for", включите "break" в оператор "if", который проверяет значение оператора "for" для соблюдения условия.

----- 3.0 - Cortex Command Lua stuff -----
________________________

--- 3.1 Этапы скрипта ---

Этапы скрипта - это части скрипта, которые выполняются только, когда объект был создан, когда он существует, или когда уничтожен. Этапы скрипта тоже требуют "end" как и операторы условий.

Функции - часть Lua, которые уже встроены в игру и взаимодействуют с содержимым в Cortex Command. Формат функции - название группы функции, двоеточие, имя функции, и её параметры (нужные данные для этого, чтобы это работало) разделяются запятыми в круглой скобке. Большинство названий групп функции Cortex Command могут быть заменены указателем чем-нибудь на то, с чем они смогут взаимодействовать. Пример функции ниже:

Информация о функции из Википедии Cortex Command Lua:

"anactor" - указатель на актора, "AddImpulseForce" - название функции, и содержимое круглой скобки - данные, необходимые для работы функции. В блоке информации о функции, "Return value", - это то, что выводит функция, когда она выполняется.
Большинство функций в Cortex Command может быть найдено в wiki, так что убедитесь проверив это.

--- 3.3 Указатели ---

Хорошо, мы наконец добрались до указателей!
В Cortex Command указатели - переменные, которые "хранят" объект в себе. Или Вы можете представить это, как гигантскую стрелку, указывающую на объект. независимо от того, что свойства Вы устанавливаете на указатель или используете функцию на нем, это произведет эффект на тот объект, на который он "казывает.

Есть несколько способов создать указатели. Обычно используют специальный оператор "for", который проверяет все объекты определенного типа и является оператором, который проверяет, является ли объект тем, который вам нужен. Кусок кода скрипта ниже присоединен к объекту, который ищет актора, с именем "Dummy" и затем устанавливает на него указатель, названный "local pointer".

for actor in MovableMan.Actors do
if actor.PresetName == "Dummy" then
local pointer = actor
break
end
end

Что делает вышеупомянутый кусок - проверяет всех акторов в игре, пока он не находит агента с "PresetName" как "Dummy". Тогда это устанавливает указатель на этого актора как "local pointer" и останавливает оператор "for" с "break". Термин "актор" является указателем на актора, и передан "local pointer" для более простой справочной информации.

Здесь 2 других строки "for", которые получают указатели на устройствах и частицах.


-- Указатель устройств
for item in MovableMan.Items do
end

-- Указатель частиц
for particle in MovableMan.Particles do
end

----- 4.0 - Функции и свойства в Cortex Command Wiki -----
________________________

----- 5.0 - Пример скрипта -----
________________________

--- 5.1 Mine ---
Этот скрипт для простой мины, которая взрывается, когда акторы находятся в пределах определенного расстояния объекта со скриптом.

-- Проверка всех акторов
for actor in MovableMan.Actors do

-- Остановка оператора
break

-- Конец оператора "if".
end

-- Конец оператора "for".
end

Итак, я видел ф-ции, которые позволяют крепить гибы друг к другу, ф-ции эти видел на кортекс-вики.

function Create(self)
self.killdist = 50;
end

function Update(self)
if math.random() <= .03 then
local part = CreateMOPixel("Spark Green");
part.Pos = self.Pos + Vector(math.random(-5,5), math.random(-15,5));
MovableMan:AddParticle(part);
for actor in MovableMan.Actors do//все последующие строчки до local curdist;
if actor.PresetName == "Browncoat Light" then
if actor.PresetName == "Browncoat Heavy" then
if actor.PresetName == "Skeleton" then
if actor.PresetName == "Thin Culled Clone" then
if actor.PresetName == "Zombie Thin Walk Path" then
if actor.PresetName == "Fat Culled Clone" then
if actor.PresetName == "Jumper" then
if actor.PresetName == "Green Clone" then
if actor.PresetName == "Blue Clone" then
if actor.PresetName == "Brain Case" then
if actor.PresetName == "Brain Robot" then
if actor.PresetName == "Soldier Light" then
if actor.PresetName == "Soldier Heavy" then
local curdist;
curdist = math.sqrt(math.pow(self.Pos.X - actor.Pos.X,2) + math.pow(self.Pos.Y - actor.Pos.Y,2))
if curdist <= self.killdist and actor:IsInGroup("Tiberium") == false then
if actor.ClassName

= "ACraft" then
actor.Health = actor.Health - 20
else
actor.Health = actor.Health - 2
end
local i = 0;
while i <= 2 do
local part = CreateMOPixel("Spark Green");
part.Pos = actor.Pos + Vector(math.random(-15,15), math.random(-15,15));
MovableMan:AddParticle(part);
i = i + 1;
end
local part = CreateMOPixel("Spark Green Glow");
part.Pos = actor.Pos + Vector(math.random(-15,15), math.random(-15,15));
MovableMan:AddParticle(part);
end
if actor.Health <= 30 and actor.Health > 0 and curdist <= self.killdist then
actor.Health = -10;
local part = CreateMOSRotating("Tiberium Debris Mini");
part.Pos = actor.Pos + Vector(math.random(-35,35), math.random(-10,0));
part.Vel = Vector(0,-15);
MovableMan:AddParticle(part);
end
end
end
end


Сама лень с вами.

Что ты хочешь изменить в коде тиберия?
Моддинг - это сезонное. По крайней мере, у меня.


Обучение Lua - Руководство для начинающих по написанию скриптов

Изучайте основы как работает Lua

Это первое руководство в этой серии.


1,650 уникальных посетителей
40 добавили в избранное














Это руководство предназначено для тех, у кого ограниченный опыт работы с LUA. Мы рассмотрим основы того, как оформлять код, строительные блоки для Вас, чтобы создавать более сложный код и предоставим некоторые примеры. Руководство написано так, чтобы сразу применять его на практике. Поэтому Вам следует открыть Tabletop Simulator и Ваш редактор LUA, чтобы следовать дальше.

Это первое руководство в этой серии. Второй – это Изучение Lua Подробнее. Третий представляет собой набор полезных функций под названием Learning Lua Functions.

Когда Вы сохраняете свои скрипты в Tabletop, он будет использовать Ваше последнее сохранение, а затем загрузит в него скрипты. Поэтому для любого скрипта, который Вы намереваетесь написать, Вам нужно будет сделать следующее:

  • Подготовьте стол так, как Вы этого хотите.
  • Сохраните стол.
  • Загрузите стол.

Не забудьте сохранить/загрузить, а затем открыть скрипт в Atom или перейти в Host>Scripting в Tabletop Simulator, чтобы начать.

Global.lua - это скрипт, который является частью файла сохранения. Именно здесь мы будем работать над большей частью этого руководства. При новом сохранении он всегда начинается с некоторого текста, сохраненного в редакторе. Просто удалите его, мы его не будем использовать.

Также можно писать скрипты и прикреплять их к объектам вместо Global. Таким образом, если Вы сохраните объект, то сохраниться и его LUA скрипт. Вы можете выполнять большинство функций с использованием скрипты Global или объекта, но мы будем работать в Global.

Часто используемая функция, встроенная в Tabletop Simulator - onload(). Эта функция запускается каждый раз при загрузке скрипта (например, если нажата кнопка Отменить(Undo) / Повторить(Redo), а также во время загрузки сохранений).
Замечу, что все переменные вне функций также инициализируются всякий раз при загрузке скрипта.
Итак, давайте начнем с его использования, чтобы запустить функцию, которую мы создадим. Функции должны начинаться с строчной буквы и не содержать пробелов. Мы будем использовать exampleFunction.

Теперь наш скрипт, когда он загружается, попытается запустить функцию с именем exampleFunction. Но мы еще не писали! Итак, теперь мы создадим нашу собственную функцию сразу после завершения функции onload.

Extra Credit: Когда Вы создаете свою собственную функцию, Вы также можете передавать переменные вместе с ней для их использования функцией. Другой способ написать наше начальное упражнение:

function onload() exampleFunction('Hello, World.') end function exampleFunction(passedString) print(passedString) end Мы создали переменную для представления строки (passString), а затем напечатали то, что содержалось в этой переменной.

Чтобы повлиять и на объект, сначала мы должны идентифицировать его в LUA. Существует несколько способов сделать это, например, идентифицировать элементы, которые подбираются или отпускаются игроками, находить объекты в скриптовых зонах и многое другое. Мы будем идентифицировать эти объекты по их GUID.

GUID – это уникальный идентификатор, который имеет каждый сгенерированный элемент в игре. Даже два одинаковых элемента будут иметь разные GUID. Чтобы найти GUID объекта, щелкните по нему правой кнопкой мыши и перейдите к Scripting. Если Вы нажмете на GUID, он скопирует его в буфер обмена. GUID всегда является строкой, поэтому не забывайте, что строки всегда в кавычках. Давайте создадим несколько переменных с идентификаторами GUID наших объектов. ОБРАТИТЕ ВНИМАНИЕ: Ваши идентификаторы GUID будут отличаться от моих.

object1_GUID = '195868' object2_GUID = '333365' checker_GUID = '7dc60d'

Затем, создадим переменные для представления наших объектов. Используем функцию onLoad(), чтобы создание происходило при загрузке скрипта. Все эти имена переменных, которых мы делали, должны начинаться со строчной буквы и не содержать пробелов, но, кроме этого, Вы можете свободно сами составлять имена переменных. Используйте такие имена, чтобы было понятно, что объект из себя представляет. Я буду использовать object1, object2 и checker для представления моих Объектов. Функция, которую мы будем использовать для идентификации, будет getObjectFromGUID(строка). Мы помещаем GUID в место для строки.

function onload() object1 = getObjectFromGUID(object1_GUID) object2 = getObjectFromGUID(object2_GUID) checker = getObjectFromGUID(checker_GUID) end

Теперь нам нужно каким-то образом манипулировать этими объектами. Мы дадим им имена. В onload() после определения наших объектов мы будем использовать функцию setName(string). Обратите внимание, что setName, как и другие функции объекта, должна быть привязана к объекту. В противном случае скрипт не поймет, имя какого объекта мы хотим изменить. Строкой в setName будет то, что мы установили для имени.

object1.setName('Object1') object2.setName('Object2') checker.setName('That Stupid Checker')

Если бы вы хотели, то нет причин, по которым вы не могли бы написать для шашки это, так:

function onload() getObjectFromGUID('7dc60d').setName('That Stupid Checker') end Причина, по которой я не одобряю это ученикам является частично эстетическим выбором, и частично для ясности чтения кода. Вы хотите, чтобы кому-то было легко понять Ваш код, и как только вы начнете делать что-то более сложное, чем изменение имени Объекта, может становиться ОЧЕНЬ трудно понять, что происходит. Это улучшает восприятие кода при внесений правок в будущем.
  • click_function = Строка --Имя вызываемой функции.
  • function_owner = Объект --Объект или Global, где находится функция.
  • label = Строка --Название на кнопке.
  • position = Таблица --Координаты X, Y и Z, для которых отображается кнопка, от центра объекта, к которому он присоединен.
  • rotation = Таблица --Поворот по осям X, Y и Z в градусах относительно объекта, к которому он привязан.
  • width = Число --Ширина кнопки по отношению к масштабу объекта.
  • height = Число --Высота кнопка по отношению к масштабу объекта.
  • font_size = Число --Размер шрифта на кнопке относительно масштаба ее объекта.
  • scale = Число --Масштаб кнопки по отношении к ее объекту.
Таблицы в LUA - это динамический гетерогенный ассоциативный массив, то есть множество пар (ключ-значение). Вы можете хранить все что угодно внутри таблицы и ссылаться на нее позже в таблице по имени или по номеру индекса (в LUA нумерация индексов в таблице начинаются с 1). Все таблицы обозначаются фигурными скобками <>. Мы создадим таблицу прямо под тем, где мы установили наши GUID, а затем заполнили ее записями для использования с функцией createButton(table). Название, которое мы выбираем для нашей таблицы это button_parameters.
button_parameters = <> button_parameters.click_function = 'buttonClicked' button_parameters.function_owner = nil button_parameters.label = 'Press Me' button_parameters.position = <0,0.8,0>button_parameters.rotation = button_parameters.width = 500 button_parameters.height = 500 button_parameters.font_size = 100 Теперь мы имеем параметры, то есть таблицу со значениями. Используем функцию объекта, чтобы создать кнопку на шашке. Запишите это внутри функции onload().
function buttonClicked() print('Learning is fun. Sort of.') --Обучение - это весело. Вроде. end

Повторно нажимайте его, потому что, конечно, вы это сделаете.

button_parameters = < click_function='buttonClicked', function_owner=nil, label='Press Me', position=<0,0.8,0>, rotation=, width=500, height=500, font_size=100 >

EXTRA CREDIT: Это идеальный момент для начала игры с разными вещами, которые вы можете делать с объектами. Перейдите на страницу «Объект» в Knowledge Base и попробуйте материал. Двигайте объекты, заставляйте их переключаться на позиции, менять их цвета, что бы вы ни думали.

EXTRA CREDIT: Кроме того, при каждом нажатии кнопки функция click_function запускается с двумя параметрами. Первая - это ссылка на объект, в частности ссылка на объект, к которому привязана кнопка. Второй - это цвет (например, "Blue" - синий) в строчном формате цвета игрока, который нажал на кнопку.

if CONDITION then --Активируется если условие было истинно end

Вы также можете добавить к нему "else", так что если утверждение ложно, вместо этого происходит что-то ДРУГОЕ (else). Обратите внимание, что я добавил комментарии, используя два минуса подряд. Компилятор игнорирует что-либо на линии после --.

if CONDITION then --Активируется если условие было истинно else --Активируется если условие было ложно end Мы попробуем несколько из них. Удалите текущее содержимое в Вашей функции buttonClicked(). Теперь введите в эту функцию следующие утверждения:
if 5 > 6 then print("5 is greater than 6") --5 больше, чем 6 end if 6 > 5 then print('6 is greater than 5') --6 больше, чем 5 end if 5 == 0 then print("Five is equal to ZERO?!") --Пять равно НУЛЮ?! else print("No, five isn't equal to zero.") --Нет, пять не равно нулю. end Еще раз удалите все скрипты внутри функции buttonClicked(). Мы собираемся создать новую переменную, а затем изменить ее. Новая переменная будет булевского типа. Булевские значения могут быть только true, false. Булевские значения всегда записываются маленькими буквами. Во-первых, мы создадим нашу переменную под нашим идентификатором GUID объектов и шашки.
Затем, в buttonClicked, мы установим некоторую логику, чтобы проверить, истинно ли значение trueOrFalse. Если оно истинно, то будет печатать, что это Истина, и переключит его на Ложь. Если кнопка снова нажата, будет печатать, что это Ложь, и переключит значение на Истина.
if trueOrFalse then print('trueOrFalse was true.') --trueOrFalse была истина. trueOrFalse = false else print('trueOrFalse was false.') --trueOrFalse была ложна. trueOrFalse = true end

Мы могли бы также написать это так "if trueOrFalse == true then", но это необязательно. Помните, что оператору IF нужно передать булевское значение. И так как trueOrFalse уже является одним из таких, мы можем отпустить "== true".

Цикл - это секция кода, которая могут запускаться несколько раз. Это один из более сложных элементов, которые Вы будете использовать в LUA. Они часто идут со таблицами, позволяя запускать код для каждой записи в таблице.

Какой вывод будет после нажатия на кнопку:

Какой вывод будет после нажатия на кнопку:

Это ещё один тип – ipairs. Pairs нужны для таблиц без числовых ключей, а ipairs нужны для таблицы с последовательными числовыми ключами (массивы). ipairs идет по порядку, когда pairs может идти в любом порядке.

Чтобы написать скрипт непосредственно в объект, щелкните на него правой кнопкой мыши, перейдите в Scripting и выберите Lua Editor (если Вы используете Atom, это откроет для него окно в Atom).

Когда вы пишете код здесь, это похоже на global. За исключением случаев, когда Вам нужно ссылаться на объект, частью которого является скрипт, вы просто пишете "self". Чтобы создать кнопку на себе, вы должны использовать self.createButton(table_of_paramiters).

Надеюсь, что это введение в LUA помогло Вам лучше понять некоторые основные механики написания скриптов.

Помните, что в Knowledge Base есть информация обо всех функциях, которые входят в состав Tabletop Simulator. Это и базовая практика с if, else, then и for позволит Вам выполнить большинство всего, что Вы хотите. Удачи.

Читайте также: