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

Rocket1972, В указанном файле вместо
Code
queue_manager():add_action("_g","game_autosave_assign","real",2500,false,"save_pri_expiation_sin_3_repair_finished")

пропиши
Code
game_autosave_assign("save_pri_expiation_sin_3_repair_finished")


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
БабайДата: Пт, 25.05.2012, 11:44 | Сообщение # 77
Ветеран
Пользователи
Сообщений: 483
Награды: 9
Репутация: [ 233 ]

Скрипт также не трогает сквады у которых есть story_id. denis2000
Это в стиле: "Как наточить нож?" - "Нужно взять точило и точить!" Ответ правильный, но тема не раскрыта.
Я вот такое определение вывел:
[cut==story_id]Если в кастомдате сквада (gamedata\configs\misc\squad_descr_имя локации.ltx) присутствует строка "story_id = ", то этот сквад определяется движком игры в категорию "квестовых-неумирайчиков-от-выброса". То есть, НПС, входящие в такой сквад могут умереть от ран, нанесенных другим НПС (сталкером или монстром), но выживают во время выброса (типа принял анабиотик). Полное бессмертие (как от ран, так и от выброса) дает параметр "invulnerable = true", который прописывается в логике НПС по пути "gamedata\configs\scripts\имя локации".[/cut]

По-моему достаточно содержательно.
У меня новый вопрос: уборщик трупов сталкеров после выброса чистит разом всю локацию, в случае смерти НПС-сталкера. Во-первых, комп у меня слабенький и во время чистки игра подвисает, что несколько мешает (особенно когда с альфой или еще с каким врагом встретился). А во-вторых: помародерствовать толком не удается. Я в death_manager.script увеличил число тел до 100, но не помогло. Как сделать, чтоб очистка производилась постепенно, по мере продвижения ГГ по локации, как в процессе игры: труп оказал рядом с ГГ, потом ГГ удаляется на какое-то расстояние от трупа, труп удаляется. В скриптах СГМ трудно ориентироваться, потому, что не все функции прокомментированы по-русски, да еще и оказаться могут где угодно. Как например спальный мешок: вот отродясь бы не подумал искать его в "системе обязательных вознаграждений", чтобы отключить.


Правильно заданный вопрос - половина правильного ответа!

Сообщение отредактировал Бабай - Пт, 25.05.2012, 11:47
 
LazurДата: Пт, 22.06.2012, 13:23 | Сообщение # 78
Новичок
Пользователи
Сообщений: 82
Награды: 3
Репутация: [ 96 ]

Вроде, мне сюда.
Делал отображение сталкеров (друзей) в КПК как в ЧН по "Учебнику от ХОВАН"
в map_spots.xml разкоментировал строку <!-- <level_map spot="alife_presentation_squad_friend_spot"/> -->, в sim_squad_scripted.script заменил функцию стандартную на:
[cut=Функция]function sim_squad_scripted:get_squad_props()
local t = self.player_id
if t == "bandit" then
t = "Сквад Бандитов"
elseif t == "ecolog" then
t = "Группа Экологов"
elseif t == "killer" then
t = "Сквад Наемников"
elseif t == "dolg" then
t = "ui_st_name_dolg"
elseif t == "freedom" then
t = "Сквад Свободы"
elseif t == "stalker" then
t = "Группа Сталкеров"
elseif t == "army" then
t = "Отряд Военных"
elseif t == "monolith" then
t = "Отряд Монолита"
elseif t == "zombied" then
t = "Группа Зомбированных"
end
return t
end[/cut]
Но отображение в КПК не получил. В чём проблема может быть? Заранее спасибо.

Отображаться будут только сквады-друзья находящиеся в онлайне. XOBAH

Хм... А возможно ли сделать так, чтоб в КПК отображались сквады-друзья, которые находятся на других локациях и если можно, то как?
P.S. Сквады, которые находятся в 150метрах от меня не отображаются.

Можно! Читай форум обсуждалось уже. Отсюда и далее. denis2000


На пыльных тропинках аномальных полей
Заспавнятся наши следы...


Сообщение отредактировал Lazur - Пт, 22.06.2012, 19:25
 
SoultakerДата: Пн, 25.06.2012, 16:45 | Сообщение # 79
Гражданский
Пользователи
Сообщений: 18
Награды: 0
Репутация: [ 0 ]

Может вопрос немного не в тему, но я думаю мне тут помогут. smile В [cut noguest=моде]http://stalker.uz/mody-zov-pripyati/xolod-mod-10.html[/cut] есть такая фишка как "Неписи снимают броню и шлемы с трупов и переодеваются. * При переодевании непися ему в инвентарь спавнится броник, который был на нём надет прежде, износ этого броника - также в зависимости от степени "износа" непися, то есть если в него стреляли, то и броник будет заспавнен соответственно изношенный. * Если непись переоделся в проапгрейженый броник, то при очередном переодевании или смерти непися будет заспавнен именно такой проапгрейженый броник. * Если у костюма имеется "съёмный" шлем, то при переодевании неписей учитывается наличие у них нужного шлема, то есть без нужного шлема он не переоденется, пока тот у него не появится. * Кроме того, неписи надевают противогазы." Я хотел бы узнать как выдрать это из того мода и добавить в сборку албора для себя. Или же где-то отдельно можно эти скрипты взять?
 
sergej5500Дата: Пн, 25.06.2012, 17:15 | Сообщение # 80
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Soultaker
Для того, что бы реализовать "Неписи снимают броню и шлемы с трупов и переодеваются" в сборке Албора, нужно найти именно те скрипты, которые отвечают за данные эффекты и совместить их с SGM-скриптами. Дело это довольно сложное и кропотливое. Что касается
Quote
Или же где-то отдельно можно эти скрипты взять?
, то проще, наверное, будет обратиться к авторам этого мода. Может быть они помогут. Что касается совмещения скриптов, то смотрите "Курс Молодого Бойца". Инструкция 2: "Адаптация Модов". Если постараться, то все может получиться.
 
MiramasterДата: Сб, 30.06.2012, 13:40 | Сообщение # 81
Гражданский
Пользователи
Сообщений: 11
Награды: 0
Репутация: [ 0 ]

просили написать сюда!
У меня такой вопрос на счёт комбезов, как например при квесте где нужно попасть к наёмникам на Юпитере, заходя к ним не в комбезе наёмников они тебя выносят. А можно ли сделать такую тему как заходя к другим групировкам и не имея соответствующего комба, было соответственное отношение при обращении к ним? Просто было бы интереснее, проникать к врагам под видом своего SGM 2.1 это так если будет в дальнейшем новые моды!
 
sergej5500Дата: Сб, 30.06.2012, 13:57 | Сообщение # 82
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Miramaster
Как это реализовано на примере базы наемников.
[cut=Проверка наличия костюма]function jup_killer_base_chief_actor_has_outfit(actor,npc,p)
local outfit_in_slot=db.actor:item_in_slot(7)
if outfit_in_slot~=nil and (find_in_string(outfit_in_slot:section(),"killer_outfit") or find_in_string(outfit_in_slot:section(),"killer_exo_outfit")) then
return true
else
return false
end
end
function jup_killer_base_chief_actor_not_outfit(actor,npc,p)
local outfit_in_slot=db.actor:item_in_slot(7)
if outfit_in_slot~=nil and find_out_string(outfit_in_slot:section(),"killer_outfit") and find_out_string(outfit_in_slot:section(),"killer_exo_outfit") then
return true
else
return false
end
end[/cut]
[cut=Диалог]<dialog id="jup_killer_base_chief_start_dialog">
<precondition>sgm_dialogs.mod_dialog_precond</precondition>
<dont_has_info>jup_killer_base_actor_hit</dont_has_info>
<phrase_list>
<phrase id="0">
<text />
<next>100</next>
<next>200</next>
</phrase>
<phrase id="100">
<text />
<dont_has_info>jup_killer_base_chief_payment</dont_has_info>
<next>101</next>
<next>109</next>
</phrase>
<phrase id="101">
<precondition>sgm_dialogs.jup_killer_base_chief_actor_not_outfit</precondition>
<text>jup_killer_base_chief_dialog_1</text>
<give_info>jup_killer_base_chief_dist</give_info>
<next>102</next>
<next>106</next>
</phrase>
<phrase id="102">
<text>jup_killer_base_chief_dialog_2</text>
<next>103</next>
</phrase>
<phrase id="103">
<text>jup_killer_base_chief_dialog_3</text>
<next>104</next>
<next>105</next>
</phrase>
<phrase id="104">
<text>jup_killer_base_chief_dialog_4</text>
<action>dialogs.break_dialog</action>
</phrase>
<phrase id="105">
<text>jup_killer_base_chief_dialog_5</text>
<give_info>jup_killer_base_actor_hit</give_info>
<action>dialogs.break_dialog</action>
</phrase>
<phrase id="106">
<text>jup_killer_base_chief_dialog_6</text>
<next>107</next>
</phrase>
<phrase id="107">
<text>jup_killer_base_chief_dialog_7</text>
<next>108</next>
<next>105</next>
</phrase>
<phrase id="108">
<text>jup_killer_base_chief_dialog_8</text>
<action>dialogs.break_dialog</action>
</phrase>
<phrase id="109">
<precondition>sgm_dialogs.jup_killer_base_chief_actor_has_outfit</precondition>
<text>jup_killer_base_chief_dialog_9</text>
<give_info>jup_killer_base_chief_dist</give_info>
<next>110</next>
<next>113</next>
<next>119</next>
</phrase>
<phrase id="110">
<has_info>jup_founded_pda_chernogo</has_info>
<text>jup_killer_base_chief_dialog_10</text>
<next>111</next>
</phrase>
<phrase id="111">
<text>jup_killer_base_chief_dialog_11</text>
<give_info>jup_killer_base_chief_payment</give_info>
<next>112</next>
</phrase>
<phrase id="112">
<text>jup_killer_base_chief_dialog_12</text>
<action>dialogs.break_dialog</action>
</phrase>
<phrase id="113">
<dont_has_info>jup_founded_pda_chernogo</dont_has_info>
<text>jup_killer_base_chief_dialog_13</text>
<next>114</next>
</phrase>
<phrase id="114">
<text>jup_killer_base_chief_dialog_14</text>
<next>115</next>
</phrase>
<phrase id="115">
<text>jup_killer_base_chief_dialog_15</text>
<next>116</next>
</phrase>
<phrase id="116">
<text>jup_killer_base_chief_dialog_16</text>
<next>117</next>
<next>118</next>
</phrase>
<phrase id="117">
<text>jup_killer_base_chief_dialog_17</text>
<action>dialogs.break_dialog</action>
</phrase>
<phrase id="118">
<text>jup_killer_base_chief_dialog_18</text>
<give_info>jup_killer_base_actor_hit</give_info>
<action>dialogs.break_dialog</action>
</phrase>
<phrase id="119">
<dont_has_info>jup_founded_pda_chernogo</dont_has_info>
<text>jup_killer_base_chief_dialog_19</text>
<next>120</next>
</phrase>
<phrase id="120">
<text>jup_killer_base_chief_dialog_20</text>
<next>121</next>
<next>122</next>
</phrase>
<phrase id="121">
<text>jup_killer_base_chief_dialog_21</text>
<action>dialogs.break_dialog</action>
</phrase>
<phrase id="122">
<text>jup_killer_base_chief_dialog_22</text>
<give_info>jup_killer_base_actor_hit</give_info>
<action>dialogs.break_dialog</action>
</phrase>
<phrase id="200">
<text />
<has_info>jup_killer_base_chief_payment</has_info>
<next>201</next>
</phrase>
<phrase id="201">
<text>jup_killer_base_chief_dialog_23</text>
<next>202</next>
</phrase>
<phrase id="202">
<text>jup_killer_base_chief_dialog_24</text>
<action>dialogs.break_dialog</action>
</phrase>
</phrase_list>
</dialog>[/cut]
Главные здесь функции:
<precondition>sgm_dialogs.jup_killer_base_chief_actor_not_outfit</precondition>
<precondition>sgm_dialogs.jup_killer_base_chief_actor_has_outfit</precondition>
В зависимости от того, выполняются они или нет, то есть есть ли у вас костюм, часовой пропускает вас на базу или нет.
Для каждой базы нужно будет прописать аналогичные функции и поправить соответствующие диалоги у часовых.
Советую прочитать Курс Молодого Бойца: Уроки 31 и 33. Там отлично описаны принципы работы с диалогами.
 
MiramasterДата: Сб, 30.06.2012, 18:02 | Сообщение # 83
Гражданский
Пользователи
Сообщений: 11
Награды: 0
Репутация: [ 0 ]

sergej5500, Спасибо за ответ, мне интересно будут ли в дальнейших модах так делать или нет?
 
sergej5500Дата: Сб, 30.06.2012, 18:12 | Сообщение # 84
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Miramaster
Quote
Спасибо за ответ, мне интересно будут ли в дальнейших модах так делать или нет?

С такими вопросами лучше обратиться к автору мода.


Сообщение отредактировал sergej5500 - Сб, 30.06.2012, 18:17
 
denis2000Дата: Пн, 23.07.2012, 22:44 | Сообщение # 85
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

У меня вопрос: Как отучить НПС, который находиться в режиме движкового боя, ломиться в закрытые двери.

"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
АазДата: Чт, 26.07.2012, 13:00 | Сообщение # 86
Хозяин Зоны
Зомби
Награды: 30
Репутация: [ 0 ]

[cut noguest=Функция]function community_relation(community, npc)
if index_for_community == nil then
load_communities_relations()
end
local relations = communities_relations[community]
if relations == nil then
return -5000
end
-- dbglog("community_relation(%s,%s): goodwill=%f relation=%f", community, npc:name(),
-- relation_registry.community_goodwill(community, npc:id()),
-- relations[index_for_community[npc:character_community()]])
return relations[index_for_community[npc:character_community()]] +
relation_registry.community_goodwill(community, npc:id())
end[/cut]
За что отвечает вышеприведенная функция, взятая из utils2.script (Freeplay Start 1.21, версия игры 1.0004) ?

Возвращает отношение конкретной группировки к конкретному НПС, функция вырвана из контекста поэтому сказать точнее нельзя. denis2000


 
AmikusДата: Вт, 31.07.2012, 12:14 | Сообщение # 87
Гражданский
Пользователи
Сообщений: 3
Награды: 0
Репутация: [ 0 ]

Привет всем) Может я не туда пишу... кто подскажет как сделать свой плеер в сталкер ЗП)
Заранее благодарен

Сборник Модостроения - Зов Припяти - Другое - #18. XOBAH

Добавлено (31.07.2012, 12:14)
---------------------------------------------
А где мне найти этот самый сборник ?

 
ГлюкДата: Вт, 31.07.2012, 12:26 | Сообщение # 88
Почетный Вольный
Вольные сталкеры
Сообщений: 2606
Награды: 17
Репутация: [ 647 ]

Quote (Amikus)
А где мне найти этот самый сборник ?
В шапке этой темы.

Quote (denis2000)
Сборник модостроения ЗП v10.10.11 (автор: XOBAH): *.CHM, *.HTML


Быть собой, верить в себя, не изменять себе...
 
GeonezisДата: Сб, 04.08.2012, 14:55 | Сообщение # 89
Разработчик «Смерти вопреки»
Свобода
Сообщений: 2360
Награды: 30
Репутация: [ 71 ]

Здравствуйте. Подскажите пожалуйста. Каким образом можно прервать проигрывание запущенного звукового файла?
Переменные объявлены глобально.
Code

local snd
local i
local len

Функция на обработку gui кнопки которая запускает проигрывание звука следующая:
[cut]
Code

function ui_gui_razia:OnButton_use_1_clicked()
if level.name()=="jupiter_underground" or level.name()=="labx8" then
      snd=sound_object([[items\radio\radio_noise_2]])
      len=snd:length()
    else
      if math.random()<0.45 then
        i=math.random(1,12)
        snd=sound_object("items\\radio\\radio_voice_"..i)
        len=snd:length()
      else
        i=math.random(1,2)
        snd=sound_object("items\\radio\\radio_noise_"..i)
        len=snd:length()
      end
    end
    if not snd:playing() then
      snd:play_no_feedback(db.actor,sound_object.s2d,0,vector():set(0,0,0),1.0)
      self.button_rac_use_1:Enable(false)
      self.button_rac_use_2:Enable(false)
      self.button_rac_use_3:Enable(false)
      self.button_rac_use_4:Enable(false)
      self.button_rac_use_5:Enable(false)   
    end    
end

[/cut]
При этой блокируется стартовая кнопка, чтобы не был возможен повторные запуск и наложение звука одного файла на другой.
Функцию остановки звука и разблокировки основных кнопок написал так:
[cut]
Code

function ui_gui_razia:OnButton_stop_clicked()
if snd~=nil then
   if snd:playing()==true then
     snd:stop()
     self.button_rac_use_1:Enable(true)
     self.button_rac_use_2:Enable(true)
     self.button_rac_use_3:Enable(true)
     self.button_rac_use_4:Enable(true)
     self.button_rac_use_5:Enable(true)
   else
     self.button_rac_use_1:Enable(true)
     self.button_rac_use_2:Enable(true)
     self.button_rac_use_3:Enable(true)
     self.button_rac_use_4:Enable(true)
     self.button_rac_use_5:Enable(true)
   end
end
end

[/cut]
Блокировка и разблокировка кнопок работают. Звук из первой функции также запускается, не работает только остановка проигрывания рандомно запущенного файла во второй (snd:stop()). Как это можно исправить? То есть каким образом переписать функцию остановки проигрывания?


Смерти Вопреки
Spectrum Project
AP_Prodaction


Сообщение отредактировал GEONEZIS - Сб, 04.08.2012, 15:13
 
denis2000Дата: Сб, 04.08.2012, 16:00 | Сообщение # 90
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

GEONEZIS, Попробуй останавливать вызовом snd:stop_deffered(), если не поможет, значит вероятно вызов snd:play_no_feedback(...) не подразумевает остановку воспроизведения и нужно использовать snd:play(...)

"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
Поиск: