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


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


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
denis2000Дата: Ср, 20.07.2016, 13:58 | Сообщение # 826
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Вы вторые сутки упорно игнорируете пропущенную вам при переносе кода строку trade.all_money = 0.

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

denis2000, в каком смысле игнорирую? что с ней не так? Файл полностью взят из мода и переменная присутствует

Добавлено (21.07.2016, 12:51)
---------------------------------------------
Всё проблема решена, переменную удалил. Заменил сразу на число коим оно являлось. Единственный вопрос как всё работало в спектрум проджект. Спасибо за помощь.

Сообщение отредактировал men_stalker - Ср, 20.07.2016, 17:08
 
sergej5500Дата: Пт, 29.07.2016, 22:32 | Сообщение # 828
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Добрый вечер.

В Зове Припяти есть квестовое ограбление личного ящика на Юпитере.

Переброска инвентаря осуществляется функцией.

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

Возможно ли с помощью этой или похожей функции осуществить переброску инвентаря, если личные ящики находятся на разных локациях? Попробовал такой код.

[cut=Код]

function esc_agr_box_relocate(actor, npc)
local inv_box_out = get_story_object("esc_b1_actor_treasure")
local inv_box_in = get_story_object("agr_b1_actor_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]

На локации Кордон (локация отправления) функция просто не сработала. Хабар никуда не переместился. Оставил хабар на Кордоне. Телепортировался на Агропром. При активации функции на Агропроме поймал жука.

[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:3566: attempt to index local 'inv_box_out' (a nil value)


stack trace:[/cut]

Реально ли решить задачу - перебросить хабар? Если это возможно, то как правильно составить функцию?
 
_SkIf_Дата: Пт, 29.07.2016, 23:10 | Сообщение # 829
Удаленные



sergej5500, попробуй так:
Код
function esc_inv_box_out()
local inv_box_out = get_story_object("esc_box_out")
local items_to_relocate = {}
local function relocate(inv_box_out, item)
table.insert(items_to_relocate, item)
end
local box_items = inv_box_out:iterate_inventory_box (relocate, inv_box_out)
end

function agr_inv_box_in()
local reloc_items = tostring(esc_inv_box_out.box_items)
local in_box = get_story_object("agr_box_in")
for k, v in pairs (reloc_items) do
xr_effects.spawn_object_in(nil, nil, {v, in_box})
end
end

Вторую функцию запускай из рестриктора, который поставь на Агро.
Код
on_info = {=actor_on_level("agroprom") -agr_reloc_esc_box_items} %=agr_inv_box_in +agr_reloc_esc_box_items%
 
makdmДата: Сб, 30.07.2016, 09:53 | Сообщение # 830
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

Цитата _SkIf_ ()
Вторую функцию запускай из рестриктора, который поставь на Агро.

Шедеврально. Закину себе в библиотеку скриптов. biggrin
Добавлено (30.07.2016, 09:53)
---------------------------------------------
sergej5500, методы iterate_inventory_box и transfer_item применяются только к клиентскому классу объекта.
Смотрите файл lua_help.script класс C++ class game_object
Поэтому, как мне кажется, только переспавн объектов в ящике-приёмнике и удаление объектов в ящике_источнике.

Как-то так бы сделал:

Код
function esc_agr_box_relocate(actor, npc)

local inv_box_out = get_story_object("esc_b1_actor_treasure")
local inv_box_id = get_story_object_id( "agr_b1_actor_treasure" )

local items_to_release = {}

local function relocate(inv_box_out, item)
items_to_release[ item:id() ] = item:section()
end
inv_box_out:iterate_inventory_box(relocate, inv_box_out)

for k,v in pairs( items_to_release ) do
local se_obj = alife():object( k )
if se_obj then
alife():release( se_obj, true )
end
alife():create( v,    vector(), 0, 0, inv_box_id )
end
end


Огромный минус этого скрипта в том, что если у вас в ящике хранятся апгрейденные стволы или броня, то все апгрейды пропадут.


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


Сообщение отредактировал makdm - Сб, 30.07.2016, 10:37
 
sergej5500Дата: Вт, 09.08.2016, 22:30 | Сообщение # 831
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Добрый вечер. Имеется функция для ГУИ-окна.

function esc_marsh_level_changer:level_ch_ok()
self:HideDialog()
game_hide_menu(1)
give_info("esc_marsh_level_changer_init")
end

При нажатии на кнопку выдается инфопорция.

Можно ли выдать инфопорцию через 20 секунд? Причем таймер прописать в этой же функции. Рестриктор для данной задачи не очень подходит.

Если это возможно, то как это сделать?

Добавлено (09.08.2016, 22:30)
---------------------------------------------
Добрый вечер. На рестриктор, имеющий story_id = esc_b1_spot, нужно поставить метку.

Для тестов пробую метку тайника. Пробовал функции.

level.map_add_object_spot_ser(esc_b1_spot,"treasure","")


Или

level.map_add_object_spot(esc_b1_spot,"treasure","")

Обе функции вешают метку не на рестриктор, а на главного героя.

Как это можно исправить?

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

Цитата sergej5500 ()
Как это можно исправить?

Первым параметром идет ид-объекта (число!), вторым имя метки, третьим имя текстовой строки.


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

Добрый вечер. Возник вопрос.

Имеется сквад со стори-ид. Допустим, esc_b3_stalker_attack_squad. Из логики рестриктора нужно проверить, в онлайне сквад или нет. Какой функцией можно воспользоваться?
 
makdmДата: Пн, 19.09.2016, 23:37 | Сообщение # 834
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

sergej5500, а разве так не работает:

local squad = get_story_squad("esc_b3_stalker_attack_squad")
if squad.online then
return true
else
return false
end


Терпение......
И все получится!
 
men_stalkerДата: Чт, 06.10.2016, 15:54 | Сообщение # 835
Инженер «Свободы»
Свобода
Сообщений: 184
Награды: 5
Репутация: [ 40 ]

Доброго времени суток, возвращяясь к теме гуи

[cut=ui_gui_elements.xml]<?xml version="1.0" encoding="windows-1251" ?>
<gui>
<background x="0" y="0" width="1024" height="768">
<texture>ui_inGame2_pda_texture</texture>
<auto_frameline x="42" y="57" width="425" height="27">
<texture>ui_inGame2_pda_buttons_leftside</texture>
</auto_frameline>
<auto_frameline x="887" y="57" width="96" height="27">
<texture>ui_inGame2_pda_buttons_rightside</texture>
</auto_frameline>
</background>

<noice_static x="25" y="33" width="973" height="683">
<texture a="70">ui_pda2_noice</texture>
</noice_static>

<caption_static x="42" y="57" width="941" height="27">
<text font="letterica16" align="l" x="5" y="5" r="170" g="170" b="170"/>
</caption_static>

<clock_wnd x="945" y="72" width="30" height="27" alignment="c">
<text font="letterica18" r="220" g="220" b="220" align="c" vert_align="c"/>
</clock_wnd>

<btn_close x="973" y="26" width="33" height="34" hint="pda_btn_close">
<texture_t>ui_inGame2_pda_offline_t</texture_t>
<texture_e>ui_inGame2_pda_offline_e</texture_e>
<texture_h>ui_inGame2_pda_offline_h</texture_h>
</btn_close>

</gui>[/cut]

[cut=ui_gui_elements.script]class "pda_alkach" (CUIScriptWnd) --Регистрация нового класса гуи-элемента от существующего класса CUIScriptWnd

function pda_alkach:__init(owner) super() --Иницилизируем класс, добавляем отсылки к функциям
self.owner = owner
self:InitControls() --Отсылка к функции регистрации элементов окна
self:InitCallBacks() --Отсылка к функции регистрации коллбеков (условий)
end

function pda_alkach:__finalize() --Функция завершения работы нового класса
end

function pda_alkach:InitControls() --Функция иницилизации элементов окна
self:SetWndRect (Frect():set(0,0,1024,768)) --Установка стандартных размеров файла
local xml, ctrl = CScriptXmlInit(), CUIWindow() --Задаем локальные переменные на классы
xml:ParseFile ("ui_gui_elements.xml") --Инициализация XML-файла Gui-элемента
self.main_panel = xml:InitStatic("background",self)
xml:InitStatic("caption_static",self.main_panel)
xml:InitStatic("noice_static",self.main_panel)
self.clock_wnd=xml:InitStatic("clock_wnd",self.main_panel)
self.button_close = xml:Init3tButton ("btn_close",self.main_panel) --Регистрация кнопки: кнопка закрытия окна
self:Register (self.button_close, "button_close")
end

function pda_alkach:InitCallBacks() --Функци коллбеков
self:AddCallback("button_close", ui_events.BUTTON_CLICKED, self.OnButton_close_clicked, self) --Коллбек кнопки закрытия
end

function pda_alkach:OnKeyboard(dik,keyboard_action) --Функция закрытия окна по нажатию на клавиатуре "Escape"
CUIScriptWnd.OnKeyboard(self,dik,keyboard_action) --Инициализируем нажатие кнопки на клаве
if keyboard_action == ui_events.WINDOW_KEY_PRESSED then --Условие: если нажата кнопка на клаве
if dik == DIK_keys.DIK_ESCAPE then --Условие: если нажата конкретно кнопка "Escape"
if has_alife_info("gui_medkit_got_cystamine") and has_alife_info("gui_medkit_got_kalium") and has_alife_info("gui_medkit_got_chlor") and has_alife_info("gui_medkit_got_antiemetic") and has_alife_info("gui_medkit_got_sulfad") then
self:HideDialog() --То при нажатии на кнопку - закрываем окошко
disable_info("gui_medkit_got_cystamine") --И деактивируем обратно инфы, чтобы потом не было глюков
disable_info("gui_medkit_got_kalium")
disable_info("gui_medkit_got_chlor")
disable_info("gui_medkit_got_antiemetic")
disable_info("gui_medkit_got_sulfad")
else --В любом другом случае
self:HideDialog() --При нажатии на кнопку закрытия, закрываем окошко
give_object_to_actor("pda_alkach") --Выдаем обратно аптечку
end
end
end
return true
end [/cut]

а в итоге

[cut][/cut]

по моим предположениям как минимум часы должны быть.
В чём может быть ошибка?


Сообщение отредактировал men_stalker - Чт, 06.10.2016, 15:54
 
denis2000Дата: Чт, 06.10.2016, 19:49 | Сообщение # 836
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Цитата men_stalker ()
по моим предположениям как минимум часы должны быть.

Ну так окно clock_wnd веротнее всего есть, а с чего вы взяли что его нет.


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

Здравствуйте, хотел бы задать вопрос относительно нодов, т.е. есть:

[cut]<tab x="443" y="57" width="468" height="27">
<button x="0" y="0" width="172" height="27" id="eptTasks" hint="pda_btn_quests_hint" frame_mode="0">
<text align="c" vert_align="c" x="0" y="0" width="157" height="27" font="letterica16">pda_btn_quests</text>
<texture>ui_inGame2_pda_button</texture>
<text_color>
<t r="255" g="255" b="255"/>
<d r="255" g="255" b="255"/>
<e r="200" g="200" b="200"/>
<h r="170" g="170" b="170"/>
</text_color>
</button>
<button x="148" y="0" width="172" height="27" id="eptRanking" hint="pda_btn_ranking_hint" frame_mode="0">
<text align="c" vert_align="c" x="0" y="0" font="letterica16">pda_btn_ranking</text>
<texture>ui_inGame2_pda_button</texture>
<text_color>
<t r="255" g="255" b="255"/>
<d r="255" g="255" b="255"/>
<e r="200" g="200" b="200"/>
<h r="170" g="170" b="170"/>
</text_color>
</button>

<button x="296" y="0" width="172" height="27" id="eptLogs" hint="pda_btn_logs_hint" frame_mode="0">
<text align="c" vert_align="c" x="0" y="0" font="letterica16">pda_btn_logs</text>
<texture>ui_inGame2_pda_button</texture>
<text_color>
<t r="255" g="255" b="255"/>
<d r="255" g="255" b="255"/>
<e r="200" g="200" b="200"/>
<h r="170" g="170" b="170"/>
</text_color>
</button>
</tab>[/cut]
Попытался зарегистрировать этот самый tap как статику, эффекта ноль. Всё работает, но кнопок нет. Как решить эту проблему?


Сообщение отредактировал men_stalker - Сб, 08.10.2016, 14:14
 
sergej5500Дата: Вс, 09.10.2016, 12:15 | Сообщение # 838
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Добрый день.

Можно ли из логики рестриктора проверить текущий уровень графики в игре? Я поставил на локацию прожектор. После этого на статике начались вылеты. На улучшенном полном освещении вылетов нет.

Нужна функция, способная проверить такую вещь. Если уровень графики - полное динамическое освещение или ниже, то нужно выдать команду на гашение прожекторов.

Какую функцию нужно добавить в xr_conditions?
 
denis2000Дата: Вс, 09.10.2016, 18:25 | Сообщение # 839
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

sergej5500, Лечите вылеты, а не плодите костыли.

"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
av661194Дата: Пн, 10.10.2016, 13:23 | Сообщение # 840
Отмычка
Пользователи
Сообщений: 39
Награды: 0
Репутация: [ 38 ]

Доброго дня!
Прикрутил к СГМ 2.2 рандомные новости (для атмосферности), но хочу сделать так, чтобы их можно было опционально включать/отключать в настройках худа. Например, если отключить события статистики, то и новости выводится не будут (тексты уже исправил). Но никак не могу найти, как это сделать.
Т.е. подскажите, как правильно записать такое условие:
if Нажата кнопка "Отключить события статистики" = false then
if zone_news then
zone_news.time_update_spam() -- новости
end
end

Какое условие должно стоять вместо русских букв?
Заранее спасибо.


Сообщение отредактировал av661194 - Пн, 10.10.2016, 13:30
 
Поиск: