Модостроение. Редактирование и создание скриптов
|
|
denis2000 | Дата: Пн, 10.10.2011, 21:17 | Сообщение # 1 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Редактирование и создание скриптов Редактирование и создание скриптов на языке LUA Если у вас появились вопросы по применению скриптов в игре. Задавайте их в этой теме - умные головы, модосторители и просто разбирающиеся в программировании люди вам ответят.
Много интересного материала здесь (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)", ее и надо расскомментировать, должно получиться вот так: Code function abort(fmt, ...) local reason = string.format(fmt, ...) error_log(reason) end Вот для примера два одинаковых вылета, первый с функцией по умолчанию, второй - с поправленной функцией
Первый: Code 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) Второй: Code 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 по ссылке из шапки и соседнюю тему "Курс молодого бойца", возможно Ваш вопрос уже рассматривался.
Если произошел вылет - выкладываем лог! Вопрос ставим четко, не забываем указывать версию игры, установленные моды их версии, установленные фиксы модов и подробно ваши правки. Помните чем подробнее вопрос, тем точнее ответ.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
sergej5500 | Дата: Вс, 22.05.2016, 22:33 | Сообщение # 766 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| Добрый вечер. Попробовал в чистом Зове Припяти сделать закладываемый рюкзак для хабара. Как в СГМ. В упрощенном варианте. Без ГУИ-окон.
[cut=Бустер][personal_rukzak]:booster $spawn = "devices\personal_rukzak" visual = dynamics\devices\dev_rukzak\dev_rukzak.ogf.ogf inv_name = st_personal_rukzak inv_name_short = st_personal_rukzak description = st_personal_rukzak_descr inv_grid_width = 2 inv_grid_height = 2 inv_grid_x = 0 inv_grid_y = 38 inv_weight = 4.0 cost = 6000[/cut]
[cut=Инвентарный рюкзак][personal_rukzak_box]:inventory_box $spawn = "devices\personal_rukzak box" visual = dynamics\devices\dev_rukzak\dev_rukzak.ogf.ogf[/cut]
[cut=Колбэк на использование бустера]if s_obj and s_obj:section_name()=="personal_rukzak" then local sobj=alife():create("personal_rukzak_box",vector():set(db.actor:position().x,db.actor:position().y,db.actor:position().z),db.actor:level_vertex_id(),db.actor:game_vertex_id()) level.map_add_object_spot_ser(s_obj, "treasure", "") end[/cut]
Для тестов использовал метку оригинальных тайников ЗП. Рюкзаки отлично спавнятся. В них можно класть вещи.
Если строка level.map_add_object_spot_ser(s_obj, "treasure", "") активна, то появляется метка тайника.
Но метка почему то ставится на актора, а не на рюкзак. И перемещается вместе с актором по локации. Где я допустил ошибку?
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
makdm | Дата: Пн, 23.05.2016, 09:58 | Сообщение # 767 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| Цитата sergej5500 ( ) Где я допустил ошибку? Вот здесь:
Цитата sergej5500 ( ) level.map_add_object_spot_ser(s_obj, "treasure", "")
Нужно передавать id объекта, а не сам объект:
level.map_add_object_spot_ser( sobj.id, "treasure", "" )
И вот это
sobj=alife():create("personal_rukzak_box",vector():set(db.actor:position().x,db.actor:position().y,db.actor:position().z),db.actor:level_vertex_id(),db.actor:game_vertex_id())
можно написать короче и выполняться будет быстрее:
local actor = db.actor local sobj=alife():create("personal_rukzak_box", actor:position(), actor:level_vertex_id(), actor:game_vertex_id())
Терпение...... И все получится!
Сообщение отредактировал makdm - Пн, 23.05.2016, 10:17 |
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
sergej5500 | Дата: Пн, 23.05.2016, 22:06 | Сообщение # 768 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| makdm,
За помощь спасибо. С метками всё в порядке. Возник новый вопрос.
Попробовал реализовать подбор рюкзака. За основу взял скрипты из СГМ.
[cut=Предмет для подъёма рюкзака][use_personal_rukzak]:identity_immunities GroupControlSection = spawn_group discovery_dependency = $spawn = "devices\use_personal_rukzak" $prefetch = 16 class = D_PDA cform = skeleton visual = dynamics\devices\dev_decoder\dev_decoder.ogf inv_grid_width = 1 inv_grid_height = 1 inv_grid_x = 0 inv_grid_y = 40 slot = 7 radius = 50 default_to_ruck = false can_trade = false inv_weight = 0.0 inv_name = st_use_personal_rukzak_title inv_name_short = st_use_personal_rukzak_title description = st_use_personal_rukzak_descr cost = 0[/cut]
[cut=Колбэк спавна]if s_obj and s_obj:section_name()=="personal_rukzak" then local actor = db.actor local sobj=alife():create("personal_rukzak_box",actor:position(),actor:level_vertex_id(),actor:game_vertex_id()) alife():create("use_personal_rukzak",vector(),0,0,sobj.id) level.map_add_object_spot_ser(sobj.id,"treasure","") end[/cut]
[cut=Скрипты для подбора рюкзака]function actor_binder:take_item_from_box(box, item) local box_name = box:name() addon_callbacks.on_take_item_from_box(box,item) end
function on_take_item_from_box(box,item) local box_name=box:section() local box_id=box:id() local box_item=item:section() if box_name="personal_rukzak_box" and box_item=="use_personal_rukzak" then if box:is_inv_box_empty()==false then relocate_items_with_inv_box(box,db.actor) end end news_manager.send_tip(db.actor,"st_treasure_rukzak_title",0,"got_ammo",3600,nil,"st_bring_obj") give_object_to_actor("personal_rukzak") game_hide_menu() alife():release(alife():object(box:id()),true) end
-- 'Переброска предметов от одного обьекта к другому. function relocate_items_with_inv_box(box,victim) local function calc(temp,item) if item~=nil then box:transfer_item(item,victim) end end box:iterate_inventory_box(calc,box) end[/cut]
При попытке взять предмет use_personal_rukzak получаю вылет.
[cut=Лог]FATAL ERROR [error]Expression : !m_error_code [error]Function : raii_guard::~raii_guard [error]File : D:\prog_repository\sources\trunk\xrServerEntities\script_storage.cpp [error]Line : 748 [error]Description : ...ing\Зов Припяти\gamedata\scripts\bind_stalker.script:126: attempt to index global 'addon_callbacks' (a nil value)
stack trace:
0023:69737365 igdumd32.dll[/cut]
Ошибка где-то в функции
[cut=Функция]function on_take_item_from_box(box,item) local box_name=box:section() local box_id=box:id() local box_item=item:section() if box_name="personal_rukzak_box" and box_item=="use_personal_rukzak" then if box:is_inv_box_empty()==false then relocate_items_with_inv_box(box,db.actor) end end news_manager.send_tip(db.actor,"st_treasure_rukzak_title",0,"got_ammo",3600,nil,"st_bring_obj") give_object_to_actor("personal_rukzak") game_hide_menu() alife():release(alife():object(box:id()),true) end[/cut]
Но я её не вижу. Проверка синтаксиса на LUA ничего не даёт.
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
makdm | Дата: Вт, 24.05.2016, 07:38 | Сообщение # 769 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| sergej5500, у тебя функция выполняется всегда, даже если ты не "нажал кнопку" в рюкзаке. Вот здесь добавь:
if box_name="personal_rukzak_box" and box_item=="use_personal_rukzak" then if box:is_inv_box_empty()==false then relocate_items_with_inv_box(box,db.actor) end else return end
В функции Цитата sergej5500 ( ) relocate_items_with_inv_box(box,victim) строчку
Цитата sergej5500 ( ) local function calc(temp,item) замени на
local function calc( box,item )
И САМОЕ главное: вот это if box_name="personal_rukzak_box" and box_item=="use_personal_rukzak" then замени на: if box_name=="personal_rukzak_box" and box_item=="use_personal_rukzak" then
Терпение...... И все получится!
Сообщение отредактировал makdm - Вт, 24.05.2016, 10:13 |
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
sergej5500 | Дата: Вт, 24.05.2016, 22:48 | Сообщение # 770 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| makdm,
Ещё раз спасибо за помощь. Скрипты работают. Остался последний вопрос. Насчёт предметов use_personal_rukzak. Эти предметы накапливаются в инвентаре ГГ. Это нехорошо. Пробовал применить функцию remove_item. Вызов из on_take_item_from_box последней строкой. Результат нулевой. Видимо, скрипт подбора рюкзака срабатывает очень быстро. И этот предмет не успевает "проявить себя" в инвентаре актора. Функция remove_item для этого предмета написана верно. При вызове её по горячей клавише предмет исчезает.
Попробовал поставить проверку инвентаря ГГ на постоянный апдейт. В СГМ сделали именно так. Это даёт результат. Но мне это не нравится.
Возможно ли удалить use_personal_rukzak из функции on_take_item_from_box? Удаление должно сработать примерно через секунду после отработки скрипта. Когда предмет отметится в инвентаре игрока.
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
makdm | Дата: Ср, 25.05.2016, 00:03 | Сообщение # 771 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| sergej5500, сразу удаляй этот объект в функции:
function on_take_item_from_box(box,item) local box_name=box:section() local box_id=box:id() local box_item=item:section() if box_name=="personal_rukzak_box" and box_item=="use_personal_rukzak" then local s_obj_item = alife():object( item:id() ) alife():release( s_obj_item, true ) if box:is_inv_box_empty()==false then relocate_items_with_inv_box(box,db.actor) end else return end news_manager.send_tip(db.actor,"st_treasure_rukzak_title",0,"got_ammo",3600,nil,"st_bring_obj") give_object_to_actor("personal_rukzak") game_hide_menu() alife():release(alife():object(box:id()),true) end
Терпение...... И все получится!
Сообщение отредактировал makdm - Ср, 25.05.2016, 00:06 |
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
sergej5500 | Дата: Сб, 28.05.2016, 00:47 | Сообщение # 772 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| Добрый вечер. На базе персонального рюкзака, который обсуждался в постах выше, попробовал сделать персональный рюкзак непися. Наподобие тех, которые спавнятся в СГМ при активации флешек. Спавн должен происходить при колбеке на использование бустера - флешки.
[cut=Конфиг][default_rukzak]:inventory_box $spawn = "devices\default_rukzak" visual = dynamics\devices\dev_rukzak\dev_rukzak.ogf
[/cut]
[cut=Тестовая функция спавна]elseif dik==DIK_keys.DIK_F10 then local escape = 1 local actor = db.actor local sobj=alife():create("default_rukzak",vector():set(-154.4246673584,-29.984952926636,-362.10906982422),38355,escape) alife():create("use_personal_rukzak",vector(),0,0,sobj.id) alife():create("medkit_army",vector(),0,0,sobj.id) alife():create("bandage",vector(),0,0,sobj.id) alife():create("wpn_abakan",vector(),0,0,sobj.id) alife():create("wpn_addon_scope",vector(),0,0,sobj.id) alife():create("wpn_lr300",vector(),0,0,sobj.id) alife():create("wpn_addon_scope_susat",vector(),0,0,sobj.id) level.map_add_object_spot_ser(sobj.id,"treasure","") [/cut]
В принципе, результат приемлемый. Рюкзак спавнится. В нём имеется хабар.
Вопрос такой. Можно ли усовершенствовать способ прописывания хабара? Сейчас для каждого предмета нужна отдельная строка. Можно ли предметы прописать в одной строке? Причем, может быть несколько одинаковых предметов.
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
makdm | Дата: Сб, 28.05.2016, 07:47 | Сообщение # 773 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| sergej5500, сделай таблицу из предметов. Сможешь в неё добавлять столько предметов, сколько хочешь.
Например:
local escape = 1 local item_tbl = {"use_personal_rukzak","medkit_army","medkit_army","wpn_abakan"} local sobj=alife():create("default_rukzak",vector():set(-154.4246673584,-29.984952926636,-362.10906982422),38355,escape) local sobj_id = sobj.id for k,v in pairs( item_tbl ) do alife():create( v, vector(), 0, 0, sobj_id ) end level.map_add_object_spot_ser( sobj_id, "treasure", "" )
З,Ы, Можно вообще сделать для каждого НПС свой рюкзак и предметы, которые должны быть в рюкзаке при его спавне, прописать прямо в секции рюкзака.
[rukzak_npc_1]:inventory_box $spawn = "devices\default_rukzak" visual = dynamics\devices\dev_rukzak\dev_rukzak.ogf items = medkit_army, wpn_abakan
[rukzak_npc_2]:rukzak_npc_1 items = bandage, wpn_lr300
и т.д. Правда функция спавна будет немного другая. Если нужна, то напишу.
Терпение...... И все получится!
Сообщение отредактировал makdm - Сб, 28.05.2016, 08:00 |
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
sergej5500 | Дата: Сб, 28.05.2016, 08:42 | Сообщение # 774 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| Цитата makdm ( ) Правда функция спавна будет немного другая. Если нужна, то напишу.
У меня немного другая мысль. У меня будет много флешек - бустеров. По одной на каждый будущий тайник. Называться они будут esc_b1_stalker_commander_deserve, esc_b2_stalker_commander_deserve, esc_b12_bandit_commander_deserve и т.д. В общем, к имени непися будет приписано deserve. Типовой конфиг такой.
[cut=Конфиг][esc_b1_stalker_commander_deserve]:booster $spawn = "devices\esc_b1_stalker_commander_deserve" visual = dynamics\devices\dev_pda\dev_pda.ogf inv_name = st_esc_b2_stalker_commander_deserve inv_name_short = st_esc_b2_stalker_commander_deserve description = st_esc_b2_stalker_commander_deserve_descr inv_weight = 0.3 inv_grid_width = 1 inv_grid_height = 1 inv_grid_x = 6 inv_grid_y = 13 cost = 1000 [/cut]
Реально ли в конфиг бустера вписать ещё 2 строки? Что то типа?
drserve_pos = -154.4246673584,-29.984952926636,-362.10906982422,38355,escape deserve_items = wpn_abakan,wpn_addon_scope,ammo_5.45x39_ap,4
И брать нужные данные из них.
А рюкзаки с хабаром сделать одной секций default_rukzak.
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
makdm | Дата: Сб, 28.05.2016, 10:05 | Сообщение # 775 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| Цитата sergej5500 ( ) Реально ли в конфиг бустера вписать ещё 2 строки? Что то типа? Ну дак это уже в SGM сделано. Посмотри файл sgm_deserves.ltx Сам спавн в файле sgm_callbacks.script, функция on_use_deserve
З.Ы. И вот это мне режет глаз - что даже "кушать не могу".
drserve_pos = -154.4246673584,-29.984952926636,-362.10906982422,38355,escape
Лучше писать точку пути из all.spawn
Терпение...... И все получится!
Сообщение отредактировал makdm - Сб, 28.05.2016, 10:48 |
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
men_stalker | Дата: Сб, 28.05.2016, 11:22 | Сообщение # 776 |
Инженер «Свободы»
Свобода
Сообщений: 184
| Доброго времени суток, хотел бы задать вопрос: можно ли выдавать инфопоршень при нахождение на определённом растоянии от spase_restrictor? То есть при выходе допустим за 150 метров от рестриктора выдавался инфопоршень , при входе ближе чем 150 м не выдавался, при выходе во второй, третий и т.д. снова выдавался
Сообщение отредактировал men_stalker - Сб, 28.05.2016, 11:23 |
|
|
Эти 0 пользователя(ей) поблагодарили men_stalker за это полезное сообщение: |
|
|
sergej5500 | Дата: Сб, 28.05.2016, 13:03 | Сообщение # 777 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| men_stalker,
Для измерения расстояния от ГГ до рестриктора можно воспользоваться функцией =dist_to_actor_ge(150) или =dist_to_actor_le(150)
Цитата makdm ( ) И вот это мне режет глаз - что даже "кушать не могу".
Возможно, выглядит это не очень красиво. Но тайники желательно ставить в укромных местах. Там, как правило, нет сетки. При расстановке таких пойнтов при помощи СДК вылезает глюк. Со скриптами таких проблем нет.
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
denis2000 | Дата: Сб, 28.05.2016, 13:40 | Сообщение # 778 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Цитата sergej5500 ( ) При расстановке таких пойнтов при помощи СДК вылезает глюк. Обратите внимание, что вам рекомендовали "точку пути", а они могут быть вне аи-сетки. А inventory_box насколько я помню должны привязываться к сетке. Вы же обращали внимание, что в оригинале тайники не инвентарные ящики и расположены где угодно, хоть на ветке дерева.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
men_stalker | Дата: Сб, 28.05.2016, 13:45 | Сообщение # 779 |
Инженер «Свободы»
Свобода
Сообщений: 184
| sergej5500, извините, а могли бы вы, если вам несложно, написать как это будет выглядеть в готовом виде? В скриптовании я пока плохо оринтириюсь, пока только учусь.
|
|
|
Эти 0 пользователя(ей) поблагодарили men_stalker за это полезное сообщение: |
|
|
denis2000 | Дата: Сб, 28.05.2016, 14:05 | Сообщение # 780 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| men_stalker, А вы точно закомы с концепцией онлайн/офлайн объектов? Ну тогда вот:
Код [logic] active = sr_idle@zone1
[sr_idle@zone1] on_info = {-infoportion =dist_to_actor_ge(150)} sr_idle@zone2 %+infoportion%
[sr_idle@zone2] on_info = {+infoportion =dist_to_actor_le(150)} sr_idle@zone1 %-infoportion%
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
|