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

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


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

Внесу небольшую лепту для желающих получить список вертексов - гейм и левел.

 

Скрытый текст

 Написал пару функций которые при активации формируют таблицу со списком - как вы ее потом будете использовать - это уже ваша проблема.

 

Получаем набор вертексов для каждого уровня.

(набор разумеется не весь - а только тех левел вертексов, которые ассоциированы c гейм вертексами в файле game_graph )

 

Скрытый текст
local lvtab ={}

function LevelVertexId()
	--for i =0, 3511 do   --можно и так делать. Номера гейм вертексов можно узнать из файла game_graph который конвертируется в txt прогой ggtool и тотал коммандером.
	--метод game_graph():valid_vertex_id(i)  в данном случае делает тоже самое - подтверждает что гейм вертекс с таким то номером существует.

	local i = 0
	while game_graph():valid_vertex_id(i) do   
		local lv = game_graph():vertex(i):level_vertex_id()  --получаем левел вертекс по гейм вертексу 
		--получаем имя уровня по его номеру из секции в  game_graph
		local ln = alife():level_name(game_graph():vertex(i):level_id())  
		if not lvtab[ln] then  
			lvtab[ln] ={}   
		end
		table.insert(lvtab[ln], lv)   --заполняем таблицу
		i = i+1
	end
end

 

 

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

[имя_уровня] ={номер, номер, номер и т.д}

 

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

Вот такой функцией, для которой нужно в файле ui_custom_msgs.xml создать блок с координатами вывода текста.

типа такого

 

<cs_debug  x="200" y="180" width="600" height="100" complex_mode="1">
	<text font="letterica16"  r="240" g="217" b="182" a="255" align="l"/>
</cs_debug>
 

(функцию вывода данных я активировал через первую функцию)

function diapason()
	local text =""

	for k, v in pairs(lvtab) do 
		local n =  table_maxn(v)
		local min_v = math.min(unpack(v)) 
		local max_v= math.max(unpack(v))
		local str = "Уровень ["..k.."]"
		local num = "число индексов ["..n.."]"
		local str = string.format("%s %s %s %s", str, min_v, max_v, num)
		text= text..str.."\\n" 
	end     

	local hud = get_hud()
	hud:AddCustomStatic("cs_debug", true)
	hud:GetCustomStatic("cs_debug"):wnd():SetTextST(text)
	hud:GetCustomStatic("cs_debug").m_endTime = time_global()/1000 + 180
end

 

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

 

Скрытый текст
local gvtab ={}

function GameVertexId()
	local i = 0
	while game_graph():valid_vertex_id(i) do
		local ln = alife():level_name(game_graph():vertex(i):level_id())
		if  not  gvtab[ln] then
			gvtab[ln] ={}
		end
		table.insert(gvtab[ln], i) 
		i = i+1
	end
	this.diapason_gv()  --вызываем функцию для вывода данных на экран
end

 

 

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

Так как геймвертексы идут неразрывно - то мы имея этот диапазон получаем точный список гейм вертеков для каждого уровня - от первого значения до последнего. Всего в игре как вы поняли 3512 гейм вертексов - от нулевого до 3511-го.

function diapason_gv()
	local text =""

	for k, v in pairs(gvtab) do 
		local n =  table_maxn(v)
		local min_v = math.min(unpack(v)) 
		local max_v= math.max(unpack(v))
		local str = "Уровень ["..k.."]"
		local num = "число индексов ["..n.."]"
		local str = string.format("%s %s %s %s", str, min_v, max_v, num)
		text= text..str.."\\n" 
    end     

	local hud = get_hud()
	hud:AddCustomStatic("cs_debug", true)
	hud:GetCustomStatic("cs_debug"):wnd():SetTextST(text)
	hud:GetCustomStatic("cs_debug").m_endTime = time_global()/1000 + 180
end
 

Выводится также мин. и макс. значения - чего в данном случае вполне достаточно.

 

чуть не забыл - так как в сталкере не работает функция table.maxn() - которая возвращает кол-во целочисленных индексов в таблице, то я пользуюсь ее самопальным аналогом, (который считает индексы всех типов - хоть числовые, хоть строковые - причем для числовых не важно идут ли они в математическом порядке или вразнобой) вызывая там где надо table_maxn(имя таблицы)

function table_maxn(tbl)
	local k = 0
	for _, v in pairs(tbl) do
		k = k + 1
	end
	return k
end

 

Полученные таким образом таблицы можно динамически использовать прямо в игре для соответствующих целей.

 


Небольшое дополнение по методам:

Скрытый текст
game_graph() --метод определения файла game.graph

vertex(*gvid*) --метод определения секции в данном файле (гейм_вертекс)

level.vertex_position(*lvid*)
возвращает векторную  позицию по левел вертексу. Применим только к активной локации. 

game_graph():vertex(*gvid*):level_point()
возвращает позицию по гейм вертексу  - локальную. (точнее говоря возвращается позиция самого гейм вертекса из соответствующей ему секции в файле game.graph)
Можно определять на любых локациях (активных/не активных).

game_graph():vertex(*gvid*):game_point()
также возвращает позицию по гейм вертексу  - только мировую(относительно всей карты игры).

game_graph():vertex(*gvid*):level_vertex_id()
возвращает  левел-вертекс по гейм-вертексу. 

alife():level_name(*level_id*)
возвращает имя уровня по его числовому идентификатору. Аргументом может служить метод приведенный ниже.

game_graph():vertex(*gvid*):level_id()
возвращает  числовой идентификатор уровня по гейм вертексу 

game_graph():valid_vertex_id(*gvid*)
возвращает boolean - true\false  -существует или нет геймвертекс

 

 

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

Поделиться этим сообщением


Ссылка на сообщение

По классу CTime:

Универсалка для получения текущих игровых даты\времени (для вывода например на худ) от Artosa (ну и меня тоже - вместе как то на форуме СП забавлялись вышеприведенными методами и в итоге пришли к почти идентичным кодам :rolleyes: )

 
--/ передаем аргументы из числа  "Y", "M", "D", h"", "m", "s", "ms" - по одной штуке, смотря какое значение текущего игрового времени или даты хотим получить; по умолчанию функция возвращает секунды.
function Get_StringOnTimeOrDate(sType)
  if sType then
    local tTime = {
      ["Y"]  = game.CTime.DateToYear,    --/ 2012
      ["M"]  = game.CTime.DateToToMonth, --/ 01/2012
      ["D"]  = game.CTime.DateToDay,     --/ 01/01/2012
      ["h"]  = game.CTime.TimeToHours,   --/ 23
      ["m"]  = game.CTime.TimeToMinutes, --/ 23:59
      ["s"]  = game.CTime.TimeToSeconds, --/ 23:59:59
      ["ms"] = game.CTime.TimeToMilisecs --/ 23:59:59:999
    }
    if sType == string.lower(sType) then --/ аргумент в нижнем регистре
      return game.get_game_time():timeToString(tTime[sType] or 0) --/> время
    end
    return game.get_game_time():dateToString(tTime[sType] or 0) --/> дата
  end
  return game.get_game_time():timeToString(game.CTime.TimeToSeconds) --/> по дефолту 23:59:59
end
 

 

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

Поделиться этим сообщением


Ссылка на сообщение

Содержание:

а) имена файлов\модулей игры - идут как строковые ключи в нижнем регистре(правило соблюдается для всех ключей вообще).

Значением ключа в данном случае является таблица содержащая(опять же как строковые ключи) все имена функций, скриптовых классов, констант и глобальных(локальные сюда не попадают) переменных модуля. Значения ключей - соответственно function, userdata, table, значение инициированных переменных - смотря что содержит файл.

б) имена движковых классов - тип значения =userdata (из lua недоступен для чтения - так что узнать список методов не получится).

в) имена Lua функций экспортированных в библиотеки игры(наконец то я узнал их точный список :rolleyes: ) - идут либо как название функции, либо как название пространства имен Lua - table, math, string - соответственно тип значения либо function, либо (во втором случае) таблица, в которой перечисляются уже сами функции экспортированные из данного пространства имен (это уже второй уровень итерации).

г) имена пространств имен игры и глобальных функций - типа device(), get_hud(), get_console(), time_global() и т.д.

д) имена глобальных скриптовых функций из файла _g.script.

 

Вроде все (хотя может чего и упустил - табличка все таки большая).

Заметил что в таблице присутствуют метод\ы (из экспортированных namespace - например из actor_stats), которые в lua_help не указаны.

 

Кстати: метатаблица _G содержит субтаблицу _g в которой практически(точно не сверял) все тоже самое, что и в таблице первого уровня, и при этом субтаблица _g содержит еще и саму себя.

 

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

Собственно можно зайти дальше - в таблицы третьего и четвертого(если есть) уровня - но это не имеет смысла, так как получим содержание таблиц из скриптов игры, которые и так можно либо посмотреть наглядно(если они заполнены), либо проитерировать в игре.

 

Код для получения распечатки _G (итерация двухуровневая):

pcall встроен для того, чтобы не вылетать на рабочий стол при итерации этой метатаблицы, так как в некоторых местах tostring'u попадаются неприемлемые для конвертации значения - nil или вызов функции. В этом случае в распечатке будет указано место ошибки и вместо значения строка "error_value".

 

 

function PrintG()
local res, value 
    for k, v in pairs(_G) do
    Console(tostring(k).." = "..tostring(v))  --Console() это моя "обертка" get_console()  - забыл ее заменить здесь
        if type(v)== "table" then
            get_console():execute("load ~ "..string.format("РАСПЕЧАТЫВАЕМ СУБТАБЛИЦУ: %s ", k))
            for key, val in pairs(_G[k]) do
            res, value = pcall(tostring, val)
                if not res then
                get_console():execute("load ~ ".."Ошибка преобразования значения: "..value)
                value="error_value"
            end
            get_console():execute("load ~ "..string.format("субтаблица: %s = %s", key, value))                
        end
        get_console():execute("load ~ ".."КОНЕЦ СУБТАБЛИЦЫ")
       end
    end 
end

 

Что хотелось бы узнать:

1) Как это можно использовать в игровых целях?

2) Как можно загрузить в эту таблицу модуль который туда еще не был кэширован (есть мнение, что пока к своему (не дефолтному) файлу(точнее к функции из него) не обратишься, он туда не кешируется, и следовательно автономный вызов функции из этого файла

function Func() body end

Func()

приводит к вылету ее не вызову так как в _G файла с этой функцией еще нет.

 

Ну и какой-нибудь дoполнительный теорбазис обо всем этом тоже не помешал бы.

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

Поделиться этим сообщением


Ссылка на сообщение
Обычно порядок другой smile.gif Есть игровая цель и думается: "Как это можно сделать?"

Обычно я так и делаю :)

 

Про кеширование: я имел ввиду вот что -

берем функцию - например такую -

function TestMessage()

news_manager.send_tip(db.actor, "Функция вызвана автономно", 0, "default", 180000)

end

и вставляем ее в файл в котором есть функции вызываемые из апдейта.

И пишем под функцией ее автономный вызов

TestMessage()

При загрузке игры функция благополучно вызывается.

Но если ее поместить в файл, который ни откуда не вызывается, то вызова не будет - так как в _G данный файл еще не был загружен.

К тому же при попытке обратиться к незагруженному в таблицу _G файлу из xml тегов (это уже пишу на основе чужого опыта) может произойти вылет.

Отсюда и вопрос - как этим процессом загрузки данных в метатаблицу _G можно манипулировать.

Поделиться этим сообщением


Ссылка на сообщение
прописать вызов функции из start_game_callback

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

----------------------------------------------------------------------------------------

По поводу вылетов при обращении к своему файлу из xml -тегов:

как я уже отметил - это не мой опыт - но опыт человека многим известного - Artosa(разработчика мультимода Симбион).

Вот что он писал по этому поводу:

То, что вызов функции из скрипта, имеющего синтаксические ошибки невозможен - это собственно и так понятно. Скрипт не считывается в метатаблицу _G/db и обращение к отсутствующей таблице -> nil.

А вот с фактом того, что первичное обращение к 'самописному' скрипту порой приводит к аналогичному результату (nil), заметил еще в давние времена, когда начинал ковыряться в кодах игры.

Причем практически 100% это заметно при вызове из диалогов (xml-ек) 'своих' функций из 'своих' скриптов.

Предполазаю, что при косвенных вызовах (через xml-тэги или аналогичное) идет обращение НЕ к скрипту, а к метатаблице _G (или даже db!) и если файл скрипта еще не был кеширован в нее - результат ->nil.

--------------------------------------------------------------------------------------

И еще - можно чуток поподробнее о функции init :rolleyes: ?

Заметил, что во всех биндерах есть функция init() или bind() и указывается она в конфиг секциях объектов которые биндятся.

Какую функцию ты имел ввиду?

---------------------------------------------------------------------------------------------

malandrinus

Спасибо за указание на prefetch() - будем тестить.

-------------------------------------------------------------

Все работает - один минус - вызов prefetch() нужно куда-то ставить :wacko: - автономность вызова функций опять же убивается.

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

Поделиться этим сообщением


Ссылка на сообщение

Kolmogor

Смысл всей этой затеи с автономностью - делать свои разработки как можно менее зависимыми от дефолтных файлов(совместимость модов будет более простая) - в плане вызовов своих функций. Например на данный момент для одной своей разработки я полностью избавился от необходимости использовать bind_stalker как для апдейта, так и в плане некоторых каллбеков - переустановил их на эктора заново в своем биндере.

 

malandrinus

Если сильно надо, поставь все необходимые вызовы prefetch в начале модуля _g.script.

Так тут дело не в том куда поставить - вариантов то масса - а в том именно, что нАдо кУда То ставить :rolleyes: - а это значит опять задейстовать\править дефолтные файлы.

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

Поделиться этим сообщением


Ссылка на сообщение

Распишу немного то, что по работе с физикой объектов освоил:

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

Применяем метод к клиентской юзердате объекта.

Далее можно обратиться к методам нижеследующих классов для нужных нам действий.

Скрытый текст

class physics_shell {

    get_joints_number() --получить число сочленений у объекта, если они конечно есть. Чаще есть только элементы и кости.

    is_breaking_blocked() -- возможно проверка на заблокированность разрушаемости объекта. У меня всегда возвращал false - имеется ввиду после применения метода block_breaking().

    get_element_by_bone_id(number) -- получить элемент по числовому идентификатору кости.

    get_linear_vel(vector&)

    is_breakable() -- разрушаем ли объект. У меня метод всегда возвращал false как для объектов класса O_PHYS_S так и для P_DSTRBL

    get_elements_number() -- получить число элементов у объекта. У ящиков и контейнеров элементов одна штука.

    unblock_breaking() -- убрать блокировку ?

    get_joint_by_bone_name(string) --получить сочленение по строковому идентификатору кости.

    get_element_by_order(number) -- получить элемент по порядковому номеру. Объекты с которым я работал имели только один элемент и его порядковый номер был соответственно 0.

    get_element_by_bone_name(string) -- получить элемент по строковому идентификатору кости.

    apply_force(number, number, number) -- применить импульс к объекту по трем координатным осям - x, y, z. Задавая разные значения для каждой оси можно варьировать направление куда объект будет "пнут" импульсом.

    get_angular_vel(vector&)

    block_breaking() -- полагал что блокирует разрушение объектов класса P_DSTRBL - однако тест не принес желаемого эффекта.

    get_joint_by_order(number) -- получить сочленение по порядковому номеру.

    get_joint_by_bone_id(number) -- видимо получить сочленение по числовому идентификатору кости.

};

 

 

Методы класса physics_element следует применять к предварительно полученному объекту элемента физической оболочки предмета.

Скрытый текст

class physics_element {

    get_density() -- получить плотность объекта. Весьма любопытные цифирьки дает - к реальной плотности материалов(железо\дерево\ткань\картон и т. д.) отношения не имеют. Тестил на разного рода ящиках и контейнерах.

    get_mass() -- получить массу . Значение совпадает с тем что возвращает метод mass() для клиентского объекта.

    is_fixed() -- проверка зафиксирован ли элемент.

    is_breakable() -- видимо проверка является ли объект разрушаемым - у меня на на объектах класса P_DSTRBL метод возвращал всегда false.

    -- Для справки - объекты класса O_BRKBL физ. оболочки не имеют - поэтому, хотя метод по названию вроде как для них, на самом деле неприменим к этому классу.

    get_volume() -- получить физический объем объекта. По результатам теста вполне вменяемые цифры - объекты мелкой вместимости дают маленькие значения, крупной - большие.

    get_linear_vel(vector&)

    fix() --зафиксировать элемент физической оболочки(фактически сделать сам объект привязанным к точке). Никто не использует - а зря. Я этот метод для фиксации своих схронов применил, а также мин-растяжек.

    get_angular_vel(vector&)

    apply_force(number, number, number) -- применить импульс к элементу объекта по трем координатным осям - x, y, z.

    release_fixed() -- удалить фиксацию элемента. Побочный эффект - объект переходит в состояние невесомости. Очень прикольно надо сказать выходит.

    global_transform(physics_element*) -- не дало никакого эффекта. Возможно неправильно применял.

};

 

 

Пример фиксации объекта - хоть в воздухе, хоть на земле. Фиксация сохраняется и после сейв\лоада. Но у мелких объектов фиксация после сейва\лоада слабая - и может легко разрушаться от приложения к нему силы. До перезагрузки - фиксируется намертво.

Скрытый текст
function ObjectFixed(id)
    if id then 
    local obj = level.object_by_id(id)
        if obj then
        local pshell = obj:get_physics_shell()
            if  pshell then 
            local element = pshell:get_element_by_order(0)
                if element then 
                element:fix()
                end
            end
        end
    end                
end

 

 

Кстати насчет метода script_server_object_version()

вот для чего он используется:

local ss_ver = script_server_object_version()
local IS_SOC = (ss_ver <= 7) -- although anything earlier then 1.0004 won't work
local IS_CS = (ss_ver > 7 and ss_ver < 12) -- although anything earlier then 1.5.0.4 won't work
local IS_COP = (ss_ver >= 12) --(ss_ver == 12)
 

комментарии думаю излишни.

 

Kirag

Спасибо. Я так и думал что как то не так их применял. Теперь более менее понятно.

Но вот только что они дают интересного(линеарное и угловое ускорение?).

И как работать с полученными значениями?

 

Изменено пользователем Kirgudu
  • Нравится 1

Поделиться этим сообщением


Ссылка на сообщение

malandrinus,

Занялся недавно скриптовыми диалогами - на практике.

В общем думаю стоит добавить в твои посты про них следующий момент:

При использовании метода AddAction(string) функция, которая вызывается им, принимает вот такой набор аргументов:

func(oSpeaker1, oSpeaker2, sDlgId, idPhrase)

первые два аргумента думаю всем понятны - юзердата собеседников, sDlgId - строковое имя диалога, и самый важный для меня аргумент - idPhrase - айди фразы (строковое или числовое - в 1.0004 используются числовые идентификаторы).

Не зная всего этого - потратил лишнее время на изобретение системы отслеживания активированных фраз в диалоге - но все оказалось гораздо проще. ;)

Функция, которая вызывается методом AddPrecondition(string) принимает немного другой набор аргументов:

precondition(oSpeaker1, oSpeaker2, sDlgId, idParent, idPhrase)

как видно тут добавился еще один - idParent, который возвращает айди родительской фразы, то есть фразы идущей перед той, в которой данный прекондишен находится.

При динамическом формировании фраз (например как у меня через цикл) - когда число фраз заранее неизвестно - значение аргумента idPhrase просто незаменимо.

Без этого я например просто не смог бы передать нужные данные для каждой конкретной фразы.

Ну правда я немного схитрил и использовал give_talk_message для некоторых ответных фраз NPC - просто с иконкой фразы красивше смотрелись (и иконка в тему).

Вот. Пока все, что выяснил интересного. Работает мой диалог отлично - так что тебе большое спасибо за раскрытие темы.

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

Поделиться этим сообщением


Ссылка на сообщение

malandrinus

Там это всё есть в первой части

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

Если продублировать и там - тогда думаю многим будет яснее. :rolleyes:

Они же не дают практически никаких преимуществ по сравнению с XML.

Ну как это не дают преимуществ - еще как дают.

Я их применил для динамического создания диалога (у одного NPC ) о продаже кодов к закодированным схронам.

Фразы во первых формируются в цикле - что в xml сделать нельзя - то есть их число заранее неизвестно и определяется длиной таблички, которая хранит коды. В момент инициализации диалога специальная функция у меня формирует временную(существующую только до закрытия диалога) табличку со всеми нужными(и свежими данными), а далее в каждую новую фразу подставляются табличные данные. И хотя сами фразы однотипные по структуре - наполнение у всех разное. Что опять же нельзя сделать из xml, где наполнение предустановлено заранее.

Ну и на каждую фразу ГГ стоит скриптовый экшен, который выполняет нужное действие ориентируясь на номер фразы.

Также использованы скриптовые прекондишены. Диалог динамически меняет - не знаю как правильно сказать - граф не граф - в общем свой состав - каждая активированная фраза о покупке тут же исчезает из диалога(так как больше не нужна), при новой инициации диалога он строится уже в новом составе(с новым числом фраз) и с обновленными данными. В случае, если данных нет - кончились - выводится фраза NPC типа "на сегодня предложений больше нет".

Диалог у меня конечно маленький (и развилок всего пара штук)- но работает как надо.

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

Поделиться этим сообщением


Ссылка на сообщение

malandrinus,

В противном случае можно нарваться на абсолютно непредсказуемые ошибки, которые зависят от таких вещей, как запустили ли вы программу только что или это уже второй и далее сейв

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

Во первых, если сделать перед началом диалога сейв, потом поговорить с NPC и купить у него всю инфу(то есть активировать все имеющиеся фразы, которые по использованию больше не выводятся - вместо них будет выводиться развилочная фраза "На сегодня ничего предложить не могу."), то после того как снова - не выходя из игры - загрузить тот же сейв перед началом диалога - получаем такую ситуацию - NPC говорит, что инфы НЕТ! То есть получается, что диалог заново - с нуля - действительно как ты и писал не выстраивается\не инициализируется. Вчера я этот момент даже не проверил.

А во вторых странная путаница выходит время от время с номерами фраз и ключами временной таблицы(они же номера фраз) хранящей инфу для фраз - в некоторых случаях они перестают совпадать. И я получаю сравнение числа с nil.

В общем требуется серьезный разбор полетов . Поможешь?

-----------------------------------------------------------------------

Путаницу с ключами вылечил.

Теперь все вроде работает без ошибок - хотя плохо, конечно, что диалог не желает обновляться вторично. У меня так происходит даже если были активированы не все фразы - при загрузке сейва сделанного по итогам диалога, все равно получаю только фразу-концовку "На сегодня ничего предложить не могу.", хотя еще несколько фраз не были использованы. Но если выйти из игры, зайти снова и загрузить этот сейв - тогда появляются все неиспользованные фразы.

Исправил и этот момент - надо было просто сохранять табличку с данными для фраз - она ведь у меня с прекондишенами для фраз связана, а так как она не сохранялась, то прекондишены после перезагрузки возвращали false для вывода фраз. Теперь в этом плане все норм.

 

А действительно никак нельзя переинициализировать диалог вручную - принудительно?

Ведь граф диалога куда то записывается при инициализации диалога...а если перезаписать...если конечно знать что и как...

 

----------------------------------------------------------------------------

Кстати, а что полезного дает строковое айди диалога - кроме того, что оно используется при выводе в лог в случае ошибки при построении диалога?

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

Поделиться этим сообщением


Ссылка на сообщение

malandrinus

Окей, насчет инициализации и хранения диалогов понял. (примерно так и думал, что есть какой то движковый storage\ массив для них).

Кстати вот и ответ на мой вопрос про айди диалогов - я имел ввиду, когда мы его получаем как входящий аргумент например из прекондишена или экшена - то какая польза от этого параметра? видимо никакой, но

диалоги ...помещаются в это хранилище, откуда при дальнейших запросах выбираются по ключу (идентификатору диалога)
. То бишь назначение айди диалогов - для внутреннего использования функциями игры. Для модмейкера получается ничего не дает. Изменено пользователем Garry_Galler

Поделиться этим сообщением


Ссылка на сообщение

А теперь, товарищи, дружно забудем такой архаизм как амкашную функцию разделения строки str_explode (и ее варианты в других модах) и начинаем пользоваться быстрыми методами:

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

Авторы Gun12, Garry_Galler, Artos - изначально был мой вариант с одним шаблоном, потом Gun12 предложил более универсальный паттерн, Artos привел все в божеский вид, ну и общими усилиями получился такой вариант (последняя редакция - чисто моя)

 

Аргументы:

sStr -- cтрока для разбора

Mode -- режим заполнения таблицы

sDiv --сепаратор: если указываем, то обязательно указать режим Mode

sPattern -- свой шаблон:если указываем, то в аргументе sDiv передать nil и обязательно указать режим Mode

 

function StringSplit(sStr, Mode, sDiv, sPattern)
    local tRet = {}
    local sPatt
    if sDiv and  not sPattern then --// если сепаратор  задан: разделяем по нему
    --// если нет шаблона - используем универсальный
    sPatt = '[^%s%'..sDiv..']+'
--// если сепаратор указан как nil, но указан  шаблон: используем его
    elseif not sDiv and  sPattern then 
    sPatt=sPattern
    else--/ если сепаратор и шаблон  не указаны: разделяем слова
    sPatt = '[%w%_]+'
    end
    if Mode == nil then --// обычный массив
        for sValue in sStr:gmatch(sPatt) do
            table.insert(tRet, sValue)
        end
    elseif Mode == true then --// таблица '[значение]=true'
        for sValue in sStr:gmatch(sPatt) do
            tRet[sValue] = true
        end
    elseif type(Mode) == "number" then --//таблица '[idx] = число или стринг'
        for sValue in sStr:gmatch(sPatt) do
        tRet[#tRet+1] = tonumber(sValue) or sValue
        end
    end
  return tRet
end

--вызовы

local t =StringSplit("vid mode 1024x768", true, nil, "%d+")  --используем свой шаблон для получения из строки двух цифр
local t =StringSplit("ammo_9x18_fmj, ammo_9x18_pmm, ammo_11.43x23_fmj", 1,",") -- делим строку по разделителю-запятой
-- делим строку на слова независимо от имеющихся разделителей
local t =StringSplit(" There will come soft rains and the smell of the ground, And swallows circling with their shimmering sound")
-- когда в строке имеется несколько видов сепараторов и нужно все их указать, можно сделать так:
local s = "ammo_9x18_fmj, ammo_9x39_pab9! ammo_9x39_ap$ ammo_9x39_sp5? ammo_9x18_pmm; ammo_11.43x23_fmj"
local t =StringSplit(s, true,",%;%?%!%$")

 

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

Поделиться этим сообщением


Ссылка на сообщение

Хотел уточнить: класс CUIStatic действительно не поддерживает вывод анимированных текстур (в формате ogm) ?

Попробовал создать экземпляр статика с ogm и вывести на худ (через AddDialogToRender()) свою видеоанимацию - вылетел(ругалась какая то движковая функция связанная с кодеком theora ).

Решил попробовать тоже самое сделать с дефолтным ogm - ui\ui_mm_fire (вдруг мое видео нечитабельным было для сталка) - тоже вылетел, правда лог другой был (малоинформативный поэтому не привожу).

 

Насчет CUIStatic я был неправ- он то как раз позволяет использовать анимированные текстуры\видео. Но если вывести их в скриптовое окно проблем нет, то вот на худ - непонятно как - использование AddDialogToRender() приводит к вылету.

 

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

Поделиться этим сообщением


Ссылка на сообщение

malandrinus

В точку. Спасибо за подсказку.

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

Вынес ссылку во внешку - все появилось(использовал для теста видео из игры). Теперь еще осталось разобраться с моим видео, которое сталкер воспроизводить не хочет - конвертил из avi в ogv прогой ffmpeg2theora, расширение сменил на ogm - но вылетает зараза - видимо что то с форматом не то. <_<

[spoiler=вот лог -думаю мало кому знакомый ;) ]stack trace:

 

001B:004AF4B9 XR_3DA.exe, CPerlinNoise3D::Get()

001B:0047BE38 XR_3DA.exe, CTheoraSurface::Update()

001B:0048CB15 XR_3DA.exe, CTexture::apply_theora()

 

 

 

PS: Да, вот еще - для расширения так как сказать кругозора - почему игра(компилятор) не видит уже скомпилированный скриптовый файл?

Ради теста решил скомпилировать свой игровой скрипт в SCITE - положил потом в в папку script, расширение .script - так не видит в упор, как будто его там и нет вовсе.

Изменено пользователем Garry_Galler
  • Полезно 1

Поделиться этим сообщением


Ссылка на сообщение
есть ли функция закрытия/открытия инвенторя(пда)?

Вот так я закрывал окно торговли

--// поставить вызов OnTrade(info_id)  в начало функции actor_binder:info_callback(npc, info_id)  - файл bind_stalker.script

local UITradeWnd

function OnTrade(info_id)
   if info_id =="ui_trade" then
   UITradeWnd = level.main_input_receiver()
   elseif info_id == "ui_trade_hide" then
   UITradeWnd = nil
   end
end

--// вызов функции закрывает окно торговли - можно ставить куда угодно -хоть на апдейт
function HideTradeWnd()
    if UITradeWnd then 
    UITradeWnd:GetHolder():start_stop_menu(UITradeWnd, true)
    end 
end

Если вместо инфопоршней на открытие\закрытие окна торговли указать инфопоршни на открытие\закрытие пда -"ui_pda" и "ui_pda_hide - или окна инвентаря - ui_inventory\ui_inventory_hide - будет тоже самое.

TRAMP14

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

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

Поделиться этим сообщением


Ссылка на сообщение
Если кто сможет выяснить условия работы этого метода - обязательно отпишитесь здесь

Насчет move_to()-метод работает, хотя не со всеми партиклами корректно. Некоторые не перемещал вообще, либо перемещал, но весьма криво - например часть партикла(если это pg) остается на месте - другая движется, либо вместо движения - создается несколько визуальных объектов, которые никуда не движутся.

local bPlay = false 
local iCountUpdate =0
local iPos
local iDir
local gObj
local oPart= particles_object("static\\zharka_static")

--// апдейтим
function MoveParticle(sid)
gObj = sid and level_object_by_sid(sid) or db.actor
if not gObj then return end 
   if bPlay then
      if not iPos then 
      iPos = gObj:position()
      iDir = gObj:direction()
      end

      iCountUpdate=iCountUpdate+1
      if  iCountUpdate==20 then 
--// через каждые 20 циклов апдейта меняем направление движения и позицию (на 1 метр)
      iDir = vector_rotate_y(iDir, math.random (-15, 15))
      iPos=iPos:add(iDir:mul(1)) 
      iCountUpdate=0 
      end 
  --// перемещаем
      local val = not oPart:playing() and oPart:play_at_pos(iPos) or oPart:move_to(iPos,iPos);
--// выключаем 
      else
      if oPart and oPart:playing() then 
      oPart:stop() 
      iPos=nil 
      iDir=nil
      end
   end
end

--/ вкл/выкл партикл :-)
function StartStop()
bPlay = not bPlay
end

 

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

Поделиться этим сообщением


Ссылка на сообщение

_Призрак_

Не уверен, но мне кажется что он должен возвращать nil после выхода врага из определенного радиуса от объекта, к которому метод был применен.

По крайне мере аналогичный метод monstr:get_corpse() возвращает юзердату ближайшего трупа только в определенном радиусе от монстра.

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

Поделиться этим сообщением


Ссылка на сообщение

Whisper

А что делает функция wait() в _g.script?

Она там... присутствует. Как памятник нерукотворный гению разрабов.

Собственно в оригинале она(если я не ошибаюсь) никак задействована, так как скрипты в которых ее можно найти - тестовый мусор.

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

ЗЫ: для запуска скрипта как подпрограммы нужно использовать lua пространство имен coroutine.

Поделиться этим сообщением


Ссылка на сообщение

Выкладываю небольшой разбор содержимого полей таблицы db.storage, которое относится в NPC.

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

ЗЫ: Оформлено все в виде функции, которая содержит таблицу: строковой идентификатор=значения поля и возвращает значения того или иного поля db.storage по его идентификатору в таблице и айди NPC ( вызов примерно такой - GetData(level_object_by_sid(sid), "target_state") ). Там где используется много операторов and - это способ защиты от вылета при обращении к несуществующему полю таблицы. Распечатку таблицы я делал сразу по всем полям, а так как у разных NPC содержание полей было разным, то такие проверки избавляли меня от вылетов.

ЗЗЫ: Данную функцию можно использовать только в тестовых целях, а не для реального применения.

  ---------------------------------------------------------------------------------------------
function GetData(npc, type)
local tMgr ={

---------------------------------------------------------------------------------------------
  --// поля стейт менеджера
    ---------------------------------------------------------------------------------------------
    state_mgr          = db.storage[npc:id()].state_mgr,                      --// юзердата класса state_manager
    target_state       = db.storage[npc:id()].state_mgr.target_state,         --// string название состояние из state_lib
    current_direction  = db.storage[npc:id()].state_mgr.current_direction,    --// vector или nil - направление взгляда? 
    target_position    = db.storage[npc:id()].state_mgr.target_position,      --// vector позиция (своя или того на кого смотрит?)  или nil
    current_object     = db.storage[npc:id()].state_mgr.current_object,       --// number  (-1  или nil)
    combat             = db.storage[npc:id()].state_mgr.combat,               --// boolean - находится ли в состоянии боя
    alife              = db.storage[npc:id()].state_mgr.alife,                --// boolean - под алайфом или нет?
    emerg              = db.storage[npc:id()].state_mgr.emerg,                --// table, в которой должны быть поля: animation и animation_nout, однако почему то их нет 
    synsound           = db.storage[npc:id()].state_mgr.synsound,             --//  ??
    yaw_delta          = db.storage[npc:id()].state_mgr.yaw_delta,            --// number  угол точности - 5 (градусов вроде)
    subanim            = db.storage[npc:id()].state_mgr.subanim,              --//  number  - 0 глубина рекурсивности анимации 
    need_reweapon      = db.storage[npc:id()].state_mgr.need_reweapon,        --// boolean 
    
    look_object        = db.storage[npc:id()].state_mgr.look_object,          --// number  - айди  объекта  на которого NPC предписано  смотреть 
    look_position      = db.storage[npc:id()].state_mgr.look_position,        --// vector  - позиция куда предписано смотреть
    ---------------------------------------------------------------------------------------------
    --// прочие поля
    ---------------------------------------------------------------------------------------------
    move_mgr           = db.storage[npc:id()].move_mgr,                       --// юзердата класса move_mgr
    state              = db.storage[npc:id()].state,                          --// должно быть юзердатой класса  -- но у меня возвращалось nil 
    ---------------------------------------------------------------------------------------------
    hit                = db.storage[npc:id()].hit,                            --// table   (но у меня таблица была nil - даже после нанесения хита NPC, в ней должно быть поле hit.who  - айди того, кто нанес хит
    ---------------------------------------------------------------------------------------------
    enemy              = db.storage[npc:id()].enemy,                          --// юзердата текущего врага
    ---------------------------------------------------------------------------------------------
    death                   = db.storage[npc:id()].death,                          --// table
    death_section           = db.storage[npc:id()].death.section,                  --// string - имя секции логики
    death_scheme            = db.storage[npc:id()].death.scheme,                   --// string   имя схемы
    death_npc               = db.storage[npc:id()].death.npc,                      --// userdata
    death_actions           = db.storage[npc:id()].death.actions,                  --// table
    death_userdata          = db.storage[npc:id()].death.actions.userdata,         --// boolean
    
    death_info              = db.storage[npc:id()].death.info[1],                                                       --// table
    death_info_section      = db.storage[npc:id()].death.info[1]  and db.storage[npc:id()].death.info[1].section,       --//??
    death_info_infop_check  = db.storage[npc:id()].death.info[1]  and db.storage[npc:id()].death.info[1].infop_check and db.storage[npc:id()].death.info[1].infop_check[1],   --// table
    death_info_infop_check_expected  = db.storage[npc:id()].death.info[1]  and db.storage[npc:id()].death.info[1].infop_check and db.storage[npc:id()].death.info[1].infop_check[1] and db.storage[npc:id()].death.info[1].infop_check[1].expected,    --// boolean
    death_info_infop_check_func      = db.storage[npc:id()].death.info[1]  and db.storage[npc:id()].death.info[1].infop_check and db.storage[npc:id()].death.info[1].infop_check[1] and db.storage[npc:id()].death.info[1].infop_check[1].func,       --//string
    death_info_infop_set    = db.storage[npc:id()].death.info[1]  and db.storage[npc:id()].death.info[1].infop_set and db.storage[npc:id()].death.info[1].infop_set[1],     --// table
    death_info_infop_set_name    = db.storage[npc:id()].death.info[1]  and db.storage[npc:id()].death.info[1].infop_set and db.storage[npc:id()].death.info[1].infop_set[1].name,               --// string - имя инфопоршня
    death_info_infop_required    = db.storage[npc:id()].death.info[1]  and db.storage[npc:id()].death.info[1].infop_set and db.storage[npc:id()].death.info[1].infop_set[1].required,           --//boolean
    
    death_info2             = db.storage[npc:id()].death.info[2],                                                       --// table
    death_info_section2     = db.storage[npc:id()].death.info[2]  and db.storage[npc:id()].death.info[2].section,       --//??
    death_info_infop_check2 = db.storage[npc:id()].death.info[2]  and db.storage[npc:id()].death.info[2].infop_check,   --// table
    death_info_infop_set2   = db.storage[npc:id()].death.info[2]  and db.storage[npc:id()].death.info[2].infop_set,     --// table
    ---------------------------------------------------------------------------------------------
    danger                 = db.storage[npc:id()].danger,                         --// table
    danger_ini             = db.storage[npc:id()].danger.ini,                     --// userdata
    danger_npc             = db.storage[npc:id()].danger.npc,                     --// userdata
    danger_section         = db.storage[npc:id()].danger.section,                 --// string
    danger_scheme          = db.storage[npc:id()].danger.scheme,                  --// string
    ignore_types           = db.storage[npc:id()].danger.ignore_types,            --// table - содержит строки игнорируемых типов объектов
    ---------------------------------------------------------------------------------------------
    abuse                  = db.storage[npc:id()].abuse,                                           --// table
    abuse_npc              = db.storage[npc:id()].abuse.npc,                                       --// userdata
    abuse_manager          = db.storage[npc:id()].abuse.abuse_manager,                             --// userdata класса CAbuseManager
    abuse_ini              = db.storage[npc:id()].abuse.ini,                                       --// userdata
    abuse_section          = db.storage[npc:id()].abuse.section,                                   --// string имя секции логики
    abuse_scheme           = db.storage[npc:id()].abuse.scheme,                                    --// string  имя схемы
    ---------------------------------------------------------------------------------------------
    wounded                      = db.storage[npc:id()].wounded,                                    --// table
    wounded_set                  = db.storage[npc:id()].wounded.wounded_set,                        --// boolean - флажок что скрипт вызывался 
    use_medkit                   = db.storage[npc:id()].wounded.use_medkit,                         --// boolean
    help_dialog                  = db.storage[npc:id()].wounded.help_dialog,                        --// string  имя диалога помощи
    wounded_section              = db.storage[npc:id()].wounded.wounded_section,                    --// string
    wounded_scheme               = db.storage[npc:id()].wounded.scheme,                             --// string  
    wounded_npc                  = db.storage[npc:id()].wounded.npc,                                --// userdata
    wounded_ini                  = db.storage[npc:id()].wounded.ini,                                --// userdata
    wound_manager                = db.storage[npc:id()].wounded.wound_manager,                      --// userdata класса Cwound_manager

    
    hp_state_infop_check               = db.storage[npc:id()].wounded.hp_fight[1].state.infop_check,      --// table  
    hp_state_infop_set                 = db.storage[npc:id()].wounded.hp_fight[1].state.infop_set,        --// table 
    
    hp_cover_state_infop_check         = db.storage[npc:id()].wounded.hp_cover[1].state.infop_check,      --// table
    hp_cover_state_infop_set           = db.storage[npc:id()].wounded.hp_cover[1].state.infop_set,        --// table
    
    hp_victim_state_infop_check        = db.storage[npc:id()].wounded.hp_victim[1].state.infop_check ,    --// table  
    hp_victim_state_infop_set          = db.storage[npc:id()].wounded.hp_victim[1].state.infop_set,       --// table     
    
    hp_fight_state_infop_check         = db.storage[npc:id()].wounded.hp_fight[1].state.infop_check,      --// table
    hp_fight_state_infop_set           = db.storage[npc:id()].wounded.hp_fight[1].state.infop_set,        --// table
    
    hp_state_see                       = db.storage[npc:id()].wounded.hp_state_see[1],                          --// table
    hp_state_see                       = db.storage[npc:id()].wounded.hp_state_see[1].dist,                     --// number  --дистанция 
    hp_state_see_state                 = db.storage[npc:id()].wounded.hp_state_see[1].state[1],                 --// table
    hp_state_see_state_section         = db.storage[npc:id()].wounded.hp_state_see[1].state[1].section,         --// string
    hp_state_see_state_infop_check     = db.storage[npc:id()].wounded.hp_state_see[1].state[1].infop_check,     --// table
    hp_state_see_state_infop_set       = db.storage[npc:id()].wounded.hp_state_see[1].state[1].infop_set,       --// table
    hp_state_see_sound                 = db.storage[npc:id()].wounded.hp_state_see[1].sound[1],                 --// table
    hp_state_see_sound_section         = db.storage[npc:id()].wounded.hp_state_see[1].sound[1].section,         --// string
    hp_state_see_sound_infop_check     = db.storage[npc:id()].wounded.hp_state_see[1].sound[1].infop_check,     --// table
    hp_state_see_sound_infop_set       = db.storage[npc:id()].wounded.hp_state_see[1].sound[1].infop_set,       --// table
    
    
    psy_state_state                    = db.storage[npc:id()].wounded.psy_state[1].state[1],                 --// table
    psy_state_state_section            = db.storage[npc:id()].wounded.psy_state[1].state[1].section,         --// string имя состояния
    psy_state_state_infop_check        = db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check and db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check[1],                --// table
    psy_state_state_infop_check_expected    = db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check and db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check[1] and db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check[1].expected,  --// boolean
    psy_state_state_infop_check_func        = db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check and db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check[1] and db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check[1].func,      --// string
    psy_state_state_infop_set          = db.storage[npc:id()].wounded.psy_state[1].state[1].infop_set,       --// table
    psy_state_state2                   = db.storage[npc:id()].wounded.psy_state[1].state[2],                 --// table
    psy_state_state_section2           = db.storage[npc:id()].wounded.psy_state[1].state[2].section,         --// string  имя состояния
    psy_state_state_infop_check2       = db.storage[npc:id()].wounded.psy_state[1].state[2].infop_check,     --// table
    psy_state_state_infop_set2         = db.storage[npc:id()].wounded.psy_state[1].state[2].infop_set,       --// table
    psy_state_sound                    = db.storage[npc:id()].wounded.psy_state[1].sound[2],                 --// table
    psy_state_sound2                   = db.storage[npc:id()].wounded.psy_state[1].sound[2],                 --// table
    
    wounded_syndata                    = db.storage[npc:id()].wounded.syndata,                   --// table
    state_wounded                      = db.storage[npc:id()].wounded.wound_manager.state,       --// string состояние физ. ранености wounded_heavy\wounded_heavy_2\wounded_heavy_3  или пси-ранености
    ---------------------------------------------------------------------------------------------
    overrides                          = db.storage[npc:id()].overrides,                      --// table - оверрайды схем, типа combat_ignore_keep_when_attacked=false или companion_enabled=false
    ---------------------------------------------------------------------------------------------
    actor_dialogs                      = db.storage[npc:id()].actor_dialogs,                  --// table - видимо список  разрешенных диалогов
    ---------------------------------------------------------------------------------------------
    actor_disable                      = db.storage[npc:id()].actor_disable,                  --// table - это тогда список  запрещенных диалогов
    ---------------------------------------------------------------------------------------------
    meet                               = db.storage[npc:id()].meet,                           --// table
    meet_npc                           = db.storage[npc:id()].meet.npc,                       --// userdata
    meet_manager                       = db.storage[npc:id()].meet.meet_manager,              --// userdata класса Cmeet_manager
    meet_precond                       = db.storage[npc:id()].meet.precond,                   --// string
    meet_abuse                         = db.storage[npc:id()].meet.abuse,                     --// boolean
    meet_set                           = db.storage[npc:id()].meet.meet_set,                  --// boolean
    init_meet                          = db.storage[npc:id()].meet.init_meet,                 --// ?? пустая строка
    meet_section                       = db.storage[npc:id()].meet.meet_section,              --// string  имя секции логики
    meet_scheme                        = db.storage[npc:id()].meet.scheme,                    --// string
    meet_ini                           = db.storage[npc:id()].meet.ini,                       --// userdata
    
    meet_use_section                   = db.storage[npc:id()].meet.use.section,               --// boolean
    meet_use_infop_check               = db.storage[npc:id()].meet.use.infop_check,           --// table
    meet_use_infop_set                 = db.storage[npc:id()].meet.use.infop_set,             --// table
    meet_use_wpn                       = db.storage[npc:id()].meet.use_wpn[1],                --// table
    meet_victim                        = db.storage[npc:id()].meet.victim[1],                 --// table
    meet_victim_state                  = db.storage[npc:id()].meet.victim.state,              --// table
    meet_victim_dist                   = db.storage[npc:id()].meet.victim.dist,                 --// number - дистанция
    meet_victim_wpn                    = db.storage[npc:id()].meet.victim_wpn[1],             --// table
    meet_victim_wpn_state              = db.storage[npc:id()].meet.victim_wpn[1].state,       --// table
    meet_victim_wpn_state1             = db.storage[npc:id()].meet.victim_wpn[1].state and db.storage[npc:id()].meet.victim_wpn[1].state[1],       --// table
    meet_victim_wpn_state1_infop_check = db.storage[npc:id()].meet.victim_wpn[1].state and db.storage[npc:id()].meet.victim_wpn[1].state[1]  and db.storage[npc:id()].meet.victim_wpn[1].state[1].infop_check,   --// table
    meet_victim_wpn_state1_infop_set   = db.storage[npc:id()].meet.victim_wpn[1].state and db.storage[npc:id()].meet.victim_wpn[1].state[1]  and db.storage[npc:id()].meet.victim_wpn[1].state[1].infop_set,     --// table
    meet_victim_wpn_state1_section     = db.storage[npc:id()].meet.victim_wpn[1].state and db.storage[npc:id()].meet.victim_wpn[1].state[1]  and db.storage[npc:id()].meet.victim_wpn[1].state[1].section,       --// string  
    
    meet_state_state                  = db.storage[npc:id()].meet.meet_state[1].state[1],    --// table
    meet_state_state_section          = db.storage[npc:id()].meet.meet_state[1].state[1] and db.storage[npc:id()].meet.meet_state[1].state[1].section,  --// string  имя состояния
    meet_state_sound                  = db.storage[npc:id()].meet.meet_state[1].sound[1],    --// table
    meet_state_sound_section          = db.storage[npc:id()].meet.meet_state[1].sound[1] and db.storage[npc:id()].meet.meet_state[1].sound[1].section,    --// string   секция звуковой схемы
    meet_state_state_infop_check      = db.storage[npc:id()].meet.meet_state[1].state[1].infop_check and db.storage[npc:id()].meet.meet_state[1].state[1].infop_check[1],    --// table
    meet_state_state_infop_set        = db.storage[npc:id()].meet.meet_state[1].state[1].infop_set,    --// table
    meet_state_sound_infop_check      = db.storage[npc:id()].meet.meet_state[1].sound[1].infop_check and db.storage[npc:id()].meet.meet_state[1].sound[1].infop_check[1],    --// table
    meet_state_sound_infop_set        = db.storage[npc:id()].meet.meet_state[1].sound[1].infop_set,    --// table
    
    meet_zone                         = db.storage[npc:id()].meet.zone,                      --// table
    meet_state_wpn                    = db.storage[npc:id()].meet.meet_state_wpn[1],         --// table
    meet_state_wpn_state              = db.storage[npc:id()].meet.meet_state_wpn[1].state,   --// table
    meet_state_wpn_state1             = db.storage[npc:id()].meet.meet_state_wpn[1].state and db.storage[npc:id()].meet.meet_state_wpn[1].state[1],   --// table
    meet_state_wpn_state1_infop_check = db.storage[npc:id()].meet.meet_state_wpn[1].state and db.storage[npc:id()].meet.meet_state_wpn[1].state[1] and db.storage[npc:id()].meet.meet_state_wpn[1].state[1].infop_check and db.storage[npc:id()].meet.meet_state_wpn[1].state[1].infop_check[1],   --// table
    meet_state_wpn_state1_infop_set   = db.storage[npc:id()].meet.meet_state_wpn[1].state and db.storage[npc:id()].meet.meet_state_wpn[1].state[1] and db.storage[npc:id()].meet.meet_state_wpn[1].state[1].infop_set,     --// table
    meet_state_wpn_state1_section     = db.storage[npc:id()].meet.meet_state_wpn[1].state and db.storage[npc:id()].meet.meet_state_wpn[1].state[1] and db.storage[npc:id()].meet.meet_state_wpn[1].state[1].section,       --// string  - имя анимки
    meet_state_wpn_state2_infop_check = db.storage[npc:id()].meet.meet_state_wpn[1].state and db.storage[npc:id()].meet.meet_state_wpn[1].state[2] and db.storage[npc:id()].meet.meet_state_wpn[1].state[2].infop_check,   --// table
    meet_state_wpn_state2_infop_set   = db.storage[npc:id()].meet.meet_state_wpn[1].state and db.storage[npc:id()].meet.meet_state_wpn[1].state[2] and db.storage[npc:id()].meet.meet_state_wpn[1].state[2].infop_set,     --// table
    meet_state_wpn_state2_section     = db.storage[npc:id()].meet.meet_state_wpn[1].state and db.storage[npc:id()].meet.meet_state_wpn[1].state[2] and db.storage[npc:id()].meet.meet_state_wpn[1].state[2].section,       --// string  - имя анимки
    
    
    meet_state_wpn_sound             = db.storage[npc:id()].meet.meet_state_wpn[1].sound,   --// table
    meet_state_wpn_dist              = db.storage[npc:id()].meet.meet_state_wpn[1].dist,    --// number  дистанция
    meet_dialog                      = db.storage[npc:id()].meet.meet_dialog[1],            --// table
    meet_dialog_section              = db.storage[npc:id()].meet.meet_dialog[1] and db.storage[npc:id()].meet.meet_dialog[1].section,    --// string   имя диалога встречи
    meet_dialog_infop_check          = db.storage[npc:id()].meet.meet_dialog[1] and db.storage[npc:id()].meet.meet_dialog[1].infop_check,--// table
    meet_dialog_infop_check1         = db.storage[npc:id()].meet.meet_dialog[1] and db.storage[npc:id()].meet.meet_dialog[1].infop_check and db.storage[npc:id()].meet.meet_dialog[1].infop_check[1],--// table
    meet_dialog_infop_set            = db.storage[npc:id()].meet.meet_dialog[1] and db.storage[npc:id()].meet.meet_dialog[1].infop_set,   --// table
    meet_dialog2                     = db.storage[npc:id()].meet.meet_dialog[2],                                                           --// table
    meet_dialog_section2             = db.storage[npc:id()].meet.meet_dialog[2] and db.storage[npc:id()].meet.meet_dialog[2].section,    --// string имя диалога встречи
    meet_dialog_infop_check2         = db.storage[npc:id()].meet.meet_dialog[2] and db.storage[npc:id()].meet.meet_dialog[2].infop_check,--// table
    meet_dialog_infop_set2           = db.storage[npc:id()].meet.meet_dialog[2] and db.storage[npc:id()].meet.meet_dialog[2].infop_set,   --// table
    meet_syndata                     = db.storage[npc:id()].meet.syndata,                   --// table
    
    ---------------------------------------------------------------------------------------------
    section_logic           = db.storage[npc:id()].section_logic,                              --// string имя секции логики
    ---------------------------------------------------------------------------------------------
    loaded_section_logic    = db.storage[npc:id()].loaded_section_logic,                       --// string имя секции логики
    ---------------------------------------------------------------------------------------------
    active_section          = db.storage[npc:id()].active_section,                             --// string имя активной секции логики
    ---------------------------------------------------------------------------------------------
    loaded_active_section   = db.storage[npc:id()].loaded_active_section,                      --// string имя активной секции логики
    ---------------------------------------------------------------------------------------------
    active_scheme           = db.storage[npc:id()].active_scheme,                              --// string тип активной  схемы логики walker\camper\remark и т.д
    ---------------------------------------------------------------------------------------------
    gulag_name              = db.storage[npc:id()].gulag_name,                                 --// string  - имя гулага NPC
    ---------------------------------------------------------------------------------------------
    loaded_gulag_name       = db.storage[npc:id()].loaded_gulag_name,                           --// string  - имя гулага NPC
    ---------------------------------------------------------------------------------------------
    loaded_ini_filename     = db.storage[npc:id()].loaded_ini_filename,                         --// string  - имя файла логики
    ---------------------------------------------------------------------------------------------
    ini_filename            = db.storage[npc:id()].ini_filename,                                --// string  - имя файла логики
    ---------------------------------------------------------------------------------------------
    stype                   = db.storage[npc:id()].stype,                                        --// number - тип схемы логики  0-4 из файла modules
    ---------------------------------------------------------------------------------------------
    zoneguard               = db.storage[npc:id()].zoneguard,                                   --// видимо поле для охранников - тип значения неизвестен
    }
    return tMgr[type]
end

 

 

Смысловую суть полей можно понять обратившись к файлам xr_схема.script - именно в них и происходит заполнение storage.

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

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

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

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