Войти на сайт Регистрация Лента форума Пользователи Правила сайта Поиск по форуму
Модератор форума: denis2000, FantomICW  
Модостроение. Общие вопросы и ответы
denis2000Дата: Сб, 15.06.2013, 11:51 | Сообщение # 1
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Помощь тем кто хочет знать больше о игре и модах

Если у вас появились вопросы по модостроению в игре 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]
 
denis2000Дата: Ср, 10.09.2014, 20:05 | Сообщение # 616
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Цитата Ay49Mihas ()
Я не знаю, как это сделать, но подозреваю, что можно.

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

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


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
Ay49MihasДата: Ср, 10.09.2014, 22:01 | Сообщение # 617
Полевой исследователь
Ученые сталкеры
Сообщений: 218
Награды: 9
Репутация: [ 83 ]

Цитата 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). Вот это имя я и не могу в нетпакет запихать, и потому и спрашиваю, как мне решить эту проблему.
 
denis2000Дата: Чт, 11.09.2014, 10:03 | Сообщение # 618
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Цитата Ay49Mihas ()
Пакет разбираю, ставлю свои параметры, это не проблема...
... имя я и не могу в нетпакет запихать, и потому и спрашиваю, как мне решить эту проблему.

При всем уважении изменить Имя, класс или ид_объекта после его создания вы не можете! Даже через нетпакет!
Имя и класс объекта задается при его создании, а ид_объекта присваевается движком в момент создания.

Если вы создаете объект коммандой alife():create(<Имя объекта>, p_position, p_lvertex_id, p_gvertex_id), то с каким именем будет создан объет вам априори известно! Вы это можете проверить считав имя созданного вами объекта.


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
Ay49MihasДата: Чт, 11.09.2014, 13:05 | Сообщение # 619
Полевой исследователь
Ученые сталкеры
Сообщений: 218
Награды: 9
Репутация: [ 83 ]

Цитата denis2000 ()
Если вы создаете объект коммандой alife():create(<Имя объекта>, p_position, p_lvertex_id, p_gvertex_id), то с каким именем будет создан объет вам априори известно!

А я почему-то считал, что имя-объекта это содержимое поля section_name, а не name. Получается, это не так? Спасибо за инфу, пороюсь более тщательно.
 
denis2000Дата: Чт, 11.09.2014, 19:13 | Сообщение # 620
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Нет имя объекта в 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 там вообще никаких точек или смарт коверов не нужно создавать. Зато проиграть анимацию и звук пожалуста. Летай себе камерой над ГГ.
Вариантов масса!


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
makdmДата: Чт, 11.09.2014, 19:58 | Сообщение # 621
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

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 вообще лишний.


Терпение......
И все получится!
 
Ay49MihasДата: Пт, 12.09.2014, 07:22 | Сообщение # 622
Полевой исследователь
Ученые сталкеры
Сообщений: 218
Награды: 9
Репутация: [ 83 ]

denis2000, makdm, спасибо за развёрнутое описание. Но, видимо, лучше всего тупо использовать схему remark, чтобы не вносить мега-изменений в глобальные механизмы функционирования всего. Дело в том, что фундаментальные знания у меня отсутствуют, тупо действую по аналогии, подсматривая уже готовые решения. Поэтому и использование схемы animpoint считал единственно возможным путём организации катсцены с участием актора.

Сообщение отредактировал Ay49Mihas - Пт, 12.09.2014, 07:23
 
suhar_Дата: Чт, 18.09.2014, 18:27 | Сообщение # 623
Бывалый
Пользователи
Сообщений: 106
Награды: 0
Репутация: [ 0 ]

Может ли кто-то подсказать по плагину db-explorer для Total Commander?
А именно, как пользоваться сей утилитой О_о
Сам плагин поставил, но вот что с ним делать дальше и как откупорить db-архивы - не понятно.

Теперь db архивы можно открывать, как обычные (например zip) просто двойным щелчком мыши или ентером. denis2000

Благодарю.


Сообщение отредактировал suhar_ - Вс, 21.09.2014, 05:11
 
KoshaДата: Чт, 18.09.2014, 18:52 | Сообщение # 624
Отмычка
Пользователи
Сообщений: 32
Награды: 0
Репутация: [ 0 ]

Подскажите
1)Как сделать так что бы спасенные новички в ЧН (бродяга и еще один) по заданию волка не умирали при удалении ГГ от лагеря?
2)Можно ли сделать так что бы диалог появлялся только после вступления ГГ В определенную групировку (Например после вступления в сталкеры) в ЧН?

Заранее спасибо
 
denis2000Дата: Чт, 18.09.2014, 20:05 | Сообщение # 625
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Цитата 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


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
KoshaДата: Пт, 19.09.2014, 19:10 | Сообщение # 626
Отмычка
Пользователи
Сообщений: 32
Награды: 0
Репутация: [ 0 ]

а как в ЧН можно заблокировать доступ к локаций? (Например, тот факт что в подземелья агропрома нельзя войти до сюжетного квеста), и как его потом разблокировать? (получил ключ например к поздземке и можешь входить-выходить)
 
makdmДата: Пт, 19.09.2014, 20:12 | Сообщение # 627
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

Kosha, в ЧН работают функции disable_level_changer и enable_level_changer из файла xr_effects.script
Вот в логике рестриктора и происходит переключение при соблюдении необходимых условий.
Поэтому переходы то закрываются, то открываются.


Терпение......
И все получится!
 
KoshaДата: Сб, 20.09.2014, 14:16 | Сообщение # 628
Отмычка
Пользователи
Сообщений: 32
Награды: 0
Репутация: [ 0 ]

Почему при модификаций фн2000 на оптику х4 через некоторое время она слетает т.е. приближает как без модификаций?
А так же она слетает если сначала поставить оптику х4 а потом другие модификаций
Заранее спасибо


Сообщение отредактировал Kosha - Сб, 20.09.2014, 14:21
 
Kontro-zzzДата: Сб, 20.09.2014, 20:38 | Сообщение # 629
Сталкер
Пользователи
Сообщений: 206
Награды: 4
Репутация: [ 151 ]

Цитата Kosha ()
Почему при модификаций фн2000 на оптику х4 через некоторое время она слетает т.е. приближает как без модификаций?

На ЧН это вроде просто баг. Зум фактор слетает на дефолтный для прицела.


GeForce™-450 GSO 1000_Mb.
Windows-7 x64 Prof.
ОЗУ 4,0 Гб.
 
suhar_Дата: Вс, 21.09.2014, 05:37 | Сообщение # 630
Бывалый
Пользователи
Сообщений: 106
Награды: 0
Репутация: [ 0 ]

Возможно, что этот вопрос уже где-то разбирался, но в КМБ уроке по добавлению оружия этого не нашёл.
Нужно ли где-то в конфигах\скриптах прописывать анимации нововведенного оружия? Т.е. у меня есть 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
 
Поиск: