Тож почнемо. Створимо в папці 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 . Після функції відступаємо і пишемо текст. Цей текст може складатися з літер латинського алфавіту та цифр, при цьому важливо, щоб цей текст починався з літери і не містить пробілів. Цей текст буде називатися функцією. Не забуваємо після назви функції дописати дві круглі дужки:
( )
Це є обов'язковим елементом. У ньому вказуються аргументи функції, із якими йде робота. У разі таких немає, але елемент обов'язковий. Далі йде сам спавн об'єкта:
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 , заспауниться калаш на вказаних координатах.
Поглиблене вивчення
Прописуємо функцію. Задаємо умову:
if логічна_умова then
В іншому випадку, виконується код, наступний за ключовим словом else
else
Але коли потрібно перевірити кілька значень (припустимо) змінної, можна скористатися ключовим словом elseif
elseif логічна_умова then
Для закриття тега:
end
Для заперечення умови можна скористатися ключовим словом not тобто.
if not логічна_умова then
Дорівнюватиме else в даній умові
if логічна_умова then ... else ... end
І так, що таке цикл. Цикл це повторення одного і того ж дії 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, 3 , 47 , 65535 ) end
і т.п. Існує ще цикл з передумовою (while a, n do), але звідси пізніше У - Які параметри ГГ можна коригувати скриптами? Про - Таких не багато, запис буде такий:
db.actor.параметр
Параметри:
radiation health psy_health power
І так покажу наочно на системі рандомного спавна. Для цього нам знадобиться таблиця максимальних значень 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_we_ " }
Таблицю записали, нарешті приступимо до оформлення головної функції
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() і при кожному завантаженні будуть спавні моби в рандомній точці