Перейти к контенту

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


Рекомендуемые сообщения

Интересно, а из всего многообразия есть что-нибудь, чем можно пнуть живого актора ? Не труп, а живого ?

Монстры - швыряют с легкостью, аномалии засасывают, неписи с дороги двигают... А скриптом ?

 

 

Ссылка на комментарий

Обычный скриптовый хит и пинает. Степень физического воздействия определяется параметром impulse.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

Сколько и куда надо этого импульса, чтобы было хоть чуть-чуть заметно ?

У меня ощущение, что на живого ГГ это не действует. Только собственно хит.

 

Ссылка на комментарий

Парсер .xml файлов для использования данных из них в скриптах. Проверено на ТЧ, на ЧН/ЗП - не знаю.

 

К примеру, нужно приаттачить кнопку к окну инвентаря, не куда попало, а, скажем, под пистолетным слотом. Такая "кнопка про пистолеты". Но, модов много, вариантов инвентаря не намного меньше. Каждый раз думать: "Что еще за кнопка посередь шкалы радиации? А-а-а! Тут же в чистой игре пистолет был!" - радости никакой. Каждый раз лазить в xml-ки, искать что и где, вручную менять - тоже приятного мало. Лучше при аттаче кнопки знать, куда ее вешать. Считать данные, как из ltx-а тоже не получается. Получить нужные координаты из класса окна - позицию в ТЧ никак, только размеры, но их мало. В общем, пришлось мудрить...

 

 

Можно получить из указанного файла только данные из конкретного тега. Тег в файле должен существовать и быть единственным. Вызов:

parse_xml.teg(filename,tegname)

Возвращает таблицу.

 

Парсер также может разобрать весь указанный файл .xml. Также он поступит, если при попытке разобрать тег имя тега tegname не указано. Здесь уже нет требования на уникальность тегов. Повторяющиеся теги заносятся в таблицу с номерами 1..N в порядке следования в файле. Вызов:

parse_xml.file(filename)

Возвращает таблицу.

 

Имя файла filename задается относительно папки config, задавать его лучше в двойных квадратных скобках - [[ui\inventory_new.xml]], тогда точно сожрет. Имя тега - обычная строка.

Проверял выборочно, но вроде бы жрет все xml-ки

 

Функция print_table(table,table_name,mode)

Сбрасывает в лог содержимое таблицы table. Название таблицы для лога - table_name или "table", если не задано.

Параметр mode имеет два осмысленных значения: "key" - в лог выводится только список полей, "val" - только значения. Во всех остальных случаях выводится "поле = значение"

Подавилось пока только на таблице db.storage - в поле actions с ключами что-то не то, похоже, не числа и не строки.

 

Функция long_string_to_table(string,string_name)

Разбивает строку длиннее 100 символов на фрагменты по 100 символов и сбрасывает в лог. Переносы - как получится, но прочитать можно. Не проверял, строкой какой именно длины игра подавится, но сам факт налицо - слишком длинные строки игра выводить не любит.

 

Обе функции для тестового вывода информации.

 

 

 

 

 

Ссылка: parse_xml.script

Мои работы:

Ночные прицелы + смена ножевого слота

AI вертолетов + ПЗРК

Soul Cube

 

Работаю только с ТЧ. С ковырянием ЧН/ЗП не связываюсь ни в какой форме. Совсем.

Ссылка на комментарий

Kirag

Хотел бы обратить внимание на критичный недостаток:

В кодах xml-фвйлов, как оригинала так и модмейкеров, нередко встречается использование табуляторов вместо пробелов.

Т.о. чистка (замена на пустой символ '') всех табуляторов в строке прочитанного файла будет приводить к ошибочному чтению наименований тэгов ...

Например, если в тэге встретится тэг <font font="letterica18" />, в котором между 'font' 'font' будет использован табулятор (иль несколько), то в игре парсер движка прочтет этот тэг правильно, а твой парсер получит 'fontfont' в качестве тэга, потеряв параметр(ы).

 

Оптимальнее этот код (строки 22,23,24 в parse_xml.script):

str_del = string.gsub(str_del,'\013',"")

str_del = string.gsub(str_del,'\010',"")

str_del = string.gsub(str_del,'\009',"")

 

заменить на:

str_del = string.gsub(str_del,'[\013|\010]','') --/ чистка/замена переносов по маске (оба за один проход)

str_del = string.gsub(str_del,'\009+',' ') --/ замена одиночных (или групп) табуляторов на одиночный пробел ('\032')

 

или даже так:

str_del = string.gsub(str_del,'[\013|\010|\009+]','\032') --/ замена переносов/табуляторов по маске (все за один проход) на одиночный пробел

str_del = string.gsub(str_del,'\032+','\032') --/ замена групп пробелов на одиночный пробел (далее меньше по-символьных итераций)

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Artos

Спасибо за подсказку, недоглядел.

 

Файл поправил и перезалил : parse_xml.script

Мои работы:

Ночные прицелы + смена ножевого слота

AI вертолетов + ПЗРК

Soul Cube

 

Работаю только с ТЧ. С ковырянием ЧН/ЗП не связываюсь ни в какой форме. Совсем.

Ссылка на комментарий

Kirag

Осмелюсь все же предложить использовать вариант:

 

str_del = string.gsub(str_del,'[\013|\010|\009+]','\032') --/ замена(!) переносов и табуляторов по шаблонам (за один проход) на одиночный пробел

str_del = string.gsub(str_del,'\032\032+','\032') --/ (опционально) замена групп пробелов на одиночный пробел (далее меньше по-символьных итераций)

 

т.к. исключает даже такие возможные извраты написания тэгов, как:

<hud_fps x="1005" y="05" width="5" height="20">

<text

x="0" y="0" font="graffiti19" r="255" g="255" b="50" a="255" align="l"/>

</hud_fps>

 

В таком случае нынешний вариант даст табличку для этого тэга:

hud_fps.textx="0".y = 0

hud_fps.textx="0".font = graffiti19

hud_fps.textx="0".a = 255

hud_fps.textx="0".r = 255

hud_fps.textx="0".g = 255

hud_fps.textx="0".b = 50

hud_fps.textx="0".align = l

 

- т.е. исказив наименование тега (text -> textx="0"), потеряв параметр 'x' из-за удаленного переноса строки (а в игре это не приводит к ошибкам).

 

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Приветствую всех...

Мужики, кто-нибудь пробовал изменять параметр SetHeading при использовании класса CUIStatic()?

SetHeading ведь служит для (поворота / наклона) статика, я правильно понимаю?

У меня он никаких действий не производит почему-то...

Жизнью в России довольны две категории людей: те, кто не в курсе и те, кто в доле.
Ссылка на комментарий
KOKC, надо создать окно на основе XML и там в XML задать параметр heading="1". Тогда будет реагировать на задание угла.
 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

Kirag

Разреши и я свои 5 копеек вставлю.

В функции find_teg всю эту конструкцию :

local open = string.find(str,"<") or 1
local len = string.len(str)
local declare_close = string.find(str,">",open+1,true) or len
local declare_space = string.find(str," ",open+1,true) or len
local declare_slash = string.find(str,"/",open+1,true) or len
local name_end = math.min(declare_close, declare_space, declare_slash) -- ближайший к открытию пробел или ">"

local teg_name = string.sub(str,open+1,name_end-1)

можно заменить на :

teg_name = str:match("<%s-(%S+)")

Изменено пользователем Gun12
Ссылка на комментарий

malandrinus, действительно, упустил я этот момент...

Спасибо...

Вот тут сталкнулся с такой проблемой:

Чтобы текст распределялся по строкам (не вылезая за установленые границы окна) в xml-файле в тег добавляется параметр complex_mode="1".

А есть его аналог в скриптовом варианте?

В lua_help что-то ничего такого не обнаружил.

Как реализовать разбитие текста на строки заданной длины?

Пол ночи просидел, мудрил - мудрил, но ничего толкового не вышло...

Например есть текст:

local text = "Это просто набор слов и ничего больше."

Как мне обработать, чтобы он "дробился" на строчки не превышающие длину например в 10 символов?

Пробовал так:

local max_size    = 10
local last_str    = ""

for tstr in string.gfind(str, "([^%s]*)%s*") do
    if string.len(last_str..tstr.." ") <= (max_size) then
         last_str    = last_str..tstr.." "
    else
        get_console():execute("load ~~~ "..tostring(last_str))
        get_console():execute("flush")
        last_str    = tstr
    end
end

Но не работает...

Выводит только первые ~10 символов

 

Изменено пользователем KOKC
Жизнью в России довольны две категории людей: те, кто не в курсе и те, кто в доле.
Ссылка на комментарий

Gun12

Предложенный тобою вариант имеет значительные недостатки:

1. Цель кода, который ты предлагаешь оптимизировать, не только в получении имени тэга (открывающей части), а и в получении индекса строки со значением окончания найденого имени тэга (name_end). Это значение используется и для поиска следующей части этого тэга (закрывающей, если конечно она должна присутствовать) и для 'начала отсчета' для параметров тэга, которые идут следом за названием.

2. Не обрабатываются ситуации, когда тэг состоит только из названия, например: <window> или <text/>, т.к. шаблон не обрабатывает символы '>' и '/', и которые ошибочно включаются в имя тэга.

 

---

KOKC, чисто скриптового варианта для организации 'переноса' длинных строк, превышающих ширину выделенную для строки, к сожалению не существует.

 

Вот вариант резки по 10 чимволов:

local lerf_str = str or "" --/ присваиваем 'остатку' всю длину строки (или пустышку)
local max_size = 10 --/ режем по 10

while lerf_str:len() > 0 do --/ есть еще что резеть/печатать?
  get_console():execute("load ~~~ " .. lerf_str:sub(1,max_size) ) --/ печать первых 10-ти
  get_console():execute("flush")
  lerf_str = lerf_str:sub(max_size+1) --/ отсекаем напечатанное
end

 

Примечание: Вместо 'lerf_str:len()' можно использовать '#lerf_str', и при выводе на печать не обязательно применять 'tostring', т.к. строка не может быть ничем другим при подобных операциях (пустой символ - тоже строка).

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Artos

В твоём примере, будет резать ровно по 10 символов., а мне нужно чтобы слова не разделялись на полуслове (это просто текст дл/я проверки), а перенос шел по принципу (это просто текст/ для проверки)...

Тоесть строка отсекалася на месте пробела ближейшего к максимально выставленной длине...

 

 

 

 

 

Изменено пользователем KOKC
Жизнью в России довольны две категории людей: те, кто не в курсе и те, кто в доле.
Ссылка на комментарий

KOKC, далеко не лучший вариант функции, но и все же

function str_explode(div,str,pos1,pos2,clear)
    local t={}
    local cpt,pos
    if pos1==nil then pos1=1 end
    if pos2==nil then pos2=pos1 end
    local cpt1=string.find(str,div,pos1,true)
    local cpt2=string.find(str,div,pos2,true)
    if cpt1 and cpt2 then
        if cpt2-cpt1>5 then
            cpt=cpt1
            pos=pos1
        else
            cpt=cpt2
            pos=pos2
        end
        repeat
            if clear then
                table.insert(t,trim(string.sub(str,1,cpt-1)))
            else
                table.insert(t,string.sub(str,1,cpt-1))
            end
            str=string.sub(str,cpt+string.len(div))
            cpt=string.find(str,div,pos,true)
        until cpt==nil
    end
    if clear then
        table.insert(t,trim(str))
    else
        table.insert(t,str)
    end
    return t
end

Vita sine libertate, nihil

Vita sine litteris - mors est

Ссылка на комментарий

Кто-нибудь знает. в каком порядке вызываются функции on_register() и on_spawn()?

Вроде бы первой вызывается on_before_register(), а дальше как?

Ссылка на комментарий

Для вывода информации в ЧН\ЗП в лог есть более удобная (и предназначенная спец. для этого) функция error_log()

 

Пример функции:

 

function mylog(f_msg)

local msg = tostring(f_msg)

local text = string.format("[%02d:%02d] %s", level.get_time_hours(), level.get_time_minutes(), msg)

error_log(text)

end

 

 

Результат:

! [LUA][ERROR] [06:53] Text

 

Насчёт ТЧ не уверен, м.б она там тоже есть, но не используется. Из плюсов - текст выводится в лог именно таким, каким его хочет видеть автор + поддерживаются кирилические символы.

 

И в дополнение к описанию класса device()

Переменная precache_frame используется для определения, видит ли игрок уровень или ещё экран загрузки.

 

-- видим ли мы еще "черный экран" или нет?

function black_screen(actor, npc)

return device().precache_frame > 1

end

Изменено пользователем *Shoker*

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

Ссылка на комментарий

Приведу более полное описание класса ini_file():

C++ class ini_file {
    ini_file (string);                                --конструктор/инициализатор объекта класса (путь к конфигурационному файлу .ltx, относительно папки config)

    function line_count("section");                    --возвращает количество параметров в указанной секции, включая материнские
    function r_bool("section", "param");            --считывает значение булевы
    function section_exist("section");                --определяет наличие указанной секции
    function r_float("section", "param");           --считывает числовое значение, с плавающей запятой
    function r_clsid("section", "param");           --возвращает sid класса секции объекта (применим только к параметру "class")
    function r_s32("section", "param");             --считывает целое число. Как положительное, так и отрицательное.
    function r_line("section", index, "default_param", "default_value"); --смотрим ниже
    function r_token("section", "param", const token_list&);  -- смотрим ниже
    function r_vector("section", "param");         --считывает значения трёхмерного вектора. "float, float, float"
    function r_u32("section", "param");             --считывает положительное целое число. Если число отрицательное, то возвращает 4294967296 (2^32)
    function r_string_wq("section", "param");    --считывает строчное значение. Если значение заключено в кавычки, то онные исключаются.
    function r_string("section", "param");          --считывает строчное значение без каких либо изменений.
    function line_exist("section", "param");        --определяет наличие указанного параметра в указанной секции.
};

 

 

Методы r_line() и r_token() требуют отдельного внимания и более полного описания:

Данный метод считывает полную строку (ключ = значение), под указанным индексом. Пример:

local ini = ini_file("blabla.ltx")
local count = ini: line_count("blabla_section")      --получаем количество параметров
for index=0, count-1 do
    local valid, key, value = ini:r_line("blabla_section", index, "default_param", "default_value") --считываем строку под указанным индексом.
    ...
end

Где:

valid = булева, наличие строки под указанным индексом

key = ключ (id, наименование параметра)

value = значение, как строка

"default_param" и "default_value" возвращаются переменным key и value соответственно, если строка под указанным индексом не найдена.

Значение "default_value", так же возвращается переменной value, если параметр key не имеет значения.

Хорошо применим, когда нужно получить все параметры и их значения, указанной секции.

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

 

 

Метод r_token() возвращает id полученного, текстового значения, из списка token_list. Итак, разберём для начала класс token_list(), чтобы было понятней использование метода r_token().

Данный класс, отвечает за виртуальный список (value = value).

C++ class token_list {
    token_list ();                           --конструктор/инициализатор списка

    function clear();                       --очистить список
    function remove(string);           --удалить ячейку списка по строчному значению.
    function name(number);           --получение строчного значения по id
    function id(string);                    --получение id по строчному значению
    function add(string, number);    --добавление ячейки в список (строчное значение, id)
};

Как видно, данный список не выделяет, кто из них является ключом, а кто значением. Но судя по тому, что удаление производится по строке, и в создании ячейки, первым аргументом является строка, то очевидно, что ключём, всётаки является именно строка, а значением номер id

 

 

Как данный класс применяется в методе r_token()?! Приведу пример:

Создадим в скрипте, список значений:

local t_list = token_list ()
t_list:add("value1", 55)
t_list:add("value2", 77)
t_list:add("value3", 99)

Далее, по созданому списку значений, установим онные в секциях конфигурационных файлов:

[section1]
param = value1
...

[section2]
param = value3
...

[section3]
param = value2
...

Теперь, чтобы получить соответсвующие id, указанным значениям в конфигурационном файле, и потребуется метод r_token():

--// создаём список
local t_list = token_list ()
t_list:add("value1", 55)
t_list:add("value2", 77)
t_list:add("value3", 99)

--//считываем по нему значения
local ini = ini_file("blabla.ltx")
local key = "param"
local id1 = ini:r_token("section1", key, t_list)  --'вернёт значение 55
local id2 = ini:r_token("section2", key, t_list)  --'вернёт значение 99
local id3 = ini:r_token("section3", key, t_list)  --'вернёт значение 77

 

 

Опаа-а!!! Ливер вылез!

Ссылка на комментарий

singapur22,

спасибо!

 

Пара дополнений:

 

r_clsid("section", "param"); --возвращает sid класса секции объекта (применим только к параметру "class")

не sid, а именно clsid. Этот метод возвращает числовое значение зарегистрированного сета, т.е. пары серверный/клиентский классы. Если помните статью про регистрацию классов, то мы в class_registrator.script пишем так:

cs_register (object_factory, "CBurer", "se_monster.se_monster", "SM_BURER", "burer_s")

здесь

CBurer - клиентский класс,

se_monster.se_monster - серверный класс,

burer_s - скриптовое имя сета. Такая константа появится в классе clsid и можно будет к ней обращаться как clsid.burer_s. При этом этой константе будет назначена уникальное числовое значение.

SM_BURER - конфиговое имя сета. Это то, что указывается в параметре class в секции объекта. Вот как раз это значение и читается методом r_clsid. При этом метод возвращает то же значение, что и соответствующая константа из класса clsid.

В игре движок читает таким образом только параметр с именем class, но в скриптах функция будет работать для параметра с любым именем (просто в этом нет практического смысла).

 

function r_string("section", "param"); --считывает строчное значение без каких либо изменений.

как раз с изменениями! Эта функция удаляет из читаемой строки все пробелы и табуляции. Таким образом, если в конфиге было:

[section]
param = ab     cd 1; 2 4; ef   5

то вызов

ini:r_string("section", "param") вернёт "abcd1;24;ef5", т.е. без пробелов. Это даже бывает иногда удобно, но часто таки надо получить нормальную строку. Для этого можно использовать таблицы строк и глобальную функцию game.translate_string(string). Но можно воспользоваться второй функцией

 

function r_string_wq("section", "param");

Эта функция читает также параметр как строку. Если двойных кавычек вокруг строки нет, то она работает в точности как r_string, а вот если кавычки есть, то функция эти кавычки удаляет, а строку оставляет без изменений. Т.е. все пробелы остаются на месте.

 

 

В заключение несколько глобальных функций для работы с файлами конфигураций в целом:

ini_file(<имя файла>) -- можно воспринимать эту функцию, как конструктор класса ini_file (в стиле Luabind), а можно как просто глобальную функцию для открытия файла с произвольным именем.

system_ini() -- возвращает открытый файл с именем "config\system.ltx". Комментарии излишни. Это главный конфигурационный файл всея игры со всеми своими включениями, распакованными и в архивах.

game_ini() -- аналогично возвращает открытый файл с именем "config\game.ltx". Тоже между прочим важный файл, содержаший информацию о всех локациях и ещё некоторые полезные вещи.

create_ini_file(<строка с текстом файла>) -- интересная функция, которая позволяет сделать объект ini_file в памяти без собственно физического файла на диске. Аргументом является текст файла конфигурации целиком со всеми переносами строк.

 

Также стоит упомянуть методы классов:

cse_abstract:spawn_ini() -- возвращает custom data серверного класса

game_object:spawn_ini() -- аналогично для клиентского класса

 

 

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

malandrinus, Если сами во всём в курсе, то что же сами то не написали полное описание? Ссылку так и держите на пост (меченый(стрелок)), где нормальных описаний, как таковых и нет.

Думаю стоит поправить мой пост, и сделать на него ссыль. Или напиши свой, более точный.

 

Изменено пользователем singapur22

Опаа-а!!! Ливер вылез!

Ссылка на комментарий

Может и известно, но все же.

 

Не секрет, что для скриптовых окон можно устанавливать реакцию на нажатие клавиши через функцию

OnKeyboard(dik, keyboard_action)

Для определения нажатой клавиши используется класс перечисление DIK_keys, в котором указаны кнопки клавиатуры и их цифровые коды, которые передаются данной функции в первом параметре.

Но там указаны далеко не все кнопки, да и вроде как не все оттуда верно. Например

    
    const MOUSE_1 = 256;
    const MOUSE_2 = 512;
    const MOUSE_3 = 1024;

в то время, как

     LMB = 337
     RMB = 338
     MMB = 339           --(колесико)

Используя эти константы можно установить действия на щелчки мышью

Vita sine libertate, nihil

Vita sine litteris - mors est

Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
  • Куратор(ы) темы:

×
×
  • Создать...