Модостроение. Редактирование и создание скриптов
|
|
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 за это полезное сообщение: |
|
|
victor12 | Дата: Вс, 28.12.2014, 01:35 | Сообщение # 556 |
Отмычка
Пользователи
Сообщений: 29
| Всем доброй ночи! Я сейчас играю в Чистое небо (SGM), играю за бандитов, как увеличить количество групп бандитов, куда залезть и что исправить. Раньше знал, но это было давно.
Intel®Core(TM2)CPU 6400 2.13\2.13GHz, ОЗУ-7ГБ(доступно 5.75 Гб), система - 64 разр., ВК - GF440 1 Гб, игра - лицензионная.
|
|
|
Эти 0 пользователя(ей) поблагодарили victor12 за это полезное сообщение: |
|
|
denis2000 | Дата: Вс, 28.12.2014, 11:41 | Сообщение # 557 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| victor12, Насколько я помню файл faction_bandit.ltx секции [expansion_*] параметр base_squad_number
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
sergej5500 | Дата: Вт, 30.12.2014, 17:10 | Сообщение # 558 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| Добрый день.
В СГМ 2.1 есть функция в _g.scripts.
[cut=Функция]function give_random_treasure(need_level,count) if count==nil then count=1 end local selected_treasure local selected_table local level_name=level.name() local its_all=true for i=1,count do if need_level==nil then if level_name=="zaton" then selected_treasure = get_random_string(treasure_with_zaton) selected_table = treasure_with_zaton elseif level_name=="jupiter" then selected_treasure = get_random_string(treasure_with_jupiter) selected_table = treasure_with_jupiter elseif level_name=="pripyat" then selected_treasure = get_random_string(treasure_with_pripyat) selected_table = treasure_with_pripyat elseif level_name=="darkvalley" then selected_treasure = get_random_string(treasure_with_darkvalley) selected_table = treasure_with_darkvalley elseif level_name=="military" then selected_treasure = get_random_string(treasure_with_military) selected_table = treasure_with_military elseif level_name=="agroprom" then selected_treasure = get_random_string(treasure_with_agroprom) selected_table = treasure_with_agroprom elseif level_name=="escape" then selected_treasure = get_random_string(treasure_with_escape) selected_table = treasure_with_escape elseif level_name=="marsh" then selected_treasure = get_random_string(treasure_with_marsh) selected_table = treasure_with_marsh else return end else if need_level=="zaton" then selected_treasure = get_random_string(treasure_with_zaton) selected_table = treasure_with_zaton elseif need_level=="jupiter" then selected_treasure = get_random_string(treasure_with_jupiter) selected_table = treasure_with_jupiter elseif need_level=="pripyat" then selected_treasure = get_random_string(treasure_with_pripyat) selected_table = treasure_with_pripyat elseif need_level=="darkvalley" then selected_treasure = get_random_string(treasure_with_darkvalley) selected_table = treasure_with_darkvalley elseif need_level=="military" then selected_treasure = get_random_string(treasure_with_military) selected_table = treasure_with_military elseif need_level=="agroprom" then selected_treasure = get_random_string(treasure_with_agroprom) selected_table = treasure_with_agroprom elseif need_level=="escape" then selected_treasure = get_random_string(treasure_with_escape) selected_table = treasure_with_escape elseif need_level=="marsh" then selected_treasure = get_random_string(treasure_with_marsh) selected_table = treasure_with_marsh else return end end if treasure_manager.get_treasure_manager():check_treasure_given(selected_treasure)~=true then treasure_manager.get_treasure_manager():give_treasure(selected_treasure) else for k,v in pairs(selected_table) do if v~=nil and treasure_manager.get_treasure_manager():check_treasure_given(v)~=true then its_all=false end end if its_all==false then give_random_treasure(need_level,1) end end end end[/cut]
Функция выдает рандомный тайник.
Вызывается в диалоге. Например, так.
[cut=Выдача награды за квест]function esc_b1_mechanic_task_complete(actor,npc) give_reward("wpn_saiga") give_reward("ammo_12x70_buck",3) give_reward("ammo_12x76_zhekan",3) dialogs.relocate_money(npc,5000,"in") give_random_treasure() give_secret(1) end[/cut]
Попробовал вызвать функцию через xr_effects.
[cut=xr_effects]function give_random_treasure() give_random_treasure() end[/cut]
В строку on_complete в секции квеста прописал вызов функции.
on_complete = %=add_actor_rank(8) =inc_faction_goodwill_to_actor(stalker:200) =give_random_treasure%
После завершения квеста вылез жучок.
[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 : ....r. - Зов Припяти\gamedata\scripts\xr_effects.script:-1: stack overflow
stack trace: [/cut]
В каком месте я допустил ошибку?
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
denis2000 | Дата: Вт, 30.12.2014, 19:05 | Сообщение # 559 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Цитата sergej5500 ( ) В каком месте я допустил ошибку? Именно в этом месте: Код function give_random_treasure() give_random_treasure() end Вы из функции вызываете ее-же рекурсивно, гарантированное переполнение стека, хорошо что без мертвого зависания винды.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
makdm | Дата: Вт, 30.12.2014, 19:06 | Сообщение # 560 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| Цитата sergej5500 ( ) В каком месте я допустил ошибку?
sergej5500, вот в этом
Цитата sergej5500 ( ) function give_random_treasure() give_random_treasure()
Функция начинает вызывать саму себя и происходит переполнение.
Назовите функцию по-другому.
Терпение...... И все получится!
|
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
sergej5500 | Дата: Вт, 30.12.2014, 19:08 | Сообщение # 561 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| Цитата denis2000 ( ) Вы из функции вызываете ее-же рекурсивно, гарантированное переполнение стека,
Тогда как её вызвать правильно, без вылета.
Сообщение отредактировал sergej5500 - Вт, 30.12.2014, 19:27 |
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
makdm | Дата: Вт, 30.12.2014, 19:35 | Сообщение # 562 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| sergej5500, да как хотите. Например так:
function give_treasure_random() give_random_treasure() end
Терпение...... И все получится!
|
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
sergej5500 | Дата: Ср, 31.12.2014, 14:27 | Сообщение # 563 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| Добрый день.
Возникла следующая проблема.
Описание проблемы
Где я допустил ошибку?
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
denis2000 | Дата: Ср, 31.12.2014, 18:14 | Сообщение # 564 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| sergej5500, talse вместо false: Код if r_mod_params("bool","repair_arms_box_parametr",talse) and pistol_in_slot~=nil then Пропущен and в условии: Код if r_mod_params("bool","repair_outfit_box_parametr",false) helm_in_slot and helm_in_slot:condition()<0.01 then
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
sergej5500 | Дата: Пт, 02.01.2015, 21:34 | Сообщение # 565 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| Добрый вечер.
Функция, отвечающая за отображение СГМ-мин ка карте в СГМ-2.1
[cut=Функция]function submodule_mines_control(object) if check_seconds(1) and dont_has_alife_info("opt_deactivate_minetrap") and r_mod_params("bool","create_mines_permition",true)==true then if find_in_string(read_string("minetraps_config","levels","misc\\config_minetraps.ltx"),level.name()) then for k,v in pairs(sgm_flags.table_mod_mineraps[level.name()]) do if object~=nil and object:alive() and get_story_object_id(v)~=nil and level.object_by_id(get_story_object_id(v))~=nil and distance_between(level.object_by_id(get_story_object_id(v)),object)<=r_mod_params("number","mine_traps_radius",4.0) then if sgm_functions.ReadAvoidMines(object:section())==false then remove_spot_on_map(get_story_object_id(v),sgm_flags.spot_ground_trap) detonate_explosive_charge(get_story_object_id(v),false) unregister_story_id(v) end end if db.actor:object("minetrap_detector") or db.actor:object("minetrap_elite_detector") then if get_story_object_id(v)~=nil then if db.actor:object("minetrap_elite_detector") then if level.object_by_id(get_story_object_id(v))~=nil and distance_between(level.object_by_id(get_story_object_id(v)),db.actor)<=75 and level.map_has_object_spot(get_story_object_id(v),sgm_flags.spot_ground_trap)==0 then play_snd_at_actor([[ambient\special\marsh_beep_1]]) add_spot_on_map(get_story_object_id(v),sgm_flags.spot_ground_trap,"st_minetrap_name") elseif level.object_by_id(get_story_object_id(v))~=nil and distance_between(level.object_by_id(get_story_object_id(v)),db.actor)>75 then remove_spot_on_map(get_story_object_id(v),sgm_flags.spot_ground_trap) end else if level.object_by_id(get_story_object_id(v))~=nil and distance_between(level.object_by_id(get_story_object_id(v)),db.actor)<=50 and level.map_has_object_spot(get_story_object_id(v),sgm_flags.spot_ground_trap)==0 then play_snd_at_actor([[ambient\special\marsh_beep_1]]) add_spot_on_map(get_story_object_id(v),sgm_flags.spot_ground_trap,"st_minetrap_name") elseif level.object_by_id(get_story_object_id(v))~=nil and distance_between(level.object_by_id(get_story_object_id(v)),db.actor)>50 then remove_spot_on_map(get_story_object_id(v),sgm_flags.spot_ground_trap) end end end else if get_story_object_id(v)~=nil and alife():object(get_story_object_id(v)) then remove_spot_on_map(get_story_object_id(v),sgm_flags.spot_ground_trap) end end end end end end[/cut]
Если игрок подорвет мину выстрелом или её подорвут собой мутанты или сталкеры, то маркер мины убирается с карты через несколько секунд. Причем закономерность не просматривается. Иногда мина удаляется практически мгновенно, иногда через минуту. Можно ли сделать функцию более стабильной?
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
denis2000 | Дата: Сб, 03.01.2015, 14:18 | Сообщение # 566 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| sergej5500, Могу предложить только убрать check_seconds(1).
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
sergej5500 | Дата: Пн, 05.01.2015, 12:54 | Сообщение # 567 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| Доброе утро. Возник такой вопрос.
Известно, что в СГМ альфовцы и прочие противники отлично видят сквозь кусты.
Пришла в головы такая идея. Ставим на локации рестриктор (длин или несколько) с именем esc_no_eye_range_1, esc_no_eye_range_2 и т.д. Рестриктор делаем без логики, со стори-ид и с множеством шейпов. Так, чтобы шейпы накрыли кустарники.
В СГМ я нашел функцию в sgm_modules:
[cut=Функция]function submodule_vision_range(object) if check_seconds(3) and r_mod_params("bool","night_blindness_range",true)==true and check_range_deterioration_exception(object) then if present_day() then if dont_has_alife_info("blackday_is_active") then if object:range()<=40 then object:set_range(80) end end else if dont_has_alife_info("blackday_is_active") then if object:range()>40 then object:set_range(20) end end end if has_alife_info("blackday_is_active") then if object:range()>40 then object:set_range(15) end end end end[/cut]
Если на локации затмение, то обзор неписей падает.
Как сделать функцию, отслеживающую попадание НПС в зону такого рестриктора? Проверку надо делать по маске имени рестриктора no_eye_range или по маске стори ид, чтобы не писать функции для отдельных рестрикторов и локацмй.Добавлено (05.01.2015, 12:54) --------------------------------------------- Добрый день.
Возник такой вопрос.
[cut=Функция]function jup_b202_inventory_box_relocate(actor, npc) local inv_box_out = get_story_object("jup_b202_actor_treasure") local inv_box_in = get_story_object("jup_b202_snag_treasure") local items_to_relocate = {} local function relocate(inv_box_out, item) table.insert(items_to_relocate, item) end inv_box_out:iterate_inventory_box (relocate, inv_box_out) for k,v in pairs(items_to_relocate) do inv_box_out:transfer_item(v, inv_box_in) end end[/cut]
Можно ли переделать функцию так, чтобы она чистила рюкзак ГГ? Забирала все предметы, кроме квестовых предметов, ножа, фонаря и бинокля. И рандомно перебрасывала их в один из инвентарных ящиков из списка.
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
denis2000 | Дата: Пн, 05.01.2015, 19:14 | Сообщение # 568 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Цитата sergej5500 ( ) Как сделать функцию, отслеживающую попадание НПС в зону такого рестриктора? Я бы не рекомендовал такое делать - это создаст существенную нагрузку на скрипты...
Цитата sergej5500 ( ) И рандомно перебрасывала их в один из инвентарных ящиков из списка. Можно конечно, берем стандартную функцию переноса предметов инвентаря ГГ в указанный ящик: Код function relocate_actor_inventory_to_box(actor, npc, p) local function transfer_object_item(item) if item:section() ~= "wpn_binoc" and item:section() ~= "wpn_knife" and item:section() ~= "device_torch" then db.actor:transfer_item(item, inv_box_1) end end inv_box_1 = get_story_object (p[1]) actor:inventory_for_each(transfer_object_item) end Преобразуется в такую: Код function relocate_actor_inventory_to_random_box(actor, npc, p) local box_table = { [1] = "<ящик 1>", [2] = "<ящик 2>", [3] = "<ящик 3>" } local not_relocated_item = { ["wpn_binoc"] = true, ["wpn_knife"] = true, ["device_torch"] = true } local function transfer_object_item(item) if not_relocated_item(item:section())~=true then db.actor:transfer_item(item, inv_box_1) end end inv_box_1 = get_story_object(box_table[math.random(1,#box_table)]) actor:inventory_for_each(transfer_object_item) end box_table - таблица стори ид ящиков для рандомного выбора, not_relocated_item - таблица не перемещаемых объектов if not_relocated_item(item:section())~=true then - условие не попадания предметов в ящик
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
sergej5500 | Дата: Пн, 05.01.2015, 21:18 | Сообщение # 569 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| denis2000,
Попробовал функцию в таком виде.
[cut=xr_effects]function esc_relocate_actor_inventory_to_random_box(actor,npc,p) local box_table = { [1] = "esc_inventory_box_13" } local not_relocated_item = { ["wpn_binoc"] = true, ["wpn_knife"] = true, ["device_torch"] = true } local function transfer_object_item(item) if not_relocated_item(item:section())~=true then db.actor:transfer_item(item,inv_box_1) end end inv_box_1 = get_story_object(box_table[math.random(1,#box_table)]) actor:inventory_for_each(transfer_object_item) end[/cut]
Ящик номер 13 находится неподалеку от точки старта. Вызвал функцию в рестрикторе стартоврго автосейва.
Вылез жук.
[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 : ...shing\Зов Припяти\gamedata\scripts\xr_effects.script:4577: attempt to call upvalue 'not_relocated_item' (a table value)
stack trace: [/cut]
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
makdm | Дата: Пн, 05.01.2015, 22:26 | Сообщение # 570 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| sergej5500, чуть-чуть поправил функцию, попробуй так:
function esc_relocate_actor_inventory_to_random_box(actor,npc,p) local box_table = { "esc_inventory_box_13" } local not_relocated_item = { ["wpn_binoc"] = true, ["wpn_knife"] = true, ["device_torch"] = true } local function transfer_object_item(item) if not_relocated_item[item:section()] == nil then db.actor:transfer_item(item,inv_box_1) end end inv_box_1 = get_story_object(box_table[math.random(1,#box_table)]) actor:inventory_for_each(transfer_object_item) end
Терпение...... И все получится!
|
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
|