Справочник по функциям и классам — S.T.A.L.K.E.R. Inside Wiki

Справочник по функциям и классам

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

Перейти к: навигация, поиск

Посты с форума AMK

Структура 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_param)
end
 
-- деструктор, вызывается при сборке объекта сборщиком мусора. Аргументов не имеет (кроме скрытого 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:

function 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);
function Enable(boolean); --вкл/выкл
function SetHeight(number); --установка высоты
function GetFrameLineWnd(string);
function SetHolder(CDialogHolder*);
function GetWidth() const; --получение ширины контрола
function GetCheckButton(string);--Получение состояния checkBox ,на выходе true или false?
function DetachChild(CUIWindow*);
function SetPPMode();
function SetFont(CGameFont*); --установка шрифта по имени
function IsShown(); --проверка видно ли контрол иль нет?
function Show(boolean); --показывать контолили нет?
function GetHeight() const; --возвращает высоту
function SetWidth(number); --устанавливает ширину
function GetListWndEx(string);
function 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?
function 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);
function WindowName();
function GetDialogWnd(string);
function 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);
function Load(string);
function IsAutoDelete();

Авторы

Статья создана: malandrinus, IQDDD, меченый

Другие места
LANGUAGE