IPB

Помощь по разделу

Сайт S.T.A.L.K.E.R. Inside / [ЗП] Параметры командной строки / Распаковщик ресурсов

>

Скрипты

 
 Орион
сообщение 13.07.2009, 11:34
Сообщение #241


Навий черны у ношьти
***************

Группа: Забанен
Сообщений: 2210
Регистрация: 11.03.2009
Из: Лиманск
Пользователь №: 10251




FAQ

Lua в X-Ray

Список всех функций, переменных, классов и т.п. что используются в Сталкере находится по адресу:
Код
gamedata/scripts/lua_help.script

Для получения файла надо распаковать игру. Можно скачать, в принципе (IMG:style_emoticons/default/smile.gif) Тут =>>Ссылко<<=
Уроки

Пример создания непися скриптами ЛУА. Автор: меченый(стрелок)
Скриптинг на инсайде



Сообщение отредактировал RayTwitty - 09.06.2018, 20:23
Перейти в начало страницы
 
 
 
Ответов
 NanoBot-AMK
сообщение 21.11.2019, 19:34
Сообщение #242


Почти Игроман
*********

Группа: Участник
Сообщений: 708
Регистрация: 10.11.2015
Пользователь №: 22739



Кстати, функции типа object_binder.update(self, delta) можно спокойно исключить, это просто пустышки, которые ничего не делают, кроме времени(2-3 мксек). Исключения только для метода net_spawn, там это нужно.
Перейти в начало страницы
 
 
 Gaz24
сообщение 23.11.2019, 07:43
Сообщение #243


Почти Игрок
**

Группа: Участник
Сообщений: 17
Регистрация: 14.01.2013
Пользователь №: 15612



Хотел добавить свою аи-схему, которая запускается во время боя. Все подключил, добавил эвалуатор, работает. А вот экшен не работает от слова совсем. В чем могла быть ошибка?

Код
Код
local base = xr_evaluators_id.combat_new_base
local eval_on_combat = base + 0

base = xr_actions_id.combat_new_base
local act_on_combat = base + 0
----------------------------------------------------------------------------------------------------------------------
-- модификация xr_combat
----------------------------------------------------------------------------------------------------------------------
class "evaluator_mod_combat" (property_evaluator)

function evaluator_mod_combat:__init(name,storage) super (nil, name)
    self.st = storage
end

function evaluator_mod_combat:evaluate()
    local cond = self.object:motivation_action_manager():current_action_id() == stalker_ids.action_combat_planner
    --news_manager.send_tip(db.actor, self.object:character_name())
    return cond
end

----------------------------------------------------------------------------------------------------------------------
class "action_mod_combat" (action_base)

function action_mod_combat:__init(name,storage) super (nil, name)
    self.st = storage
end

function action_mod_combat:initialize()
    action_base.initialize(self)
    news_manager.send_tip(db.actor, 1)
end

function action_mod_combat:execute()
    action_base.execute(self)
end

function action_mod_combat:finalize()
    action_base.finalize(self)
end

----------------------------------------------------------------------------------------------------------------------
-- binder
----------------------------------------------------------------------------------------------------------------------
function add_to_binder(npc, ini, scheme, section, storage)
    local manager = npc:motivation_action_manager()

    manager:add_evaluator( eval_on_combat, this.evaluator_mod_combat("eval_mod_combat",storage) )

    local action = this.action_mod_combat("act_mod_combat",storage)
    --action:add_precondition(world_property(stalker_ids.property_alive, true))
    manager:add_action(act_on_combat, action)
end


Сообщение отредактировал Gaz24 - 23.11.2019, 08:18
Перейти в начало страницы
 
 
 abramcumner
сообщение 23.11.2019, 10:55
Сообщение #244


Босс
********************

Группа: Участник
Сообщений: 4348
Регистрация: 27.04.2011
Из: Россия
Пользователь №: 14366



Цитата(Gaz24 @ 23.11.2019, 07:39) *
Хотел добавить свою аи-схему, которая запускается во время боя. Все подключил, добавил эвалуатор, работает. А вот экшен не работает от слова совсем. В чем могла быть ошибка?

Он и не должен работать, ты же экшен никак в GOAP не встроил:
1. твоему экшену надо добавить прекондишен и эффект. Например, что он вызывается, когда world_property(eval_on_combat) = true и обещает перевести world_property(eval_on_combat) в false.
2. добавить существующему экшену прекондишен world_property(eval_on_combat) = false, например к stalker_ids.action_combat_planner

Тогда НПЦ попытается в очередной раз попытается решить загадку зоны; увидит, что ему мешает world_property(eval_on_combat) = true(пункт 2); для устранения такой неприятности у него есть твой экшен(пункт 1) и НПЦ запустит твой экшен.

Посмотри на аи-схемы из оригинала или из модов. Там есть оба пункта.
Перейти в начало страницы
 
 
 Gaz24
сообщение 23.11.2019, 11:54
Сообщение #245


Почти Игрок
**

Группа: Участник
Сообщений: 17
Регистрация: 14.01.2013
Пользователь №: 15612



abramcumner, я со своим эвалуатором использовал изначально, поэтому другой запустил. Сделал так, как ты посоветовал. Все равно экшен не срабатывает. Я может плохо написал из-за своего непонимания.

Код
Код
local action = manager:action(stalker_ids.action_combat_planner)
action:add_precondition(world_property(world_property(eval_on_combat), true))
local action = this.action_mod_combat("act_mod_combat",storage)
action:add_effect(world_property(world_property(eval_on_combat), false))
manager:add_action(act_on_combat, action)
Перейти в начало страницы
 
 
 abramcumner
сообщение 23.11.2019, 13:16
Сообщение #246


Босс
********************

Группа: Участник
Сообщений: 4348
Регистрация: 27.04.2011
Из: Россия
Пользователь №: 14366



Gaz24, не так. К сожалению не могу найти статью по аи-схемам в сталкере.

Смотри цель любого сталкера - решить загадку зоны, это world_property(puzzleSolved)=true, такой эффект есть у экшена xr_actions_id.alife. Но у него есть прекондишены: жив, нет врагов и тд. Планировщик НПЦ смотрит, как решить загадку зоны, она решается экшеном stalker_ids.action_alife. У него есть прекондишены, планировщик их проверяет. Если все выполнены, то нпц решает загадку зоны, игра заканчивается(в том самом билде). Если не выполнены, то планировщик ищет экшен, который выполнит прекондишен. У него опять проверяет прекондишены, ищет новый экшен,... В итоге доходит до экшена, который может сейчас выполнить и который ведет к решению загадки зоны.

Например логика и гулаги подрубаются так: к экшену xr_actions_id.alife добавляется прекондишен типа "need_remark"=false, а action_remark умеет переводить need_remark в false. Сначала отыграй анимку, а потом можешь решать загадку зоны.

Теперь по-твоему коду. Ты combat_planner`у добавил прекондишен eval_on_combat=true. Планировщик будет искать экшен, который переводит eval_on_combat в true. Но такого нет - act_mod_combat переводит eval_on_combat в false. Надо в эффекте поменять false на true. После этого твой экшен должен начать бесконечно вызываться. Ну и для срабатывания твоего экшена нужен враг, без него боевка и не будет запускаться.

И так не надо писать "world_property(world_property(eval_on_combat), true)", просто "world_property(eval_on_combat, true)".

Сейчас по идее аи-схема должна зависать. Если запустить такой скрипт на отладочном движке, то в лог будет выведен дамп с указанием, что пошло не так.

Сообщение отредактировал abramcumner - 23.11.2019, 13:16
Перейти в начало страницы
 
 
 Gaz24
сообщение 23.11.2019, 14:04
Сообщение #247


Почти Игрок
**

Группа: Участник
Сообщений: 17
Регистрация: 14.01.2013
Пользователь №: 15612



abramcumner, заработало, спасибо. Правда с прекондишенами надо поиграться. А так, осознал.

Если ты говорил про эту статью, то я на нее очень сильно опирался, но из-за своего косяка вообще не понимал.

Сообщение отредактировал Gaz24 - 23.11.2019, 14:14
Перейти в начало страницы
 
 
 RayTwitty
сообщение 08.01.2020, 22:34
Сообщение #248


Босс
********************

Группа: Участник
Сообщений: 4296
Регистрация: 24.09.2010
Пользователь №: 14086



В дополнение к посту про class ini_file

uint64<class_id> r_clsid(string<section>, string<line>) - возвращает id класса по имени класса (т.е. вызов ini:r_clsid(obj:section(), "class") полностью эквивалентен вызову obj:clsid()).
string<result> r_string_wq(string<section>, string<line>) - тоже самое что и стандартный r_string, только этот метод убирает ещё и кавычки.
Пример
Код
[mysection]
param = "myvalue"

------------------

print(ini:r_string("mysection", "param"))
print(ini:r_string_wq("mysection", "param"))

Результаты
Код
"myvalue"
myvalue
vector<result> r_vector(string<section>, string<line>) - разбивает строку вида "param = number,number,number" и возвращает сформированный из этих компонентов вектор.
int32<result> r_s32(string<section>, string<line>) - возвращает 4-байтовое целое число в диапазоне [-2.147.483.648, 2.147.483.647].
uint32<result> r_u32(string<section>, string<line>) - возвращает 4-байтовое беззнаковое целое число в диапазоне [0, 4.294.967.295].
int<item_id> r_token(string<section>, string<line>, token_list*) - довольно интересный метод, который работает следующим образом:
Открыть
Допустим, у нас имеется токен (лист с именами и их идентификаторами):
Код
local my_token = token_list()
my_token:add("value1", 0)
my_token:add("value2", 1)
my_token:add("value3", 2)

И имеется конфиг со строкой:
Код
[mysection]
param = value2

Нам нужно выяснить, какому идентификатору соответствует это значение (и соответствует ли вообще). Читаем:
Код
local item_id = ini:r_token("mysection", "param", my_token)
log(item_id)

Результат
Код
1

(что соответствует value2 = 1).
Если значение в конфиге не соответствует никакому значению из токена, то вернет ноль.

И ещё, сразу сюда же - метод ini_file* create_ini_file(string<file_text>)
Собственно создает конфиг-файл. После чего, с ним можно работать как и с обычным конфигом:
Код
local ini = create_ini_file("[mysection]\nmyparam = value")


З.Ы. Это перенос моего старого поста с другого форума. Пусть будет и здесь.
Перейти в начало страницы
 
 
 Diesel
сообщение 02.07.2020, 20:22
Сообщение #249


Игроман
**********

Группа: Участник
Сообщений: 774
Регистрация: 07.08.2015
Пользователь №: 22230



Вопрос по скрипту ОГСМ ogsm_rt_manager.script. В игре, с локациями ЧН, вылета не было. Вылет идёт по спавну в алспавн мертвого сталкера на новой локации.

--Регистрация целей для тасков типа kill_stalker
function CRandomTask:register_target(obj)
if IsStalker(obj) then
for k,v in pairs(self.task_id_by_type["kill_stalker"]) do -- !!! ТУТ ВЫЛЕТ !!!
if obj.alive ~= nil and obj:alive() == true and
obj:profile_name() == self.task_info[v].target
then
if self.task_info[v].target_objects == nil then
self.task_info[v].target_objects = {}
end
table.insert(self.task_info[v].target_objects, obj.id)
end
end
end
end

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


Может перечисление локаций ЧН сделать, типа такого?
if level.name() == "agroprom_underground" then

Или куда то надо новую локацию прописать или трупы? Тупизна меня обуяла.

А там еще ака Bak намутил rx_wmgr.script - что на сивой кобыле не проехать.

Короче, для нового уровня - ОГСМ - это Ж...

Сообщение отредактировал Diesel - 02.07.2020, 21:15
Перейти в начало страницы
 
 
 Diesel
сообщение 09.08.2020, 02:18
Сообщение #250


Игроман
**********

Группа: Участник
Сообщений: 774
Регистрация: 07.08.2015
Пользователь №: 22230



Кто желает разобраться в хитросплетениях диалога. Вылет идёт когда раненому даю аптечку в ЧН (мод SGM).
Вылетает рандомно. В интернетах разумного ответа нет.

FATAL ERROR

[error]Expression : !phrase_dialog->m_PhraseVector.empty()
[error]Function : CPhraseDialog::SayPhrase
[error]File : .\PhraseDialog.cpp
[error]Line : 146
[error]Description : No available phrase to say, dialog[dm_hello_dialog]


stack trace:

0023:0077B1D3 xrCore.dll, xrDebug::backend(), x:\source_scs602\components\engine\xrcore\xrdebugnew.cpp, 278
0023:0077B381 xrCore.dll, xrDebug::fail(), x:\source_scs602\components\engine\xrcore\xrdebugnew.cpp, 366
0023:046E1113 xrGame.dll, CPhraseDialog::SayPhrase(), x:\source_scs602\components\engine\xrgame\phrasedialog.cpp, 146
0023:046E432A xrGame.dll, CPhraseDialogManager::SayPhrase(), x:\source_scs602\components\engine\xrgame\phrasedialogmanager.cpp, 77
0023:0490187A xrGame.dll, CUITalkWnd::SayPhrase(), x:\source_scs602\components\engine\xrgame\ui\uitalkwnd.cpp, 304
0023:04901D3F xrGame.dll, CUITalkWnd::UpdateQuestions(), x:\source_scs602\components\engine\xrgame\ui\uitalkwnd.cpp, 139
0023:04901EDA xrGame.dll, CUITalkWnd::Update(), x:\source_scs602\components\engine\xrgame\ui\uitalkwnd.cpp, 218
0023:04902317 xrGame.dll, CUITalkWnd::InitTalkDialog(), x:\source_scs602\components\engine\xrgame\ui\uitalkwnd.cpp, 83
0023:04902408 xrGame.dll, CUITalkWnd::Show(), x:\source_scs602\components\engine\xrgame\ui\uitalkwnd.cpp, 240
0023:048E81ED xrGame.dll, CDialogHolder::StartMenu(), x:\source_scs602\components\engine\xrgame\uidialogholder.cpp, 77
0023:048E82E8 xrGame.dll, CDialogHolder::StartStopMenu(), x:\source_scs602\components\engine\xrgame\uidialogholder.cpp, 224
0023:04960A28 xrGame.dll, CUIGameSP::StartTalk(), x:\source_scs602\components\engine\xrgame\uigamesp.cpp, 157
0023:046A956F xrGame.dll, CActor::RunTalkDialog(), x:\source_scs602\components\engine\xrgame\actor_communication.cpp, 210
0023:046A97B8 xrGame.dll, CActor::TryToTalk(), x:\source_scs602\components\engine\xrgame\actor_communication.cpp, 194
0023:046BCFA3 xrGame.dll, CActor::ActorUse(), x:\source_scs602\components\engine\xrgame\actorinput.cpp, 402
0023:046BD47C xrGame.dll, CActor::IR_OnKeyboardPress(), x:\source_scs602\components\engine\xrgame\actorinput.cpp, 144
0023:0468189B xrGame.dll, CLevel::IR_OnKeyboardPress(), x:\source_scs602\components\engine\xrgame\level_input.cpp, 416
0023:00411A02 xrEngine.exe, CInput::KeyUpdate(), x:\source_scs602\components\engine\xrengine\xr_input.cpp, 201

Движковый вылет

bool CPhraseDialog::SayPhrase (DIALOG_SHARED_PTR& phrase_dialog, const shared_str& phrase_id)
{
THROW(phrase_dialog->IsInited());

phrase_dialog->m_SaidPhraseID = phrase_id;

bool first_is_speaking = phrase_dialog->FirstIsSpeaking();
phrase_dialog->m_bFirstIsSpeaking = !phrase_dialog->m_bFirstIsSpeaking;

const CGameObject* pSpeakerGO1 = smart_cast<const CGameObject*>(phrase_dialog->FirstSpeaker()); VERIFY(pSpeakerGO1);
const CGameObject* pSpeakerGO2 = smart_cast<const CGameObject*>(phrase_dialog->SecondSpeaker()); VERIFY(pSpeakerGO2);
if(!first_is_speaking) std::swap(pSpeakerGO1, pSpeakerGO2);

CPhraseGraph::CVertex* phrase_vertex = phrase_dialog->data()->m_PhraseGraph.vertex(phrase_dialog->m_SaidPhraseID);
THROW(phrase_vertex);

CPhrase* last_phrase = phrase_vertex->data();

//вызвать скриптовую присоединенную функцию
//активируется после сказанной фразы
//первый параметр - тот кто говорит фразу, второй - тот кто слушает
last_phrase->GetScriptHelper()->Action(pSpeakerGO1, pSpeakerGO2, *phrase_dialog->m_DialogId, phrase_id.c_str());

//больше нет фраз, чтоб говорить
phrase_dialog->m_PhraseVector.clear();
if(phrase_vertex->edges().empty())
{
phrase_dialog->m_bFinished = true;
}
else
{
//обновить список фраз, которые сейчас сможет говорить собеседник
for(xr_vector<CPhraseGraph::CEdge>::const_iterator it = phrase_vertex->edges().begin();
it != phrase_vertex->edges().end();
it++)
{
const CPhraseGraph::CEdge& edge = *it;
CPhraseGraph::CVertex* next_phrase_vertex = phrase_dialog->data()->m_PhraseGraph.vertex(edge.vertex_id());
THROW (next_phrase_vertex);
shared_str next_phrase_id = next_phrase_vertex->vertex_id();
if(next_phrase_vertex->data()->GetScriptHelper()->Precondition(pSpeakerGO2, pSpeakerGO1, *phrase_dialog->m_DialogId, phrase_id.c_str(), next_phrase_id.c_str()))
{
phrase_dialog->m_PhraseVector.push_back(next_phrase_vertex->data());
#ifdef DEBUG
if(psAI_Flags.test(aiDialogs))
{
LPCSTR phrase_text = next_phrase_vertex->data()->GetText();
shared_str id = next_phrase_vertex->data()->GetID();
Msg("----added phrase text [%s] phrase_id=[%s] id=[%s] to dialog [%s]", phrase_text, phrase_id, id, phrase_dialog->m_DialogId.c_str());
}
#endif
}

}

R_ASSERT2 (
!phrase_dialog->m_PhraseVector.empty(),
make_string(
"No available phrase to say, dialog[%s]",
*phrase_dialog->m_DialogId
)

);

//упорядочить списко по убыванию благосклонности
std::sort(phrase_dialog->m_PhraseVector.begin(),
phrase_dialog->m_PhraseVector.end(), PhraseGoodwillPred);
}



//сообщить CDialogManager, что сказана фраза
//и ожидается ответ
if(first_is_speaking)
phrase_dialog->SecondSpeaker()->ReceivePhrase(phrase_dialog);
else
phrase_dialog->FirstSpeaker()->ReceivePhrase(phrase_dialog);


return phrase_dialog?!phrase_dialog->m_bFinished:true;
}


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

Сообщение отредактировал Diesel - 09.08.2020, 02:49
Перейти в начало страницы
 
 
 Pavel_Blend
сообщение 07.09.2020, 16:02
Сообщение #251


Продвинутый геймер
********

Группа: Участник
Сообщений: 314
Регистрация: 12.11.2012
Пользователь №: 15200



Недавно возобновил изучение луа. Вот вроде бы проще питона, но как-то труднее его изучить. Может из-за того, что желание изучать меньше. В общем пытаюсь хоть что-то сделать в скриптах. Максимум удалось вывести сообщение в консоль. При изучении нужно знать две вещи: сам луа и собственно функции движка (в блендере это называется API, наверное в X-Ray это тоже API в виде lua функций).
С первым вроде бы понятно, информацию найти можно, а вот со вторым труднее. Читал на АМК посты по функциям и ничего не понятно.

В общем вопросы (эти вопросы по ТЧ скриптам):

как вообще можно встроить свои собственные скрипты в сталкер? Я пока знаю, что можно в диалогах прописать вызов скрипта и функции. А какие ещё способы есть?

И как сделать редактор погоды в игре? Чтобы нажать клавишу, после чего появятся интерфейс с крутилками (которые управляются клавиатурой), который будет в углу и не будет загораживать обзор и при появлении этих крутилок можно спокойно перемещаться по локации (то есть движение мыши не блокируется, как это происходит при открытии инвентаря). И как сделать печать изменённых параметров погоды на экран (чтобы можно было сделать скрин параметров, а потом переписать их в конфиг)?
Перейти в начало страницы
 
 
 RayTwitty
сообщение 07.09.2020, 21:20
Сообщение #252


Босс
********************

Группа: Участник
Сообщений: 4296
Регистрация: 24.09.2010
Пользователь №: 14086



Цитата(Pavel_Blend @ 07.09.2020, 16:02) *
При изучении нужно знать две вещи: сам луа и собственно функции движка (в блендере это называется API, наверное в X-Ray это тоже API в виде lua функций).

Луа в сталкере это по сути интерфейс, осуществляющий доступ к внутридвижковым объектам. Этакая надстройка на логикой внутри движка.

Цитата(Pavel_Blend @ 07.09.2020, 16:02) *
как вообще можно встроить свои собственные скрипты в сталкер? Я пока знаю, что можно в диалогах прописать вызов скрипта и функции. А какие ещё способы есть?

Можно просто вызвать любую функцию в скрипте, тогда он инициализируется. Поскольку, почти все начинают работать с конкретными объектами и чаще всего с актором, свои скрипты инициализируют из bind_stalker.script.

Цитата(Pavel_Blend @ 07.09.2020, 16:02) *
И как сделать редактор погоды в игре?

В ТЧ без правок движка никак. Исходя из первой моей цитаты, тебе потребуется написать экспорт движковых функций в Lua, после чего написать на основе оконной системы сталкера весь интерфейс. Задача весьма нетривиальная и не на пару часов.

Сообщение отредактировал RayTwitty - 07.09.2020, 21:22
Перейти в начало страницы
 
 
 Pavel_Blend
сообщение 08.09.2020, 17:44
Сообщение #253


Продвинутый геймер
********

Группа: Участник
Сообщений: 314
Регистрация: 12.11.2012
Пользователь №: 15200



Цитата(RayTwitty @ 07.09.2020, 21:20) *
Можно просто вызвать любую функцию в скрипте, тогда он инициализируется. Поскольку, почти все начинают работать с конкретными объектами и чаще всего с актором, свои скрипты инициализируют из bind_stalker.script.

а вообще, какой принцип работы скриптов в сталкере? Вот в blender game engine есть такое понятие, как такт, который длится 1/60 секунд. Во время этого такта выполняются действия. А в сталкере как всё работает? Например, как работает bind_stalker? В этом скрипте каждый кадр выполняется определённая функция? Или данный скрипт выполняется один раз за весь сеанс игры? И вообще где выполняется основная работа скриптовой системы? Вот к примеру скрипт из диалога выполнится только один раз. А какие скрипты непрерывно работают в игре и обрабатывают события?
Перейти в начало страницы
 
 
 Diesel
сообщение 08.09.2020, 21:35
Сообщение #254


Игроман
**********

Группа: Участник
Сообщений: 774
Регистрация: 07.08.2015
Пользователь №: 22230



Pavel_Blend, движок заранее заготовленные внедряет свои щупальца в скрипты. И ждёт их изменений, согласно обновлений в движке.
В движке создаются скрипты, как основа, для луа. Каждая функция луа, заранее прописана в движок. Если и не прописана, то предок этой функции всё равно в движке есть.

В поиск визуалки забей .def и увидишь сколько их там.

Сообщение отредактировал Diesel - 08.09.2020, 21:56
Перейти в начало страницы
 
 
 RayTwitty
сообщение 08.09.2020, 23:06
Сообщение #255


Босс
********************

Группа: Участник
Сообщений: 4296
Регистрация: 24.09.2010
Пользователь №: 14086



Цитата(Pavel_Blend @ 08.09.2020, 17:44) *
В этом скрипте каждый кадр выполняется определённая функция?

Нет, в движке есть глобальный шедулер (апдейтер), из которого уже апдейтятся все онлайновые объекты (он в свою очередь вроде бы как раз из рендера должен вызываться, но я уже не помню). Покадрового апдейта в скриптах нет, у актора вроде бы интервал каждые 20-40 мс, он динамичен, для этого есть переменная delta в аргументе. У других объектов интервал в целях оптимизации может быть больше.

Цитата(Pavel_Blend @ 08.09.2020, 17:44) *
Или данный скрипт выполняется один раз за весь сеанс игры?

Код который ничем не обернут (не в функции, не в таблице и т.д.), вызывается при инициализации скрипта. Сам скрипт может инициализироваться только при его вызове, и это не гарантированно при старте игры. бинд_сталкер например инитится при появлении онлайнового актора, если конечно до этого момента еще кто-нибудь в этот скрипт не полезет за чем нибудь. Проще говоря, скрипты инициализируются по мере надобности.

Плюс те же функции в биндерах, вызываются при определенных события. Например net_spawn при появлении актора на уровне, update - периодический апдейт (см. выше) и т.д.

Цитата(Pavel_Blend @ 08.09.2020, 17:44) *
А какие скрипты непрерывно работают в игре и обрабатывают события?

Ну кроме апдейта объектов и некоторых апдейтов в UI-интерфейсах таких нет.
Перейти в начало страницы
 
 
 Pavel_Blend
сообщение 10.09.2020, 12:23
Сообщение #256


Продвинутый геймер
********

Группа: Участник
Сообщений: 314
Регистрация: 12.11.2012
Пользователь №: 15200



А с помощью скриптов возможно сделать такую вещь:

добавить отметки в пда на все динамические объекты. На сталкеров, на мутантов, тайники, физические объекты, лампочки, бочки, аномалии, еду, патроны, оружие. В общем на всё. И сделать так, чтобы при убийстве сталкера, в пда была метка его трупа. Только метка меняла цвет на серый. Была метка бандита, к примеру, красной, а при убийстве стала серой. И чтобы можно было скрывать метки по типу: аномалии, тайники, трупы, физ. объекты и т. д.

И как можно полностью отключить респавн? Чтобы новые мутанты и сталкеры не появлялись?
Перейти в начало страницы
 
 
 Yara
сообщение 10.09.2020, 21:31
Сообщение #257


Геймер
******

Группа: Участник
Сообщений: 101
Регистрация: 20.03.2014
Из: omsk
Пользователь №: 19526



Цитата(Pavel_Blend @ 10.09.2020, 15:23) *
И как можно полностью отключить респавн? Чтобы новые мутанты и сталкеры не появлялись?

Попробуй в se_respawn.script заремить строку self:spawn(), а для отметок всего использую такое:
...

CODE

По клавише в главном меню: ui_main_menu.script,
-----------------------------
function main_menu:OnKeyboard(dik, keyboard_action) --virtual function
...
if keyboard_action == ui_events.WINDOW_KEY_PRESSED then
...
if dik == DIK_keys.DIK_NUMPAD0 then
if (level.present() and db.actor ~= nil and db.actor:alive()) then
this.mark_all_objects()
end
end



В самый конец файла добавить:

function mark_all_objects()
for i=1,65535,1 do
local obj = alife():object(i)
if (obj and obj.parent_id and obj.parent_id == 65535) then
local obj_name = obj:name()

-- from _g.script

if (IsStalker(obj)) then
level.map_add_object_spot(obj.id, "obj_location", tostring(obj_name))
end
if (IsMonster(obj)) then
--if (IsMonster(obj) and obj:alive()) then -- только живых
level.map_add_object_spot(obj.id, "obj_location", tostring(obj_name))
end

if (
isWeapon(obj) or -- оружие

-- from lua_help.script

get_clsid(obj)==clsid.wpn_ammo or -- патроны
get_clsid(obj)==clsid.wpn_ammo_og7b or -- выстрелы рг/пг
get_clsid(obj)==clsid.wpn_ammo_vog25 or
get_clsid(obj)==clsid.wpn_ammo_m209 or

get_clsid(obj)==clsid.obj_explosive or -- взрывные бочки и прочее

get_clsid(obj)==clsid.obj_food or -- еда и медицина
get_clsid(obj)==clsid.obj_antirad or
get_clsid(obj)==clsid.obj_bandage or
get_clsid(obj)==clsid.obj_bottle or
get_clsid(obj)==clsid.obj_medkit or

get_clsid(obj)==clsid.equ_stalker_s or -- костюмы

get_clsid(obj)==clsid.artefact_s or -- арты
get_clsid(obj)==clsid.artefact or

get_clsid(obj)==clsid.inventory_box or -- тайники
get_clsid(obj)==clsid.obj_phskeleton or -- физ.объекты
get_clsid(obj)==clsid.obj_phys_destroyable or
get_clsid(obj)==clsid.obj_physic or
get_clsid(obj)==clsid.obj_breakable or
get_clsid(obj)==clsid.script_phys or
get_clsid(obj)==clsid.obj_climable or -- лестницы
get_clsid(obj)==clsid.projector or -- прожектор
get_clsid(obj)==clsid.hanging_lamp or -- лампочки

get_clsid(obj)==clsid.ameba_zone or -- аномалии
get_clsid(obj)==clsid.torrid_zone or
get_clsid(obj)==clsid.zone or
get_clsid(obj)==clsid.zone_acid_fog or
get_clsid(obj)==clsid.zone_bfuzz_s or
get_clsid(obj)==clsid.zone_dead or
get_clsid(obj)==clsid.zone_galant_s or
get_clsid(obj)==clsid.zone_galantine or
get_clsid(obj)==clsid.zone_mbald_s or
get_clsid(obj)==clsid.zone_mincer_s or
get_clsid(obj)==clsid.zone_mosquito_bald or
get_clsid(obj)==clsid.zone_radioactive or
get_clsid(obj)==clsid.zone_rusty_hair or
get_clsid(obj)==clsid.nogravity_zone or

get_clsid(obj)==clsid.level_changer or -- переходы
get_clsid(obj)==clsid.respawn or -- респавнеры
get_clsid(obj)==clsid.smart_terrain or -- смарты
get_clsid(obj)==clsid.script_restr or -- рестрикторы
get_clsid(obj)==clsid.script_zone or
get_clsid(obj)==clsid.car_s or -- машины
get_clsid(obj)==clsid.script_heli or -- вертолёты
get_clsid(obj)==clsid.helicopter
)
then
level.map_add_object_spot(obj.id, "obj_location", tostring(obj_name))
end

end
end
end



Добавить в map_spots.xml,
-----------------------------
<!-- debug icon -->
<obj_location>
<level_map spot="obj_location_spot"/>
<mini_map spot="obj_location_spot"/>
</obj_location>
<obj_location_spot x="0" y="0" width="4" height="4" alignment="c" stretch="1">
<texture r="0" g="255" b="255">ui_minimap_point</texture>
</obj_location_spot>

Перейти в начало страницы
 
 
 RayTwitty
сообщение 12.09.2020, 23:30
Сообщение #258


Босс
********************

Группа: Участник
Сообщений: 4296
Регистрация: 24.09.2010
Пользователь №: 14086



Цитата(Pavel_Blend @ 10.09.2020, 12:23) *
А с помощью скриптов возможно сделать такую вещь:

добавить отметки в пда на все динамические объекты. На сталкеров, на мутантов, тайники, физические объекты, лампочки, бочки, аномалии, еду, патроны, оружие. В общем на всё.

Можно. Перебираешь все айдишники (1..65536, 0 - актор, его пропускаем) объектов в игре через alife():object(id), или если нужно только онлайновых то level.object_by_id(id). Добавляем метку через level.map_add_object_spot.

Цитата(Pavel_Blend @ 10.09.2020, 12:23) *
И сделать так, чтобы при убийстве сталкера, в пда была метка его трупа. Только метка меняла цвет на серый. Была метка бандита, к примеру, красной, а при убийстве стала серой.

Так это штатный механизм ПДА. Надо только тег level_spot/mini_spot в xml конфиге проверить/сделать.

Цитата(Pavel_Blend @ 10.09.2020, 12:23) *
И чтобы можно было скрывать метки по типу: аномалии, тайники, трупы, физ. объекты и т. д.

Для этого нужно написать UI, в котором добавлять/удалять метки по типу объекта. Скрывать нельзя, только если экспортировать из движка получение CUIStatic метки.

Цитата(RayTwitty @ 07.09.2020, 21:20) *
В ТЧ без правок движка никак. Исходя из первой моей цитаты, тебе потребуется написать экспорт движковых функций в Lua, после чего написать на основе оконной системы сталкера весь интерфейс. Задача весьма нетривиальная и не на пару часов.

Вот кстати чувак сделал консольные команды, к которым можно привязаться в интерфейсе (IMG:style_emoticons/default/biggrin.gif)
https://www.gameru.net/forum/index.php?s=&a...t&p=1680713
Правда команд мало, и вообще это нужно было бы сделать через экспорт методов, но уж как есть.
Перейти в начало страницы
 
 
 Pavel_Blend
сообщение 13.09.2020, 13:01
Сообщение #259


Продвинутый геймер
********

Группа: Участник
Сообщений: 314
Регистрация: 12.11.2012
Пользователь №: 15200



RayTwitty, попробовал редактор погоды. Трудновато редактировать. Хотелось бы иметь ползунки, чтобы плавно менять цвета. Ну или чтобы были горячие клавиши. Например, стрелки (вниз-вверх - листать параметры, влево-вправо - менять значения параметров). И ещё трудно угадать цвет солнца. Всё таки без игрового редактора удобнее тем, что можно загрузить в фотошоп текстуру неба и пипеткой скопировать цвет солнца. А потом пропорционально его увеличить или уменьшить.

А что ещё интересного можно сделать с помощью скриптов, кроме проставления меток?

И вопрос: я проставил метки на всех сталкеров и удалил респавн. Зачистил локации от врагов, но не от всех. Остались монолитовцы, к примеру. Они видны на карте, но их там нет. И монстры. Монолитовцы в припяти возле гаражей у костра. Они не спавнятся. Не выполнено определённое условие для их спавна. В userdata у них прописано это:

CODE
[smart_terrains]
none = true

[logic]
active = kamp1
combat_ignore = combat_ignore

;on_signal = arrived | camper2 %+pri_wave1_side_start%

[kamp1]
center_point = pri_sideway_left_kamp

[combat_ignore]


Как заспавнить с помощью скриптов объекты, которые уже есть, но не заспавнены (как монолитовцы).

(IMG:https://images.gameru.net/thumb/a2a1f2326979e8c.jpg)
Перейти в начало страницы
 
 
 AndreySol
сообщение 30.09.2020, 17:06
Сообщение #260


Геймер
******

Группа: Участник
Сообщений: 149
Регистрация: 16.02.2014
Пользователь №: 19339



Цитата
А что ещё интересного можно сделать с помощью скриптов, кроме проставления меток?

Ну так весь сюжет в общем-то скриптами строится. Вся логика объектов в конечном счете разворачивается в скрипты(xr_logic.script и все схемы поведения), все гулаги и их работы(xr_gulag.script). Спавн объектов, всякие UI-окна с различным функционалом.
Перейти в начало страницы
 
 
 
 

 
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 

Текстовая версия Сейчас: 30.10.2020, 23:16