Модостроение. Редактирование и создание скриптов
|
|
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 за это полезное сообщение: |
|
|
men_stalker | Дата: Вс, 26.06.2016, 18:44 | Сообщение # 811 |
Инженер «Свободы»
Свобода
Сообщений: 184
| Здравствуйте, хотел бы задать вопрос: как можно зарегистрировать скрипт mob_trade для Сидора? И для него же возможность прописывания параметра level_spot ?
|
|
|
Эти 0 пользователя(ей) поблагодарили men_stalker за это полезное сообщение: |
|
|
sergej5500 | Дата: Вс, 26.06.2016, 18:58 | Сообщение # 812 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| men_stalker,
Схемы поведения сталкеров регистрируются в файле gamedata\scripts\modules.
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
men_stalker | Дата: Пн, 27.06.2016, 07:27 | Сообщение # 813 |
Инженер «Свободы»
Свобода
Сообщений: 184
| sergej5500, mob_trade это не схема поведения(вы вероятно спутали с mob_trader), это файл с условиями, ну то есть там условия необходимые для логики Сидора(хорошо/плохо поторговал и др)
|
|
|
Эти 0 пользователя(ей) поблагодарили men_stalker за это полезное сообщение: |
|
|
denis2000 | Дата: Пн, 27.06.2016, 07:54 | Сообщение # 814 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| men_stalker, mob_trade это схема поведения! Регистрируется там, где вам и указали.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
tema796 | Дата: Вс, 10.07.2016, 23:49 | Сообщение # 815 |
Гражданский
Пользователи
Сообщений: 20
| Платформа: Зов Припяти Здравствуйте. Я адоптировал заканчивающие болты от Charsi и появилось такая проблема. После "использование" болта я не могу его подобрать. Хотя они должны
[cut noguest=bolt_binder]-- биндер болтов local t={}
function init(obj) obj:bind_object(BBolt(obj)) end
class "BBolt" (object_binder)
function BBolt:__init(obj) super(obj) end
function BBolt:update(delta) if not t[self.object:id()] then local ps=self.object:get_physics_shell() if ps then local curr_vel=vector() ps:get_angular_vel(curr_vel) if curr_vel:magnitude()>1 then t[self.object:id()]=true bolt_mod.remove_bolt(self.object) end end end object_binder.update(self, delta) end
function BBolt:net_spawn(data) self.object:set_callback(callback.use_object, self.use_callback, self) return object_binder.net_spawn(self, data) end
function BBolt:use_callback(obj, who) bolt_mod.retrieve_bolt() db.actor:drop_item_and_teleport(obj,vector():set(0,-100,0)) obj:bind_object(nil) end
function BBolt:net_save_relevant() return true end[/cut]
[cut noguest=bolt_mod] -------------- конечное количество болтов ------------- ------------------ реализация Charsi ------------------ ------------ 19/01/2013 [адаптация под ЧН ] ----------- -------------------------------------------------------
local infinity = false -- true - только подбираются,false - подбираются и заканчиваются
------------------------------------------------------- local st = nil
function on_item_take(obj) if not infinity then if not st then st = CCustStBoltCntr() end if obj:section()=="fake_bolt" then if xr_logic.pstor_retrieve(db.actor,"b_dr") then remove_item(obj) spawn_item_in_inv("bolt") xr_logic.pstor_store(db.actor,"b_dr",false) end st.bolt_cnt=st.bolt_cnt+1 elseif obj:section()=="bolt" then if xr_logic.pstor_retrieve(db.actor,"b_dr") then del_bolt() end st.bolt_cnt=st.bolt_cnt+1 end end end
function on_item_drop(obj) if not infinity then if obj:section()=="fake_bolt" then st.bolt_cnt=st.bolt_cnt-1 end if obj:section()=="bolt" then st.bolt_cnt=st.bolt_cnt-1 xr_logic.pstor_store(db.actor,"b_dr",true) end end end
function update() if not infinity then st:upd_cnt() end end
function remove_bolt(bolt) if not infinity and not remove_item(db.actor:object("fake_bolt")) then del_bolt() end if st.bolt_cnt==1 then db.actor:drop_item_and_teleport(bolt,vector():set(0,-100,0)) end end
function del_bolt() db.actor:drop_item_and_teleport(db.actor:item_in_slot(6),vector():set(0,-100,0)) end
function remove_item(item) if item then local sobj=alife():object(item:id()) if sobj then alife():release(sobj,true) end return true end return false end
function spawn_item_in_inv( sect ) alife():create(sect,db.actor:position(),db.actor:level_vertex_id(),db.actor:game_vertex_id(),0) end
function retrieve_bolt() if not infinity then if st.bolt_cnt>0 then spawn_item_in_inv( "fake_bolt" ) else xr_logic.pstor_store(db.actor,"b_dr",false) spawn_item_in_inv( "bolt" ) end end end
class "CCustStBoltCntr" (CUIScriptWnd) function CCustStBoltCntr:__init() super() self.bolt_cnt = 0 self:SetWndRect (Frect():set(0,0,1024,768)) local xml = CScriptXmlInit() xml:ParseFile("ui_test.xml") self.Count = xml:InitStatic("count", self) self.Count:TextControl():SetText("") self.Icon = xml:InitStatic("icon", self) get_hud():AddDialogToRender(self.Count) end function on_net_destroy() get_hud():RemoveDialogToRender(self.Count) Count = nil end function CCustStBoltCntr:upd_cnt() if db.actor:active_slot() == 6 then self.Count:Show(true) self.Icon:Show(true) self.Count:TextControl():SetText(self.bolt_cnt) else self.Count:Show(false) self.Icon:Show(false) end end [/cut]
[cut noguest=Секция "bolt"] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; BOLT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[bolt]:identity_immunities,weapon_probability,default_weapon_params class = II_BOLT cform = skeleton visual = dynamics\devices\dev_bolt\dev_bolt.ogf inv_name = st_bolt $prefetch = 16 inv_name_short = st_bolt inv_weight = .0
ef_weapon_type = 1
inv_grid_width = 1 inv_grid_height = 1 inv_grid_x = 0 inv_grid_y = 0
animation_slot = 6 single_handed = 0
attach_position_offset = -0.03, -0.05, 0.03 attach_angle_offset = 0,0,0 attach_bone_name =
slot = 5 hud = bolt_hud force_min = 10 force_const = 20 force_max = 20 force_grow_speed = 10
destroy_time = 10000 script_binding = bolt_binder.init
cost = 0
throw_point = 0.4, 0.3, 0.1 throw_dir = 0,0,1
third_person_throw_point_offset = -0.05,0.848,0.706
PDM_disp_base = 1.0 PDM_disp_vel_factor = 1.0 PDM_disp_accel_factor = 1.0 PDM_disp_crouch = 1.0 PDM_disp_crouch_no_acc = 1.0
[bolt_hud]:hud_base fire_point = 0,0,0 fire_bone = wpn_body
attach_place_idx = 0 item_visual = dynamics\devices\dev_bolt\dev_bolt_hud
hands_position = -0.021000,-0.160000,0.002500 hands_orientation = -0.500000,1.000000,1.149999 hands_position_16x9 = 0.033000,-0.189500,0.039000 hands_orientation_16x9 = 2.349998,2.749999,2.849998
item_position = 0 , 0 ,0 item_orientation = 0 , 0 ,0
anm_hide = dev_bolt_holster anm_show = dev_bolt_draw anm_idle = dev_bolt_idle anm_bore = dev_bolt_idle_bore anm_idle_moving = dev_bolt_idle_moving anm_idle_sprint = dev_bolt_idle_sprint
anm_throw_begin = dev_bolt_shoot_start anm_throw_idle = dev_bolt_shoot_idle anm_throw = dev_bolt_shoot_end
throw_point = 0.0,0.4,0.3 throw_dir = 0,0,1 [/cut]
[cut noguest=Секция "fake_bolt"] [fake_bolt]:device_pda visual = dynamics\devices\dev_bolt\dev_bolt.ogf inv_name = st_bolt_fake inv_name_short = st_bolt_fake inv_grid_width = 1 inv_grid_height = 1 inv_grid_x = 9 inv_grid_y = 30 inv_weight = .0 description = "Болт 32х100.Лучший друг сталкера."[/cut]
|
|
|
Эти 0 пользователя(ей) поблагодарили tema796 за это полезное сообщение: |
|
|
denis2000 | Дата: Пн, 11.07.2016, 09:40 | Сообщение # 816 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| tema796, Похоже, что на ЗП данная реализация работать не будет.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
Hunter209305 | Дата: Чт, 14.07.2016, 21:35 | Сообщение # 817 |
Гражданский
Пользователи
Сообщений: 1
| Платформа: Зов Припяти Здравствуйте. В SGM 2.2 пытаюсь реализовать анимацию использования РС-15. Т.е. предмет в инвентаре появляется через некоторое время после использования. Возникла проблема с передачей remote_charge_delay. [cut noguest=Ошибка]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 : ...l of pripyat\gamedata\scripts\ui_mod_elements.script:1781: attempt to perform arithmetic on field 'remote_charge_delay' (a nil value)[/cut]
[cut noguest=Код]cfg_remote_charge_delay=0 class "remote_charge" (CUIScriptWnd) function remote_charge:__init(owner) super() cfg_remote_charge_delay=0 self.remote_charge_delay=0 self.owner = owner self:InitControls() self:InitCallBacks() end function remote_charge:__finalize() end function remote_charge:InitControls() self:SetWndRect(Frect():set(0,0,1024,768)) local xml = CScriptXmlInit() xml:ParseFile("ui_mod_elements.xml") self.remote_charge_form=xml:InitStatic("remote_charge_form",self) self:Register(xml:Init3tButton("remote_charge_form:btn_place",self.remote_charge_form),"btn_place") self:Register(xml:Init3tButton("remote_charge_form:btn_cancel",self.remote_charge_form),"btn_cancel") self:Register(xml:Init3tButton("remote_charge_form:btn_charge_delay_dec",self.remote_charge_form),"btn_charge_delay_dec") self:Register(xml:Init3tButton("remote_charge_form:btn_charge_delay_inc",self.remote_charge_form),"btn_charge_delay_inc") self.charge_delay_field=xml:InitStatic("remote_charge_form:charge_delay_field",self.remote_charge_form) end function remote_charge:InitCallBacks() self:AddCallback("btn_place",ui_events.BUTTON_CLICKED,self.btn_place,self) self:AddCallback("btn_cancel",ui_events.BUTTON_CLICKED,self.btn_cancel,self) self:AddCallback("btn_charge_delay_dec",ui_events.BUTTON_CLICKED,self.btn_charge_delay_dec,self) self:AddCallback("btn_charge_delay_inc",ui_events.BUTTON_CLICKED,self.btn_charge_delay_inc,self) end function remote_charge:OnKeyboard(dik,keyboard_action) CUIScriptWnd.OnKeyboard(self,dik,keyboard_action) if keyboard_action == ui_events.WINDOW_KEY_PRESSED then if dik == DIK_keys.DIK_ESCAPE then self:btn_cancel() end end return true end function remote_charge:Update() CUIScriptWnd.Update(self) if not object_alive(db.actor) then self:btn_cancel() end if self.remote_charge_delay<0 then self.remote_charge_delay=0 end if self.remote_charge_delay==0 then self.charge_delay_field:TextControl():SetText(game.translate_string("st_remote_charge_delay_deactivated")) else local charge_delay=self.remote_charge_delay/1000 self.charge_delay_field:TextControl():SetText(game.translate_string("st_remote_charge_delay_timer").." "..charge_delay.." "..game.translate_string("st_remote_charge_delay_value")) end end function remote_charge:btn_charge_delay_dec() self.remote_charge_delay=self.remote_charge_delay-1000 end function remote_charge:btn_charge_delay_inc() self.remote_charge_delay=self.remote_charge_delay+1000 end function remote_charge:btn_place() db.actor:give_info_portion("use_remote_explosive_charge") db.actor:give_info_portion("use_item_need_hide_weapon") start_time_use = game.get_game_time(); self:HideDialog() end function remote_charge:btn_cancel() db.actor:give_info_portion("back_remote_explosive_charge") db.actor:give_info_portion("use_item_need_hide_weapon") start_time_hide = game.get_game_time(); self:HideDialog() end function chargetimer() local time_to_hide = 10; local time_to_use = 10; if db.actor:has_info("use_remote_explosive_charge") and (start_time_use == nil or game.get_game_time():diffSec(start_time_use) >= time_to_use) then cfg_remote_charge_delay=self.remote_charge_delay local obj=create("remote_charge",db.actor:position().x,db.actor:position().y,db.actor:position().z,db.actor:level_vertex_id(),db.actor:game_vertex_id()) if self.remote_charge_delay==0 then add_spot_on_map(obj.id,sgm_flags.spot_remote_charge,"st_remote_charge_spot") else local charge_delay=self.remote_charge_delay/1000 --1781 add_spot_on_map(obj.id,sgm_flags.spot_remote_charge,game.translate_string("st_remote_charge_spot")..": "..charge_delay.." "..game.translate_string("st_remote_charge_delay_value")) end check_actor_item_to_add("remote_charge_control") db.actor:disable_info_portion("use_remote_explosive_charge") end if db.actor:has_info("back_remote_explosive_charge") and (start_time_hide == nil or game.get_game_time():diffSec(start_time_hide) >= time_to_hide) then give_object_to_actor("remote_explosive_charge") db.actor:disable_info_portion("back_remote_explosive_charge") end end[/cut] Последняя функция - моя. Проблема вроде глупая, но решение найти не могу.
Сообщение отредактировал Hunter209305 - Чт, 14.07.2016, 21:38 |
|
|
Эти 0 пользователя(ей) поблагодарили Hunter209305 за это полезное сообщение: |
|
|
denis2000 | Дата: Пт, 15.07.2016, 08:05 | Сообщение # 818 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Hunter209305, Ну видимо self.remote_charge_delay == nil, поскольку функция chargetimer была вызвана до определения этой переменной.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
men_stalker | Дата: Пн, 18.07.2016, 15:37 | Сообщение # 819 |
Инженер «Свободы»
Свобода
Сообщений: 184
| Здравствуйте, только только заметил вылет при с торговлей с Сидоровичем: [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 : ...Е.Р. - Зов Припяти\gamedata\scripts\mob_trade.script:81: attempt to perform arithmetic on field 'all_money' (a nil value) [/cut]
[cut=вот функция]function mob_trade:on_trade(buy_coast, sell_coast) local trade = self:storage_trade_section() trade.buy_coast = buy_coast trade.sell_coast = sell_coast trade.all_money = trade.all_money + buy_coast + sell_coast trade.exchanged = true
if xr_logic.try_switch_to_another_section(self.object, self.st, db.actor) then return end end [/cut]
P.S. Скрипт взят из спектрум проджект (путь во мгле). Там работает нормально, не вылетает.
|
|
|
Эти 0 пользователя(ей) поблагодарили men_stalker за это полезное сообщение: |
|
|
denis2000 | Дата: Пн, 18.07.2016, 18:48 | Сообщение # 820 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| men_stalker, Переменная trade.all_money предварительно не определена.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
men_stalker | Дата: Вт, 19.07.2016, 14:04 | Сообщение # 821 |
Инженер «Свободы»
Свобода
Сообщений: 184
| denis2000, единственные упоминания этой переменной в спектрум проджект присутствуют лишь в этой функции и в этом же скрипте: trade.all_money = 0 trade.trading = true trade.exchanged = false Ну и в xr_conditions: function trade_all_money(actor, npc) return db.storage[npc:id()].trade.all_money > 2000 endДобавлено (19.07.2016, 14:04) --------------------------------------------- Какое значение надо переменной trade.all_money придать?
|
|
|
Эти 0 пользователя(ей) поблагодарили men_stalker за это полезное сообщение: |
|
|
denis2000 | Дата: Вт, 19.07.2016, 18:41 | Сообщение # 822 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Цитата men_stalker ( ) единственные упоминания этой переменной в спектрум проджект присутствуют лишь в этой функции и в этом же скрипте: trade.all_money = 0 Вы полагаете это просто случайность? Или все таки в скриптах каждая буква на своем месте должна быть?
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
men_stalker | Дата: Ср, 20.07.2016, 07:48 | Сообщение # 823 |
Инженер «Свободы»
Свобода
Сообщений: 184
| denis2000, конечно я не думаю что это случайность. Но при этом я даже не знаю где может быть ошибка.
|
|
|
Эти 0 пользователя(ей) поблагодарили men_stalker за это полезное сообщение: |
|
|
denis2000 | Дата: Ср, 20.07.2016, 08:20 | Сообщение # 824 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Цитата men_stalker ( ) Но при этом я даже не знаю где может быть ошибка Ошибка в том, цитирую себя:
Цитата denis2000 ( ) Переменная trade.all_money предварительно не определена. Где еще встречается упоминание trade.all_money? Цитирую вас:
Цитата men_stalker ( ) в этом же скрипте: trade.all_money = 0 А теперь пожалуйста сложите все это и сделайте вывод.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
men_stalker | Дата: Ср, 20.07.2016, 13:16 | Сообщение # 825 |
Инженер «Свободы»
Свобода
Сообщений: 184
| denis2000, я очень ценю вашу помощь, но скажите прямо: где ошибка?
|
|
|
Эти 0 пользователя(ей) поблагодарили men_stalker за это полезное сообщение: |
|
|
|