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


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


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
sergej5500Дата: Вт, 24.05.2016, 22:48 | Сообщение # 766
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

makdm,

Ещё раз спасибо за помощь. Скрипты работают. Остался последний вопрос. Насчёт предметов use_personal_rukzak. Эти предметы накапливаются в инвентаре ГГ. Это нехорошо. Пробовал применить функцию remove_item. Вызов из on_take_item_from_box последней строкой. Результат нулевой. Видимо, скрипт подбора рюкзака срабатывает очень быстро. И этот предмет не успевает "проявить себя" в инвентаре актора. Функция remove_item для этого предмета написана верно. При вызове её по горячей клавише предмет исчезает.

Попробовал поставить проверку инвентаря ГГ на постоянный апдейт. В СГМ сделали именно так. Это даёт результат. Но мне это не нравится.

Возможно ли удалить use_personal_rukzak из функции on_take_item_from_box? Удаление должно сработать примерно через секунду после отработки скрипта. Когда предмет отметится в инвентаре игрока.
 
makdmДата: Ср, 25.05.2016, 00:03 | Сообщение # 767
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

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
 
sergej5500Дата: Сб, 28.05.2016, 00:47 | Сообщение # 768
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Добрый вечер. На базе персонального рюкзака, который обсуждался в постах выше, попробовал сделать персональный рюкзак непися. Наподобие тех, которые спавнятся в СГМ при активации флешек. Спавн должен происходить при колбеке на использование бустера - флешки.

[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]

В принципе, результат приемлемый. Рюкзак спавнится. В нём имеется хабар.

Вопрос такой. Можно ли усовершенствовать способ прописывания хабара? Сейчас для каждого предмета нужна отдельная строка. Можно ли предметы прописать в одной строке? Причем, может быть несколько одинаковых предметов.
 
makdmДата: Сб, 28.05.2016, 07:47 | Сообщение # 769
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

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
 
sergej5500Дата: Сб, 28.05.2016, 08:42 | Сообщение # 770
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Цитата 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.
 
makdmДата: Сб, 28.05.2016, 10:05 | Сообщение # 771
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

Цитата 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
 
men_stalkerДата: Сб, 28.05.2016, 11:22 | Сообщение # 772
Инженер «Свободы»
Свобода
Сообщений: 184
Награды: 5
Репутация: [ 40 ]

Доброго времени суток, хотел бы задать вопрос: можно ли выдавать инфопоршень при нахождение на определённом растоянии от spase_restrictor? То есть при выходе допустим за 150 метров от рестриктора выдавался инфопоршень , при входе ближе чем 150 м не выдавался, при выходе во второй, третий и т.д. снова выдавался

Сообщение отредактировал men_stalker - Сб, 28.05.2016, 11:23
 
sergej5500Дата: Сб, 28.05.2016, 13:03 | Сообщение # 773
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

men_stalker,

Для измерения расстояния от ГГ до рестриктора можно воспользоваться функцией =dist_to_actor_ge(150) или =dist_to_actor_le(150)

Цитата makdm ()
И вот это мне режет глаз - что даже "кушать не могу".


Возможно, выглядит это не очень красиво. Но тайники желательно ставить в укромных местах. Там, как правило, нет сетки. При расстановке таких пойнтов при помощи СДК вылезает глюк. Со скриптами таких проблем нет.
 
denis2000Дата: Сб, 28.05.2016, 13:40 | Сообщение # 774
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Цитата sergej5500 ()
При расстановке таких пойнтов при помощи СДК вылезает глюк.

Обратите внимание, что вам рекомендовали "точку пути", а они могут быть вне аи-сетки. А inventory_box насколько я помню должны привязываться к сетке. Вы же обращали внимание, что в оригинале тайники не инвентарные ящики и расположены где угодно, хоть на ветке дерева.


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

sergej5500, извините, а могли бы вы, если вам несложно, написать как это будет выглядеть в готовом виде? В скриптовании я пока плохо оринтириюсь, пока только учусь.
 
denis2000Дата: Сб, 28.05.2016, 14:05 | Сообщение # 776
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

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%


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
sergej5500Дата: Вс, 29.05.2016, 09:25 | Сообщение # 777
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Цитата makdm ()
Ну дак это уже в SGM сделано. Посмотри файл sgm_deserves.ltx


Провел ряд экспериментов. Остановился на такой функции.

[cut=Функция]-- 'Создание наградного тайника с заполнением.
function create_deserve_rukzak(x,y,z,lv,gv,items_tbl)
local actor = db.actor
local items_table = {"ammo_9x18_fmj","ammo_9x19_fmj","ammo_12x70_buck","ammo_5.45x39_fmj","ammo_5.56x45_ss190","grenade_f1","grenade_rgd5",
"bandage","medkit","medkit_army","antirad","drug_booster","drug_coagulant","drug_psy_blockade","drug_antidot","drug_radioprotector","drug_anabiotic",
"bread","kolbasa","conserva","vodka","energy_drink"}
--if gv=escape or gv=esc then gv=1
--end
--if gv==esc or gv==escape then gv==1
--end
local sobj=alife():create("deserve_rukzak",vector():set(x,y,z),lv,gv)
alife():create("use_personal_rukzak",vector(),0,0,sobj.id)
if items_tbl~=nil then
local parse_first_table=utils.parse_spawns(items_tbl)
for k,v in pairs(parse_first_table) do
for i=1,v.prob do
alife():create(v.section,vector(),0,0,sobj.id)
end
end
end
if items_tbl~=nil then
for i = 1, 5+math.random(-2,3) do
alife():create(items_table[math.random(#items_table)],vector(),0,0,sobj.id)
end
else
for i = 1, 8+math.random(-3,5) do
alife():create(items_table[math.random(#items_table)],vector(),0,0,sobj.id)
end
end
level.map_add_object_spot_ser(sobj.id,"treasure","")
xr_effects.send_tip(db.actor,nil,{"st_found_new_treasure","got_ammo"})
end[/cut]

Спавн тайника вызываю строкой типа.

create_deserve_rukzak(-264.24667358398,-21.472173690796,-278.95037841797,5414,1,"wpn_abakan,wpn_addon_scope,ammo_5.45x39_ap,4")

Тайник кооректно спавнится, отображается на карте и засчитывается в статистику. Кроме постоянного, работает рандомное заполнение.

Хочу вместо гейм-вертекса в строке спавна писать

create_deserve_rukzak(-264.24667358398,-21.472173690796,-278.95037841797,5414,esc,"wpn_abakan,wpn_addon_scope,ammo_5.45x39_ap,4")

или

create_deserve_rukzak(-264.24667358398,-21.472173690796,-278.95037841797,5414,escape,"wpn_abakan,wpn_addon_scope,ammo_5.45x39_ap,4")

Соответственно, функция create_deserve_rukzak должна вместо esc или escape присвоить гейм-вертексу конкретное числовое значение. И заспавнить рюкзак. Это нужно, чтобы после подключения новых локаций, когда гейм-вертексы наверняка поменяются, не пришлось пересчитывать вертексы у всех спавнящихся тайников. Можно было бы поменять присваемое значение гейм-вертекса в этой функции.

Как это правильно сделать? Код

--if gv=escape or gv=esc then gv=1
--end
--if gv==esc or gv==escape then gv==1
--end

не работает. Игра просто не грузится. Вылет при выборе сейва для загрузки.

P.S. Проблему решил самостоятельно.


Сообщение отредактировал sergej5500 - Вс, 29.05.2016, 10:39
 
lychagin0Дата: Вс, 29.05.2016, 09:39 | Сообщение # 778
Легенда Зоны
Вольные сталкеры
Сообщений: 1303
Награды: 9
Репутация: [ 278 ]

sergej5500, Привет, не совсем понял одно: если рюкзак спавниться на локе с ГГ то может вот так

create("esc_heli_boss",db.actor:position().x+4,db.actor:position().y,db.actor:position().z+1,db.actor:level_vertex_id() ,db.actor:game_vertex_id())




Сообщение отредактировал lychagin0 - Вс, 29.05.2016, 09:41
 
sergej5500Дата: Вс, 29.05.2016, 10:11 | Сообщение # 779
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Цитата lychagin0 ()
Привет, не совсем понял одно: если рюкзак спавниться на локе с ГГ то может вот так


Эта функция так же применяется для спавна рюкзаков после юзания флешек. Как в СГМ. Флешка может быть заюзана на другой локации.
 
makdmДата: Вс, 29.05.2016, 10:48 | Сообщение # 780
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

sergej5500, левел вертекс и гейм вертекс ЛЮБОЙ локации в игре можно получить с помощью такой функции.

Вызов функции для локации Бар:

local lv_id, gv_id = get_lvid_gvid_level( "l05_bar" ) -- здесь имя локации, как в папке levels

Код
function get_lvid_gvid_level( need_level )
        local gv_id = 0
    local lv_id = 0
    while game_graph():valid_vertex_id( gv_id ) do
  local level = alife():level_name( game_graph():vertex( gv_id ):level_id() )
  if level == need_level then
   lv_id = game_graph():vertex( gv_id ):level_vertex_id()
   break
  end
    gv_id = gv_id + 1
    end
return lv_id, gv_id
end


Терпение......
И все получится!


Сообщение отредактировал makdm - Вс, 29.05.2016, 10:58
 
Поиск: