Модостроение. Общие вопросы и ответы
|
|
denis2000 | Дата: Сб, 15.06.2013, 11:51 | Сообщение # 1 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Помощь тем кто хочет знать больше о игре и модах Если у вас появились вопросы по модостроению в игре S.T.A.L.K.E.R. Задавайте их в этой теме - умные головы, модосторители и просто разбирающиеся в программировании люди вам ответят.
Много интересного материала здесь (wiki), Lua_help.script, Help из SDK 0.7
Сборник модостроения ЗП v10.10.11 (автор: XOBAH): *.CHM, *.HTML [cut noguest=Если у вас не открывается файл CHM]Если у вас не открывается файл: 1. Запустите [Пуск]=>[Выполнить] (либо хот-кей [WIN]+[R]) 2. Введите команду (без кавычек) "regsvr32 %windir%\system32\hhctrl.ocx" 3. Если вылезло окно об успешном завершении вы все сделали правильно и можете перезагружать компьютер (а может и не надо) Также: файлы МОГУТ не открываться если в пути к файлу есть: символы кириллицы, "_", "#" Также: есть не стандартные программы-просмоторщики CHM файлов. Например: FBReader[/cut] [cut=Где найти лог игры после вылета]Что такое LOG ошибки, и как мне его найти? Это система отладки происходивших вылетов, которая подается игрой в форме текста, хотя не всегда. Для того чтоб найти LOG необходимо зайти вот сюда:
В Win хр лог находится:
C:\Documents and Settings\All Users\Документы\S.T.A.L.K.E.R. - Зов Припяти\logs
Затем открываете первый файл в формате TXT, и в нем отбираете с низу 25 строчек. После кидаете эти 25 строчек в сообщение на форум.
В Win7 лог находится C:\Users\Public\Documents\S.T.A.L.K.E.R. - Зов Припяти\logs
Путь к папке с логом можно найти открыв файл fsgame.ltx который находится в корневой директории ЗП, за это отвечает строка: ... $app_data_root$ = true | false| $fs_root$| users\(тут мы указываем что папка пользователя, будет хранится рядом с Fsgame.ltx) ... $logs$ = true| false| $app_data_root$| logs\(а тут мы указываем что в папке пользователя, в подпапке Logs будут храниться наши логи) ... [/cut][cut=Получение более подробной информации о вылете (ХОВАН)] Открываем файл _g.script и ищем такую функцию: function abort(fmt, ...) Там есть заккомментированная строчка "--error_log(reason)", ее и надо расскомментировать, должно получиться вот так: Код function abort(fmt, ...) local reason = string.format(fmt, ...) error_log(reason) end Вот для примера два одинаковых вылета, первый с функцией по умолчанию, второй - с поправленной функцией
Первый: Код Expression : !m_error_code Function : raii_guard::~raii_guard File : D:\prog_repository\sources\trunk\xrServerEntities\script_storage.cpp Line : 748 Description : ....a.l.k.e.r. - Зов Припяти\gamedata\scripts\_g.script:478: bad argument #2 to 'format' (string expected, got nil) Второй: Код Expression : 0 Function : ErrorLog File : D:\prog_repository\sources\trunk\xrServerEntities\script_engine_script.cpp Line : 49 Description : 'Attempt to read a non-existant string field 'path_walk' in section 'walker@mechanic' [/cut]
Перед тем, как задать вопрос в этой теме, прочтите все предыдущие страницы, статьи в wiki по ссылке из шапки и соседнюю тему "Курс молодого бойца", возможно Ваш вопрос уже рассматривался.
Если произошел вылет - выкладываем лог! Вопрос ставим четко, не забываем указывать версию игры, установленные моды их версии, установленные фиксы модов и подробно ваши правки. Помните чем подробнее вопрос, тем точнее ответ.
Посты, для которых есть свои категории, из этой темы будут удаляться или перемещаться в соответсвующую тему. Персональных извещений в ЛС о переносе\удалении поста не будет, ищите сами. Учитывайте, что в системах Ucoz тема не обновляется в статистике при переносе поста. Посты, написанные здесь-же после переноса, будут расцениваться как кросспостинг, со всеми вытекающими
[cut noguest=Первый юбилей нашей темы] Здравствуйте господа модостроители, и все так или иначе причастные к этому. Нашей теме исполнился 1 год. От души поздравляю Всех Вас дорогие друзья, творческих успехов. Хочу так же выразить отдельную благодарность denis2000 и ХОВАН. tracker 23.06.11
[/cut]
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
denis2000 | Дата: Ср, 10.09.2014, 20:05 | Сообщение # 616 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Цитата Ay49Mihas ( ) Я не знаю, как это сделать, но подозреваю, что можно. Можно и вам подсказали путь, как это сделать: Спавните, разбираете нет пакет серверного объекта, меняете параметры, пишите в пакет серверного объекта все изменения. Алгоритм тот же, что и при создании рестриктора.
И добавили: Готовую функцию, я думаю, вряд ли кто вам выдаст. Ну, если только кто-то это уже делал и захочет с вами поделиться готовым решением.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
Ay49Mihas | Дата: Ср, 10.09.2014, 22:01 | Сообщение # 617 |
Полевой исследователь
Ученые сталкеры
Сообщений: 218
| Цитата denis2000 ( ) Можно и вам подсказали путь, как это сделать При всём уважении, но спрашивал я не это. Пакет разбираю, ставлю свои параметры, это не проблема. Код function create_smartcover(name,radius,x,y,z,lv,gv) if z==nil and lv==nil and gv==nil then se_obj=alife():create("smart_cover",level.vertex_position(x),x,y) else se_obj=alife():create("smart_cover",vector():set(x,y,z),lv,gv) end setup_smartcover(se_obj,radius,name) end function setup_smartcover(se_obj,radius,name) local packet = net_packet() se_obj:STATE_Write(packet) local game_vertex_id = packet:r_u16() local distance = packet:r_float() local direct_control = 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 spawn_story_id = packet:r_s32() local shape = r_shape(packet) local description = packet:r_stringZ() local hold_position_time = packet:r_s32() local enter_min_enemy_distance = packet:r_s32() local exit_min_enemy_distance = packet:r_s32() local is_combat_cover = packet:r_u8() local MP_respawn = packet:r_u8() local last_description = packet:r_stringZ() local num_loopholes = packet:r_u8() local loopholes = {} if num_loopholes > 0 then for i=1,num_loopholes do loopholes[packet:r_stringZ()] = packet:r_u8() end end description = "animpoint_stay_table" hold_position_time = 0 enter_min_enemy_distance = 15 exit_min_enemy_distance = 10 MP_respawn = 1 last_description = "animpoint_stay_table" num_loopholes = 1 loopholes = {} loopholes["animpoint_stay_table"] = 1 shape = {} shape.count = 1 shape.shapes = {} shape.shapes[1] = {} shape.shapes[1].type = 0 shape.shapes[1].center = vector():set(0,0,0) shape.shapes[1].radius = radius packet:w_u16(game_vertex_id) packet:w_float(distance) packet:w_s32(direct_control) packet:w_s32(level_vertex_id) packet:w_s32(object_flags) packet:w_stringZ(custom_data) packet:w_s32(story_id) packet:w_s32(spawn_story_id) w_shape(packet, shape) packet:w_stringZ(description) packet:w_s32(hold_position_time) packet:w_s32(enter_min_enemy_distance) packet:w_s32(exit_min_enemy_distance) packet:w_u8(is_combat_cover) packet:w_u8(MP_respawn) packet:w_stringZ(last_description) packet:w_u8(num_loopholes) if num_loopholes > 0 then for k, v in pairs(loopholes) do packet:w_stringZ(k) packet:w_u8(v) end end se_obj:STATE_Read(packet, packet:w_tell() - packet:r_tell()) return sobj end Но дело в том, что создаётся анонимный смарткавер. Потом как к нему обращаться? Только через экземпляр объекта и соответственно только через скрипт на LUA? Я вообще думал заранее написать логику актора, чтобы он сидел в этом смарткавере во время анимпоинта. Но в этой логике надо указать имя смарткавера (cover_name = my_successful_cover). Вот это имя я и не могу в нетпакет запихать, и потому и спрашиваю, как мне решить эту проблему.
|
|
|
Эти 0 пользователя(ей) поблагодарили Ay49Mihas за это полезное сообщение: |
|
|
denis2000 | Дата: Чт, 11.09.2014, 10:03 | Сообщение # 618 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Цитата Ay49Mihas ( ) Пакет разбираю, ставлю свои параметры, это не проблема... ... имя я и не могу в нетпакет запихать, и потому и спрашиваю, как мне решить эту проблему. При всем уважении изменить Имя, класс или ид_объекта после его создания вы не можете! Даже через нетпакет! Имя и класс объекта задается при его создании, а ид_объекта присваевается движком в момент создания.
Если вы создаете объект коммандой alife():create(<Имя объекта>, p_position, p_lvertex_id, p_gvertex_id), то с каким именем будет создан объет вам априори известно! Вы это можете проверить считав имя созданного вами объекта.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
Ay49Mihas | Дата: Чт, 11.09.2014, 13:05 | Сообщение # 619 |
Полевой исследователь
Ученые сталкеры
Сообщений: 218
| Цитата denis2000 ( ) Если вы создаете объект коммандой alife():create(<Имя объекта>, p_position, p_lvertex_id, p_gvertex_id), то с каким именем будет создан объет вам априори известно! А я почему-то считал, что имя-объекта это содержимое поля section_name, а не name. Получается, это не так? Спасибо за инфу, пороюсь более тщательно.
|
|
|
Эти 0 пользователя(ей) поблагодарили Ay49Mihas за это полезное сообщение: |
|
|
denis2000 | Дата: Чт, 11.09.2014, 19:13 | Сообщение # 620 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Нет имя объекта в all.spawn задается параметром name, а section_name - это имя секции из которой берутся базовые параметры объекта. При спавне через скрипт имя формируется из имени секции: Код obj:name() = obj:section_name()..tostring(obj.id) то есть имя секции плюс ид_объекта, под таким именем смарт ковер и будет зарегистрирован в таблице se_smart_cover.registered_smartcovers, откуда потом успешно взят скриптом xr_animpoint.script который и отвечает за работу НПС на анимпоинте. А значит вам придется формировать логику НПС динамически в скрипте, ссылаясь на анимпоинт по имени obj:name() или obj:section_name()..tostring(obj.id) (см. gulag_general.script), либо в файле se_smart_cover.script вместо: Код registered_smartcovers[self:name()] = self прописать: Код if self:name() ~= self:section_name()..tostring(self.id) then registered_smartcovers[self:name()] = self else registered_smartcovers[self:section_name()] = self registered_smartcovers[self:name()] = self end И вместо Код registered_smartcovers[self:name()] = nil прописать Код if self:name() ~= self:section_name()..tostring(self.id) then registered_smartcovers[self:name()] = nil else registered_smartcovers[self:section_name()] = nil registered_smartcovers[self:name()] = nil end Тогда к смарту созданному динамически можно будет обратиться и по имени секции (в этом случае уникальность имени секции будет вашей задачей). Или в конце концов прописать созданному смарт коверу стори_ид и дополнить скрипт xr_animpoint.script на предмет работы не только по имени, но и пори_ид. Можно также использовать схему remark там вообще никаких точек или смарт коверов не нужно создавать. Зато проиграть анимацию и звук пожалуста. Летай себе камерой над ГГ. Вариантов масса!
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
makdm | Дата: Чт, 11.09.2014, 19:58 | Сообщение # 621 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| Ay49Mihas, развиваю идею Дениса, можно сделать так. В функции function create_smartcover(name,radius,x,y,z,lv,gv) в конце перед setup_smartcover(se_obj,radius,name) прописать
xr_animpoint.actor_smart_cover = se_obj:section_name()..tostring( se_obj.id )
А в файле xr_animpoint.script сначала перед class "evaluator_need_animpoint" (property_evaluator) прописать actor_smart_cover = nil, а затем в функции function set_scheme(npc, ini, scheme, section, gulag_name) перед end прописать
if npc:section() == "actor_visual_stalker" and actor_smart_cover ~= nil then st.cover_name = actor_smart_cover actor_smart_cover = nil end
Тогда в логике параметр cover_name вообще лишний.
Терпение...... И все получится!
|
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
Ay49Mihas | Дата: Пт, 12.09.2014, 07:22 | Сообщение # 622 |
Полевой исследователь
Ученые сталкеры
Сообщений: 218
| denis2000, makdm, спасибо за развёрнутое описание. Но, видимо, лучше всего тупо использовать схему remark, чтобы не вносить мега-изменений в глобальные механизмы функционирования всего. Дело в том, что фундаментальные знания у меня отсутствуют, тупо действую по аналогии, подсматривая уже готовые решения. Поэтому и использование схемы animpoint считал единственно возможным путём организации катсцены с участием актора.
Сообщение отредактировал Ay49Mihas - Пт, 12.09.2014, 07:23 |
|
|
Эти 0 пользователя(ей) поблагодарили Ay49Mihas за это полезное сообщение: |
|
|
suhar_ | Дата: Чт, 18.09.2014, 18:27 | Сообщение # 623 |
Бывалый
Пользователи
Сообщений: 106
| Может ли кто-то подсказать по плагину db-explorer для Total Commander? А именно, как пользоваться сей утилитой О_о Сам плагин поставил, но вот что с ним делать дальше и как откупорить db-архивы - не понятно.
Теперь db архивы можно открывать, как обычные (например zip) просто двойным щелчком мыши или ентером. denis2000
Благодарю.
Сообщение отредактировал suhar_ - Вс, 21.09.2014, 05:11 |
|
|
Эти 0 пользователя(ей) поблагодарили suhar_ за это полезное сообщение: |
|
|
Kosha | Дата: Чт, 18.09.2014, 18:52 | Сообщение # 624 |
Отмычка
Пользователи
Сообщений: 32
| Подскажите 1)Как сделать так что бы спасенные новички в ЧН (бродяга и еще один) по заданию волка не умирали при удалении ГГ от лагеря? 2)Можно ли сделать так что бы диалог появлялся только после вступления ГГ В определенную групировку (Например после вступления в сталкеры) в ЧН?
Заранее спасибо
|
|
|
Эти 0 пользователя(ей) поблагодарили Kosha за это полезное сообщение: |
|
|
denis2000 | Дата: Чт, 18.09.2014, 20:05 | Сообщение # 625 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Цитата Kosha ( ) Можно ли сделать так что бы диалог появлялся только после вступления ГГ В определенную групировку Конечно в диалоге пишешь: <precondition>скрипт.функция возвращающая true если ГГ в определенной группировке</precondition> Пример функции: Код function actor_in_dolg(actor, npc) for k,v in pairs(sim_board.get_sim_board().players) do if v.community_player == true and v.player_name == "dolg" then return true end end return false end
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
Kosha | Дата: Пт, 19.09.2014, 19:10 | Сообщение # 626 |
Отмычка
Пользователи
Сообщений: 32
| а как в ЧН можно заблокировать доступ к локаций? (Например, тот факт что в подземелья агропрома нельзя войти до сюжетного квеста), и как его потом разблокировать? (получил ключ например к поздземке и можешь входить-выходить)
|
|
|
Эти 0 пользователя(ей) поблагодарили Kosha за это полезное сообщение: |
|
|
makdm | Дата: Пт, 19.09.2014, 20:12 | Сообщение # 627 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| Kosha, в ЧН работают функции disable_level_changer и enable_level_changer из файла xr_effects.script Вот в логике рестриктора и происходит переключение при соблюдении необходимых условий. Поэтому переходы то закрываются, то открываются.
Терпение...... И все получится!
|
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
Kosha | Дата: Сб, 20.09.2014, 14:16 | Сообщение # 628 |
Отмычка
Пользователи
Сообщений: 32
| Почему при модификаций фн2000 на оптику х4 через некоторое время она слетает т.е. приближает как без модификаций? А так же она слетает если сначала поставить оптику х4 а потом другие модификаций Заранее спасибо
Сообщение отредактировал Kosha - Сб, 20.09.2014, 14:21 |
|
|
Эти 0 пользователя(ей) поблагодарили Kosha за это полезное сообщение: |
|
|
Kontro-zzz | Дата: Сб, 20.09.2014, 20:38 | Сообщение # 629 |
Сталкер
Пользователи
Сообщений: 206
| Цитата Kosha ( ) Почему при модификаций фн2000 на оптику х4 через некоторое время она слетает т.е. приближает как без модификаций? На ЧН это вроде просто баг. Зум фактор слетает на дефолтный для прицела.
GeForce™-450 GSO 1000_Mb. Windows-7 x64 Prof. ОЗУ 4,0 Гб.
|
|
|
Эти 0 пользователя(ей) поблагодарили Kontro-zzz за это полезное сообщение: |
|
|
suhar_ | Дата: Вс, 21.09.2014, 05:37 | Сообщение # 630 |
Бывалый
Пользователи
Сообщений: 106
| Возможно, что этот вопрос уже где-то разбирался, но в КМБ уроке по добавлению оружия этого не нашёл. Нужно ли где-то в конфигах\скриптах прописывать анимации нововведенного оружия? Т.е. у меня есть 2 набора файлов анимаций. Первый лежит по адресу - gamedata\meshes\dynamics\weapons\wpn_МоёОружие\wpn_МоёОружие_hud_animation.omf. Название файла по структуре совпадает с огф-моделью wpn_МоёОружие_hud.ogf в этой же папке. Возможно, что программа при поиске анимаций опирается на название модели, и прописывать его (этот файл с анимацией) не нужно. Поэтому и сомневаюсь. Второй набор здесь gamedata\anims\camera_effects\weapon\ и состоит из нескольких файлов со структурой названия МоёОружие_НазваниеДействия.anm/.anm1. Изучил оригинальную папку в ЗП и увидел, что для разного оружия набор этих файлов отличается. Например, для Абакана их 9, а для ПКМа всего один. Почему так? Ведь конфиг ПКМа (как и Абакана) использует полный набор из 9 уникальных (не заимствованный у других стволов) [cut=анимаций]anm_show = pkm_draw anm_hide = pkm_holster anm_idle = pkm_idle anm_idle_sprint = pkm_idle_sprint anm_idle_moving = pkm_idle_moving anm_shots = pkm_shoot anm_reload = pkm_reload anm_idle_aim = pkm_idle_aim anm_bore = pkm_idle_bore[/cut] в то время как файл всего один. Объясните пожалуйста. И нужно ли их (анимации из второго набора) где-то прописывать?
[cut=Лог вылета]Expression : pm->m_animations.size() Function : player_hud_motion_container::load File : D:\prog_repository\sources\trunk\xrGame\player_hud.cpp Line : 92 Description : motion not found [НазваниеАнимации] [/cut]
Сообщение отредактировал suhar_ - Вс, 21.09.2014, 05:52 |
|
|
Эти 0 пользователя(ей) поблагодарили suhar_ за это полезное сообщение: |
|
|
|