Войти на сайт Регистрация Лента форума Пользователи Правила сайта Поиск по форуму
Модератор форума: denis2000, FantomICW  
Модостроение. Редактирование и создание скриптов
denis2000Дата: Пн, 10.10.2011, 21:17 | Сообщение # 1
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Редактирование и создание скриптов

Редактирование и создание скриптов на языке 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 по ссылке из шапки и соседнюю тему "Курс молодого бойца",
возможно Ваш вопрос уже рассматривался.


Если произошел вылет - выкладываем лог! Вопрос ставим четко, не забываем указывать версию игры, установленные моды их версии, установленные фиксы модов и подробно ваши правки.
Помните чем подробнее вопрос, тем точнее ответ.


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
men_stalkerДата: Вс, 26.06.2016, 18:44 | Сообщение # 811
Инженер «Свободы»
Свобода
Сообщений: 184
Награды: 5
Репутация: [ 40 ]

Здравствуйте, хотел бы задать вопрос: как можно зарегистрировать скрипт mob_trade для Сидора? И для него же возможность прописывания параметра level_spot ?
 
sergej5500Дата: Вс, 26.06.2016, 18:58 | Сообщение # 812
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

men_stalker,

Схемы поведения сталкеров регистрируются в файле gamedata\scripts\modules.
 
men_stalkerДата: Пн, 27.06.2016, 07:27 | Сообщение # 813
Инженер «Свободы»
Свобода
Сообщений: 184
Награды: 5
Репутация: [ 40 ]

sergej5500, mob_trade это не схема поведения(вы вероятно спутали с mob_trader), это файл с условиями, ну то есть там условия необходимые для логики Сидора(хорошо/плохо поторговал и др)
 
denis2000Дата: Пн, 27.06.2016, 07:54 | Сообщение # 814
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

men_stalker, mob_trade это схема поведения! Регистрируется там, где вам и указали.

"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
tema796Дата: Вс, 10.07.2016, 23:49 | Сообщение # 815
Гражданский
Пользователи
Сообщений: 20
Награды: 0
Репутация: [ -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]
 
denis2000Дата: Пн, 11.07.2016, 09:40 | Сообщение # 816
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

tema796, Похоже, что на ЗП данная реализация работать не будет.

"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
Hunter209305Дата: Чт, 14.07.2016, 21:35 | Сообщение # 817
Гражданский
Пользователи
Сообщений: 1
Награды: 0
Репутация: [ 0 ]

Платформа: Зов Припяти
Здравствуйте. В 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
 
denis2000Дата: Пт, 15.07.2016, 08:05 | Сообщение # 818
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Hunter209305, Ну видимо self.remote_charge_delay == nil, поскольку функция chargetimer была вызвана до определения этой переменной.

"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
men_stalkerДата: Пн, 18.07.2016, 15:37 | Сообщение # 819
Инженер «Свободы»
Свобода
Сообщений: 184
Награды: 5
Репутация: [ 40 ]

Здравствуйте, только только заметил вылет при с торговлей с Сидоровичем:
[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.
Скрипт взят из спектрум проджект (путь во мгле). Там работает нормально, не вылетает.
 
denis2000Дата: Пн, 18.07.2016, 18:48 | Сообщение # 820
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

men_stalker, Переменная trade.all_money предварительно не определена.

"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
men_stalkerДата: Вт, 19.07.2016, 14:04 | Сообщение # 821
Инженер «Свободы»
Свобода
Сообщений: 184
Награды: 5
Репутация: [ 40 ]

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 придать?

 
denis2000Дата: Вт, 19.07.2016, 18:41 | Сообщение # 822
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Цитата men_stalker ()
единственные упоминания этой переменной в спектрум проджект присутствуют лишь в этой функции и
в этом же скрипте:
trade.all_money = 0

Вы полагаете это просто случайность? Или все таки в скриптах каждая буква на своем месте должна быть?


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
men_stalkerДата: Ср, 20.07.2016, 07:48 | Сообщение # 823
Инженер «Свободы»
Свобода
Сообщений: 184
Награды: 5
Репутация: [ 40 ]

denis2000, конечно я не думаю что это случайность. Но при этом я даже не знаю где может быть ошибка.
 
denis2000Дата: Ср, 20.07.2016, 08:20 | Сообщение # 824
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Цитата men_stalker ()
Но при этом я даже не знаю где может быть ошибка

Ошибка в том, цитирую себя:
Цитата denis2000 ()
Переменная trade.all_money предварительно не определена.

Где еще встречается упоминание trade.all_money? Цитирую вас:
Цитата men_stalker ()
в этом же скрипте:
trade.all_money = 0

А теперь пожалуйста сложите все это и сделайте вывод.


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
men_stalkerДата: Ср, 20.07.2016, 13:16 | Сообщение # 825
Инженер «Свободы»
Свобода
Сообщений: 184
Награды: 5
Репутация: [ 40 ]

denis2000, я очень ценю вашу помощь, но скажите прямо: где ошибка?
 
Поиск: