Модостроение. Редактирование и создание скриптов
|
|
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 за это полезное сообщение: |
|
|
strelok200 | Дата: Вс, 24.08.2014, 15:14 | Сообщение # 526 |
Бывалый
Свобода
Сообщений: 126
| FantomICW, Спасибо, конечно, но я воспользуюсь немного другим вариантом local npc_state = state_mgr.get_state( npc ) if state_lib.states[ npc_state ].animation == "probe_stand" then
|
|
|
Эти 0 пользователя(ей) поблагодарили strelok200 за это полезное сообщение: |
|
|
makdm | Дата: Вс, 24.08.2014, 17:48 | Сообщение # 527 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| Цитата sergej5500 ( ) , чтобы не вылетало? sergej5500, вместо box прописать npc
Терпение...... И все получится!
|
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
sergej5500 | Дата: Вс, 24.08.2014, 18:24 | Сообщение # 528 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| makdm,
Дмитрий, добрый день. Переделал код так:
[cut=xr_effects]function jup_rasvet_spez_taynik_1_binder(actor,npc) if find_in_string(npc:section(),"jup_rasvet_spez_taynik_1") and not has_alife_info("jup_rasvet_spez_taynik_1_zalogen") then if get_item_section_f_inventory_box(box,"detector_elite") and get_item_section_f_inventory_box(box,"medkit") and get_item_section_f_inventory_box(box,"bandage") and (get_item_section_f_inventory_box(box,"antirad") or get_item_section_f_inventory_box(box,"psy_complex")) and get_item_section_f_inventory_box(box,"cs_heavy_outfit") and ((get_item_section_f_inventory_box(box,"wpn_abakan") and get_item_section_f_inventory_box(box,"ammo_5.45x")) or (get_item_section_f_inventory_box(box,"wpn_l85") and get_item_section_f_inventory_box(box,"ammo_5.56x")) or (get_item_section_f_inventory_box(box,"wpn_wincheaster1300") and get_item_section_f_inventory_box(box,"ammo_12x"))) then game_hide_menu() give_info("jup_rasvet_spez_taynik_1_zalogen") end end end[/cut]
При подходе к тайнику получил лог.
[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 : ...ogram files 1\Зов Припяти\gamedata\scripts\_g.script:2552: attempt to index local 'obj_box' (a nil value)
stack trace:[/cut]
[cut=_g]-- 'Проверка наличия предметов с указанной частью секции, в инвентарном обьекте. function get_item_section_f_inventory_box(obj_box,target_item) local result=false local function check_items(temp,item) if item~=nil and find_in_string(item:section(),target_item) then result=true return true end end obj_box:iterate_inventory_box(check_items,obj_box) return result end[/cut]
2552 строка obj_box:iterate_inventory_box(check_items,obj_box)
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
makdm | Дата: Вс, 24.08.2014, 18:44 | Сообщение # 529 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| sergej5500, в функцию get_item_section_f_inventory_box передаётся ссылка на клиентский объект Поэтому в вызове функции везде нужно исправить box на npc
get_item_section_f_inventory_box(npc,"ammo_12x") и т.д.
Терпение...... И все получится!
Сообщение отредактировал makdm - Вс, 24.08.2014, 18:45 |
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
Alice | Дата: Пн, 25.08.2014, 17:40 | Сообщение # 530 |
Гражданский
Пользователи
Сообщений: 12
| Подскажите, пожалуйста, где в ЗП рассчитываются цены на ремонт брони и оружия. Плиззз.
|
|
|
Эти 0 пользователя(ей) поблагодарили Alice за это полезное сообщение: |
|
|
denis2000 | Дата: Пн, 25.08.2014, 17:55 | Сообщение # 531 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Alice, В файле inventory_upgrades.script в функции how_much_repair в строке 190: Код return math.floor(cost*(1-item_condition)*cof * cur_price_percent)
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
Alice | Дата: Пн, 25.08.2014, 18:23 | Сообщение # 532 |
Гражданский
Пользователи
Сообщений: 12
| denis2000, огромное спасибо. А то ремонт в несколько раз превышает стоимость шмотки. Как то не правильно это.
Не подскажите еще , как на разрешение 19:6 (1920 х 1080) оптические прицелы поправить. Они у меня все овальные. Вроде в файле scopes_16.xml нужно что-то сделать , но вот что я не знаю. И гугл выдает только готовые моды.
|
|
|
Эти 0 пользователя(ей) поблагодарили Alice за это полезное сообщение: |
|
|
denis2000 | Дата: Пн, 25.08.2014, 20:01 | Сообщение # 533 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Alice, Да править нужно файл scopes_16.xml, покажу на примере тега wpn_crosshair: Код <wpn_crosshair x="0" y="0" width="1024" height="768"> <auto_static x="85" y="0" width="854" height="768" stretch="1"> <texture>wpn_crosshair</texture> </auto_static> <auto_static x="0" y="0" width="86" height="768" stretch="1"> <texture>wpn_crosshair_add_l</texture> </auto_static> <auto_static x="939" y="0" width="85" height="768" stretch="1"> <texture>wpn_crosshair_add_r</texture> </auto_static> </wpn_crosshair> Текст вверху на русском означает, что есть текстура wpn_crosshair с координатами левоговерхнего угла (x, y) 0,0 и размером (width, height) 1024 на 768. Эта текстура составная и состоит из трех: wpn_crosshair, wpn_crosshair_add_l, wpn_crosshair_add_r. Которые размещены на базовой текстуре следующим образом: Текстура wpn_crosshair левый верхний угол в координатах x="85" y="0", размер width="854" height="768", остальные две текстуры призваны закрыть участки не закрытые первой текстурой тоесть x="0" y="0" width="86" height="768" и x="939" y="0" width="85" height="768". Для того, чтобы расширить по горизонтали нужно увеличивать размер текстуры <texture>wpn_crosshair</texture> параметры x (уменьшать вплоть до 0) и width (увеличивать вплоть до 1024) в теге auto_static (изменять параметры нужно на одну и ту же величину иначе центр текстуры сместиться и прицел перестанет показывать в реальную точку прицеливания), соответственно увеличению центральной текстуры нужно уменьшать боковые текстуры-заглушки.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
gamer | Дата: Ср, 27.08.2014, 01:11 | Сообщение # 534 |
Новичок
Пользователи
Сообщений: 82
| подскажите как правильно совмещать скрипты например вот этот [cut noguest=скрипт 1]function generic_physics_binder:use_callback(obj,who) sgm_utilizator.utilizator_reward(self.object) sgm_callbacks.on_use_box(self.object) if obj:clsid()==clsid.inventory_box then local box_name = obj:name() end if self.st.active_section then xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "use_callback", obj, who) end if sgm_functions.read_obj_variable(obj,"inv_used")==nil or sgm_functions.read_obj_variable(obj,"inv_used")=="nil" then sgm_functions.write_obj_variable(obj,"inv_used","searched") if find_out_string(self.object:section(),"sgm_secret_") and find_out_string(self.object:section(),"dv_") then sgm_callbacks.on_first_use_box(obj) end end if find_in_string(self.object:section(),"sgm_secret_") then sgm_callbacks.on_search_secret(self.object) elseif find_in_string(self.object:section(),"dv_") and find_in_string(self.object:section(),"_unpack") then sgm_callbacks.on_search_deserve(self.object) end end [/cut]
[cut noguest=скрипт 2]function generic_physics_binder:use_callback(obj, who) if obj:clsid() == clsid.inventory_box then local box_name = obj:name() end if self.st.active_section then xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "use_callback", obj, who) end -- ARS MOD -------------------------- ars.on_physics_use(obj,who) -- ARS MOD -------------------------- end [/cut]
Я совместил так [cut noguest=скрипт 3]function generic_physics_binder:use_callback(obj,who) sgm_utilizator.utilizator_reward(self.object) sgm_callbacks.on_use_box(self.object) if obj:clsid()==clsid.inventory_box then local box_name = obj:name() end if self.st.active_section then xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "use_callback", obj, who) end if sgm_functions.read_obj_variable(obj,"inv_used")==nil or sgm_functions.read_obj_variable(obj,"inv_used")=="nil" then sgm_functions.write_obj_variable(obj,"inv_used","searched") if find_out_string(self.object:section(),"sgm_secret_") and find_out_string(self.object:section(),"dv_") then sgm_callbacks.on_first_use_box(obj) end end if find_in_string(self.object:section(),"sgm_secret_") then sgm_callbacks.on_search_secret(self.object) elseif find_in_string(self.object:section(),"dv_") and find_in_string(self.object:section(),"_unpack") then sgm_callbacks.on_search_deserve(self.object) end if obj:clsid() == clsid.inventory_box then local box_name = obj:name() end if self.st.active_section then xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "use_callback", obj, who) end -- ARS MOD -------------------------- ars.on_physics_use(obj,who) -- ARS MOD -------------------------- end end[/cut]
|
|
|
Эти 0 пользователя(ей) поблагодарили gamer за это полезное сообщение: |
|
|
denis2000 | Дата: Ср, 27.08.2014, 08:32 | Сообщение # 535 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| gamer, В первый скрипт добавляем ars.on_physics_use(obj,who). Все скрипты совмещены! Итого: Код function generic_physics_binder:use_callback(obj,who) sgm_utilizator.utilizator_reward(self.object) sgm_callbacks.on_use_box(self.object) if obj:clsid()==clsid.inventory_box then local box_name = obj:name() end if self.st.active_section then xr_logic.issue_event(self.object, self.st[self.st.active_scheme], "use_callback", obj, who) end if sgm_functions.read_obj_variable(obj,"inv_used")==nil or sgm_functions.read_obj_variable(obj,"inv_used")=="nil" then sgm_functions.write_obj_variable(obj,"inv_used","searched") if find_out_string(self.object:section(),"sgm_secret_") and find_out_string(self.object:section(),"dv_") then sgm_callbacks.on_first_use_box(obj) end end if find_in_string(self.object:section(),"sgm_secret_") then sgm_callbacks.on_search_secret(self.object) elseif find_in_string(self.object:section(),"dv_") and find_in_string(self.object:section(),"_unpack") then sgm_callbacks.on_search_deserve(self.object) end -- ARS MOD -------------------------- ars.on_physics_use(obj,who) -- ARS MOD -------------------------- end Более того конструкция: Код if obj:clsid()==clsid.inventory_box then local box_name = obj:name() end Вообше никому не нужна, поскольку переменная box_name далее нигде не используется, а у вас этот код дважды замонстрячен. И эвент дважды выдается на использование объекта.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
gamer | Дата: Вт, 09.09.2014, 22:35 | Сообщение # 536 |
Новичок
Пользователи
Сообщений: 82
| Подскажите где ошибка
[cut noguest=скрипт]function motivator_binder:net_destroy() if rx_ai then rx_ai.npc_net_destroy(self.object) end xrs_dyn_music.npc_table[self.object:id()] = nil xr_combat_ignore.fighting_with_actor_npcs[self.object:id()] = nil xr_sound.stop_sounds_by_id(self.object:id()) local st = db.storage[self.object:id()] if st.active_scheme then xr_logic.issue_event(self.object, st[st.active_scheme], "net_destroy", self.object) end if self.st.reach_task then xr_logic.issue_event(self.object, self.st.reach_task, "net_destroy", self.object) end local on_offline_condlist = db.storage[self.object:id()] and db.storage[self.object:id()].overrides and db.storage[self.object:id()].overrides.on_offline_condlist if on_offline_condlist ~= nil then xr_logic.pick_section_from_condlist(db.actor, self.object, on_offline_condlist) end if db.offline_objects[self.object:id()] then db.offline_objects[self.object:id()].level_vertex_id = self.object:level_vertex_id() db.offline_objects[self.object:id()].active_section = db.storage[self.object:id()].active_section end db.del_obj(self.object) db.storage[self.object:id()] = nil self:clear_callbacks() if self.e_index ~= nil then db.delete_enemy( self.e_index ) end object_binder.net_destroy(self) end[/cut]
[cut noguest=Лог]* Game vicsi - quicksave.scop is successfully saved to file 'profiles\savedgames\vicsi - quicksave.scop' * [win32]: free[2317444 K], reserved[233460 K], committed[1643336 K] * [ D3D ]: textures[538098 K] * [x-ray]: crt heap[440690 K], process heap[12924 K], game lua[45899 K], render[1886 K] * [x-ray]: economy: strings[53234 K], smem[16530 K] * Saving spawns... * Saving objects... * 13892 objects are successfully saved * Game vicsi - quicksave.scop is successfully saved to file 'profiles\savedgames\vicsi - quicksave.scop' 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 : ...talker sigerous\gamedata\scripts\xr_motivator.script:121: attempt to call field 'npc_net_destroy' (a nil value)
stack trace: [/cut]
|
|
|
Эти 0 пользователя(ей) поблагодарили gamer за это полезное сообщение: |
|
|
sergej5500 | Дата: Вт, 09.09.2014, 23:43 | Сообщение # 537 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| Добрый вечер. Интересует такой момент.
1. Функция спавна мертвого сталкера. xr_effects.spawn_corpse(actor, nil, {"sim_default_monolith_4","pri_ecolog_briefing_spawn"})
2. Допустим, что у нас есть список спавн-пойнтов. zat_dead_spawn_1, zat_dead_spawn_2, zat_dead_spawn_3, zat_dead_spawn_4, zat_dead_spawn_5, ... и т.д. Всего 20. Или 30.
3. Допустим, что имеется список мертвых сталкеров. sim_default_duty_0, sim_default_duty_1, sim_default_duty_2, ... и т.д. Всего 30. Или 40.
Можно ли написать функцию, которая на каждом из входящих в список спавн-пойнте рандомно заспавнит одного сталкера из входящих в список мертвых сталкеров? Как такая функция будет выглядеть?
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
makdm | Дата: Ср, 10.09.2014, 09:24 | Сообщение # 538 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| sergej5500, попробуй так ( в таблицы можно добавлять сколько угодно секций и точек спавна ), сделано для трёх точек и трёх секций сталкеров [cut noguest] function spawn_corpse_random() local section_table = {"sim_default_duty_0","sim_default_duty_1","sim_default_duty_2"} local point_table = {"zat_dead_spawn_1","zat_dead_spawn_2","zat_dead_spawn_3"} for i = 1, #point_table do xr_effects.spawn_corpse(actor, nil, {section_table[math.random(#section_table)],point_table[i]}) end end [/cut] Добавлено (10.09.2014, 09:08) --------------------------------------------- Есть и второй вариант. Если точно известно количество точек спавна и они называются одинаково, а меняется только цифра на конце, а также известно точное количество секций сталкеров и они также одинаковы в названии и меняется также только цифра на конце, то чтобы не заниматься писаниной больших таблиц, скрипт можно переделать.
Например секции сталкеров: sim_default_duty_1 ... sim_default_duty_40 Имена точек: zat_dead_spawn_1 ... zat_dead_spawn_30
Тогда функция будет такой [cut noguest] function spawn_corpse_random() for i = 1, 30 do local section_index = math.random(1,40) local section = "sim_default_duty_"..section_index local point = "zat_dead_spawn_"..i xr_effects.spawn_corpse(actor, nil, {section,point}) end end[/cut]
Добавлено (10.09.2014, 09:24) --------------------------------------------- gamer, в файле gamedata\scripts\rx_ai.script не найдена функция npc_net_destroy
Терпение...... И все получится!
Сообщение отредактировал makdm - Ср, 10.09.2014, 09:25 |
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
gamer | Дата: Ср, 10.09.2014, 15:19 | Сообщение # 539 |
Новичок
Пользователи
Сообщений: 82
| Правильно понимаю,shader font2 не находит ?
[cut noguest=log]* Game lederlager - начало игры.scop is successfully saved to file 'profiles\savedgames\lederlager - начало игры.scop' compiling shader font2 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 : d:\stalker sigerous\gamedata\scripts\_g.script:846: bad argument #3 to 'format' (string expected, got nil)
stack trace:[/cut]
|
|
|
Эти 0 пользователя(ей) поблагодарили gamer за это полезное сообщение: |
|
|
makdm | Дата: Ср, 10.09.2014, 15:29 | Сообщение # 540 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| gamer, после вылета в папке gamedata открой файл mod_crash_log.txt и посмотри там причину вылета
Терпение...... И все получится!
|
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
|