Страница 3 из 4

Re: Скриптование сценариев

СообщениеДобавлено: 18.12.2020, 18:18
aleksei999
Светлана,вот скрипт. Или надо полностью?

Добавлено спустя 25 минут 34 секунды:
Вот полный
function OnEvent ( event )

if ( event == "cinematic" ) then
SysCall ( "ScenarioManager:LockControls" ) ;
SysCall ( "CameraManager:ActivateCamera" , "introcinematic" , 0 ) ;
end

if ( event == "cabcamera") then
SysCall ( "CameraManager:ActivateCamera" , "CabCamera" , 0 ) ;
SysCall ( "ScenarioManager:UnlockControls" ) ;
end

if ( event == "introM62" ) then
SysCall ( "M62:SetControlValue" , "Horn" , 0 , 1 ) ;
SysCall ( "ScenarioManager:TriggerDeferredEvent" , "OfTiffon" , 1 ) ;
return TRUE ;
end

if ( event == "OffTifon" ) then
SysCall ( "M62:SetControlValue" , "Horn" , 0 , 0 ) ;
return TRUE ;
end

if ( event == "introM62" ) then
SysCall ( "M62:SetControlValue" , "Horn" , 0 , 1 ) ;
SysCall ( "ScenarioManager:TriggerDeferredEvent" , "OffTifon" , 1 ) ;
return TRUE ;
end

if ( event == "OffTifon" ) then
SysCall ( "M62:SetControlValue" , "Horn" , 0 , 0) ;
return TRUE ;
end

if ( event == "introIR1" ) then
SysCall ( "IR1:SetControlValue" , "Horn" , 0 , 1) ;
SysCall ( "ScenarioManager:TriggerDeferredEvent" , "OffTifon" , 2 ) ;
return TRUE ;
end

if ( event == "OffTifon" ) then
SysCall ( "IR1:SetControlValue" , "Horn" , 0 , 0) ;
return TRUE ;
end

if ( event == "introM62" ) then
SysCall ( "M62:SetControlValue" , "Horn" , 0 , 1) ;
SysCall ( "ScenarioManager:TriggerDeferredEvent" , "OffTifon" , 1 ) ;
return TRUE ;
end

if ( event == "OffTifon" ) then
SysCall ( "M62:SetControlValue" , "Horn" , 0 , 0) ;
return TRUE ;
end


return FALSE ;
end

function TestCondition ( condition )
end

Re: Скриптование сценариев

СообщениеДобавлено: 18.12.2020, 21:37
Света
Ну, понятно, тот блок, где подается команда на выключение тифона ЭР1 попросту не выполняется.
Принцип работы этого куска кода такой: сначала в сценарии задается событие "introIR1", которое в скрипте вызывает функцию OnEvent (event). В этой функции в строке 58 (if event == "introIR1" then) условие сравнения выполняется, после чего в строке 59 устанавливается контрол "Horn", а в следующей строке (60) запускается следующее событие "OffTifon", которое должно будет выполнится через 2 секунды. После чего через оператор return выполнение функции завершается. Когда эти 2 секунды проходят, по этому событию ("OffTifon") вызывается функция OnEvent (event), в строке 42 выполняется условие (if event == "OffTifon" then), после чего программа попытается выключить тифон у М62 в строке 43 и завершит функцию в строке 44, не добравшись до условия в строках 64, 65 и 66. Именно поэтому тифон ЭР1 не выключился.
Вот тот же скрин, где я зеленым цветом показываю прохождение по функции при первом вхождении, а красным - при втором:
Изображение

Вот скрин полной версии функции, открытый в Programmer`s Notepad. Всего в теле функции присутствует целых 4 однотипных условия "if (event == "OffTifon") then", что в данном случае является ошибкой, так как в первом из них выполнение функции прекратится по оператору return и остальные три не выполнятся никогда. Также имеется опечатка: в строке 15 задается отложенное событие "OfTiffon", которого нет в функции OnEvent:
Изображение

Для того, чтобы запустить тифон электрички, а потом, спустя 2 секунды, выключить его, достаточно такой функции:
Код: Выделить всё
function OnEvent ( event )

--   if ( event == "cinematic" ) then
--      SysCall ( "ScenarioManager:LockControls" ) ;
--      SysCall ( "CameraManager:ActivateCamera" , "introcinematic" , 0 ) ;
--   end

--   if ( event == "cabcamera") then
--      SysCall ( "CameraManager:ActivateCamera" , "CabCamera" , 0 ) ;
--      SysCall ( "ScenarioManager:UnlockControls" ) ;
--   end

   if event == "introIR1" then
      SysCall ("IR1:SetControlValue", "Horn", 0, 1)
      SysCall ("ScenarioManager:TriggerDeferredEvent", "OffTifon_ER1", 2)
      return TRUE
   end

   if event == "OffTifon_ER1" then
      SysCall ("IR1:SetControlValue", "Horn", 0, 0)
      return TRUE
   end
   
   return FALSE ;
end

При этом начальные 2 ветки закомментированы, так как я не знаю, используются ли они в сценарии, если да - то их надо раскомментировать.

Re: Скриптование сценариев

СообщениеДобавлено: 19.12.2020, 19:11
aleksei999
Светлана! Огромнейшее Вам спасибо! Все получилось! Просто сменил однотипные условия-OffTifon на OffTifon_IR1, и убрал опечатку, как Вы показали. Теперь у меня при отправлении 3ТЭ10М-0037 подает два гудка,потом ЭРка по прибытии сигналит 3 секунды,ну и напоследок проезжая мимо игрока тот же 3ТЭ10м подает сигнал. Все работает! Спасибо еще раз,сам бы не справился))

Re: Скриптование сценариев

СообщениеДобавлено: 21.12.2020, 01:00
ПитерМен
Приветствую!
Тоже заинтересовала данная тематика около полугода назад, почитав форум и в частности эту тему, обнаружил интересное решение от Konst-81. Скрипт рабочий, но при реализации в сценарии возникли проблемы. Основная проблема состоит в том, что при включенном EAX звук сигналов (тифон, свисток) присутствует только на внешней камере, а в кабине отсутствует, кроме ЭР1-159 и TЭП70 (что для меня остается загадкой т.к. в конфигах звука прописан параметр PlayState как OUTSIDE - только снаружи, а не BOTH). Глубоко не копая, для себя решил проблему заменой в конфигах звука всего ПС параметра OUTSIDE на BOTH, но сценарии делаются не только для себя (кстати, переделаны и перезалиты два последних сценария, "порожняк" и "поезд №2777", но они даже не анонсированы по вышеуказанной причине, мало кто катается на внешней камере). С выходом 3ТЭ10М возник еще вопрос. Реализация свистка сделана немного необычно. В контрол "Horn" нужно задать значение "-1". Вопрос к Свете, как грамотно реализовать это в скрипте от Konst-81?

Re: Скриптование сценариев

СообщениеДобавлено: 21.12.2020, 08:04
Света
За скрипт от Konst-81 не знаю, простых и универсальных решений, чтобы при таком алгоритме отрабатывались отрицательные значения, я не нахожу. Могу предложить другой вариант, свою более современную версию:
Код: Выделить всё
------------------------------------------------
-- Scenario Script
------------------------------------------------

-- true/false defn
FALSE = 0
TRUE = 1

------------------------------------------------
-- Fn OnEvent
function OnEvent (event)
   if string.lower (string.sub (event, 1, 6)) == "signal" then
      local event_data = string.split (event, "*")
      --[1] - событие ("Signal")
      --[2] - номер локомотива
      --[3] - локомотив
      --[4] - тип сигнала
      --[5] - продолжительность
     
      local tab_locomotive = {
         ["3te10m"]   = {horn = {name = "Horn", on = 1, off = 0}, whistle = {name = "Horn", on = -1, off = 0}},
         ["tem2"]   = {horn = {name = "Horn", on = 1, off = 0}, whistle = {name = "Whistle", on = 1, off = 0}},
      }
    
     event_data[3] = string.lower (event_data[3])
     event_data[4] = string.lower (event_data[4])
      
      local control = tab_locomotive[event_data[3]][event_data[4]].name
      local value_on = tonumber (tab_locomotive[event_data[3]][event_data[4]].on) or 0
      local value_off = tonumber (tab_locomotive[event_data[3]][event_data[4]].off) or 0
      local delay = tonumber (event_data[5]) or 0
     
      if delay > 0 then
         SysCall (event_data[2]..":SetControlValue", control, 0, value_on)
         event_data[5] = "0"
         SysCall ("ScenarioManager:TriggerDeferredEvent", table.concat (event_data, "*"), delay)
      else
         SysCall (event_data[2]..":SetControlValue", control, 0, value_off)
      end
      return 1
   end

   -- Другие события   
   --   if event == ... then
   --   [...]
   --   end
   
   return 0
   
end -- function OnEvent (event)

function string:split (delimiter)
   local result = {}
   local from  = 1
   local index = 1
   local delim_from, delim_to = string.find (self, delimiter, from)

   while delim_from do
      result[index] = string.sub(self, from , delim_from - 1)
      from  = delim_to + 1
      delim_from, delim_to = string.find (self, delimiter, from)
      index = index + 1
   end

   result[index] = string.sub (self, from)
   return result
end


Как пользоваться этой штукой? Самая важная часть программы - таблица локомотивов. Сейчас в ней вписаны 2 локомотива - 3ТЭ10М и ТЭМ2. Это для примера. Если надо заставить посигналить другой локомотив, его надо добавить в эту таблицу, указав удобное название локомотива, имена контролов и их значения во включенном и выключенном состояниях, сохранив структуру таблицы. Все записи в таблице должны быть прописными буквами (кроме названий контролов, там надо сохранять оригинальный регистр), это важно!
Событие подается в таком виде: "Signal*номер_локомотива*тип_локомотива*тип_сигнала*длительность". Здесь:
- "Signal" - метка события, запускающая функцию;
- "номер_локомотива" - бортовой номер локомотива, который должен подать сигнал;
- "тип_локомотива" - марка (или тип, как правильней), то, что указано в таблице скрипта ("3te10m", "tem2" и т.д.);
- "тип_сигнала" - категория, заданная в таблице скрипта. Для "3te10m", например, это horn и whistle;
- "длительность" - время в секундах, которое должен подаваться сигнал перед выключением. Только целые числа, дроби не поддерживаются симулятором!
Пример события для обработки: "Signal*16174756*3te10m*horn*2" - локомотив 3ТЭ10М, бортовой номер 16174756, подаст тифон на протяжении 2 сек; "Signal*16174756*3te10m*whistle*1" - тот же тепловоз подаст свисток длительностью 1 сек.

Типы локомотивов и типы сигналов могут иметь любые названия. Вполне допустимо такое поле в таблице:
Код: Выделить всё
["drugoi_lok"]   = {dudelka = {name = "Houkacka", on = 1, off = 0}, svistelka = {name = "Pistala", on = -1, off = 0}},

Тогда вызов уже будет выглядеть, как пример, таким образом: "Signal*1111*drugoi_lok*svistelka*2", "Signal*1111*drugoi_lok*dudelka*2"

Если событие задано правильно и отработано функцией, то в логмейте (когда он запущен) будет сделана запись об этом. Также следом запишется выполнение автоматически сгенерированного события, выключающего сигнал:
[Scenario Manager 6:22:36] Trace cScenarioManager.cpp : 3846 = Event: Signal*16174756*3te10m*horn*2 handled
[Scenario Manager 6:22:38] Trace cScenarioManager.cpp : 3846 = Event: signal*16174756*3te10m*horn*0 handled

По этим записям можно контролировать работу функции.

Функция string:split (delimiter) обязательно должна быть в скрипте, в любом месте.

Re: Скриптование сценариев

СообщениеДобавлено: 21.12.2020, 17:05
ПитерМен
Света, спасибо вам за участие и потраченное время!
Спасибо за идею, теперь, насколько я понял (еще не пробовал), можно вписать оригинальный номер локомотива, что актуально для ТЭМ2 (чтобы не пропадал номер на борту тепловоза), а также за подробное объяснение с примерами!
:clap2:

Re: Скриптование сценариев

СообщениеДобавлено: 28.12.2020, 22:47
aleksei999
Здравствуйте! Это опять я. Не выдержал все же,у самого не получилось. Может кто нибудь знает? Допустим, если мы ставим в трафик такие локи как 2Тэ10м-Mozaj,ЭР-1-159, вообщем у которых реализован прожектор,буферники и.т.п. Я пытался через скрипт сценария включить прожектор в ЭРке,у меня ничего не вышло :( Может кто нибудь пробовал? Может есть пример скрипта? Поделитесь пожалуйста....

Re: Скриптование сценариев

СообщениеДобавлено: 29.12.2020, 16:36
hellishfire
Алексей, суть в том, что почти всегда у ПС свои названия контролов - переменных, которые задаёт автор ПСа. На примере свистков и тифонов это видно.
Нужно сначала узнать название контрола, который отвечает за нужный эффект. Для этого можно либо ковырять конфиг ПСа, либо запускать симулятор с доп. параметром -EnableStateDialog и (важно) запустить симулятор в окне.
При запуске сценария с выбранным ПСом окно будет выглядеть так:
Изображение
В нём можно увидеть список контролов этого ПС и их текущие значения.
Из него мы видим, что ЭР1 контрол прожектора - Prozhektor
Соответственно, SysCall ("номер_вашего_пс:SetControlValue", "Prozhektor", 0, 1)

Re: Скриптование сценариев

СообщениеДобавлено: 29.12.2020, 23:06
aleksei999
Игорь,спасибо! Включил прожектор на трафиковой Эрке,как Вы сказали! Получилось)

Re: Скриптование сценариев

СообщениеДобавлено: 25.03.2021, 21:19
andreyprotaskin
Здравствуйте! А как писать производственный скрипт для Railworks Train Simulator?

Re: Скриптование сценариев

СообщениеДобавлено: 25.03.2021, 22:04
Света
Offtopic :
Ваше Высочайшее Величество! Не велите казнить, велите слово молвить! Прошу Вас милостиво соблаговолить и, тем самым, снизойти к пояснению недостойным, что есть "производственный скрипт" и какие скрипты, помимо оного, ещё могут быть? Опасаясь Вашего праведнейшего гнева, осмелюсь предложить Вашему Монаршему Достоинству проследовать по этой ссылке, осчастливить своим вниманием находящийся там таинственный пергамент с секретными знаниями и до тех пор, пока не выучишь все там написанное наизусть, умоляю, не задавай больше этот вопрос, не заставляй тебя банить за нарушение правил!

Re: Маршрут "ст.им.Шевченко - Цветково"

СообщениеДобавлено: 19.08.2021, 21:36
djus
Offtopic :
А возможно с помощью скрипта в сценарии реализовать падение давления в ТМ (Продувка) ?

Re: Маршрут "ст.им.Шевченко - Цветково"

СообщениеДобавлено: 19.08.2021, 21:53
stoune
Offtopic :
Есть же для этого специальная тема для таких вопросов. В теории продувку в сценарии можно сделать. Но это надо точно знать и понимать на какой контрол воздействовать. И скорее всего, это возможно только если ПС поддерживает такое воздействие. Т.е. у ПСа должен быть какой то свободный невидимый контрол концевого крана по типу стоп-крана только без видимой анимации. И в рамках РВ это будет чисто визуал на манометрах.

Re: Скриптование сценариев

СообщениеДобавлено: 18.02.2023, 17:10
ПитерМен
Приветствую.
ПитерМен писал(а):Возник еще вопрос. А как грамотно заслать в контрол "Horn" "1"? С оригинальным номером ЭРки у меня не прокатывает. Если заменить в номере вагона буквы "ER" на цифры, то контрол работает. Но пропадают буквы"ЭР" в номере на борту и "морде" вагона (видимо движок игры не дружен с буквами в номерах ПС).

Света писал(а):Могу предположить, что был неверный регистр, а симулятор очень к этому чувствительный.

Света, вы, как всегда, правы. Мой косяк. :fool: Не обратил внимание на строку:
local event_data = string.split (string.lower (event), "*")
из вашего кода, который взял отсюда. Заменив строку на:
local event_data = string.split ((event), "*") - все заработало.
Так что буквы в номерах ПС допустимы и ЭРка с оригинальным номером исправно подает звуковые сигналы.
P.S.
Спасибо Свете за помощь и Олегу за классную ЭРку из моего детства.

Re: Скриптование сценариев

СообщениеДобавлено: 18.02.2023, 23:33
Света
Спасибо!
На самом деле, косяк, как раз, мой - мне следовало быть повнимательнее и сообразить сразу, что string.lower не только устранит возможные ошибки регистра (ради чего, собственно, эта функция и применена), а и переформатирует номер локомотива, чего делать нельзя.
За спасибо - спасибо, а за невнимательность и косяк - сорри, не со зла...