Структура Lua_help
Сам фаїл можна знайти в gamedata\scripts\lua_help.script
C++ class [клас] {
const [опис1] = [константа1];
const [опис2] = [константа2];
...
[константи замінюють описи під час виклику методів класів];
property [властивість1];
property [властивість2];
...
[властивості (property) – це характеристика будь-якого класу, яка може піддаватися мат. операціям, злиттям, присвоєнням тощо
читаються через точку: obj.health];
[глобальна(-і) функція(-ії), якою викликається клас];
function [метод1] ([аргумент 1 функції 1], [аргумент 2 функції 1]...);
function [метод2] ([аргумент 1 функції2]...);
...
[методи - це спеціальні функції, що виконують операції з класами та повертають значення після операцій над класами.
викликаються через двокрапку: obj: add_animation (...)];
}
Створення свого класу
Свій клас можна додати так:
class "my_cool_class"
Тут "my_cool_class" – ім'я мого нового класу. Записується у лапках, тобто. це рядок.
Потім можна додавати до цього класу свої методи:
- це спеціальний метод – конструктор. Буде викликаний під час створення класу.
function my_cool_class:__init(num)
self.my_param = num -- додали до свого класу змінну end
--
звичайний метод
function my_cool_class:cool_method_of_my_class()
get_console():execute("lua_bind_in_action_".. self.my_para викликається при складанні об'єкта збирачем сміття. Аргументів не має (крім прихованого self. про це див. далі) function my_cool_class:__finalize() get_console():execute("good_by_"..self.my_param) end
Потім можна створювати екземпляри свого класу, викликати їх методи та ін.
local obj1 = my_cool_class(1) - тут створюється новий об'єкт. При цьому викликається конструктор і
йому передаються аргументи цього виклику (в даному випадку число 1).
local obj2 = my_cool_class(4)
obj1:cool_method_of_my_class()
obj2:cool_method_of_my_class()
Як тільки об'єкт стає непотрібним (тобто на нього більше немає посилань), він видаляється збирачем сміття. У цьому викликається його метод __finalize
До чого тут self. self - це прихований перший аргумент. Конструкція виду:
function class_name:fun_name(<список аргументів>)
end
насправді еквівалентна конструкції
function class_name.fun_name(self, <список аргументів>)
end
Зверніть увагу на двокрапку в першому випадку і точку в другому.
При виклик методу конструкція виду:
object_name:fun_name(<список аргументів>)
еквівалентна конструкції
object_name.fun_name(object_name, <список аргументів>)
Це означає, що як self зазвичай передається сам же об'єкт. "Як правило" - це тому, що можна в принципі передати щось інше. Але краще за цю угоду не порушувати.
Все це чудово, але яка від цього користь? Ну, зробив я свій клас, і що з ним робити?
Загалом класи - це непоганий засіб організації свого коду. Ті, хто володіє об'єктно-орієнтованим підходом, знайдуть це розширення дуже зручним. Зокрема такі класи, які ні до чого не прив'язані, в скриптах сталкера використовуються в деяких місцях. Однак справжня сила цієї технології не в цьому. За допомогою цієї технології можна розширювати класи, експортовані в Lua з боку двигуна гри. Про це йтиметься у наступній частині.
Спадкування від експортованих класів
Отже, крім створення власних класів, технологія Luabind дозволяє створювати класи на основі вже існуючих. Це реалізовано як своєрідного успадкування. Робиться це за допомогою наступної конструкції:
class "my_derived_class" (base_class)
Тут: "my_derived_class" як і раніше – це ім'я нового класу.
base_class - це вже існуючий клас, який буде базовим для новоствореного. Ім'я обрано довільно, але мається на увазі, що такий клас експортовано і призначено для успадкування.
Не будь-який клас з експортованих з боку хост-додатка можна використовувати як базовий. На боці хост-додатка має бути створений спеціальний клас-обгортка. Якщо його немає, то нічого хорошого не вийде. Швидше за все при спробі використовувати успадкований клас у Lua будуть малозрозумілі проблеми та вильоти, так що треба знати точно, чи можна від конкретного класу успадковувати.
Питання, який глибини можливо успадкування, тобто. чи можна успадковувати від похідного класу, мені поки що до кінця не зрозумілий. З іншого боку, у цьому практично немає потреби.
Отже, після виконання зазначеної конструкції з'являється клас my_derived_class, який є копією класу base_class. Він точно такі самі методи, як і його базового класу. Поки що від цього мало толку. Але тепер можна перевизначити методи нашого класу, змінивши таким чином його поведінку. Робиться це як і, як і раніше, але з деякими доповненнями.
-- конструктор
function my_derived_class:__init(num) super(num)
end
-- звичайний метод
function my_cool_class:some_method(<список аргументів>)
base_class.some_method(self, <список аргументів>)
end
-- деструктор
function my_cool_class:__finalize()
end
На що варто звернути увагу.
По-перше, конструкція super(num). Це виклик конструктора базового класу.
По-друге, для виклику методу базового класу методу успадкованого використовується інша конструкція base_class.some_method(self, ). Тут треба використовувати альтернативну форму виклику методу (з точкою та явною вказівкою першого аргументу self).
Нарешті, метод __finalize() не вимагає виклику цього методу для базового класу, оскільки той буде викликаний автоматично при видаленні об'єкта збирачем сміття.
Власне, і все. Тепер можна користуватися створеним класом: створювати об'єкти цього класу, викликати їх методи та ін. Тут уже все залежить від конкретних цілей та потребує знання конкретних класів.
сlass alife_simulator
alife_simulator – клас для управління серверними об'єктами. У грі існує лише один екземпляр такого класу, і отримати його можна за допомогою виклику глобальної функції alife().
level_name(level_id) - повертає ім'я рівня за його id
create_ammo(<ім'я секції патронів>, position, lvid, gvid, id, amount) - створення пачок з патронами create
(<ім'я секції об'єкта>, position, lvid, gvid, id ) -- створення об'єктів у інвентарі
create(<ім'я секції об'єкта>, position, lvid, gvid) -- створення об'єктів лише на рівні
у всіх функція створення об'єктів
position - об'єкт класу vector. Не може бути nil, інакше виліт
lvid – level vertex id
gvid – game vertex id
id – це куди спавнім. Якщо інвентар, то вказуємо id непися чи нуль (для актора)
release(sobj, boolean) -- видаляє об'єкт sobj. Навіщо другий булівський аргумент – не відомо.
У всіх прикладах він або відсутній, або встановлений у true
object(id) - повертає серверний об'єкт за його ID. Якщо не знайшов nil
story_object(sid) - повертає серверний об'єкт з його story id. Якщо не знайшов nil
actor() - повертає серверний об'єкт актора
set_switch_online(id, boolean) - переводить в онлайн об'єкт з ідентифікатором id
set_switch_offline(id, boolean) - те ж, але в офлайн
dont_has_info(const number&, string); -- перевірка на Неотриманий інфопоршень(db.actor:dont_has_info("infoportion")
-- або alife():actor():dont_has_info("infoportion")).
has_info - протилежна
імовірно:
switch_distance() - радіус перемикання в офлайн?
switch_distance(number) - встановлення цього радіусу?
level_id() - поточний номер рівня?
object(string) - отримання об'єкта з його імені. Не пам'ятаю, що за ім'я.
object(number, boolean) - те саме, що й object(number)? на що впливає другий аргумент?
valid_object_id(number) - перевірка наявності об'єкта за id?
alife():create( <індекс об'єкта в all.spawn> ) --
spawn_id(number) -- індекс об'єкта в all.spawn для об'єкта із заданим id ?
невідомо:
add_out_restriction(cse_alife_monster_abstract*, number);
set_interactive(number, boolean);
add_in_restriction(cse_alife_monster_abstract*, number);
function remove_in_restriction(cse_alife_monster_abstract*, number);
remove_out_restriction(cse_alife_monster_abstract*, number);
kill_entity(cse_alife_monster_abstract*, const number&, cse_alife_schedulable*);
kill_entity(alife_simulator*, cse_alife_monster_abstract*, const number&);
kill_entity(alife_simulator*, cse_alife_monster_abstract*);
has_info(const number&, string);
remove_all_restrictions(number, const enum RestrictionSpace::ERestrictorTypes&);
Приклад використання:
local sim = alife() -- отримуємо сам об'єкт класу alife_simulator
local sactor = sim:actor() -- отримуємо серверний об'єкт для актора
class vector
vector - допоміжний клас, що містить три координати і дозволяє виконувати з ними різні маніпуляції. Об'єкти класу vector є аргументами багатьох функцій та повертаються багатьма функціями. наприклад, вище про метод create класу alife_simulator. Окремий об'єкт класу вектор створюється виклик глобальної функції vector(). Під час створення має координати [0,0,0].
Список методів класу vector
v:set_length(number) - залишити напрямок, змінити довжину
v:normalize(); - зробити довжину одиничною
v:magnitude() -- довжина вектора v
v1:distance_to(v2) -- відстань між v1 і v2
v1:distance_to_sqr(v2) -- квадрат відстані між v1 та v2
v1:crossproduct(v2) -- векторна твір, добуток. Повертає вектор
v1: dotproduct(v2) - скалярне твір. Повертає число
v: sub (number); - відняти з кожного компонента v число number
v1: sub (v2); -- відняти почленно вектор v2 з v1 і помістити в v1
v1:sub(v2, v3) -- відняти з v2 - v3 і помістити в v1
аналогічно:
add - почленное додавання
mul - почленное множення
div - почленное поділ
max/min - почленный максимум/мінімум
v1:clamp(v2) -- почленное обрізання першого другим
average -- почленное середнє
invert -- почленная інверсія знака
v1:abs(v2); - Копіює почленно позитивні компоненти в v1 з v2
lerp(v1, v2, number) - лінійна інтерполяція між двома векторами
- якщо number більше 1, то виходить за них - екстраполяція
v1:reflect(v2, v3) - має бути відображення одного вектора від площини, що визначається іншою. Не перевіряв
v1: slide (v2, v3); - ймовірно, проекція одного вектора на площину, що визначається іншою. Не впевнений
v1:distance_to_xz(v2) - враховуючи, що площина XZ - це площина паралельна землі, то, можливо, це
довжина проекції на землю шляху від точки до точки. Не перевіряв
v:getP() - зенітний кут у радіанах (кут нахилу над площиною XZ )
v:getH() - азимутальний кут у радіанах (кут у площині XZ між проекцією вектора на цю площину та віссю Z)
setHP - відповідно для встановлення цих значень
v1:align() - вирівнює вектор уздовж осі x або z і нормує його. Значення з y ігнорується.
У результаті завжди повертається одне із чотирьох значень ([1,0,0], [-1,0,0], [0,0,1], [0,0,-1])
v4:mad(v1,v2 ,v3) - скажена операція =) помножити почленно друге на третє і скласти з
першим, тобто. v4 = v1 + v2*v3 (назва операції mad == mul + add)
v1:inertion(v2, number) -- v1 = v2 + (v1-v2)*number (теж почленно)
v1:similar(v2, number) - Порівняння векторів на рівність з похибкою number. Видає 1 або 0
Приклад використання:
local v1 = vector()
v1:set(1,2,3)
local v2 = vector():set(4,5,6)
local dist = v1:distance_to(v2)
class fcolor
C++ class fcolor {
property a; --альфа-колір, що відповідає за прозорість.
property b; --blue-колір, що відповідає за синій відтінок кольору.
property g; --green-колір, що відповідає за зелений відтінок кольору.
property r; --red-колір, який відповідає за червоний відтінок колір.
fcolor();
function set(number, number, number, number); --установка кольору (r, g, b, a)
function set (const fcolor &); --установка кольору за вже наявним класом "fcolor()"
function set(number); -- не знаю. припускаю, що є кілька наперед підготовлених кольорів з індексами для кожного.
};
Приклад використання:
color = fcolor()
color.a = 50
color.g = 255
color.r = 100
color.b = 50
або
color = fcolor()
color:set(100,255,50,50)
class hit
Бувають випадки, при яких необхідно завдати певної шкоди неписю або мобу, при цьому імітувавши потрапляння до нього. Для цього існує метод класу game_object:
функція hit (hit *);
Щоб використати цей метод, потрібно зазначити аргументи. У разі має об'єкт іншого класу - hit. Ось його опис:
C++ class hit {
const burn=0; - Тут йдуть константи типів шкоди, що використовуються у властивості "type". Усі ми чудово знаємо, що означає кожен.
const chemical_burn = 6;
const dummy = 11;
const explosion = 7;
const fire_wound = 8;
const radiation = 4;
const shock = 1;
const strike = 2;
const telepatic = 5;
const wound = 3;
property direction; --дирекція збитків
property draftsman; --позначає персонажа, який завдав шкоди.
property impulse; --імпульс шкоди
property power; -сила втрата
property type; -- тип втрати (див. константи)
hit ();
hit (const hit*);
function bone (string); --метод із зазначенням кістки шкоди
};
Приклад використання:
hit = hit() -- створення об'єкта класу hit
hit.direction = vector(): set (1,0,0) -- дирекція по осі x
hit.draftsman = db.actor -- завдав шкоди актор
hit.impulse = 600 --імпульс
hit.power = 1.45 --хіт
hit.type = 2 --тип урону - постріл
hit:bone("bip01_head") -- удар припадає на голову
obj:hit(hit)
-- наносимо шкоду
"Функції часу"
time_global() -- реальний час (в мілісекундах) з початку запуску програми
game.time() -- ігровий час (в ігрових мілісекундах) з початку гри (тобто з початку проходження гри)
level.get_time_days() -- день місяця за ігровим часом
level.get_time_hours() -- година поточного ігрового дня
level.get_time_minutes() -- хвилина поточної ігрової години
level.get_time_factor() -- повертає відношення швидкості перебігу ігрового часу до швидкості реального
--(game_time_speed / real_time_speed)
level .set_time_factor(number) -- встановлює це ставлення
game.get_game_time() -- повертає ігровий час як об'єкта класу CTime. Клас CTime я опишу докладно
- якось потім, а поки опишу тільки пару його методів.
конструктор. Викликається через простір назв game
game.CTime()
Дефолтові значення
year, month, day = 1
hour, min, sek, ms = 0
CTime.set(year, month, day, hour, min, sek, ms) -- встановлює всі дані про час
метод CTime.get описаний так:
function get (number&, number&, number&, number&, number&, number&, number&);
що наводить на думку про сім аргументів. однак з точки зору Lua цей метод не набуває аргументів, зате повертає сім значень.
Приклад використання обох методів:
local t = game.CTime() -- створення об'єкта з дефолтовими значеннями
t:set(2009, 7, 11, 8, 11, 22, 333) -- встановили всі значення
local y,m,d,h,min,sec ms = t:get() -- отримали всі значення
Клас CTime (нерозібраний)
C++ class CTime {
const DateToDay = 0;
const DateToMonth = 1;
const DateToYear = 2;
const TimeToHours = 0;
const TimeToMilisecs = 3;
const TimeToMinutes = 1;
const TimeToSeconds = 2;
CTime();
CTime (const CTime&);
function sub(CTime*);
function timeToString(number);
function dateToString(number);
operator ==(const CTime&, CTime);
function get(number&, number&, number&, number&, number&, number&, number&);
function set(number, number, number, number, number, number, number);
function setHMSms(number, number, number, number);
function diffSec(CTime*);
operator <(const CTime&, CTime);
operator + (CTime&, CTime);
operator >=(const CTime&, CTime);
function setHMS(number, number, number);
operator > (const CTime&, CTime);
operator -(CTime&, CTime);
operator <=(const CTime&, CTime);
function add(CTime*);
};
клас CUIScriptWnd
CUIScriptWnd(); --для роботи з вікном...
function _construct();
function Register(CUIWindow*);
function Register(CUIWindow*, string);
функція Enable(boolean); --вкл/викл
function SetHeight(number); --установка висоти
function GetFrameLineWnd(string);
функція SetHolder (CDialogHolder *);
function GetWidth() const; --отримання ширини контролю
function GetCheckButton(string);--Отримання стану checkBox ,на виході true чи false?
функція DetachChild (CUIWindow *);
function SetPPMode();
функція SetFont(CGameFont*); --установка шрифту на ім'я
function IsShown(); --перевірка чи видно контроль чи ні?
функція Show(boolean); -Показувати контолілі ні?
function GetHeight() const; --повертає висоту
function SetWidth(number); --встановлює ширину
function GetListWndEx(string);
функція IsEnabled();
function ResetPPMode();
function GetPropertiesBox(string);
function GetFont(); --повертає шрифт встановлений setFont?
function Update();
function AddCallback(string, number, const function<void>&); --відповідні контролю з дію?
function AddCallback(string, number, const function<void>&, object);--відповідні контролю з дію?
function GetButton(string);--Отримуємо останню кнопку?
function SetAutoDelete(boolean);
function OnKeyboard(number, enum EUIMessages); - Колбек натискання на клавіатурі
function Dispatch(number, number);
function GetListWnd(string);--отримання вікна ListBoxa?
функція AttachChild (CUIWindow *);
function GetStatic(string);--отримання тексту мітки
function SetWndPos(number, number);--установка позиції вікна(x,y)
function GetTabControl(string);
function GetRadioButton(string);--стан RadioButtton на виходьте true або false
function Init(number, number, number, number);--ініціалізація вікна ... читай FormInitializatione (x, y, width, height)
function Init (Frect );--ініціалізація вікна
function GetFrameWindow(string);
функція WindowName();
function GetDialogWnd(string);
функція GetHolder();
function SetWndRect(Frect);--установка координат кутів
function SetWndRect(number, number, number, number);--установка координат кутів
function GetEditBox(string);--отримання тексту з ЕдітБокса
function SetWindowName(string); формі(caption)
function GetProgressBar(string);
function GetMessageBox(string);
function SetWndSize(number, number);
функція Load (string);
функція IsAutoDelete();