Начальные сведения о скриптах — S.T.A.L.K.E.R. Inside Wiki

Начальные сведения о скриптах

Материал из S.T.A.L.K.E.R. Inside Wiki

Версия от 08:54, 6 июля 2016; FX (обсуждение | вклад)

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

ПРЕДИСЛОВИЕ

Lamp.gif Для чего нужны скрипты и сведения и их использовании - Rez@niy aka Oxygenium
В скриптах содержаться инструкции для выполнения по условиям.


Итак, начнём. Создадим в папке gamedata/scripts файл с любым названием и расширением .script. Пускай, my_test.script. В нем будем прописывать функции.

Рассмотрим простой скрипт спавна предмета в рюкзак ГГ. Пропишем:
--*********************************************
--**TESTING**
--*********************************************
--
-- Создает в рюкзаке ГГ "калаш"
function ak_create()
    alife():create("wpn_ak74", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id())
end

Давайте разбирать.

Игра считывает весь код из файла, поэтому не удивляйтесь, если игра вылетит при наличии лишнего текста, символов и прочего ненужного в скрипте. Однако, подобных проблем возникать не будет, если мы закомментируем лишнее. Чтобы игра не считывала текст, перед ним мы ставим две черточки, два минуса, два дефиса, в общем называйте как угодно:
--
Часто таким образом оставляют словесную подсказку того, что делает данный участок кода, либо комментируют код, который на данный момент не нужен, но возможно пригодится в дальнейшем. В общем, зачастую комментарий - это пояснения к исходному тексту программы. В данном случае, система не будет считывать следующие строки:
--*********************************************
--**TESTING**
--*********************************************
--
-- Создает в рюкзаке ГГ "калаш"

Многострочный комментарий выглядит так

--[[ком
мен
та
рий]]

Идем дальше. function - всегда обязательное начало, это что-то в роде id в языке LUA. После function отступаем и пишем текст. Данный текст может состоять из букв латинского алфавита и цифр, при этом важно, чтобы этот текст начинался с буквы и в нём не содержалось пробелов. Этот текст будет названием функции. Не забываем после названия функции дописать две круглые скобки:

()

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

alife():create("wpn_ak74", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id())

В конце функции обязательно наличие end. Он означает конец функции. Логично, правда? :)

Напоминаю, при таком раскладе АК-74 заспавнится в рюкзак ГГ. Если же мы пожелаем заспавнить калаш где-нибудь на локации, вызов спавна приобретет следующий вид:

alife():create("wpn_ak74", vector():set(-81.800, -4.980, -72.739), 186578, 76)

АК заспавнится в вагончике, недалеко от Деревни новичков.

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

function название_функции()
    alife():create("имя_секции_предмета", vector():set(x,y,z), level_vertex_id, game_vertex_id)
end

Про конкретные значения. alife():create - стандартный вызов спавна vector():set - инициализация координат x,y,z - координаты места по долготе, высоте, ширине level_vertex_id и game_vertex_id - дополнительные координаты относительно локации Все это нужно снимать в игре. Есть множество способов. Что касается спавна в рюкзак ГГ, тут с координатами действует немного другая схема. Объект актора можно получить посредством вот такой записи: db.actor, а получить его данные можно вот так:

db.actor:position() - координаты x,y,z актера

db.actor:level_vertex_id(),db.actor:game_vertex_id() - думаю, понятно

db.actor:id() - дополнительный параметр, сам id актера, нужен, чтоб предмет заспавнился именно в рюкзак.

На самом деле, для спавна в инвентарь атору, значение координат, левел и гейм вертексов не важны, а ключевым является последний параметр - id актора, в игре оно всегда равно нулю. Т.е. заспавнить тот же "Калаш" в рюкзак можно и так:
alife():create("wpn_ak74", vector(), 0, 0, 0)


Написали? Отлично!
Теперь осталось только подключить это к игре, то есть вызвать функцию спавна.
Идём в файл dialogs_escape.xml и выбираем какой-нибудь диалог.
Там, после поля text, одной из фраз диалога приписываем:

<action>my_test.ak_create</action>

Как это понимать:

<action>название_скрипта.название_функции</action>


Всё, сохраняем и тестируем. В итоге, когда вы в игре нажмёте на фразу после которой находится action, заспауниться калаш на указанных координатах.

Углублённое изучение

Lamp.gif Условия в Луа - Rez@niy and FX
Далее идём в более углублённое изучение. Изучаем построение




Прописываем функцию. Задаём условие:

if логическое_условие then

В противном случае, выполняется код, следующий за ключевым словом else

else

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

elseif логическое_условие then

Для закрытия тэга:

end

Для отрицания условия можно воспользоваться ключевым словом not Т.е.

if not логическое_условие then

Будет равен else в данном условии

if логическое_условие then
...
else
...
end
Lamp.gif Циклы в Луа - Меченый
Далее идём в более углублённое изучение.




И так, что же такое цикл. Цикл это повторение одного и того же действия n-ое кол-во раз, которое выглядит так:

for i=1,n,step do
 ...
end

За место i может быть любая переменная, за место n - число которое больше первоначального значения(i)
Здесь i - это счетчик цикла. Эта переменная локальна для цикла, т.е. она доступна только внутри тела цикла.
1 - начальное значение счетчика, n - конечное.
step - шаг цикла ( указывать необязательно, по умолчанию равно 1 )
Переменные, объявленные локальными в теле цикла, доступны только внутри цикла.

local con = get_console()
For i = 10,5,-2 do
	con:execute("i="..tostring(i)) -- выведет в консоль последовательно 10, 8, 6
end
con:execute("i="..tostring(i)) -- выведет строку "i=nil",т.к. счетчик уже недоступен.
 

В - А для чего можно использовать цикл? О - Чтобы выполнить некоторый набор инструкций несколько раз.
Пример 1.Перебор по id. Узнаем монстр ли объект,если да, то функция пишет в консоль строку вида "monster_"<имя объекта>, иначе "no_monster_"<имя объекта>

local con = console()
for id=1,65534 do
	local obj = level.object_by_id(id)
	if obj~= nil then
		if IsMonster(obj) then
			con:execute("monster_"..obj:name())
		else
			con:execute("no_monster_"..obj:name())
		end
	end
end

Пример 2.Спавн/

local pos = vector():set(-220.21,-19.93,-158.98)
for i=1,5 do --функция повторится 5 раз,следовательно будет заспавнено 5 АК 
	alife():create("wpn_ak47",pos,33447,47,65535)
end

и т.п. существует ещё цикл с предусловием (while a,n do),но об этом позже В - Какие параметры ГГ можно корректировать скриптами? О - Таких не много, запись будет такой :

db.actor.параметр

Параметры:

radiation
health
psy_health
power
Lamp.gif Таблицы в Луа - Меченый
Далее идём в более углублённое изучение.




И так, покажу наглядно на системе рандомного спавна. Для этого нам понадобится таблица максимальных значений level_vertex_id и game_vertex_id выглядит она так:

local level_vertexes={
l01_escape = {lvid=595580, gvid=44},
l02_garbage = {lvid=384039, gvid=265},
l03_agroprom = {lvid=438379, gvid=693},
l04_darkvalley = {lvid=392517, gvid=813},
l06_rostok = {lvid=69283, gvid=1311},
l07_military = {lvid=915663, gvid=1546},
l10_radar = {lvid=796328, gvid=1868},
l11_pripyat = {lvid=295965, gvid=2269}
}

ЗЫ: Извините, что не для всех уровней. Так, таблица у нас есть, теперь нам нужно написать функцию спавна. Давайте покажу на Монстрах. Создадим таблицу с секциями спавна монстров: (Я буду использовать свои наработки, поэтому таких секции у вас не будет, эта таблица - пример)

local mutants = {
"zombie_ghost_hell",
"zombie_normal_hell",
"zombie_immortal_hell",
"bloodsucker_weak_hell",
"tushkano_normal_hell",
"snork_weak_hell",
"burer_weak_hell",
"cat_weak_hell",
"chimera_weak_hell",
"gigant_strong_hell"
}

Таблицу записали, наконец приступим к оформлению главной функции

function random_spawn()
local count = math.random(5,20) --выбираем кол-во заспавненых мобов
local section = mutants[math.random(table.getn(mutants))] -- выбираем секцию моба
local lv = math.random(level_vertexes[level.name()]["lvid"]) --выбираем левел вертекс
local gv = level_vertexes[level.name()]["gvid"] --выбираем гэйм вертекс
for ind = 1, count do
	alife():create(section, level.vertex_position(lv), lv, gv)--\\level.vertex_position(lv) - позиция левел вертекса
end
end

Далее помещаем вызов функции в bind_stalker.script в net_spawn() и при каждой загрузке будут спавнится мобы в рандомной точке

Помощь новичкам

Различные полезные функции и методы перенесены в эту статью [1]

Авторы

Оригинальный вид статьи:

  • Rez@nyi
  • Меченый

Переоформление, перестройка, дополнение статьи:

  • FantomICW
  • FX
Другие места
LANGUAGE