-
_images
-
ru
-
_articles
-
_quests
-
_triggers
-
affect
-
arena
-
ba
-
building
-
d
-
dance_event
-
DragonLair
-
ds
-
forked
-
game
-
global
-
guild
-
highscore
-
horse
-
item
-
marriage
-
member
-
mgmt
-
mob
-
pc
-
q
-
indexed_articles
-
Основы Lua
В данной статье будут рассмотрены основные и наиболее простые для понимания возможности Lua.
Условные операторы
Lua, как и большинство других языков программирования, базируется на простой логике: если выражение верно, то выполняем определенные инструкции, а если не верно, то просто не выполняем их.
Начнем с простого примера:
if 10 > 5 then
syschat("горошек ")
end
Понять это можно так: если 10 больше 5, тогда отправляем сообщение в чат слово «горошек». Другими словами, если между if и then выражение является истиной (true), то будут выполнены соответствующие инструкции. Ключевое слово end закрывает управляющие конструкции. Управляющая конструкция — это всё, что находится между if и end.
Более сложный пример:
if 5 > 10 then
syschat("горошек ") -- это сообщение мы не увидим
else
syschat("кукуруза ") -- мы увидим это сообщение
end
В данном примере я поменял числа местами и расширил управляющую конструкцию секцией else. Данное ключевое слово переводится как «иначе». Данная секция содержит инструкции, которые будут исполнены в случае, если условия идущих ранее секций являются ложью. Грубо говоря, мы в секции с if проверяем, больше ли 5 чем 10. Разумеется, это ложь (false), поэтому выполняется секция else.
И третий пример:
if 5 > 10 then
syschat("горошек ") -- это сообщение мы не увидим
elseif 5 > 1 then
syschat("пюрешечка ") -- мы увидим это сообщение
else
syschat("кукуруза ") -- это сообщение мы не увидим
end
Я использовал оператор elseif. Данный оператор является некой смесью операторов if и else. Он выполняется в случае, если условия идущих ранее секций являются ложью, но только в том случае, если его условие является истиной. Если его условие было бы ложью, то выполнилась бы секция else.
Во всей управляющей конструкции (от if до end) может быть выполнена только одна секция. Если у вас несколько секций, то выполнена будет только первая из них, условия которой являются истиной:
if 5 > 10 then
syschat("горошек ") -- это сообщение мы не увидим
elseif 5 > 1 then
syschat("пюрешечка ") -- мы увидим это сообщение
elseif 5 > 2 then
syschat("котлетки ") -- это сообщение мы не увидим
else
syschat("кукуруза ") -- это сообщение мы не увидим
end
Операторы сравнения
В Lua существует несколько операторов сравнения:
| Оператор | Назначение |
|---|---|
| == | равно |
| > | больше |
| < | меньше |
| >= | больше или равно |
| <= | меньше или равно |
| ~= | не равно |
| != | не равно |
Оператор != является синонимом оператора ~=. Более того, оператор != отсутствует в оригинальном Lua. Также обратите внимание на то, что оператор равенства состоит из двух знаков «равно». Оператор = (один знак) — это оператор присваивания, о котором будет рассказано позже.
В данном примере все секции являются истиной:
if 1 == 1 then
-- истина
end
if 10 > 5 then
-- истина
end
if 5 < 10 then
-- истина
end
if 10 <= 10 then
-- истина
end
if 10 >= 9 then
-- истина
end
if 5 ~= 10 then
-- истина
end
Логические операторы
В Lua существует несколько логических операторов:
| Оператор | Значение |
|---|---|
| and | и |
| or | или |
| not | не |
Данные операторы позволяют группировать условия для секций. Наглядный пример:
if 10 > 5 and 10 > 7 then
syschat("банан ") -- мы увидим это сообщение
else
syschat("мармелад ") -- это сообщение мы не увидим
end
Данный пример можно прочитать так: если 10 больше 5 и 10 больше 7, то показываем в чат слово «банан», иначе показываем в чат слово «мармелад». Здесь условие будет истиной только в том случае, если оба выражения являются истиной. Если в примере выше 10 > 7 поменять на 7 > 10, то в чат отобразится слово «мармелад».
Пример с оператором or:
if 7 > 55 or 10 > 5 then
syschat("нутелла ") -- мы увидим это сообщение
else
syschat("варенье ") -- это сообщение мы не увидим
end
Данный пример можно прочитать так: если 7 больше 55 или 10 больше 5, то показываем в чат слово «нутелла», иначе показываем в чат слово «варенье». Для оператора or важно, чтобы выполнялось хотя бы одно из условий. В данном случае у нас одно выполняется — 10 больше 5.
Пример с оператором not:
if not (10 > 5) then
syschat("гороховый суп ") -- это сообщение мы не увидим
else
syschat("шаверма ") -- мы увидим это сообщение
end
Данный оператор меняет ложь на истину и наоборот. В данном примере у нас 10 больше 5 — это истина, но оператор поменял истину на ложь, потому что шаверма вкуснее горохового супа, поэтому сработала секция else.
Операторы можно компоновать. Например, вот так:
if not ((10 > 5 and 10 > 6) or (11 > 3 and 43 < 6)) then
syschat("фалафель ")
else
syschat("брокколи ")
end
Попробуйте самостоятельно догадаться, какое слово будет выведено в чат. (10 > 5 and 10 > 6) — это истина, а на второе выражение можно даже не смотреть. И истина меняется на ложь оператором not. Это будет «брокколи».
У операторов and и or есть важная особенность. Если у оператора and первое условие является ложью, то второе условие он даже не проверяет. Если у оператора or первое условие является истиной, то второе условие он уже не проверяет. Подробно этот момент будет рассмотрен в углубленном изучении Lua, там же будет объяснено, почему это важно.
Арифметические операторы
В Lua, разумеется, можно проводить арифметические действия. Существуют следующие арифметические операторы:
| Оператор | Значение |
|---|---|
| + | сложение |
| - | вычитание |
| * | умножение |
| / | деление |
| ^ | возведение в степень |
Использовать их можно, например, так:
if 50 == 10 + 40 then
syschat("печенье ")
end
Порядок выполнения операторов такой же, как в обычной арифметике. Но если вам необходимо изменить порядок, вы можете также, как и в арифметике, использовать скобки:
if 140 == 10 * 4 + 10 then
syschat("зефир ") -- это сообщение мы не увидим
end
if 140 == 10 * (4 + 10) then
syschat("конфеты ") -- мы увидим это сообщение
end
Оператор возведения в степень работает так же, как и обычная степень в арифметике. То бишь код 5 ^ 2 идентичен арифметической записи 52. В арифметической записи данный оператор выполняется в первую очередь, даже раньше умножения и деления.
Переменные
Переменные — это способ временного хранения данных. Переменной присваивается имя и значение:
taco = 50
В данном примере мы переменной taco присвоили значение 50. Оператор = называется «оператор присваивания». Использовать это можно так:
taco = 50
if taco > 10 then
syschat("арбуз ")
end
Так как переменная taco равна числу 50, то она больше числа 10. Разумеется, переменные можно перезаписывать:
taco = 50
if taco > 10 then
syschat("арбуз ") -- мы увидим это сообщение
end
taco = 1000
if taco > 420 then
syschat("вареник ") -- это сообщение мы тоже увидим
end
Переменные могут состоять из латинских букв любого регистра, цифер и нижних прочерков. Переменная не может начинаться с цифры. Несколько примеров:
taco = 50 -- правильная переменная
taco_buritto = 50 -- правильная переменная
taco_123 = 50 -- правильная переменная
taco23_45buritto = 50 -- правильная переменная
_taco_123_buritto = 50 -- правильная переменная
Taco_Buritto = 50 -- правильная переменная
123taco = 50 -- неправильная переменная
taco-buritto = 50 -- неправильная переменная
taco_буритто = 50 -- неправильная переменная
Переменные не могут принимать имена зарегистрированных ключевых слов; вот их список: and, break, do, else, elseif, end, false, for, function, if, in, local, nil, not, or, repeat, return, then, true, until, while, quest, state, when, begin и with. Также названия переменных не должны совпадать с названиями семейств функций, самих функций, квестов, стадий, триггеров и таймеров (некоторые из этих терминов будут объяснены в будущем).
Выше был показан пример использования глобальной переменной. Существуют еще локальные переменные, которые задаются с помощью ключевого слова local:
local buritto = 50
Отличие локальной переменной от глобальной в том, что её область видимости ограничена. Наглядный пример:
local buritto = 50
if buritto == 50 then
syschat("буритто ") -- мы увидим это сообщение
local taco = 70
end
if taco == 70 then
syschat("тако ") -- это сообщение мы не увидим
end
Локальные переменные видны только в секции, в которой они были заданы:
local buritto = 50
if buritto == 50 then
syschat("буритто ") -- мы увидим это сообщение
local taco = 70
if taco == 70 then
syschat("чебурек ") -- мы увидим это сообщение
if taco == 70 and buritto == 50 then
syschat("курочка гриль ") -- мы увидим это сообщение
end
end
end
if taco == 70 then
syschat("тако ") -- это сообщение мы не увидим
end
У глобальных переменных такого ограничения нет. Если бы мы убрали ключевое слово local, когда задавали переменную taco, то мы бы увидели и последнее сообщение — «тако». Может показаться, что глобальные переменные удобнее локальных из-за того, что у них нет ограничения по области видимости, но все же лучше использовать глобальные только там, где это необходимо. При их использовании сложнее запутаться. Вред глобальных переменных будет объяснён в более глубогом изучении Lua.
Данный пример идентичен тому, что демонстрировался выше, но мы увидим последнее сообщение без помощи глобальных переменных:
local buritto = 50
local taco
if buritto == 50 then
syschat("буритто ") -- мы увидим это сообщение
taco = 70
if taco == 70 then
syschat("чебурек ") -- мы увидим это сообщение
if taco == 70 and buritto == 50 then
syschat("курочка гриль ") -- мы увидим это сообщение
end
end
end
if taco == 70 then
syschat("тако ") -- мы увидим это сообщение
end
В строке local taco мы объявили переменную taco как локальную, но не задали ей значение. В строке taco = 70 мы задали локальной переменной значение. Сначала Lua проверяет, существует ли локальная переменная с именем taco, и если существует, то перезаписывает ее значение, а если не существует, то перезаписывает значение глобальной переменной.
Комментарии в Lua
Комментарии в коде позволяют вам внести в него некую ясность для людей, которые потом этот код будут просматривать. Комментарии можно задать двумя способами: двумя дефисами -- и вот так: --[[ ... ]].
Первый вариант позволяет закомментировать всё, что идет в данной строке справа от двух дефисов. Во всех примерах кода на этой странице вы можете увидеть применение подобных комментариев.
Второй вариант позволяет закомментировать несколько строк. Пример:
--[[
В переменной milk указывается количество литров молока, необходимое для приготовления каши на троих человек.
Если будете менять переменную, то обязательно сообщите мне об этом.
]]
milk = 1
Разумеется, всё, что находится в комментариях, является простым текстом и никак не влияет на код:
local pizza = 50
-- pizza = 12
if pizza > 30 then
syschat("пицца ") -- мы увидим это сообщение
end
Типы данных
В Lua существует несколько типов данных. В примерах выше мы использовали только числа, строки и несознательно булевы выражения, но существует еще несколько:
- number — числа. Числами в Lua являются как целые числа, так и с плавающей точкой. Например,
343и34.4— это всё числа. - string — строки. Строкой считается, например,
"мороженое", а также числа, заключенные в кавычки. Подробнее в примере ниже. - nil — ничего. Данный тип подразумевает собой пустоту.
- boolean — булево выражение. Данный тип может быть либо
true(истина), либоfalse(ложь). Данный тип будет рассмотрен чутка позже. - table — таблицы. Например,
{10, 23}, Данный тип будет рассмотрен позже.
Существует еще два типа данных — userdata и thread, но они при написании квестов не используются, поэтому мы их рассматривать не будем.
Данный пример демонстрирует типы данных. Функция type() сообщает тип данных, которые в нее заключены, а функция syschat() выводит эти данные в чат:
syschat(type(123)) --> number
syschat(type(123.432)) --> number
syschat(type("123")) --> string
syschat(type("мороженка ")) --> string
syschat(type("мороженка за 123 рубля ")) --> string
syschat(type(" ")) --> string
syschat(type("")) --> string
syschat(type(syschat)) --> function
syschat(type(type)) --> function
syschat(type(true)) --> boolean
syschat(type(false)) --> boolean
syschat(type(10 > 5)) --> boolean
syschat(type({213, 123})) --> table
syschat(type({})) --> table
local table_example = {213, 123}
syschat(type(table_example[1])) --> number
-- -- -- -- -- -- -- -- -- --
syschat(type(arwerdvdw3qr)) --> nil
local arwerdvdw3qr
syschat(type(arwerdvdw3qr)) --> nil
arwerdvdw3qr = 123
syschat(type(arwerdvdw3qr)) --> number
Обратите внимание на фрагмент кода, отделенный чертой. Т.к. не существует функции arwerdvdw3qr() и переменная не задана, то тип данных является nil. Но вдруг мы задаем переменную с таким именем, присваиваем ей число и тип данных становится number.
В арифметических выражениях числа, являющиеся строками, автоматически преобразуются в формат number:
if "5" + 5 == 10 then
syschat("собачий корм ")
end
Важно! В арифметических выражениях могут участвовать только числа. Участие данных другого типа приведет к ошибке.
Булев тип данных представляет собой либо истину (true), либо ложь (false):
local dumpling = 100 > 50
В переменной dumpling содержится истина, то бишь true. Использовать это можно так:
local dumpling = 100 > 50
if dumpling then
syschat("пельмени ")
end
Более простой вариант использования булевых выражений выглядит так:
local is_virgin = true
local has_girlfriend = false
Обратите внимание на то, что true и false в примере выше — это не переменные, а зарезервированные ключевые слова, которые означают истину и ложь соответственно.
Также некоторые функции могут сообщать истину или ложь. Например, функция pc.is_gm() сообщает, является ли игрок администратором или нет. Если он администратор, то сообщается истина, а иначе — ложь:
if pc.is_gm() then
syschat("я администратор ")
else
syschat("я не администратор ")
end
Вот еще несколько секций, условия которых являются истиной:
local a = true
if a then
-- истина
end
a = false
if not a then
-- истина
end
if a == false then
-- истина
end
if not (a == true) then
-- истина
end
У типа данных nil есть маленькая особенность: в управляющих конструкциях он интерпретируется как ложь, хоть ей и не является:
-- Обратите внимание на то, что переменную rafaello мы нигде не задавали, поэтому она равна nil
if rafaello then
syschat("рафаэлло ") -- это сообщение мы не увидим
end
if not rafaello then
syschat("рафаэлло ") -- мы увидим это сообщение
end
if rafaello == nil then
syschat("рафаэлло ") -- мы увидим это сообщение
end
if rafaello == false then
syschat("рафаэлло ") -- это сообщение мы не увидим
end
Конкатенация строк
Конкатенация строк — это их объединение. Объединяются строки оператором .. (две точки). Простой пример:
--[[
В Lua можно одним выражением задавать сразу несколько значений разным переменным.
Тут я задал переменной 'a' значение "abc", а переменной 'b' - "def"
]]
local a, b = "abc", "def"
if a .. b == "abcdef" then
syschat("пончик ")
end
Разумеется, объединять можно не только переменные, но и числа со строками:
local food = "Пончик "
syschat(food .. "был очень " .. "вкусным и стоил всего " .. (5 * 5) .. " рублей.")
--[[
Выведет сообщение в чат:
Пончик был очень вкусным и стоил всего 25 рублей.
]]
Арифметические выражения всегда заключайте в скобки, если вы производите вычисления прямо внутри строки, как показано примером выше.
Еще несколько примеров:
syschat(12 .. 34) --> 1234
local x = "Hello"
local y = " World"
syschat(x .. y) --> Hello World
syschat(x) --> Hello
local z = 15 * 3
syschat(x .. y .. " " .. z) --> Hello World 45
local n = x .. y
syschat(n) --> Hello World
local a = 5
local b = 10
syschat((a .. b) * 2) --> 1020