-
_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 и квестах
Функции позволяют выполнять определенный набор или последовательность действий. Основное назначение встроенных функций — это совершение уникальных действий, а назначение самопальных функций — возможность сократить количество кода, пакуя повторящийся код в функции.
Встроенные функции
Основное назначение квестов — это использование квестовых функций. Квестовые функции вшиты в ядро сервера и могут сообщать ту или иную информацию. Например, функция pc.get_name() сообщает имя игрока:
quest example begin
state start begin
--[[
Если ник игрока "terron", то представить в своей голове данную строку можно так:
when login with "terron" == "terron" begin
Вместо функции как бы подставляется значение, которое она сообщает.
]]
when login with pc.get_name() == "terron" begin
syschat("Привет, terron! ")
end
end
end
На самом деле, правильнее говорить не «сообщают», а «возвращают», поэтому дальше мы будем придерживаться именно этого термина.
Встроенные функции могут возвращать данные любого типа. Вот несколько примеров:
quest example begin
state start begin
when login begin
syschat("Привет, " .. pc.get_name() .. "! ")
syschat("Ваш уровень - " .. pc.get_level()) -- сообщает уровень игрока (тип number)
syschat("Ваш баланс - " .. pc.get_gold() .. " янг. ") -- сообщает количество янг игрока (тип number)
if pc.is_gm() then -- сообщает, является ли игрок администратором (тип boolean)
syschat("Хорошего рабочего дня, уважаемый администратор! ")
else
syschat("Отличного фарма и удачи, уважаемый игрок! ")
end
end
end
end
Также с помощью квестовых функций можно менять информацию об игроке. В данном примере мы при каждом входе в игру функцией pc.change_gold() будем увеличивать баланс янг игрока на 500:
quest example begin
state start begin
when login begin
local gold = 500
syschat("Привет, " .. pc.get_name() .. "! Вам было начислено " .. gold .. " за то, что вы крутой! ")
pc.change_gold(gold)
end
end
end
Т.к. функция pc.change_gold() ничего не возвращает, то бишь возвращает nil (вы не забыли, что nil — это «ничего» или просто «пустота»?), то заключать ее в переменную или объединять с какой-либо строкой смысла нет. Она просто меняет баланс игрока и всё.
Мы передали в данную функцию число 500 как параметр. Функции могут принимать так называемые параметры (также известны как «аргументы функции»). Параметры заключаются в скобки, идущие после названия функции. Если параметров несколько, то они разделяются запятыми:
quest example begin
state start begin
when login begin
syschat("Привет, " .. pc.get_name() .. "! Вы получили 5 красных зелий за то, что вы крутой! ")
--[[
27001 - это vnum красного зелья
5 - это количество
]]
pc.give_item2(27001, 5) -- данная функция выдает игроку определенный предмет в определенном количестве
end
end
end
Некоторые функции возвращают не одно, а несколько значений. Это одна из особенностей языка Lua. Правда, подобных встроенных функций очень мало. Например, функция pc.get_start_location() сообщает индекс локации и координаты площади первого города игрока в зависимости от его империи. Работать с такими функциями нужно так:
quest example begin
state start begin
when login begin
local index, coordinate_x, coordinate_y = pc.get_start_location()
syschat("Индекс вашего первого города: " .. index)
syschat("Координата по оси X: " .. coordinate_x)
syschat("Координата по оси Y: " .. coordinate_y)
end
end
end
Подробнее о том, сколько значений и вообще что возвращает функция, можно узнать из статьи о ней — в этом репозитории задокументировано большинство квестовых функций.
Самопальные функции
Вы можете самостоятельно создавать функции в Lua, например, чтобы не писать один и тот же код по несколько раз. Самый простой способ создать функцию:
quest example begin
state start begin
function calculate_ab(a, b)
return a + b
end
when login begin
local beer, vodka = 500, 800
syschat(example.calculate_ab(beer, vodka)) --> 1300
end
end
end
Правила именования функций такие же, как у переменных, ведь функции тоже являются переменными, просто вместо числел и строк они хранят в себе тип данных function. Внутри квестов функции могут задаваться только внутри state.
В примере выше мы задали функцию внутри state. Когда функция задается внутри state, то при ее вызове обязательно надо указывать перед ней название квеста (example.calculate_ab()). Область видимости у функций ограничивается всем квестом, независимо от того, в какой стадии была задана функция:
--[[
При каждом входе в игру игрок будет видеть разные сообщения:
]]
quest example begin
state start begin
function calculate_ab(a, b)
return a + b
end
when login begin
syschat("Start: " .. example.calculate_ab(1, 2)) --> Start 3
set_state("test")
end
end
state test begin
when login begin
syschat("Test: " .. example.calculate_ab(3, 4)) --> Test 7
set_state("start")
end
end
end
Функции создаются при помощи ключевого слова function. После ключевого слова идет название функции и в скобках заключаются параметры функции. Параметры указываются как переменные и область видимости у этих переменных будет локальной только внутри функции. Наша функция calculate_ab() принимает 2 числа и считает их, а затем возвращает значение ключевым словом return. Код, идущий внутри секции ниже return, уже не исполняется:
quest example begin
state start begin
function calculate_ab(a, b)
local val = a + b
return val
syschat("Посчитали и вот: " .. val) -- данное сообщение мы не увидим, т.к. выполнение секции закончилось на return
end
when login begin
local beer, vodka = 500, 800
syschat(example.calculate_ab(beer, vodka)) --> 1300
end
end
end
Если не передавать в return каких-либо значений, то функция ничего не вернет, то бишь nil:
quest example begin
state start begin
function calculate_ab(a, b)
local val = a + b
syschat("Посчитали и вот: " .. val)
return
syschat("Второе сообщение... ") -- это сообщение мы не увидим
end
when login begin
local beer, vodka = 500, 800
local how_much = example.calculate_ab(beer, vodka) -- в этот момент появится сообщение "Посчитали и вот: 1300", так как в этот момент исполняется функция calculate_ab()
if how_much then
syschat(how_much) -- мы не увидим это сообщение т.к. how_much == nil
end
end
end
end
В отличие от оригинального Lua, внутри квестов динамически создавать функции через переменные нельзя. Зато функции можно создавать глобально. Глобальные функции можно будет использовать во всех квестах, а не только в том, в котором она была создана. Такие функции создаются в файле questlib.lua. Особенность этого файла в том, что код, находящийся в нем, исполняется только один раз во время запуска сервера. То есть мы объявляем в этом файле функцию один раз, файл запускается сервером один раз и на время работы сервера он будет помнить о том, что существуют такие-то функции и переменные, заданные в questlib.lua. Добавьте в самый конец файла нашу функцию:
function calculate_ab(a, b)
local val = a + b
return val
end
Также функции в questlib.lua можно задавать как переменные (а в самих квестах нельзя!). Результат данного примера будет идентичен примеру выше:
local calculate_ab = function(a, b)
local val = a + b
return val
end
И чтобы функция начала работать в квестах, ее необходимо добавить в файл quest_functions (без расширения). Просто в конец файла добавьте calculate_ab и всё. Не забудьте про то, что последние строки в файлах должны быть пустыми! Теперь нашу функцию можно использовать в квестах:
quest example begin
state start begin
when login begin
local beer, vodka = 500, 800
syschat(calculate_ab(beer, vodka)) --> 1300
end
end
end
Обратите внимание на то, что при использовании функций, заданных глобально, использовать приставку в виде названия квеста не нужно.