Информация: Уважаемые посетители! В течение нескольких месяцев на форуме существовала проблема с регистрацией новых пользователей, о которой администрации стало известно недавно. Если вы ранее пытались зарегистрироваться на форуме, но не получили на ваш e-mail письмо с ссылкой для подтверждения регистрации, просим вас зарегистрироваться повторно. Приносим извинения за доставленные неудобства. Если вы все еще испытываете проблемы с регистрацией на форуме, обратитесь за помощью на e-mail: mr.angelo@railroadsim.net

supermax
 
Сообщения: 596
Зарегистрирован: 24.08.2011, 14:03
Откуда: Краснодар
Играю в: Train Simulator Classic
Имя: Максим
Блог: Просмотр блога (2)
Архивы
- Июль 2013
+ Декабрь 2011
Поиск в блогах

1 из 52 из 53 из 54 из 55 из 5

Скриптование ПС для Railworks 4

Постоянная ссылка supermax 15.07.2013, 14:29

Есть такая область в RW, которая не была затронута в DevDocs обстоятельно - это скриптование. Как правильно и как грамотно писать скрипты разработчики игры решили не писать, чтобы не способствовать конкуренции. В данной
статье по максимуму будет приоткрыта завеса тайны в этот прекрасный и богатый мир скриптования.

Пункт 1. Введение
Скрипты в RW пишутся на языке сценариев Lua, изучение синтаксиса которого не вызовет особых проблем для начинающих. Какой функционал доступен? По сути доступен весь функционал языка версии 5.1, за исключением того, что
разработчики не могут писать вставки на C++ или пользоваться интерфейсом программированяи приложений (API).
Основы языка можно постигать с помощью http://www.lua.ru, а для пользователей, владеющих английским языком, есть расширенная версия: http://www.lua.org


Пункт 2. Основы языка
В lua нам при скриптовании подвижного состава прийдётся оперировать следующими типами данных:
1) числовой (number);
2) строка (string);
3) логический (boolean);
4) функция (function).
Ещё есть поток, неопределённый тип, пользовательские данные, таблица, но эти типы данных при скриптовании с большей вероятностью не пригодятся не пригодятся. А если и пригодятся - то подробно о них можно почитать на сайтах
http://www.lua.ru и http://www.lua.org.
Lua отличается от многих языков программирования динамической типизацией. Переменная может возникнуть хоть посредине или в конце скрипта и при этом не требуется её предварительного объявления. Также переменные склоны к
полиморфизму, очень легко перетекают из одного типа в другой.
var = 1
var = "Hello!"
var = true
function var
Переменная var была по всем 4 типам данных описанных выше соответственно. Но если необходимо пользоваться одним именем переменной, но переменная будет иметь разные имена, то может использоваться "венгерская" система
озаглавливания: перед именем переменной ставить префикс её типа (у функции нет префикса!):
Код: Выделить всё
строка-> s_[имя переменной]
числовой-> n_[имя переменной]
логический-> b_[имя переменной]

Далее рассмотрим ключевые слова, которые могут понадобиться для составления условий:
and - оператор для увязки двух условий одновременно и то и то. Если оба условия правда, то выполняются операторы следующие после then, если нет, то или конец или выполнение операторов после else(elseif).
or - оператор для выбора или то или то. Выполнение по ветви да, по сути происходит, если хотя бы одно из условий правда, если оба ложь, то идём по else(elseif).
not - отрицания, если не это, то в случае правды по ветви then. В случае лжи по ветви else(elseif) или конец.
nil - равноценно отрицанию.
А вот кстати и операции сравнения, которые пригодятся в скриптах:
Код: Выделить всё
 ==    ~=    <     >     <=    >=

1) "==" применяется при сравнении на равенство в условиях, например:
Код: Выделить всё
if(var == 3) then..
end

2) "не равно" применяется, когда необходимо проверить, а переменная "не равна данному числу или данным символам"?
Код: Выделить всё
if(var ~=9) then..
end

3) знак меньше или больше, а также меньше или равно, больше или равно - сравнение с числами, и только для числовых переменных применяются данные знаки!
В основном при написании скрипта к подвижному составу создаются условия, обращения к зарезервированным функциям, получениям их значениям, присваивание новых значений зарезервированных функций и написание пользовательских функций.

Слово о функциях. Функция как отдельный тип имеет довольно простой синтаксис:
Код: Выделить всё
function [name]()
[операторы]
end

Функция может быть как без параметра после её имени указываются пустые скобки или передавать параметр(ы).
Код: Выделить всё
name(time)
name()
name(value, index)

Если Вы указали имена параметров в качестве аргумента функции, не забивайте не нужными значениями, чтобы не происходило перекрытий.
Важно помнить: функции, условия, циклы обязательно должны заканчиваться ключевым словом end, именно оно определяет, что функция, условие, цикл завершаетя именно после этого оператора.

Условие начинается с ключевого слова if. Дальше в скобках уже указывается условие. Допускается как по ветви "нет" делать описание, так можно и исключать ключевое слово else, и сразу писать end.
Код: Выделить всё
if (var <9) then
bor = 2 + reg
else
var = bor + 4
end

Но может сложиться такая ситуация, когда необходимо через одно условие проверять несколько ситуаций, тогда можно создать ветвящееся условие. Делается как и в примере выше, только вместо ключевого слова else появляется
elseif и пишется условие, и таких ветвлений можно делать столько сколько необходимо разработчику. Важно понимать ключевое слово end закрывающее конструкцию ставится в самом конце, а не после каждого ветвления, т.е.:
Код: Выделить всё
if (var <9) then
bor = 2 + reg
elseif(var >14) then
var = bor + 4
elseif(var >24) then
var = var + 9
end

О циклах подробнее можно узнать из сайтов пункта 1. В разработке применяются редко. Да и не так много ситуаций где может понадобиться цикл.
Команды в lua пишутся построчно, интерпретируется каждая строка как отдельная команда или выражение, поэтому необязательно как в Си ставить ; после каждой строчки, ошибки не будет.
Чтобы не запутаться в собственном коде часто используются комментарии.
Однострочный комментарий:
Код: Выделить всё
--Cabin light on

Многострочный комментарий:
Код: Выделить всё
--[[Traction locomotive.
Set power]]

Более подробно всё можно прочитать на сайтах, которые указаны в пункте 1.
Можно сделать разбивку большого скрипта на несколько скриптов. При этом в главном Engine или Simulation скрипте надо подключить дочерние скрипты, делается это так:
Код: Выделить всё
--include=CommonScripts\Common UK Colour Light Script.lua
--include=..\CommonScripts\Common Signal Script.lua

В 1-й строке указано подключение дочернего к родительскому, если он находится на уровень или несколько ниже в иерархии относительно родительского. Во 2-й строке указано подключение дочернего к родительскому, если он находится
на уровень или несколько выше в иерархии относительно родительского. При компиляции Lua.exe соберёт дочерние и родительский в 1 скрипт и скомпилирует, что в итоге у локомотива будет только 2 скрипта - Engine и Simulation,
хотя в Source их может быть много.


Пункт 3. Структура Engine и Simulation скрипта.
Для подвижного состава всегда создаётся 2 скрипта:
Engine - скрипт, где располагаются функция для получения сообщений от других локомотивов, функция, отлавливающая изменения значения контролов элементов управления и т.д.
Simulation - скрипт, состоящий из 2 зарезервированных функций, где описывается вся симуляция процессов локомотива (собственный амперметр, тяга, вольтметр, индикация или симуляция работы каких-либо вспомогательных устройств).
Важно понимать и различать, что функция Update(time) Engine скрипта выполняется как для единицы подвижного состава под управлением игрока, так и под управлением AI. А Update(time) для Simulation скрипта выполняется только
на единице подвижного состава игрока, а AI данный скрипт не видит
.
Важно понимать, что зарезервированные функции, от пользовательских отличаются тем, что они вызываются в результате событий заложенных в ядре игры, а выполнение пользовательских должно быть инициировано в какой-либо другой
пользовательской или зарезервированной функции, чтобы по принципу домино пошло выполнение функции.

Структура Engine скрипта:
1) function Initialise()
Частота выполнения: выполняется только 1 раз при запуске сценария с подвижным составом.
В функции присваиваются значения переменным, булевым функциям. Для переменных и вызовов скрипта Engine.
Переназначать переменные за телом данной функции можно если указывать её имя заглавными буквами, т.е. например:
Код: Выделить всё
message_PANTO = 18902748

В теле функции указываются предустановленные значения переменных (если необходимо, для устранения возникновения возможных ошибок при выполнения скрипта):
Код: Выделить всё
function Initialise()
Voltage = 0
CheckLamp = false
Rezistor = 300
end


2) function Update(time)
Частота выполнения: выполняется каждый кадр во время сценария.
В данной функции мы по сути описываем то, что может изменяться постоянно. Это значения переменных, изменение значения ControlValues, которые мы извлекаем из постоянно меняющихся зарезервированных переменных, различные
анимации (пантографы, жалюзи, штоки, цилиндры и т.п.). Также имеется и передаваемый параметр time, который может использоваться в условиях.
Аргумент time - хранит время с последнего обновления функции.
Пример:
Код: Выделить всё
function Update(time)
simulationTime = Call( "*:GetSimulationTime")
if((val + simulationTime) > (val2 + time)) then
 val3 = simulationTime
end
end


3) function OnControlValueChange (name, index, value)
Частота выполнения: выполняется при взаимодействии с интерфейсным элементом, либо маппером.
В данной функции описывается реакция на изменение значения леверов и переключателей в кабине. Если, например, контрол N, к которому привязали тумблер со значением 0 стал 1, т.е. взяли и переключили и нужна реакция
(включение или выключение чего-то, выполнение каких-либо действий), то используется данная функция.
Аргумент name - получение имени контрола из Engine конфига.
Аргумент index - получение индекса, если контрол может быть использоваться в нескольких экземплярах.
Аргумент value - получение значения данного контрола в данный момент времени.
Пример:
Код: Выделить всё
function OnControlValueChange (name, index, value)
   if Call("*:ControlExists", name, index) then
      Call("*:SetControlValue", name, index, value)
   end
   if (name == "CabLight") then
      if(value == 1) then   
         Call("Light_Cab:Activate", 1)
      else
         Call("Light_Cab:Activate", 0)
      end
   elseif(name == "PriborLight") then
      if(value == 1) then   
         Call("Pribor_Light:Activate", 1)
      else
         Call("Pribor_Light:Activate", 0)
      end
   end
end

Если переключить тумблер, который добавлен к контролу CabLight, то начнётся выполнение функции OnControlValueChange и в неё будут переданы 3 параметра: name, index, value. С помощью условия следует описать все события контролов.
При этом те контролы у которых не задаётся логика работы, но есть элементы управления надо проверить с помощью Call вызова существование контрола ( Call( "*:ControlExists", name, index )).

4) function OnConsistMessage (message, argument, direction)
Частота выполнения: выполняется на подвижном составе при получении сообщения от другой единицы подвижного состава.
В данной функции описывается реакция на полученные сообщения от другой единицы подвижного состава.
Аргумент message - получение цифрового кода сообщения.
Аргумент argument - получение значения сообщения. Строковое либо числовое.
Аргумент direction - направление отправленного сообщения. 1 - отправлено сообщение назад, 0 - сообщение отправлено вперёд.
Пример:
Код: Выделить всё
--В начале кода
VNTH_MSGID = 1818190303
VNTL_MSGID = 1818190304
function OnConsistMessage (message, argument, direction)
    if(message == VNTL_MSGID) then
      Call("*:SetControlValue", "vnt_low", 0, argument)
      Call("SendConsistMessage", message, argument, direction)
    elseif(message == VNTH_MSGID) then
      Call("*:SetControlValue", "vnt_hight", 0, argument)
      Call("SendConsistMessage", message, argument, direction)
   else
      Call("SendConsistMessage", message, argument, direction)
   end      
end

В начале кода определено присваивание переменным числового кода. Присваивание делается для удобства восприятия и задания осмысленного имени сообщения. Важно, чтобы на единице подвижного состава где будет приниматься сообщение
был определён такой же код сообщения. В теле функции при получении сообщения идёт выполнение кода при условии что будет указано в условии имя сообщения (числовой код, либо присовоение числового коду переменной). Чтобы сообщение
ушло дальше на следующие единицы подвижного состава необходимо ретранслировать передачу сообщения с тем же кодом, аргументом, направлением вызовом - Call("SendConsistMessage", message, argument, direction). Ретрансляцию также
надо обеспечить для сообщений, которые не описаны в принимаемой единице подвижного состава, так как приём сообщения может быть у последующих.

5) OnCustomSignalMessage (ConsistMessage)
Частота выполнения: выполняется на подвижном составе при получении сообщения от светофора.
В данной функции описывается реакция на полученные сообщения от светофоров. Скрипт светофоров может отсылать сообщения на подвижной состав с помощью зарезервированного сообщения с кодом 15.
Код: Выделить всё
function OnCustomSignalMessage (ConsistMessage)
SignalState   = tonumber(string.sub(ConsistMessage,1,2))      
end

Приходящее сообщение может быть как строковым аргументом так и числовым. Но в случае строкового аргумента в 1-м сообщении может быть отправлено много полезной информации. Если её в скрипте светофора формировать в строку по специальной системе, то при приёме можно без труда разделить и преобразовать к нужному типу.

Структура Simulation скрипта:
1) function Setup()
Частота выполнения: выполняется только 1 раз при запуске сценария с подвижным составом.
Назначение такое же как и у Initialise() только расптространяется на переменные Simulation скрипта.

2) function Update(inteval)
Частота выполнения: выполняется каждый кадр во время сценария.
Назначение такое же как и у Update(time) только распространяется на подвижную единицу, управляемую игроком.
Аргумент inteval - хранит время с последнего обновления функции.

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


Пункт 4. Список обычных (Call) и системных (SysCall) вызовов
Если вызов адресован к дочернему объекту, то у первого строкового параметра перед ним указывается ":" и указывается имя дочернего объекта:
Код: Выделить всё
Call("child:SetText")

Если вызов адресован как ко всем дочерним объектам, так и к родительским, то указывается "*:" :
Код: Выделить всё
Call("*:BeginUpdate")

Также вощзможна адресация к родительскому объекту:
Код: Выделить всё
Call("BeginUpdate")

Обычные вызовы (Call)
Обычные вызовы (Call) могут осуществляться из скриптов подвижного состава (Engine, Simulation, подключаемые скрипты), из скриптов переездов, из скриптов светофора, из скриптов скриптуемых объектов.
Обычный вызов представляет собой слово Call, а в скобках указываются через запятую строковые/числовые параметры.
Для удобного поиска по нужным функциям они разделены на категории с указанием тегов. ПО ним Вы можете найти нужные функции (поиск браузера - Ctrl+F):
#свет - функции по работе с источниками света;
#объект - функции по работе с объектом, его анимацией;
#частицы - функции по работе с частицами - Emitter;
#элементы_управления - функции по работе с контролами (ControlValues);
#параметры_ПС - функции снятия параметров подвижного состава, связанные с массой, скоростью, с режимами управления и т.д.;
#параметры_трека - функции снятия параметров с трека;
#параметры_сценария - функции снятия параметров сценария.

Call("BeginUpdate")
Аргументы: нет.
Возвращает: нет.
Использование: используется, когда скрипт должен выполнять выполнение функции Update в течение нескольких кадров. Обычно данный вызов используется в функции Initialise.

Call("EndUpdate")
Аргументы: нет.
Возвращает: нет.
Использование: используется, когда скрипт должен прекратить выполнение функции Update в течение нескольких кадров.

Call("ActivateNode", [name_node], [value])
#объект
Аргументы:
[name_node] - строковый аргумент (указывается в " "). Указывается имя показываемого/скрываемого объекта.
[value] - числовой аргумент. 0 - скрыть объект, 1 - показать объект.
Возвращает: нет.
Использование: показ/скрытие объекта в модели. В качестве имени объекта используется имя, заданное объекту в 3ds max.
Пример:
Код: Выделить всё
Call("ActivateNode", "projector", 0) --скрыть в модели узел с именем projector
Call("ActivateNode", "projector", 1) --показать в модели узел с именем projector


Call("AddTime", [name_animation], [value])
#объект
Аргументы:
[name_animation] - строковый аргумент (указывается в " "). Указывается имя проигрываемой анимации (прописывается в конфиге в блоке AnimSet).
[value] - числовой аргумент. Указывается время в секундах (+/-) на которое необходимо переключить анимацию.
Возвращает: 0, если анимация не достигла своего конца или начала, в противном случае время, оставшееся.
Использование: проигрывание анимации.
Пример:
time = 7
Код: Выделить всё
Call("AddTime", "Panto", time) --проигрывание анимации с именем Panto


Call("Reset", [name_animation])
#объект
Аргументы:
[name_animation] - строковый аргумент (указывается в " "). Указывается имя проигрываемой анимации (прописывается в конфиге в блоке AnimSet).
Возвращает: нет.
Использование: сброс анимации в нулевой кадр (0 секунд).
Пример:
Код: Выделить всё
Call("Reset", "WindowRight") --сброс анимации с именем WindowRight


Call("[name_child]:SetText", [characters], [set])
#объект
Аргументы:
[name_child] - вывод текста посредством показа текстур можно осуществлять с помощью primarydigits и secondarydigits дочерних объектов, если используются дочерние объекты указывается имя дочернего объекта (в конфиге блок Children).
[characters] - строковый аргумент, обозначающий показываемый текст в соответствии с созданным конфигом Named texture set blueprint.
[set] - число, выбор набора текстур. Primarydigits - 0, Secondarydigits - 1.
Возвращает: нет.
Использование: вывод заданного текста на плоскости показом текстур.
Пример:
value = "Hello"
Код: Выделить всё
Call("Tablo:SetText", value, 0) --вывод текста "Hello" с помощью текстур из набора primarydigits.


Call("[name_child]:Activate", [value])
#свет
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child источника света.
[value] - числовой аргумент. 0 - отключить свет, 1 - включить свет.
Возвращает: нет.
Использование: включение/отключение источника света, добавляемого к объекту. Имя задаётся в блоке child в поле "ChildName".
Пример:
Код: Выделить всё
Call("Light_Projector:Activate", 0) --отключить источник света child "Light_Projector"
Call("Light_Projector:Activate", 1) --включить источник света child "Light_Projector"


Call("[name_child]:SetColour", [R], [G], [B])
#свет
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child источника света.
[R] - числовой аргумент. Выбор оттенка красного (от 0 до 1).
[G] - числовой аргумент. Выбор оттенка зелёного (от 0 до 1).
[B] - числовой аргумент. Выбор оттенка синего (от 0 до 1).
Возвращает: нет.
Использование: настройка цветовой модели источника света, добавляемого к объекту. Имя задаётся в блоке child в поле "ChildName".
Пример:
Код: Выделить всё
Call("Light_Projector:SetColour", 0.99, 0.97, 0.92) --сменить цветовую модель источника света с прошлой на новую (R=0.99, G=0.97, B=0.92) в child "Light_Projector"


Call("[name_child]:SetRange", [value])
#свет
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child источника света.
[value] - числовой аргумент. Выбор дистанции освещения (в метрах).
Возвращает: нет.
Использование: настройка дистанции освещения источника света, добавляемого к объекту. Имя задаётся в блоке child в поле "ChildName".
Пример:
Код: Выделить всё
Call("Light_Projector:SetRange", 40) --изменить дистанцию освещения источника света в child "Light_Projector".


Call("[name_child]:SetUmbraAngle", [value])
#свет
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child источника света.
[value] - числовой аргумент. Выбор угла полной тени (в градусах).
Возвращает: нет.
Использование: настройка угла полной тени источника света, добавляемого к объекту. Имя задаётся в блоке child в поле "ChildName". В конфиге света Spot light blueprint равноценен пункту "Theta".
Пример:
Код: Выделить всё
Call("Light_Projector:SetUmbraAngle", 60) --изменить угол полной тени источника света в child "Light_Projector".


Call("[name_child]:SetPenumbraAngle", [value])
#свет
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child источника света.
[value] - числовой аргумент. Выбор угла полутени (в градусах).
Возвращает: нет.
Использование: настройка угла полутени источника света, добавляемого к объекту. Имя задаётся в блоке child в поле "ChildName". В конфиге света Spot light blueprint равноценен пункту "Phi".
Пример:
Код: Выделить всё
Call("Light_Projector:SetPenumbraAngle", 50) --изменить угол полутени источника света в child "Light_Projector".


Call("[name_child]:GetColour")
#свет
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child источника света.
Возвращает: 3 параметра: оттенок красного, зелёного, синего (RGB).
Использование: получение цветовой модели источника света, добавляемого к объекту. Имя задаётся в блоке child в поле "ChildName".
Пример:
Код: Выделить всё
ColourR, ColourG, ColourB = Call("Light_Projector:GetColour") --получить цветовую модель источника света в child "Light_Projector"


Call("[name_child]:GetRange")
#свет
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child источника света.
Возвращает: дистанцию освещения источника света.
Использование: настройка дистанции освещения источника света, добавляемого к объекту. Имя задаётся в блоке child в поле "ChildName".
Пример:
Код: Выделить всё
RangeLight = Call("Light_Projector:GetRange") --получить дистанцию освещения источника света в child "Light_Projector".


Call("[name_child]:GetUmbraAngle")
#свет
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child источника света.
Возвращает: угол полной тений источника света.
Использование: получение угла полной тени источника света, добавляемого к объекту. Имя задаётся в блоке child в поле "ChildName". В конфиге света Spot light blueprint равноценен пункту "Theta".
Пример:
Код: Выделить всё
UmbraLight = Call("Light_Projector:GetUmbraAngle") --получить угол полной тени источника света в child "Light_Projector".


Call("[name_child]:GetPenumbraAngle", [value])
#свет
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child источника света.
Возвращает: угол полутени источника света.
Использование: получение угла полутени источника света, добавляемого к объекту. Имя задаётся в блоке child в поле "ChildName". В конфиге света Spot light blueprint равноценен пункту "Phi".
Пример:
Код: Выделить всё
PenUmbraLight = Call("Light_Projector:GetPenumbraAngle") --получить угол полутени источника света в child "Light_Projector".


Call("[name_child]:RestartEmitter")
#частицы
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child эмиттера.
Возвращает: нет.
Использование: перезапуск эмиттера.
Пример:
Код: Выделить всё
Call("Smoke1:RestartEmitter") --перезапуск эмиттера с именем в child "Smoke1".


Call("[name_child]:GetEmitterActive")
#частицы
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child эмиттера.
Возвращает: состояние эмиттера (0 - выключен, 1 - включен).
Использование: получение текущего состояния эмиттера.
Пример:
Код: Выделить всё
SmokeState = Call("Smoke1:GetEmitterActive") --получение текущего состояния эмиттера с именем в child "Smoke1".


Call("[name_child]:GetEmitterRate")
#частицы
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child эмиттера.
Возвращает: число, обозначающее количество частиц (от 0 до 1).
Использование: получение текущего количества частиц эмиттера.
Пример:
Код: Выделить всё
SmokeRate = Call("Smoke1:GetEmitterRate") --получение текущего количества частиц эмиттера с именем в child "Smoke1".


Call("[name_child]:GetEmitterColour")
#частицы
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child эмиттера.
Возвращает: 3 параметра: оттенок красного, зелёного, синего (RGB) частиц эмиттера.
Использование: получение текущей цветовой модели частиц эмиттера.
Пример:
Код: Выделить всё
SmokeR, SmokeG, SmokeB = Call("Smoke1:GetEmitterColour") --получение аддитивной цветовой модели частиц эмиттера с именем в child "Smoke1".


Call("[name_child]:SetEmitterActive", [value])
#частицы
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child эмиттера.
[value] - числовое значение (1 - включить эмиттер, 0 - выключить эмиттер).
Возвращает: нет.
Использование: изменение текущего состояния эмиттера.
Пример:
Код: Выделить всё
Call("Smoke1:SetEmitterActive", 1) --включение эмиттера с именем в child "Smoke1".


Call("[name_child]:SetEmitterRate", [value])
#частицы
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child эмиттера.
[value] - числовое значение. От 0 до 1 - количество частиц эмиттера.
Возвращает: нет.
Использование: изменение текущего уровня частиц эмиттера.
Пример:
Код: Выделить всё
Call("Smoke1:SetEmitterRate", 0.02) --изменение текущего количества частиц эмиттера с именем в child "Smoke1".


Call("[name_child]:SetEmitterColour", [R], [G], [B])
#частицы
Аргументы:
[name_child] - строковый аргумент (указывается в " "). Указывается имя child эмиттера.
[R] - числовой аргумент. Выбор оттенка красного (от 0 до 1).
[G] - числовой аргумент. Выбор оттенка зелёного (от 0 до 1).
[B] - числовой аргумент. Выбор оттенка синего (от 0 до 1).
Возвращает: нет.
Использование: настройка цветовой модели эмиттера, добавляемого к объекту. Имя задаётся в блоке child в поле "ChildName".
Пример:
Код: Выделить всё
Call("Smoke1:SetEmitterColour", 0.99, 0.97, 0.92) --сменить цветовую модель эмиттера с прошлой на новую (R=0.99, G=0.97, B=0.92) в child "Smoke1"


Call("SetControlValue", [name_control], [index], [value])
#элементы_управления
Аргументы:
[name_control] - имя контрола из конфига (Wagon blueprint|Engine blueprint).
[index] - индекс (ныне используется, пишется 0).
[value] - устанавливаеме значение контрола.
Возвращает: нет.
Использование: установка нового значения контролу.
Пример:
Код: Выделить всё
Call("SetControlValue", "Regulator", 0, 0.4) --установить значение 0.4 контролу Regulator из конфига Engine|Wagon blueprint


Call("GetControlValue", [name_control], [index])
#элементы_управления
Аргументы:
[name_control] - имя контрола из конфига (Wagon blueprint|Engine blueprint).
[index] - индекс (ныне используется, пишется 0).
Возвращает: число, находящееся в пределах Minimum Value и Maximum Value (Wagon blueprint|Engine blueprint).
Использование: получение текущего значения контрола.
Пример:
Код: Выделить всё
RegulatorState = Call("GetControlValue", "Regulator", 0) --получить текущее значение контрола Regulator из конфига Engine|Wagon blueprint


Call("GetControlMinimum", [name_control], [index])
#элементы_управления
Аргументы:
[name_control] - имя контрола из конфига (Wagon blueprint|Engine blueprint).
[index] - индекс (ныне используется, пишется 0).
Возвращает: число, являющееся минимальным значением контрола, сответствует значению поля Minimum Value (Wagon blueprint|Engine blueprint).
Использование: получение минимального значения контрола.
Пример:
Код: Выделить всё
minValue = Call("GetControlMinimum", "Notch", 0) --получить минимальное значение контрола Notch из конфига Engine|Wagon blueprint


Call("GetControlMaximum", [name_control], [index])
#элементы_управления
Аргументы:
[name_control] - имя контрола из конфига (Wagon blueprint|Engine blueprint).
[index] - индекс (ныне используется, пишется 0).
Возвращает: число, являющееся максимальным значением контрола, сответствует значению поля Maximum Value (Wagon blueprint|Engine blueprint).
Использование: получение максимального значения контрола.
Пример:
Код: Выделить всё
maxValue = Call("GetControlMaximum", "Notch", 0) --получить максимальное значение контрола Notch из конфига Engine|Wagon blueprint


Call("ControlExists", [name_control], [index])
#элементы_управления
Аргументы:
[name_control] - возможное имя контрола из конфига (Wagon blueprint|Engine blueprint).
[index] - индекс (ныне используется, пишется 0).
Возвращает: true/false (1/0). true - если контрол у конфига существует, false - если не существует.
Использование: проверка существования контрола в конфиге, используется обычно в функции OnControlValueChange(name, index, value).
Пример:
Код: Выделить всё
if Call("*:ControlExists", name, index) then --если существует контрол с именем, помещаемым в переменную name, то устанавливаем значение для этого контрола из переменной value.
      Call("*:SetControlValue", name, index, value)
   end


Call("GetTotalMass")
#параметры_ПС
Возвращает:число, являющееся общей массой состава, в тоннах.
Использование: получение общей массы состава.
Пример:
Код: Выделить всё
 TotalMass = Call("GetTotalMass") -- получение массы состава


Call("GetConsistTotalMass")
#параметры_ПС
Возвращает:число, являющееся общей массой единицы ПС, в тоннах.
Использование: получение массы единицы ПС, в которой используется данная функция.
Пример:
Код: Выделить всё
 Mass = Call("GetConsistTotalMass") -- получение массы единицы ПС


Call("GetConsistLength")
#параметры_ПС
Возвращает:число, являющееся общей длиной состава, в метрах.
Использование: получение длины состава.
Пример:
Код: Выделить всё
 Length = Call("GetConsistLength") -- получение общей длины состава


Call("GetIsDeadEngine")
#параметры_ПС
Возвращает:true/false, являющееся состоянием рабоспособности единицы ПС (false - рабочая, true - нерабочая).
Использование: получение состояния единицы (рабочая/не рабочая).
Пример:
Код: Выделить всё
 State = Call("GetIsDeadEngine") -- получение состояния рабоспособности единицы ПС.


Call("GetIsEngineWithKey")
#параметры_ПС
Возвращает:true/false, false - единица ПС управляется AI, true - единица ПС управляется игроком.
Использование: получение состояния управления единицей ПС.
Пример:
Код: Выделить всё
 State = Call("GetIsEngineWithKey") -- получение состояния управления единицей ПС.


Call("GetRVNumber")
#параметры_ПС
Возвращает:строку, которая является номером единицы ПС.
Использование: получение номера единицы ПС, вводимого в редакторе сценариев или выдаваемого автоматически из диапазона значений согласно csv файлу.
Пример:
Код: Выделить всё
 Number = Call("GetRVNumber") -- получение номера единицы ПС.


Call("GetTractiveEffort")
#параметры_ПС
Возвращает:число, измеряется в кН.
Использование: получение тягового усилия для единицы ПС.
Пример:
Код: Выделить всё
 Traction = Call("GetTractiveEffort") -- получение тягового усилия для единицы ПС.


Call("GetAcceleration")
#параметры_ПС
Возвращает:число, измеряется в м/с^2.
Использование: получение ускорения для единицы ПС.
Пример:
Код: Выделить всё
 Traction = Call("GetAcceleration") -- получение ускорения для единицы ПС.


Call("GetSpeed")
#параметры_ПС
Возвращает:число, измеряется в м/с.
Использование: получение текущей скорости для единицы ПС.
Пример:
Код: Выделить всё
 Speed = Call("GetSpeed") -- получение текущей скорости для единицы ПС.


Call("IsExpertMode")
#параметры_ПС
Возвращает:true/false, true - управление в режиме эксперта в сценарии, false - упрощённое управление.
Использование: получения уровня сложности управления (простой/эксперт).
Пример:
Код: Выделить всё
 Mode = Call("IsExpertMode") -- получения уровня сложности управления.


Call("GetSimulationTime")
#параметры_ПС
Возвращает:число, время в секундах.
Использование: получения времени в секундах от начала сценария.
Пример:
Код: Выделить всё
 SimulationTime = Call("GetSimulationTime") -- получения времени в секундах от начала сценария.


Call("GetIsPlayer")
#параметры_ПС
Возвращает:true/false, false - единица ПС управляется AI, true - единица ПС управляется игроком.
Использование: получение состояния управления единицей ПС.
Пример:
Код: Выделить всё
 State = Call("GetIsPlayer") -- получение состояния управления единицей ПС.


Call("SendConsistMessage", [message], [argument], [direction])
#параметры_ПС
Аргументы:
[message] - код сообщения - числовой. Может представлен быть в виде константы, для которой в начале задаётся соответствие коду.
[argument] - аргумент сообщения - его содержимое. Может быть как числовым аргументом, так и строкой.
b][direction][/b] - направление отправки сообщения. 0 - вперёд, 1 - назад.
Возвращает: нет
Использование: для отправки сообщения от светофора (signal blueprint) к ПС, а также от одной единице ПС к другой. см. функции OnConsistMessage, OnCustomSignalMessage.
Пример:
Код: Выделить всё
MSG_TEST = 293742732 --присвоение константе числового кода сообщения.
function Update(time)
   Call("SendConsistMessage", MSG_TEST, argument, 1) --отправка сообщения назад, аргумент находится в переменной argument, имя сообщения присвоено константе MSG_TEST
end


Call("GetCurvature")
#параметры_трека
Возвращает: число, которое является частным от 1/[радиус_кривой]. При этом если кривая уходит вправо - число будет положительным, если влево - отрицательным.
Использование: для получения данных о радиусе кривой.
Пример:
Код: Выделить всё
 Curvature = Call("GetCurvature")


Call("GetCurvatureAhead")
#параметры_трека
Возвращает: число, которое является частным от 1/[радиус_кривой]. При этом если кривая уходит вправо - число будет положительным, если влево - отрицательным.
Использование: для получения данных о радиусе кривой пройденной ПС.
Пример:
Код: Выделить всё
 Curvature = Call("GetCurvatureAhead")


Call("GetGradient")
#параметры_трека
Возвращает: число, величина уклона в тысячных. К примеру, если возвращено значение 0.7 - значит подъём 7 тысячных (7 метров на 1 км). Если значение положительное - подъём, если отрицательное - спуск.
Использование: для получения данных об уклоне, который проезжает ПС.
Пример:
Код: Выделить всё
 Gradient = Call("GetGradient")


Call("GetCurrentSpeedLimit")
#параметры_трека
Возвращает: число, лимит трека, возвращает скорость в м/с.
Использование: для получения данных о лимите скорости на треке, который проезжает ПС.
Пример:
Код: Выделить всё
 Limit = Call("GetCurrentSpeedLimit")


Call("GetNextSpeedLimit")
#параметры_трека
Возвращает: число, 0 или 1. 0 - лимитирующая скорость не будет изменяться (действующая до конца трека), 1 - лимитирующая скорость будет изменяться в меньшую или большую сторону.
Использование: для получения состояния изменения лимитирующей скорости.
Пример:
Код: Выделить всё
 StateLimit = Call("GetNextSpeedLimit")


Call("*:GetNextRestrictiveSignal", [direction], [distance_min], [distance_max])
#параметры_сигнала
Аргументы:
direction - направление (0 - вперед, 1 - назад);
distance_min - минимальная дистанция "сканирования", м*
*минимальное расстояние сканирования при работе скрипта - 10 сантиметров
distance_max - максимальная дистанция "сканирования", м
Возвращает: 4 значения:
type – тип запрещающего сигнала (-1 указывает на то, что нет ограничительных сигналов в пределах 10 км; 0 означает конец трека;
1 указывает, что до ограничительного сигнала меньше 10 км);
state - указывает на состояние сигнала (0 - чисто, 1 - предупреждение и 2 - стоп);
distance - расстояние до сигнала (в метрах);
aspect - статус сигнала по 2D-карте.
Использование: Позволяет совершать действия в зависисмости от типа, состояния и расстояния до сигнала.
Пример:
Код: Выделить всё
type, state, distance, aspect = Call("*:GetNextRestrictiveSignal", 1, 0, 1250)


Системные вызовы (SysCall)
Системные вызовы (SysCall) могут осуществляться из скриптов подвижного состава (Engine, Simulation, подключаемые скрипты), из скриптов переездов, из скриптов светофора, из скриптов скриптуемых объектов и сценарных скриптов.
Системный вызов представляет собой слово SysCall, а в скобках указываются через запятую строковые/числовые параметры.

SysCall("GetSeason")
#параметры_сценария
Возвращает: число, определяющее текущее время года в сценарии. 0 - весна, 1 - лето, 2 - осень, 3 - зима.
Использование: позволяет получить текущее время года в сценарии.
Пример:
Код: Выделить всё
 Season = SysCall("GetSeason")


SysCall("GetTimeOfDay")
#параметры_сценария
Возвращает: число, определяющее текущее время в сценарии, в секундах. К примеру, если функция возвращает число 43200, значит текущее время в сценарии 12:00:00.
Использование: позволяет получить текущее время в сценарии.
Пример:
Код: Выделить всё
 TimeOfDay = SysCall("GetTimeOfDay")


SysCall("GetScenarioTime")
#параметры_сценария
Аналогично функции Call("GetSimulationTime")
Использование: в сценарных скриптах, для получения времени, пройденного от старта сценария.


Если у Вас есть информация какие аргументы у функций приведённых в списке ниже, напишите мне в ЛС, я добавлю в блог. если обнаружили ошибки или опечатки - пишите в комментариях. Спасибо за внимание.
Call:
LockControl --#блокировка_управления
IsControlLocked --#блокировка_управления
GetWiperPairCount --#стеклоочиститель
SetWiperValue --#стеклоочиститель
GetWiperValue --#стеклоочиститель
GetFireboxMass --#параметры_ПС
SetPowerProportion --#параметры_ПС
SetBrakeFailureValue --#параметры_ПС
ShowConsole --unknown
SetStateName --unknown
SetDebugDisplay --unknown

SysCall:
UnlockControls --#параметры_сценария
LockControls --#параметры_сценария
FormatString --#параметры_сценария
IsAtDestination --#параметры_сценария
ShowAlertMessageExt --#параметры_сценария
ShowInfoMessageExt --#параметры_сценария
ShowMessage --#параметры_сценария
GetConditionStatus --#параметры_сценария
EndConditionCheck --#параметры_сценария
BeginConditionCheck --#параметры_сценария
CancelDeferredEvent --#параметры_сценария
TriggerDeferredEvent --#параметры_сценария
TriggerScenarioComplete --#параметры_сценария
TriggerScenarioFailure --#параметры_сценария
Последний раз редактировалось BooYa 13.03.2016, 11:41, всего редактировалось 11 раз(а).

7 раз подумай - 1 раз напиши.
3 комментариев 552336 просмотров
Комментарии

Re: Скриптование ПС для Railworks 4

Постоянная ссылка A1iv 13.08.2013, 00:49

+5, спасибо! Хотя сложно все это, Ух.. :swoon:
Последний раз редактировалось A1iv 18.06.2014, 01:06, всего редактировалось 3 раз(а).
Аватара пользователя
A1iv
 
Сообщения: 442
Зарегистрирован: 27.10.2011, 03:30
Откуда: РФ, Тверская обл.
Имя: Алексей
Блог: Просмотр блога (10)

Re: Скриптование ПС для Railworks 4

Постоянная ссылка радиомастер 19.12.2015, 15:41

Call("GetTractiveEffort") измеряется не в кН , а от 0 до 1 . 0 соответствует 0 , а 1 соответствует максимальной тяге (которая прописана в симуляции)
Объекты от радиомастера для RailWorks бесплатно Способ поддержки ПСБ 2200 0303 3116 4229 Save DONBASS People from Kiev Agression
Аватара пользователя
радиомастер
 
Сообщения: 2378
Зарегистрирован: 23.10.2010, 18:42
Откуда: Макеевка
Играю в: Train Simulator Classic
Роль: Разработчик
Имя: Костик
Блог: Просмотр блога (4)

Re: Скриптование ПС для Railworks 4

Постоянная ссылка le Sandro 22.03.2016, 23:42

Пост от Светы с RW2.ru
Всем доброго дня :)
Уважаемые разработчики, хочу обратить ваше внимание на то, что в описании вызова Call("GetNextRestrictiveSignal") допущена серьёзная ошибка, а именно – утверждение, что при использовании вызова нет возвращаемых данных.

На самом деле возвращается 4 значения:

type, state, distance, aspect = Call("*:GetNextRestrictiveSignal", 1, 0, 1250)

где type – тип запрещающего сигнала (-1 указывает на то, что нет ограничительных сигналов в пределах 10 км; 0 означает конец трека;
1 указывает, что до ограничительного сигнала меньше 10 км);
state - указывает на состояние сигнала (0 - чисто, 1 - предупреждение и 2 - стоп);
distance - расстояние до сигнала (в метрах);
aspect - статус сигнала по 2D-карте.
Последний раз редактировалось le Sandro 22.03.2016, 23:45, всего редактировалось 4 раз(а).
Аватара пользователя
le Sandro
 
Сообщения: 2705
Зарегистрирован: 30.03.2005, 00:14
Откуда: Пенза
Играю в: Train Simulator Classic
Роль: Разработчик
Блог: Просмотр блога (2)

Кто сейчас на конференции

Зарегистрированные пользователи: Google [Bot]