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

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

Всем доброго дня.

Установил на чистый ТЧ 1.0004 сборку "Внешнее хранилище" всеми уважаемого Artos. Лежит у меня давно, не вспомню откуда скачал - вот ссылка на нее http://rghost.ru/48630478. Выполнил все шаги установки по вложенной инструкции:

Использование:
1. Добавить в конфиги (например в system.ltx) секцию [custom_storage];
2. Добавить в конфиги файл-конфиг модуля нет-пакетов (m_netpk.ltx):
3. Скопировать se_stor.script m_netpk.script и m_helpers.script в папку скриптов игры.
4. Добавить новый класс CUST_ST <-> clsid.custom_storage в файл class_registrator.script;
5. Добавить в биндер актора коды вызова события "сохранение игры" или функцию сохранения хранилища;
6. Внести изменения в алгоритм сохранения и чтения данных в биндере актора (bind_stalker.script);

Кроме того, пунктом 7 добавил инициализацию модулей в _g.script о чем, кстати, в инструкции умалчивается.

function start_game_callback()
	printf	("start_game_callback called")
	task_manager.clear_task_manager()
	treasure_manager.clear_treasure_manager()
	xr_sound.clear_all_sound_object()
	dialog_manager.fill_phrase_table()	
	m_netpk.init() -- этот сразу подключил, есть инструкция к нему отдельная	
	se_stor.init() -- этот уже позже, по безнадёге, но не помогло
end

Сохранение с НИ рядом с Сидоровичем благополучно происходит и загружается, но стоит с ним перетереть и выйти за дверь, так при попытке сохраниться получаю вылет:

[error]Arguments     : LUA error: ...ograms\s.t.a.l.k.e.r\gamedata\scripts\se_stor.script:143: attempt to call field 'size' (a nil value)

Прошу поддержки как у автора, так и у всех, кто может пролить свет на правила пользования этим инструментом.

Заранее благодарен.

 

 

Ссылка на комментарий
Кто-нибудь знает, каким способом можно получить координаты расположения курсора на экране? Singapur22 делал это, вот ссылка на его журнал: http://www.stalker-portal.ru/plug.php?e=weblogs&m=page&id=17245 . Но мне этот способ не подходит, так как создаваемые статики "перекрывают" основное окно.
 

 

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

@boryan67, покажи 143-ю строчку скрипта (в Notepad++ например их видно)

Скорее всего ты забыл добавить функцию table.size(), которая считает кол-во элементов в таблице.

Кажется она сидит в m_helpers.script хотя точно не уверен, видимо ты его не до конца подключил. 
Так что или подруби её или перенеси её вручную в se_stor, поменяй название на какое нибудь table_size()
и в скрипте измени все вызовы. 

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

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

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

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

@boryan67, просто в данном комплекте в модуле m_helpers.script не хватает реализации глобальной функции size пространства имён table.
Добавь где-нибудь в модуле (например, в разделе expansion classes functionality) следующее:

function fGetSizeTable(tTbl)
	if type(tTbl) == 'table' then --/ не таблица?
		if next(tTbl) then --/ не пустая?
			local iCnt = 0
			for _,_ in pairs(tTbl) do
				iCnt = iCnt +1
			end
			return iCnt --/>
		end
	else
		printf("fGetSizeTable:arg(%s)=[%s]~NOT_table:<%s>", type(tTbl), tTbl, "Warning!")
	end
	return 0 --/>
end
if not table.size then
	table.size = this.fGetSizeTable
end

 


 

Изменено пользователем Kirgudu
  • Нравится 2
Ссылка на комментарий

@Kirgudu, добавил приведенный фрагмент, стало заметно лучше. Сохранения/загрузки происходят, но только пока что-либо в хранилище не поместили. После записи в хранилище сохранение происходит, но при загрузке вылет:

Arguments     : LUA error: ...ograms\s.t.a.l.k.e.r\gamedata\scripts\se_stor.script:184: attempt to call field 'size' (a nil value)

Та же хреновина, но теперь при загрузке. 

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

@boryan67, строка se_stor.script:184 - чисто информационная и ее стОило бы изначально или закомментировать или стереть, но раз уж попала в комплект, то вот временное решение:

а) Как уже дал подсказку Kirgudu в посте выше - добавить код для table.size . Или можно заменить в se_stor.script эти вызовы на m_netpk.table_size() .

б) Добавить в конце _g.script строку: prefetch("m_helper") --/#!# common functions 'expansion helper'

 

Немного позже выложу освеженный комплект...

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

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

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

@Artos, был бы премного благодарен за обновленный полнофункциональный комплект. Да, и не я один, думаю. Особенно важным для меня является сохранение во внешнем хранилище простых таблиц, о чем я уже в ЛС писал.

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

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

@boryan67, суть внешнего (точнее универсального) хранилища - сохранять все, что помещено в db.storehouse и восстанавливать при загрузках игры. Соответственно если помещать в эту таблицу свои "простые" таблички и/или другие "простые" данные - то никаких проблем не возникнет. В последней версии сохранять можно гораздо больше типов данных (помимо строк, чисел, таблиц, ... можно сохранять вектора, таймеры, ...) и если получится вырезать из общего мода - к вечеру/ночи дам полный вариант".

"Отрегулированность и надежность" данного метода (хранения) проверена уже годами на SIMBION'e и месяцами в LA (в несколько измененном виде). Однако замечу, что и надежность и оптимальность зависят от степени интегрированности кодов в весь скриптовой набор игры. В вышеуказанных модах все данные из пакета актора вынесены именно во внешнее хранилище, что исключило любые ошибки с переполнениями или невалидными данными. Т.о. если говорить о " зависимости успешности трудов многих людей за несколько лет" - то посоветую взглянуть все же на полный вариант использования хранилища. Если будет время - то дам два варианта: а) только хранилище с минимальными правками исходных кодов игры SoC и б) хранилище с рекомендованными расширениями. Второй вариант все же потребует работы головы и рук... ;-)

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

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

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

Мне нужно написать таймер, и сохранить его в pstor или пакет, пока не выходит, не подскажете рациональный способ?

 

 

local time = time_global()
function my_timer()
local delay = 300
if time_global()>time+delay*1000 then
 time=time_global()
 return true
   end
end
packet:w_u32(delay)
delay = reader:r_u32()
Ссылка на комментарий

Окей, начнём с того, что сохраняешь ты в сейв переменную delay, которая ВСЕГДА равна 300 вместо своего таймера timer.

Притом там где ты её сохраняешь она скорее всего вообще не доступна и равна nil, т.к находится внутри функции my_timer()

А закончим тем что этот таймер вообще бессмысленно сохранять потому что time_global() после перезагрузки начинает отчёт с нуля. Тебе тогда вместо time_global() нужно использовать game.time(), он ведёт отсчёт от начала новой игры. С ним возможно есть косяк с переполнением но тебе пока не стоит заботится об этой проблеме. 

local time = 0
 local delay = 300
 function my_timer()
  if time == 0 then
   --\\ Первый вызов этой функции
   time = game.time()
  else
   if game.time() > time+delay*1000 then
    time = game.time()
    return true
   end
  end
 end

packet:w_u32(time)
time = reader:r_u32()
Этот таймер начнёт свой отсчёт после первого вызова.

 

Опиши лучше подробней для чего тебе нужен таймер.

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

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

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

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

Условно говоря таймер мне нужен для, ну допустим, "умер один сталкер, запустили таймер на час игрового времени, и через час умер второй". Соответственно в этот час мы можем сохраниться/загрузиться.

 

Спасибо за пояснения, но(!) ранее в соседней теме критиковали game.time(), и высказывались в пользу game.get_game_time(). Как перевести таймер на метод game.get_game_time()? Просто хотелось бы сразу сделать как надо.

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

http://www.amk-team.ru/forum/index.php?showtopic=12753

В таком случаи найди здесь "Универсальные таймеры" и лучше используй их. 

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

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

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

Или я чего то не понял в работе этих функций в ЗП, или я чего то сломал, но:

применяя на сталкере best_enemy(), best_danger() и get_enemy() они практически всегда возвращают nil даже если я стою перед ним и он сажает очередь за очередью из автомата. Кто нибудь сталкивался с подобным? Есть ли универсальный и точный способ определить что сталкер сейчас находится в состоянии опасности? 

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

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

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

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

Всем привет, возникла проблема при спавне вертолета через скрипт в Чистом небе. С вероятностью 80% будет получен вылет:

* MEMORY USAGE: 317715 K
* End of synchronization A[1] R[1]

FATAL ERROR

[error]Expression : motion_ID.valid()
[error]Function : CKinematicsAnimated::ID_Cycle
[error]File : E:\priquel\sources\engine\Layers\xrRender\SkeletonAnimated.cpp
[error]Line : 208
[error]Description : ! MODEL: can't find cycle:
[error]Arguments : $editor


stack trace:

 

 

 

Функция спавна:

 

 

function heli(section,posx,posy,posz,lvid,gvid,logic)
local obj = alife():create(section,vector():set(posx,posy,posz),lvid,gvid)
local packet = net_packet()
obj:STATE_Write(packet)

-- свойства cse_alife_object
local game_vertex_id = packet:r_u16()
local cse_alife_object__unk1_f32 = packet:r_float()
local cse_alife_object__unk2_s32 = packet:r_s32()
local level_vertex_id = packet:r_s32()
local object_flags = packet:r_s32()
local custom_data = packet:r_stringZ()
local story_id = packet:r_s32()
local cse_alife_object__unk3_s32 = packet:r_s32()

-- свойства cse_visual
local model_visual = packet:r_stringZ()
local cse_visual__unk1_u8 = packet:r_u8()
-- свойства cse_motion
local motion_name = packet:r_stringZ()

-- свойства cse_ph_skeleton
local skeleton_name = packet:r_stringZ()
local cse_ph_skeleton__unk1_u8 = packet:r_u8()
local cse_ph_skeleton__unk2_u16 = packet:r_u16()

-- свойства cse_alife_helicopter
local cse_alife_helicopter__unk1_sz = packet:r_stringZ()
local engine_sound = packet:r_stringZ()

--устанавливаем логику
custom_data = "[logic]\ncfg = scripts\\heli\\"..logic..".ltx"

-- теперь заполняем нужные параметры
-- свойства cse_alife_object
packet:w_begin(game_vertex_id)
packet:w_float(cse_alife_object__unk1_f32)
packet:w_s32(cse_alife_object__unk2_s32)
packet:w_s32(level_vertex_id)
object_flags = bit_not(5) -- ~5 = 0xfffffffa
packet:w_s32(object_flags)
packet:w_stringZ(custom_data)
packet:w_s32(-1)
packet:w_s32(cse_alife_object__unk3_s32)

-- свойства cse_visual
packet:w_stringZ(model_visual)
packet:w_u8(cse_visual__unk1_u8)

-- свойства cse_motion
packet:w_stringZ(motion_name)

-- свойства cse_ph_skeleton
skeleton_name = "idle"
packet:w_stringZ(skeleton_name)
packet:w_u8(cse_ph_skeleton__unk1_u8)
packet:w_u16(cse_ph_skeleton__unk2_u16)

-- свойства cse_alife_helicopter
cse_alife_helicopter__unk1_sz = "idle"
engine_sound = "alexmx\\helicopter"
packet:w_stringZ(cse_alife_helicopter__unk1_sz)
packet:w_stringZ(engine_sound)

-- считываем скорректированные параметры
packet:r_seek(0)
obj:STATE_Read(packet, packet:w_tell())


return obj
end

 

 

 

Также используется функция спавна пары этому вертолета:

 

 

function heli_copy(section,pos,lvid,gvid,id,logic)
--читаем данные из прототипа
local prototype = alife():object(id)
local packet1 = net_packet()
prototype:STATE_Write(packet1)

-- свойства cse_alife_object
local game_vertex_id1 = packet1:r_u16()
local cse_alife_object1__unk1_f32 = packet1:r_float()
local cse_alife_object1__unk2_s32 = packet1:r_s32()
local level_vertex_id1 = packet1:r_s32()
local object_flags1 = packet1:r_s32()
local custom_data1 = packet1:r_stringZ()

local obj = alife():create(section,pos,lvid,gvid)
local packet = net_packet()
obj:STATE_Write(packet)

-- свойства cse_alife_object
local game_vertex_id = packet:r_u16()
local cse_alife_object__unk1_f32 = packet:r_float()
local cse_alife_object__unk2_s32 = packet:r_s32()
local level_vertex_id = packet:r_s32()
local object_flags = packet:r_s32()
local custom_data = packet:r_stringZ()
local story_id = packet:r_s32()
local cse_alife_object__unk3_s32 = packet:r_s32()

-- свойства cse_visual
local model_visual = packet:r_stringZ()
local cse_visual__unk1_u8 = packet:r_u8()
-- свойства cse_motion
local motion_name = packet:r_stringZ()

-- свойства cse_ph_skeleton
local skeleton_name = packet:r_stringZ()
local cse_ph_skeleton__unk1_u8 = packet:r_u8()
local cse_ph_skeleton__unk2_u16 = packet:r_u16()

-- свойства cse_alife_helicopter
local cse_alife_helicopter__unk1_sz = packet:r_stringZ()
local engine_sound = packet:r_stringZ()

--устанавливаем логику
game_vertex_id = game_vertex_id1
level_vertex_id = level_vertex_id1
object_flags = object_flags1
if not logic then
custom_data = custom_data1
else
custom_data = "[logic]\ncfg = scripts\\heli\\"..logic..".ltx"
end

-- теперь заполняем нужные параметры
-- свойства cse_alife_object
packet:w_begin(game_vertex_id)
packet:w_float(cse_alife_object__unk1_f32)
packet:w_s32(cse_alife_object__unk2_s32)
packet:w_s32(level_vertex_id)
object_flags = bit_not(5) -- ~5 = 0xfffffffa
packet:w_s32(object_flags)
packet:w_stringZ(custom_data)
packet:w_s32(-1)
packet:w_s32(cse_alife_object__unk3_s32)

-- свойства cse_visual
packet:w_stringZ(model_visual)
packet:w_u8(cse_visual__unk1_u8)

-- свойства cse_motion
packet:w_stringZ(motion_name)

-- свойства cse_ph_skeleton
skeleton_name = "idle"
packet:w_stringZ(skeleton_name)
packet:w_u8(cse_ph_skeleton__unk1_u8)
packet:w_u16(cse_ph_skeleton__unk2_u16)

-- свойства cse_alife_helicopter
cse_alife_helicopter__unk1_sz = "idle"
engine_sound = "alexmx\\helicopter"
packet:w_stringZ(cse_alife_helicopter__unk1_sz)
packet:w_stringZ(engine_sound)

-- считываем скорректированные параметры
packet:r_seek(0)
obj:STATE_Read(packet, packet:w_tell())


return obj
end

 

 

 

В связи с этим вопрос какова причина вылета?

P.S. Используется AI-вертолетов, во время спавна вертолеты будут переведены в online(спавнятся недалеко от ГГ).

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

Ты должен указать вертолёту его анимацию, параметр motion_name

По умолчанию он прописан как $editor, поэтому происходит вылет. 
Тебе нужно тут:
-- свойства cse_motion
packet
:w_stringZ(motion_name)

Указать название анимации, кажется idle чтобы просто висел.

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

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

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

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

Пробовал, будет получаться вылет, какой не помню, со ссылкой на 431 строчку. При загрузке квик-сэйвов, поэтому был вынужден отказаться, обновленный m_netpk вышел недавно насколько я знаю.

*Shoker*

Сейчас попробую.

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

@Старлей, конечно можно пробовать и кое-как заставить работать то, о чем пишешь, но вероятность будет отлична от 100%, т.к. в работе с net_packet'ами в ЧН и ЗП есть нюанс и его требуется учитывать:
При получении чистого пакета: local packet = net_packet() - из-за особенностей движка в ЧН и ЗН позиция записи может быть установлена не на начало и последующая запись в такой "чистый" пакет может происходить НЕ с начала. Далее, после записи своих данных, ты устанавливаешь позицию чтения в начало: packet:r_seek(0- т.о. при записи параметров в объект могут попасть "лишние" байты, присутствовавшие в пакете, исказив все параметры...
Чтобы этого не происходило, требуется при получении "чистого" пакета принудительно выставлять позицию записи полученного нового нет-пакета в начало (т.е. принудительно "очищать" его). 

local packet = net_packet() --/ получение "чистого" пакета
packet:w_begin(0) --/ установка: начальная позиция записи данных (+2)
obj:STATE_Write(packet)
...
packet:r_seek(2) --/ установка: читать 'с начальной позиции записанных данных' (+2)

- тут из-за отсутствия метода w_seek(number) используется метод w_begin(0), который устанавливает позицию записи в начало и прописывает 2 байта, которые при чтении следует пропустить: r_seek(2).

(обо всем этом не раз уже писалось, хотя и давно...)

Примечание: Актуальная версия m_netpk автоматически все это делает и заодно автоматом изменяет и критически важные дефолтные параметры (motion_name, startup_animation) и устанавливает флаги, остается, если требуется, добавить/изменить 'engine_sound'.

 

P.S. @Старлей,  твой вылет (MODEL: can't find cycle) связан с параметром 'startup_animation', который аналогично 'motion_name' нужно устанавливать в 'idle'.

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

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

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

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

*Shoker*

3/6 тестов прошли успешно, правда тут такая фишка с тестами...

Тест 1: Запускаю сталкер, загружаю сейв, пытаюсь заспавнить - все хорошо спавнится.

Тест 2: продолжаю Тест 1, не выходя из игры, загружаю этот же сейв - получаю вылет, указанный выше.

Тест 3: запускаю заново сталкер, загружаю тот же сейв, вертолеты спавнятся на ура.

Тест 4: опять же не выходя из игры, загружаю этот же сейв, при спавне вылет

Тест 5 и 6 в том же духе.

 Artos

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

 

 

===============

 Artos

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

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

@Старлей, это уже начинаются погадалки...  :angry:

Если вылет при перезапуске сэйва (не выходя из игры) связан с: MODEL: can't find cycle - то тебе ясно расписано что требуется изменить параметр 'startup_animation' (помимо других) в момент спавна вертушки. Если вылет иной, то и приводи строки лога, в которых пишется о причине ошибки, дабы не гадать на кофейной гуще.

Вполне вероятно, что у тебя проблемы с деревом диалога(ов), которое сохраняется со "старой" игры (НЕ пересоздается заново), т.к. треды диалогов обновляются/пересоздаются только при выходе из игры в ОС и загрузке сэйва. Проверяй прекондишены и пр. для твоих диалогов...

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

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

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

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

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

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

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

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

Войти

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

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

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

AMK-Team.ru

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