Модостроение. Общие вопросы и ответы
|
|
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 за это полезное сообщение: |
|
|
alex_xp_77 | Дата: Чт, 12.06.2014, 16:37 | Сообщение # 436 |
Научный сотрудник.
Ученые сталкеры
Сообщений: 242
| Добрый день всей планете Сергиус!! Извиняюсь за не полный вопрос, вчера вымотался, на работе и с музыкой в игре, вот файлы которые я менял 1) редактирование конфига ui_mm_main тут : http://SSMaker.ru/85adffac/ 2) папка sounds с ogg треками тут http://SSMaker.ru/960c12b3/
Больше ничего не правил!! И еще, кто разбирается, как сделать микс исполнителей, помогите , точнее подскажите как этого добиться?? Был бы очень признателен!!
Сообщение отредактировал alex_xp_77 - Чт, 12.06.2014, 18:12 |
|
|
Эти 0 пользователя(ей) поблагодарили alex_xp_77 за это полезное сообщение: |
|
|
denis2000 | Дата: Чт, 12.06.2014, 21:37 | Сообщение # 437 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Цитата alex_xp_77 ( ) Больше ничего не правил!! Этого вполне достаточно. Смотри в конфиге указал играть файл music\wasteland2 или файл music\wasteland3: Код <menu_music>music\wasteland2</menu_music> <menu_music>music\wasteland3</menu_music> Теперь собственно в папке должны быть ЧЕТЫРЕ файла: Код music\wasteland2_l music\wasteland2_r music\wasteland3_l music\wasteland3_r По два файла для стереозвучания, а у тебя ровно в половину файлов меньше - где брать недостающие? Правильно из оригинальных файлов, в результате левый канал новый файл правый старый или наоборот
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
alex_xp_77 | Дата: Чт, 12.06.2014, 22:22 | Сообщение # 438 |
Научный сотрудник.
Ученые сталкеры
Сообщений: 242
| Денис не подскажете как же мне сделать микс, то есть 3, и более композиций??Как напримере солянки??Хотя думаю сам погяжу как там, так и будет у меня )) Весьма благодарен!! Что то у меня никак не получается внедрить вообще никакую музыку один лишь лог : [cut][error]Expression : wave&&wave->length() [error]Function : CSoundRender_Source::LoadWave [error]File : E:\stalker\patch_1_0004\xrSound\SoundRender_Source_loader.cpp [error]Line : 65 [error]Description : Can't open wave file: [error]Arguments : d:\сталкер тени чернобыля для теста\s.t.a.l.k.e.r. - shadow of chernobyl\gamedata\sounds\music\wasteland_3_l.ogg[/cut]
Что бы я не менял , все равно одно и тоже, странно вчера загрузилось, хоть и был эффект музыка на музыку...
Просто вчера выбирались файлы music\wasteland2. А в случае выбора music\wasteland3 вылет из-за отсутствия файла. denis2000
Сообщение отредактировал alex_xp_77 - Чт, 12.06.2014, 23:21 |
|
|
Эти 0 пользователя(ей) поблагодарили alex_xp_77 за это полезное сообщение: |
|
|
a4927860 | Дата: Пт, 13.06.2014, 13:21 | Сообщение # 439 |
Новичок
Пользователи
Сообщений: 81
| denis2000, Спасибо большое за подробные ответы.
Сделал итем запускающий скрипт
Нужно: 1) найти нпс на которого наведен курсор (прицел) если он не дальше h 2) найти всех нпс в радиусе r от нпс к которому идет первоначальное действие Собственно вопрос - как их указывать в скриптах (и первого и последующих)?
У вас в аномальном костюме стоит проверка на монстре в файле bind_monster однако на сколько я понимаю это идет запуск скрипта, у меня же скрипт запускает сам игрок по заранее не известному объекту (опять таки в уроках я этого не нашел - хотя может просто проморгал)
Следующим шагом будет применение Силы к нпс/объекту - бросок вверх, притягивание, отталкивание. Скрипт гравигана я курю уже третий день но пока мало что понимаю
update кажется нашел кусок отвечающий за поиск объекта, но чтото уж больно он адский 46 строк на поиск и проверку предмета, может таки можно по легче как то сделать? Код function ggun_binder:capture(cone,dist) if not cone then cone = 0.999 end -- на деле - cos угла захвата на дистанции dist if not dist then dist = 13 end -- дистанция захвата local back = 2 -- смещение конуса захвата за спину актора. dist = dist + back local capt_id = nil local capt_obj = nil local dist_min = 1.2*dist local cone_max = 0.8*cone for id,v in pairs (ggunable) do local cobj = level.object_by_id(id) if cobj and cobj:get_physics_shell() then local rvec = cobj:center():sub(device().cam_pos:mad(device().cam_dir, -2.0)) local r = rvec:magnitude() if r < 1.1*dist and r > back + 1 then -- в радиусе захвата, но перед актором local proj = rvec:dotproduct(device().cam_dir) local cos_a = proj/r if cos_a > cone then -- попадает в конус прицеливания if cos_a >= cone_max and r < dist_min then -- если предмет хотя бы не дальше от оси прицеливания, чем предыдущий выбранный, -- но ближе по расстоянию, то выбираем его dist_min = r cone_max = cos_a capt_id = id capt_obj = cobj end end end else ggunable[id] = nil end end if capt_id and capt_obj then -- если выбрали подходящий объект для захвата self.target = capt_obj -- запомнили self.target_id = capt_id -- запомнили id self.capture_nomove_counter = 3 capt_obj:set_const_force(vector():set(0,1,0), capt_obj:mass()*19.62, 65535*65535) else if not self.sound_nohold:playing() then if not self.block_nohold then self.sound_nohold:play_at_pos(db.actor, self.gun_end_pos) self.block_nohold = true end end end end
Сообщение отредактировал a4927860 - Пт, 13.06.2014, 16:43 |
|
|
Эти 0 пользователя(ей) поблагодарили a4927860 за это полезное сообщение: |
|
|
denis2000 | Дата: Пт, 13.06.2014, 19:46 | Сообщение # 440 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| a4927860, Я делал Локатор объектов с отображением меток на «забрале», там НПС находящиеся на небольшой дистанции в поле зрения помечаются метками на экране. В принципе если метка ложиться в определенное пространство экрана, то можно считать что НПС в секторе прицела. Затем итерируясь по таблице НПС можно выбрать тех которые находятся от прицельного на расстоянии не более заданного.
Цитата a4927860 ( ) можно по легче как то сделать? Автору скрипта виднее. Хотите упростить - пожалуйста, упрощайте.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
a4927860 | Дата: Пт, 13.06.2014, 19:58 | Сообщение # 441 |
Новичок
Пользователи
Сообщений: 81
| denis2000, Имелось ввиду - нет ли простого универсального решения согласно которому вычисляется таргет? например - совпадение с перекрестием прицела?
должны же быть - убить нпс или добавить выбранному нпс предмет, чтото такое же простое как скрипт проверки предметов.
|
|
|
Эти 0 пользователя(ей) поблагодарили a4927860 за это полезное сообщение: |
|
|
denis2000 | Дата: Пт, 13.06.2014, 20:02 | Сообщение # 442 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Цитата a4927860 ( ) например - совпадение с перекрестием прицела? Кто в перекрестье прицела знает движок, но если он не обучен сообщить эту информацию придется интенсивно работать скриптам и головам программистов.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
a4927860 | Дата: Пт, 13.06.2014, 21:16 | Сообщение # 443 |
Новичок
Пользователи
Сообщений: 81
| Цитата denis2000 ( ) придется интенсивно работать скриптам
Я боялся это услышать. На самом деле часто бывают ситуации которые с точки зрения простой логики объяснить трудно, например подсчет одинаковых предметов в инвентаре не просто каунтом а циклом с проверкой. Ну да ладно будем копать...
Спасибо за советы, надеюсь не сильно отвлек =)Добавлено (13.06.2014, 21:16) --------------------------------------------- решил разбить задачу (которая оказалась значительно сложнее чем думалось) допустим на секунду что я нашел объект который мне нужен - как определить что этот объект - нпс?
|
|
|
Эти 0 пользователя(ей) поблагодарили a4927860 за это полезное сообщение: |
|
|
denis2000 | Дата: Пт, 13.06.2014, 21:22 | Сообщение # 444 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Цитата a4927860 ( ) как определить что этот объект - нпс? Глобальная функция IsStalker должна вернуть true. Код if IsStalker(object) then ... end
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
makdm | Дата: Пт, 13.06.2014, 21:38 | Сообщение # 445 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| a4927860, Скрипт, который передает объект в необходимую модмейкеру функцию, давно написан. Используется при стрельбе из БТР. Там сделано так, куда поворачивается камера ГГ ( прицел статичен, поворачивается именно камера и создаётся иллюзия наведения прицела), туда же и поворачивается пушка БТР. Скрипт универсальный и может использоваться, как для НПС ( Сталкеры и монстры ), так и для других объектов ( БТРы, вертушки). Главное, чтобы объект биндился. Покажу на примере Сталкера.
[cut noguest]
В файле xr_motivator.script в методе UPDATE пишите.
Код if self.object:alive() then if actor_target(self.object) then self.target = self.object:id() end end
В самый конец файла добавляете две функции
Код function actor_target(object) if db.actor and object then local dangerang = 1/object:position():distance_to(device().cam_pos) local ang = horz_angle(device().cam_dir, object:position():sub(device().cam_pos)) local tgt = ang > -dangerang and ang < dangerang if tgt then return true else return false end end return false end
function horz_angle(vec1,vec2) local x = vec2.x*vec1.x+vec2.z*vec1.z local y = -vec2.z*vec1.x+vec2.x*vec1.z return math.atan2(y,x) end
Теперь ID объекта, на который наведено перекрестие, хранится в переменной self.target Можете передать её в вашу функцию или разобраться с ней нам месте. [/cut]
Терпение...... И все получится!
Сообщение отредактировал makdm - Пт, 13.06.2014, 21:53 |
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
a4927860 | Дата: Сб, 14.06.2014, 00:52 | Сообщение # 446 |
Новичок
Пользователи
Сообщений: 81
| makdm, Спасибо! п.с. еще раз посмотрел уроки на тему возвращения к жизни бтр - там такого нет
Речь видимо идет о моде Время Альянса ver. 2.0. denis2000
Ох как же грустно мало знать, а отпуск не бесконечный увы... [cut] Код if self.object:alive() then -- Добавление апдейта для таргета ABILITY if actor_target(self.object) then self.target = self.object:id() end end
я поместил в function motivator_binder:update(delta)
два оставшихся куска - в самый конец файла
в своем я соответственно делаю Код if item_name=="hero_ability_1" then give_object_to_actor("hero_ability_1") function kill() local oNpc = level.object_by_id(self.target) if oNpc and IsStalker(self.target) and db.actor:id()~= self.target then oNpc:kill(oNpc) end end function dell_kluk_final() local se_obj = alife():object("self.target") if se_obj then alife():release(se_obj, true) end end end
предмет что характерно выдается - больше ни чего не происходит. хотя хоть один из них но должен вроде сработать...[/cut]
|
|
|
Эти 0 пользователя(ей) поблагодарили a4927860 за это полезное сообщение: |
|
|
makdm | Дата: Сб, 14.06.2014, 09:43 | Сообщение # 447 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| Цитата a4927860 ( ) в своем я соответственно делаю
a4927860, немного не так. Откуда ваша функция знает, что такое self.target ? Для неё значение self.target = nil Нужно передавать ID в вашу функцию.
if self.object:alive() then -- Добавление апдейта для таргета ABILITY if actor_target(self.object) then ИМЯ_ВАШЕГО_ФАЙЛА.ИМЯ_ВАШЕЙ_ФУНКЦИИ( self.object:id() ) end end
И вот это:
if oNpc and IsStalker(self.target) and db.actor:id()~= self.target then
Раз аргумент передан из биндера, то как oNpc может быть nil? Вы передаёте это из биндера Сталкера, то зачем ещё раз проверять, что это Сталкер? Зачем сравнивать его ID с ID актора? Абсолютно ненужные проверки.
Терпение...... И все получится!
|
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
a4927860 | Дата: Сб, 14.06.2014, 17:16 | Сообщение # 448 |
Новичок
Пользователи
Сообщений: 81
| Цитата makdm ( ) ИМЯ_ВАШЕГО_ФАЙЛА.ИМЯ_ВАШЕЙ_ФУНКЦИИ( self.object:id() )
[cut] Я по всей видимости чегото основопологающего не понимаю... [cut] так? Код if self.object:alive() then -- Добавление апдейта для таргета ABILITY if actor_target(self.object) then Hero_ability.on_use_hero_ability(self.target) = self.object:id() end end
или же я добавляю в свой скрипт local target=xr_motivator.motivator_binder(self.target)? не работает в любом случае [/cut]
Добавлено (14.06.2014, 14:19) --------------------------------------------- мне кажется что я ошибаюсь в каких то мелочах которые просто не вижу исходя из учебников и уроков. Господа если у вас есть возможность связаться со мной и немного времени на объяснение - я буду очень признателен.
Добавлено (14.06.2014, 16:00) --------------------------------------------- кажется понял...
[cut] Код if self.object:alive() then -- Добавление апдейта для таргета ABILITY if actor_target(self.object) then self.target = self.object:id() Hero_ability.on_use(self.target) end end [/cut]
вот только теперь у меня ругается моя функция на: attempt to index local 'sect' (a number value) на сколько я понимаю это происходит из за того что изначально функция предназначенна для обработки действий предмета и в ней используются соответствующие параметры.
Добавлено (14.06.2014, 16:39) --------------------------------------------- я в ступоре. после того как я вроде обошел предыдущую ошибку выводом функции kill в корень своей функции с последующим обращением к ней из мотиватора она начала ругаться на то что self.target = nil я добавил условие проверки self.target ~= nil но после этого ругаться стало вообще на мотиватор - xr_motivator.script:354: attempt to index global 'Hero_ability' (a nil value) - из серии куда вы посылаете.. [/cut]
Добавлено (14.06.2014, 17:16) --------------------------------------------- Вернулся к схеме с одной функцией...
У меня в результвте: Из мотиватора передается self.target А из bind_stalker передается (obj) таким образом они похоже конфликтуют...
Мне нужно чтобы при использовании предмета на персонаже на котором стоит курсор выполнялось действие, то есть информация нужна и от туда и от туда.
Как разрулить это?
[cut noguest=собственно мой скрипт ] Код function on_use(sect) --Переменные local actor=db.actor local item_name=sect:section() -вот тут ругается если давать инф от мотиватора local actor_pos=db.actor:position() local active_slot=db.actor:active_slot() local active_item=db.actor:active_item() local pistol_in_slot=db.actor:item_in_slot(2) local rifle_in_slot=db.actor:item_in_slot(3) local outfit_in_slot=db.actor:item_in_slot(7) local helm_in_slot=db.actor:item_in_slot(12)
if item_name=="hero_ability_1" then give_object_to_actor("hero_ability_1") -- local oNpc = level.object_by_id(self.target) -- Сейчас отрубил чтобы не вылетало почем зря но здесь должена быть собственно функция выполняющаяся над объектом, для примера взял убийство - его точно не промаргаешь -- if oNpc then -- oNpc:kill(oNpc) -- end end
end [/cut]
Сообщение отредактировал a4927860 - Сб, 14.06.2014, 19:05 |
|
|
Эти 0 пользователя(ей) поблагодарили a4927860 за это полезное сообщение: |
|
|
alex_xp_77 | Дата: Сб, 14.06.2014, 18:47 | Сообщение # 449 |
Научный сотрудник.
Ученые сталкеры
Сообщений: 242
| Дорого вечера уважаемой публике!! У меня вопрос, много раз задавал, в последний раз все понял, сделал по схеме Дениса2000, но она что то не работает, странно, должна играть музыка но вылетает, что не так делаю, вот скрины настроек!! Папка music http://SSMaker.ru/dbbccf7f/ папка ui---ui_mm_main http://SSMaker.ru/ed9279dd/ Лог[cut noguest=Читать далее] ! Missing ogg-comment, file: d:\сталкер тени чернобыля для теста\s.t.a.l.k.e.r. - shadow of chernobyl\gamedata\sounds\characters_voice\scenario\video\intro_gsc_wp_r.ogg
FATAL ERROR
[error]Expression : wave&&wave->length() [error]Function : CSoundRender_Source::LoadWave [error]File : E:\stalker\patch_1_0004\xrSound\SoundRender_Source_loader.cpp [error]Line : 65 [error]Description : Can't open wave file: [error]Arguments : d:\сталкер тени чернобыля для теста\s.t.a.l.k.e.r. - shadow of chernobyl\gamedata\sounds\music\wasteland4_l.ogg][/cut]
Помогите понять что я делаю не так??? Весьма благодарен за любую помощь!!
Файлы музыка именуете неправильно. Прочтите в логе какого файла ждет движек и посмотрите как поименовали вы. denis2000
Низкий поклон от меня Денис2000, все работает как часы, но вот в чем вопрос, у меня композиция заканчивается и все, то есть дальше треки не проигрываются, мне вот интересно можно ли прокрутку на паузе, то есть в меню, что бы треки включались спонтанным методом, не одна что бы проирывала и все, а шли далее треки спонтанным выбором??
Работает только так: выбирается случайная композиция из указанного списка и проигрывается до конца, все. denis2000
Сообщение отредактировал alex_xp_77 - Сб, 14.06.2014, 20:35 |
|
|
Эти 0 пользователя(ей) поблагодарили alex_xp_77 за это полезное сообщение: |
|
|
makdm | Дата: Сб, 14.06.2014, 20:55 | Сообщение # 450 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| Цитата a4927860 ( ) я в ступоре. a4927860, вам немного почитать основы модинга и ступор пройдёт. Делаете так, например ГГ наводит перекрестие на НПС и принимает аптечку - НПС помирает. [cut noguest] В мотиваторе в методе update пишите
Код if self.object:alive() then if actor_target( self.object ) then hero_ability.target_on = self.object:id() else if hero_ability.target_on ~= nil then if hero_ability.target_on == self.object:id() then hero_ability.target_on = nil end end end end
Теперь сама функция on_use в файле hero_ability.script
Код
target_on = nil
function on_use( sect ) local item_name=sect:section() if item_name=="medkit" and target_on ~= nil then give_object_to_actor("hero_ability_1") local oNpc = level.object_by_id(target_on) if oNpc then oNpc:kill(oNpc) end end
end [/cut]
Терпение...... И все получится!
Сообщение отредактировал makdm - Сб, 14.06.2014, 21:07 |
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
|