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

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

*Shoker*, ты хотел сохранять в файл(текстовый и тп) свои переменные, и делать название файла таким же, как и название сейва?

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

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

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

Viнt@rь, там проблема не с сохранением и последующим чтением имени доп. файла, а с тем, как определить это имя. Есть 2 категории сэйвов, для которых сделать это затруднительно - квиксэйвы пользователя и автосэйвы, которые происходят при переходе на другую локацию (после диалога "вы уверены, что хотите перейти?..").

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

Kirgudu, нет никакой проблемы, если, как и говорит Viнt@rь, при создании сохранения запоминать эксклюзивное имя для "своего" доп.файла и, при загрузке считывать это имя, и соответственно из него все необходимое.

Однако, пора прекращать мусолить эту тему, тем более сам автор вопроса уже пошел по правильному пути (ИМХО), т.е. избрав путь хранить все в одном файле - самом сэйве игры.

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

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

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

Впрочем, действительно, раз нет решения, то и обсуждать нечего.

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

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

 

P.S.

Учитывая, что все же для некоторых вопрос остался открытым, о чем говорят слова из ЛС:

...никто так и не привёл в теме ни одного примера, как можно отделить друг от друга всего два из общего количества типов сэйвов: квик по клавише F6 и автосэйв после отрабатывания диалога смены локации (в отличие от любого другого автосэйва, он так же, как и квиксэйв, не запускается из доступных скриптов консольной командой. ... Только общие слова. Тоже своего рода шоры, только с другой стороны, не находишь? А в результате обменялись в теме недоказанными мнениями.
Попробуем все же досказать недосказанное или недочитанное ;-)

Имеется три основных момента:

1. Метод вызова: Все(!) сэйвы могут быть следующих типов:

1) Квик-сэйв (quicksave) - сохранение, которое создается при нажатии горячей кнопки, забинденной на это действие (обычно <F6>).

2. Штатный сэйв (nameFile.sav) - сохранение, которое создается через вызов меню и задания желаемого игроком имени.

3) Штатный авто-сэйв (autosave) - сохранение, которое создается при переходе актора на другую локацию.

При чем, это может быть как после "диалога смены локации", т.е. согласия игрока на переход, так и без оного, т.е. если переход имеет своим свойством silent_mode = 1 (без подтверждения).

 

Особняком стоят еще два типа:

4) Движковый авто-сэйв (autosave) - сэйв, который создается автоматически через определенное время непрерывной игры, что задается параметром autosave_interval.

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

"save my_save.sav".

 

2. Движковый, скриптовой или консольный:

Легко увидеть, что вышеназванные 1) и 4) имеют движковую природу вызова, 5) - консольную, остальные - вызываются скриптами.

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

Для штатных авто-сэйвов легко определить в методе биндера актора то, что актор собрался переходить на другую локацию и это и будет однозначным фактом того, что создается именно autosave.sav. Вот тут как раз и надеты шоры у Kirgudu..

 

3. Сохранение с прерыванием игры или без:

Сохранения могут создаваться с продолжением игры, т.е. без ее прерывания и при выходе из игры.

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

 

Итого в свете вопроса и недопоняток из цитаты выше - можно дать некоторые пояснения:

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

2. Квик-сэйв и движковый авто-сэйв отлавливаются тоже достаточно однозначно.

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

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

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

quicksave_2012_11_14__18_50.sav и quicksave_mod_2012_11_14__18_50.sav.

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

3. Ну и остался по сути последний "ручной" вариант создания сэйва игроком из консоли.

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

 

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

 

 

На этом, наверное, можно закрыть эту тему. Если же у кого-то остались конкретные вопросы "а как это сделать?" - то и говорить нужно о конкретном, а не об общем.

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

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

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

Очередное напоминание очередному 'нечитателю', но "писателю":

Куда задавать вопрос?[/b]":']

1. Поисковиком или иначе ищем - а не задавался ли подобный вопрос и не давался ли уже ответ(ы).

2. Читаем шапки топиков и по рекомендованным ссылкам просматриваем ФАКи, статьи и т.п.

3. Если вопрос по наличию или использованию функций/методов -> "Справочник по функциям и классам" + lua_help.script

4. Если вопрос по типичным функциям Lua -> "Язык Lua. Общие вопросы программирования"

5. Если вопрос типа "а как сделать/что означает/...?" -> "Ковырялка" соответствующей версии игры ТЧ/ЧН/ЗП

6. Если вопрос по конкретным игровым скриптам,алгоритмам или их заготовкам,черновикам, проблемам скриптов - этот топик.

... по тектурам, моделям, перл-скриптам, SDK и т.д. -> тематические топики.

 

Примечание: Адресные или личные вопросы (к конкретным адресатам) и "спасибки" -> ЛС

 

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

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

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

Прошу не пинать за нубские вопросы, скриптинг только осваиваю.

Вопрос по level.map_add_object_spot() и level.map_add_object_spot_ser(). Собственно исходя из справочной инфы все понятно, но такие нюансы:

В ЗП для отображения меток на объектах используется именно level.map_add_object_spot в pda.script (функция fill_primary_objects()), которая берет список объектов из таблицы и как я понял, апдейтится постоянно. Собственно почему нельзя было один раз в начале игры проставить все метки level.map_add_object_spot_ser? Это связано с ресурсами и производительностью?

Просто с заполнением новых локаций что будет экономней для ресурсов - проставить те-же 10-20 меток один раз вызвав level.map_add_object_spot_ser() или раздувать таблицу в pda.script?

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

Clayman, все же прежде чем задавать подобный вопросы стОит получше освоить "скриптинг", дабы не задавать преждевременных вопросов по вырванным кускам из контекста алгоритмов...

1. В ЗП для установки меток на объекты используется не только указанная тобою функция fill_primary_objects в pda.script.

2. Ты не правильно понял, точнее не дочитал алгоритм, и соответственно сделал неверные выводы о "постоянном апдейте" функции fill_primary_objects.

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

Т.о. в скриптах разработчики и сделали именно однократный вызов функции и установку меток, т.е. с'экономив ресурсы, о чем ты и переспрашиваешь.

"Раздувать" ли таблицу в pda.script - решать конечно же тебе, можно сделать и по-своему. Важно учесть момент установки меток, дабы сам объект успел появиться в игре, и первый апдейт актора тут как раз вполне подходит.

 

 

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

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

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

Вот кусок кода из ТЧ(1.004)

local ini = system_ini()

local weather = level.get_weather() -- тип погоды
local weather_sect = ini:r_string("weathers", weather) -- секция погоды, соответствующая типу

В ЧН работать не хочет, вылет...

Попробовал заменить на такой код:

local ini = ini_file("game.ltx")
local weather = utils.cfg_get_string(ini, level.name(), "weathers", db.actor, false, "", "[default]")
local weather_sect = ini:r_string("weathers", weather) -- секция погоды, соответствующая типу

Тоже будет вылет(через раз), иногда загружается игра.

Вот лог вылета:

Клиент: Синхронизация...

* phase time: 9 ms

* phase cmem: 221717 K

* [win32]: free[3093848 K], reserved[108356 K], committed[992036 K]

* [ D3D ]: textures[364135 K]

* [x-ray]: crt heap[221717 K], process heap[8541 K], game lua[92729 K], render[185 K]

* [x-ray]: economy: strings[15913 K], smem[1050 K]

! Cannot find saved game ~:ogsm_cleaner_release_wpn_mp51258

* Log file has been saved successfully!

! Can't find texture 'tree\tree_fuflo'

* MEMORY USAGE: 271197 K

* End of synchronization A[1] R[1]

 

FATAL ERROR

 

[error]Expression : fatal error

[error]Function : CInifile::r_section

[error]File : E:\priquel\sources\engine\xrCore\Xr_ini.cpp

[error]Line : 443

[error]Description :

[error]Arguments : Can't open section 'weathers'

 

 

stack trace:

 

 

Так вот вопрос, как заставить его работать в чн?

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

Старлей,

1. В ТЧ нет упомянутых тобою строк, по крайней мере в level_weathers.script, на котором и построен погодный менеджер. Очевидно у тебя некий "погодный" мод под ТЧ и, ты просто напросто пытаешься "сшить" абсолютно несовместимые строки.

2. Строка: local weather = utils.cfg_get_string(ini, level.name(), "weathers", db.actor, false, "", "[default]")

вычитывает из погодных конфигов погодную секцию типа: sect_default_weather (ТЧ) иль sect_marsh (ЧН), т.е. возвращает именно из секции [weathers] запрошенную секцию для конкретного уровня.

Исходя из логики, можно предположить, что эта секция и будет запрашиваемой в 3-ей строке weather_sect.

Твоя же строка: local weather_sect = ini:r_string("weathers", weather). по сути пытается запросить повторно из той же самой секции (weathers) нечто, но уже не по имени уровня, а по ... некоей полученной из игры погоде - результат очевиден.

 

Не буду далее гадать, т.к. нет информации.

Даже если в 3-ей строке простое присвоение: local weather_sect = weather , позволит тебе избавиться от текущего вылета этого куска кода - скорее всего ты далее опять получишь ошибку, но по другой причине/строке.

Тебе требуется разбираться с твоим "погодным" модом и адаптировать его под ЧН, т.к. погодные конфиги ТЧ и ЧН (да и сами менеджеры) все же различны.

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

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

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

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


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

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

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

 

Мне что-то казалось, что бокс от кости тоже скрывается. Впрочем, я не проверял.

 

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

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

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

 

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

malandrinus, я уже пробовал так делать. Если будет мягкая привязка у модели, то все равно будет стяжка фейсов к нулевым координатам. Если же грубая привязка, то будет видна щель между костями. Я много как пробовал, но выход нашел только этот. Хотя он и не до конца хорош, скорее как прототип.

 

LL_SetBoneVisible, к сожалению, действует только на визуальную составляющую, на коллизийный бокс никакого влияния не оказывает.

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

SkyLoader,

учитывая, что обсуждение "костей" уже давно оторвалось от сути и цели заданного вопроса (#4809), и никоим образом уже не относится к теме топика, предлагаю дальнейшее вести в более подходящих топиках, например, "Редактирование движка X-Ray" или "X-Ray extensions".

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

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

За'use'в поиск в данной теме нашел, что данный вылет:

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:

 

 

при спавне вертолета, происходит, т.к. " При спавне вертолёта через скрипт, обязательно требуется перепаковка net_packet, с переназначением параметров:"

skeleton_name = idle
startup_animation = idle

 

Для спавна вертолета я использую такую функцию:

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 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(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 = "vehicles\\helicopter\\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

 

 

Так вот подскажите, что сюда добавить, чтобы устанавливолось startup_animation = idle?

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

Старлей, в приведенной тобою функции спавна вертушки function heli(...) уже все есть, т.е. строка

cse_alife_helicopter__unk1_sz = "idle"

как раз и задает(изменяет) в нет-пакете значение параметра startup_animation = idle, просто для переменной использовано иное имя, которое ты можешь заменить своим более понятным.

Примечание: При спавне вертолетов желательно объекту задавать и параметр engine_sound (он у тебя также задается), в котором прописан звук двигателей (или '$no_sound'). Путь к звуковому файлу зависит от версии игры (ТЧ или ЧН) или от мода. У тебя прописан "для ЧН".

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

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

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

Не совсем. С одной стороны, причина была в изменениях, внесенных в скрипт респавнеров. Баг "вылечил" тем, что сделал наличие db.actor обязательным условием, что исключило слишком ранний скриптовый спавн, а именно - ДО той стадии, на которой метод on_register будет вызван для всех обЪектов, загруженных из all.spawn.

С другой стороны, любой скрипт, в котором до этой стадии будет вызван скриптовый спавн какого-либо обЪекта, вернёт проявление бага.

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

Когда-то давно в НС появился "ПДА" для хранения переменных, не лезущих в pstor актору (netpacket_pda_binder.script)

в числе прочего там есть такое:

function init(obj)
   local new_binder = my_binder(obj)
   obj:bind_object(new_binder)
end

class "my_binder" (object_binder)
function my_binder:__init(obj) super(obj)
end

 

При переходе в онлайн этого самого netpacket_pda дергаются последовательно *:__init(), init(), *:reload, ну и далее по тексту.

Но КАК ? В смысле, netpacket_pda_binder.init() кем вызывается вот в таком-то вот порядке ?

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

Dennis_Chikin, объектом к которому "прикручен" биндер. Нет, вызываются методы конечно движком, но, так сказать, виновник этого - объект. В общем вот здесь всё весьма подробно расписано: >>ClicK Me<<.

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

Dennis_Chikin, функция netpacket_pda_binder.init() вызывается в том случае, если в конфиге секции объекта (например для device_pda) будет прописан параметр:

script_binding = netpacket_pda_binder.init

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

Ну а далее, последовательность вызова движком методов самого биндера можно подсмотреть в xr_motivator.script, где сами разрабы оставили нам комменты:

порядок вызова методов биндера:

reload

reinit

load

net_spawn

Примечание: Метод 'load' будет вызываться только для объекта(ов) уже сохранявшегося в игре (если был save), т.е. при первом спавне объекта в игру этот метод не вызывается.

 

Примечание 2: ИМХО, метод с хранением "излишних" данных в КПК или "флешке" устарел и имеет больше недостатков, чем преимуществ по сравнению с уже известным методом хранения в специальном технологическом серверном объекте (se_custom_storage). Подробности такого метода (by malandrinus) и наработки по скриптам были рассмотрены около года назад в теме "Язык Lua. Общие вопросы программирования".

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

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

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

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

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

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

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

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

Войти

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

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

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