Наборы улучшений Train Simulator

Обсуждение вопросов и решение проблем, связанных с внутриигровым редактором, а также процессом разработки самостоятельных дополнений или игровых модификаций.
Аватара пользователя
Cross
Разработчик
Сообщения: 6330
Зарегистрирован: 14 дек 2011
Откуда: Москва
Репутация: 2985

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение Cross »

Стандартные сценарии SD50 D&RGW добавлены в архив Soldier Summit

--- добавлено позже в 06 авг 2015, 22:44 ---

Стандартные сценарии West Highland Line (South) доступны для скачивания. Забираем, проверяем, наслаждаемся стандартным режимом :)
*Train Simulator 2018*
Изображение
Аватара пользователя
Света
Разработчик
Сообщения: 752
Зарегистрирован: 13 мар 2015
Репутация: 1470

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение Света »

Cross писал(а):Света
наша тема выходит за рамки той, в которой ведём диалог. Так что этот вопрос можно обсудить в теме с патчами для ПС. Знания языка C и C++ здесь желательны, так как они наиболее похожи на Lua.
1) да, локальные переменные можно создавать.
2) на счёт этого не понял. Как бы просто пишется скрипт, задаются функции и условия, потом проверяется всё на локомотиве.
3) что за программное прерывание?
4) вообще нужен хороший скриптёр! :)
Cross
По пункту 2:
Спойлер
каждая программа считывается по кольцу (я имею ввиду основной код). А подпрограммы вызываются по необходимости. И может такое быть, что подпрограмма не будет вызвана вообще ни разу. Я же не до конца понимаю, чем для движка является скрипт - модуль, который прорабатывается после основного кода (и встраивается в него), или же это аналог подпрограммы, который вызывается при определенных условиях. Если первый вариант (т.е. скрипт прорабатывается периодично), то устроить таймер ИМХО несложно - объявить локальную переменную и при каждом считывании движком скриптового кода инкрементировать/декрементировать ее значение (как-то имя переменной=имя переменной+(-)1 ). Во втором случае будет немного посложнее.
По пункту 3:
Спойлер
Прерывание - это когда процессор откладывает выполнение основной программы и переключается на выполнение другой задачи, а когда закончит, продолжает выполнение основной программы с того места, где остановился. Отличие от подпрограмм заключается в том, что прерывание вызывается в произвольный момент времени. Самый простой пример - это электронные часы. Когда проходит определенный промежуток времени (к примеру 1 сек), компьютер откладывает выполнение текущих процессов и увеличивает счетчик секунд на 1 (пример очень грубый), а затем возвращается к прерванной работе.
Этот пример - это аппаратное прерывание, т.е. вызывается внутренними системами компьютера. А программное прерывание - это вызов по событиям или триггеру, заданному программой (например, совпадение нескольких условий).
Я приношу свои извинения, может я несколько путано расписываю то, что в принципе несложно, просто мне трудно переложить ассемблерные понятия на язык высокого уровня :oops: .

--- добавлено позже в 07 авг 2015, 13:17 ---

Ну вот, насколько я понимаю структуру и синтаксис lua, то это должно выглядеть примерно так:
В функции, исполняемой каждый кадр, инкрементируем нашу локальную переменную, имя которой counter

Код: Выделить всё

function Update(time)
if (counter==101)then
counter = 1
else
counter = counter + 1
end
end
А в части скрипта, отвечающей за манипуляции с кнопками локомотива и исполняемой только при нажатии клавиш проверяем вероятность возникновения поломки:

Код: Выделить всё

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   
...
            if (counter < porog) then      //если значение счетчика меньше заданного порога, то при 
                                        //включении света в кабине произойдет поломка. Если значение
                                        //порога будет 12, то вероятность "поломки" будет 1:12
            Call("команда, по которой инициируется "поломка")
            end
...        
       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
Аргумент name - получение имени контрола из Engine конфига.
Аргумент index - получение индекса, если контрол может быть использоваться в нескольких экземплярах.
Аргумент value - получение значения данного контрола в данный момент времени.
Троеточиями обозначена сделанная мной вставка.
Простите за возможные ошибки, главное, чтобы мне удалось передать идею :roll:
Сильные люди - это не те, у которых всё хорошо, а те, у которых всё хорошо несмотря ни на что.
Аватара пользователя
Cross
Разработчик
Сообщения: 6330
Зарегистрирован: 14 дек 2011
Откуда: Москва
Репутация: 2985

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение Cross »

ну вот, Lua для вас оказался простым и очень даже понятным :) я сужу по написанному коду и в перспективе оно работает. Теперь разберём пункты 2 и 3. Из того, что мне более-менее стало ясно, отвечу таким образом - По пункту 2: В игре есть встроенные движковые функции, по которым работают базовые параметры управления тягой, тормозом, реверсом, свет фар, плунжер экстренного тормоза, песочница, функции амперметра и оборотов в минуту у двигателей, вероятно что-то ещё. А есть дополнительные пользовательские функции, которые пишутся уже в скрипте - например свет в кабине, работа DRA, DSD или DVD с их таймерами и условиями срабатывания, виртуальные функции для базовых параметров перечилсенных выше (в этом случае мы получаем бОльший функционал), чтобы было ещё понятней, что я имею ввиду, поясню - например у нас сработала система DSD, мы не отреагировали, сорвало стоп кран и, самое интересное, здесь блокируется базовый параметр Regulator, который отвечает за ручку тяги в кабине. Согласитесь, было бы нереалистично, если бы ручку тяги заклинило и она бы не двигалась больше. Для этого существуют виртуальные пользовательские функции, которые завязываются на управление и связаны в скрипте с базовыми движковыми функциями. Если у нас прописана такая виртуальная функция в бинарнике лока и она связана в скрипте с базой, то при срабатывании той самой DSD и срыве стоп крана (при заданных условиях) мы уже имеем возможность двигать ручку тяги, ибо она не блокируется никогда, но параметр Regulator бы не реагировал, то есть двигай ручку как угодно, а тяги не будет. Затем, при определённых условиях мы возвращаем связь виртуальной функции и базы и всё снова работает. Фух, сложно объяснил? Увлёкся малость.

теперь По пункту 3: программное прерывание - это вызов по событиям или триггеру, заданному программой (например, совпадение нескольких условий). Здесь мне не всё ясно до конца. События можно прописать в скрипте на условиях и зависимостях от этих условий. Можно создать триггеры как это было в разработке вояджера у JT, тогда эти триггеры размещаются в сценариях в заданных местах и таким образом можно организовать любую гадость машинисту, но такой способ я не хочу практиковать никак, ибо он слишком линейный, а хочется непредсказуемости.

Света
Если вы готовы мне помочь в скриптовке локомотивов и таким образом в разработке патчей, то я буду только рад и очень рекомендую изучить каждый патч в плане скриптов и поглядеть как и что там устроено. Ваши примеры близки к правде и должны работать в игре
*Train Simulator 2018*
Изображение
Аватара пользователя
Света
Разработчик
Сообщения: 752
Зарегистрирован: 13 мар 2015
Репутация: 1470

Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение Света »

Cross писал(а): есть дополнительные пользовательские функции, которые пишутся уже в скрипте
понятно, значит код скрипта компилятор подключает к основному коду и считывание происходит циклично.
Cross писал(а): при срабатывании той самой DSD и срыве стоп крана (при заданных условиях) мы уже имеем возможность двигать ручку тяги, ибо она не блокируется никогда, но параметр Regulator бы не реагировал, то есть двигай ручку как угодно, а тяги не будет. Затем, при определённых условиях мы возвращаем связь виртуальной функции и базы и всё снова работает. Фух, сложно объяснил? Увлёкся малость.
Ничего, я думаю, что суть мне понятна :) .
Cross писал(а): программное прерывание - это вызов по событиям или триггеру, заданному программой (например, совпадение нескольких условий). Здесь мне не всё ясно до конца.
Я вижу, что в lua понятия "прерывание" нет, но это и неудивительно. Если Вам знакомо понятие "флаги" в программировании и интересно, то я смогу объяснить, что это. Для скриптования, судя по всему, это не нужно.
Cross писал(а): ... эти триггеры размещаются в сценариях в заданных местах и таким образом можно организовать любую гадость машинисту, но такой способ я не хочу практиковать никак, ибо он слишком линейный, а хочется непредсказуемости.
Тогда мой метод очень просто может реализовать непредсказуемость. Например, при прохождении триггера сверяется значение счетчика, и если оно ниже порога, начинается обратный отсчет этого значения. По истечении этого отсчета происходит поломка, характер которой, опять-таки может определяться значением счетчика. Фактически, одной переменной, можно сделать случайными место, время, характер поломки, и саму поломку. А, ну может понадобиться ещё одна защитная переменная-диспетчер. А значение счетчика по-любому будет случайным, ведь при инкрементировании 20-30 раз в секунду он тысячи раз успеет переполниться до прохождения триггера =) . Кстати, продолжительность сценария не будет играть совершенно никакой роли.
Cross писал(а): Света
Если вы готовы мне помочь в скриптовке локомотивов и таким образом в разработке патчей, то я буду только рад и очень рекомендую изучить каждый патч в плане скриптов и поглядеть как и что там устроено. Ваши примеры близки к правде и должны работать в игре
Мне очень хочется внести какой-нибудь вклад в сим. Если мне удастся хоть как-то помочь, это будет замечательно :roll: ! Главный вопрос - чем конкретно я могу помочь?
Последний раз редактировалось Света 07 авг 2015, 18:29, всего редактировалось 1 раз.
Сильные люди - это не те, у которых всё хорошо, а те, у которых всё хорошо несмотря ни на что.
Аватара пользователя
pROssO
Ветеран
Сообщения: 3519
Зарегистрирован: 21 май 2012
Откуда: Минск
Репутация: 4859

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение pROssO »

Позволю себе вставить свои 5 копеек. :)
Если всё же говорить о таймере то:

Код: Выделить всё

function Initialise ()
FaultTime = math.random (60, 36000)
FaultOccured = 0                                                   -- позволяет проследить, чтобы неисправность не случилась дважды  
end     
function Update (time)
if FaultOccured == 0 then
        if time == FaultTime then
                  Call (-- неисправность)
                  FaultOccured = 1
         end
end
end
В данном конкретном случае, неисправность случится где-то между 1 минутой и 10 часами (36000 секундами) после начала сценария. То есть, если сценарий бы длился больше 10 часов, то вероятность составила бы 100%, больше 5 - 50% и т.д.
Аватара пользователя
Света
Разработчик
Сообщения: 752
Зарегистрирован: 13 мар 2015
Репутация: 1470

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение Света »

pROssO
Как я понимаю, FaultOccured является флагом события, 1 раз устанавливается и, если его не сбросить, будет установлен до конца сценария?
Сильные люди - это не те, у которых всё хорошо, а те, у которых всё хорошо несмотря ни на что.
Аватара пользователя
pROssO
Ветеран
Сообщения: 3519
Зарегистрирован: 21 май 2012
Откуда: Минск
Репутация: 4859

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение pROssO »

Света, FaultOccured - переменная, в которой хранится информация, произошло ли уже событие. Нужно для того, чтобы неисправность не случилась дважды - к примеру, как лампочка в кабине может перегореть ещё раз.
Поясню. Функция Initialise () прорабатывается симом 1 раз, в начале сценария. Функция Update (time) (time возвращает время с начала сценария) прорабатывается каждый кадр в ходе сценария.
Аватара пользователя
Света
Разработчик
Сообщения: 752
Зарегистрирован: 13 мар 2015
Репутация: 1470

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение Света »

Да, суть та же. Эта переменная названа мной "защитная переменная-диспетчер" выше. Есть смысл сделать несколько таких, а поломки сгруппировать как те, что могут повториться (заглохший двигатель) и те, что повториться не могут (лампочка в кабине, как Вы верно отметили :) ). Правда, скрипт получится достаточно сложным =) . Но кататься станет интереснее.
Сильные люди - это не те, у которых всё хорошо, а те, у которых всё хорошо несмотря ни на что.
Аватара пользователя
Cross
Разработчик
Сообщения: 6330
Зарегистрирован: 14 дек 2011
Откуда: Москва
Репутация: 2985

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение Cross »

Света
Главный вопрос - чем конкретно я могу помочь?
написанием скриптов и можете помочь) Речь не идёт о полном написании с нуля, здесь важны только сложные моменты, когда таковые появятся, а они обязательно будут. Вот сейчас остался нерешённым вопрос о блокировке управления у Class 47, когда пищит DSD. Пока что можно сбросить тормоз в ноль одним касанием кнопки и работать с тягой. Как мне пояснил pROssO, при срабатывании DSD по прошествии нескольких секунд, если не нажать на педаль, то блокируется управление тягой (ручку можно дёргать, а эффекта на базовую функцию от неё ноль), затем срабатывает экстренный тормоз (также ручку тормоза можно дёргать, но сама базовая функция не будет реагировать). Далее условие на разблокировку управления. Мы должны нажать педаль DSD, чтобы деактивировать пищалку и перевести виртуальный тормоз в положение "экстренный", а затем в положение "отпустить", тогда управление снова активируется. Я ломал голову, но не пришёл к результату.
Вот здесь для начала можно попробовать помочь. Скрипт от Class 47 должен вам быть ясен
*Train Simulator 2018*
Изображение
Аватара пользователя
Света
Разработчик
Сообщения: 752
Зарегистрирован: 13 мар 2015
Репутация: 1470

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение Света »

Cross
Вы можете скинуть мне файл скрипта? И ещё - "Мы должны нажать педаль DSD, чтобы деактивировать пищалку и перевести виртуальный тормоз в положение "экстренный", а затем в положение "отпустить", тогда управление снова активируется." - это то, что есть или то, чего надо добиться?
Последний раз редактировалось Света 07 авг 2015, 18:56, всего редактировалось 1 раз.
Сильные люди - это не те, у которых всё хорошо, а те, у которых всё хорошо несмотря ни на что.
Аватара пользователя
Cross
Разработчик
Сообщения: 6330
Зарегистрирован: 14 дек 2011
Откуда: Москва
Репутация: 2985

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение Cross »

Света
так в первом посте ссылка на патчи есть, вот там всё лежит. Для проверки рекомендую установить патч. Можно не целиком. Будут дополнительные вопросы, разъясню
*Train Simulator 2018*
Изображение
Аватара пользователя
pROssO
Ветеран
Сообщения: 3519
Зарегистрирован: 21 май 2012
Откуда: Минск
Репутация: 4859

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение pROssO »

В случае нескольких неисправностей, придётся делать несколько FaultTime и несколько защитных переменных (только для тех поломок, которые не могут повториться). Мы же не хотим, чтобы все неисправности случились все вместе, верно?
С другой стороны, немного призадумавшись над своим подходом, я понял, что защитные переменные как таковые вообще не нужны. В самом начале сценария уже сгенерировано время, когда произойдёт поломка, и оно точно не повторится. Для повторяющихся неисправностей нужно слегка изменить код.

Код: Выделить всё

function Initialise ()
PreviousFaultTime = 0
FaultTimer = math.random (60, 36000)
end
function Update (time)
if time == PreviousFaultTime + FaultTimer then
             Call (-- неисправность)
             PreviousFaultTime = time
             FaultTimer = math.random (60, 36000)
end
end
Таким образом, время для первой неисправности будет сгенерировано в начале сценария, а для каждой следущей - при наступлении очередного случая. Поясню, что здесь мы говорим об одной и той же неисправности (например, глушится двигатель), но повторяется она многократно - ну, как сказать, если вы будете ездить 7 суток, то она и вправду случится не раз, а если 1 час, то скорее всего этого вообще ни разу не случится.



Про DSD + DVD, восстановление контроля должно идти следующим образом: поскольку положения рукоятей реверса, тяги и тормоза не соответствуют текущим показателям (рассинхронизация), то виртуальные контроллы (то есть сами рукояти) не связаны с реальными (то, что понимает сим).
Поэтому для того, чтобы реверс и рукоять тяги вновь связались с управлением, нужно перевести их в нейтраль и 0 соответственно. Что же касается рукояти тормоза, то сразу она переводится в аварийное (синхронизация), а затем уже можно отпустить тормоз.

При работе с аварийным, я попытался сделать так: если реальный тормоз (то, в каком состоянии находятся тормоза) не равен виртуальному (то, где находится рукоять тормоза), то реальный = аварийное. Не работает - любое передвижение рукояти тормоза сразу же возвращает управление, даже если она не дошла до аварийного. Моя идея сейчас - создать дополнительную переменную, которая активируется при срабатывании аварийного и фиксирует положение реального тормоза в аварийном, пока виртуальный тормоз сам не станет в аварийное.
Аватара пользователя
Света
Разработчик
Сообщения: 752
Зарегистрирован: 13 мар 2015
Репутация: 1470

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение Света »

Cross
Я не могу его скачать, у меня трафик нэта 2 кбит/с :bad: .Точнее, смогу, но не скоро.
Сильные люди - это не те, у которых всё хорошо, а те, у которых всё хорошо несмотря ни на что.
Аватара пользователя
Cross
Разработчик
Сообщения: 6330
Зарегистрирован: 14 дек 2011
Откуда: Москва
Репутация: 2985

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение Cross »

pROssO
а нельзя ли задать общий счётчик рандомных чисел для всех неисправностей? и сделать как-то на выбор какую неисправность активировать, а когда активируется, то чтобы счётчик заново обновлялся на произвольное значение. Может быть даже потребуется сделать ID неисправностям и задать их в math.random на выбор

--- добавлено позже в 07 авг 2015, 20:06 ---

Света
печально. Ну тогда сам код здесь оставляю

Код: Выделить всё

--------------------------------------------------------------------------------------
-- Engine Script for Class 47
--
-- (c) Railsimulator.com 2011
--
-- Provides script for variable exhaust smoke.
-- Animates cooling vents based on RPM.
--
--------------------------------------------------------------------------------------


-- maximum tractive effort for determining smoke density. Acceleration rate for AI.

MAXTE = 0.5
ACCELRATE = 0.25

gSmokeColourR = 1.0
gSmokeColourG = 1.0
gSmokeColourB = 1.0
gEmitRate = 0.05

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

function Initialise ()


-- Get emitter values.

	gSmokeColourR, gSmokeColourG, gSmokeColourB = Call( "Exhaust:GetEmitterColour" )


-- Stores for checking when values have changed.

	gDriven = 0

-- Stores for vent positions.

	gFrontVent = 0
	gBackVent = 0


	isPlayerLoco = false
	isExpert = false
	DSDDELAY = 60 
	gDSDStartCount = 0
	gDSDStopCount = 0
	isDSDTriggered = false
	isSafetyIsolated = false
	isReverserDSDReset = true
	gReverserDSDTimer = 0
	gRunningTime = 0

	gReverserState = 0
	gRegulator = 0
	gBrakeState = 0

	aws_warn_time = 0
	prev_aws = 0
	prev_awsreset = 0

	gAWSReady = true
	gAWSTesting = false

	Call( "BeginUpdate" )
	
end

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

function OnControlValueChange ( name, index, value )

	if Call( "*:ControlExists", name, index ) then

		Call( "*:SetControlValue", name, index, value );

	end

	-- Virtual Function and DSD if Player is loco and Expert mode
	if isPlayerLoco and isExpert then
		-- DSD Disable/Enable
		if name == "SafetyIsolation" then

			if value == 1 then 
				isSafetyIsolated = true
				alert("Class 47", "DSD Disabled", 1)
			end
			if value == 0 then
				isSafetyIsolated = false
				alert("Class 47", "DSD Enabled", 1)
			end
			gDSDStartCount = 0
		end
		
		-- Visual Alarms Enabled/Disabled
		--if name == "VisualAlarms" then
		--
		--	if value == 1 then
		--		alert("Visual Alarms", "Enabled", 1)
		--	end
		--	if value == 0 then
		--		alert("Visual Alarms", "Disabled", 1)
		--	end
		--end

		if name == "VirtualReverser" then

			if value == 0 then
				gReverserState = -1
			elseif value == 1 then
				gReverserState = 0
			elseif value == 2 then
				gReverserState = 1
			end
			Call( "*:SetControlValue", "Reverser", 0, gReverserState )
			
			if (value == 2 or value < 0.5) and isReverserDSDReset and gRunningTime > gReverserDSDTimer then
				if isSafetyIsolated == false then
					Call( "*:SetControlValue", "DSD", 0, 1 )
				elseif isSafetyIsolated == true then
					Call( "*:SetControlValue", "DSD", 0, 0 )
				end
				isReverserDSDReset = false
			elseif value == 1 and isReverserDSDReset == false then
				Call( "*:SetControlValue", "DSD", 0, 0 )
				isReverserDSDReset = true
				gReverserDSDTimer = gRunningTime
			end
		end

		if name == "VirtualThrottle" then

			gRegulator = Call( "*:GetControlValue", "VirtualThrottle", 0)
			Call( "*:SetControlValue", "Regulator", 0, gRegulator )
		end
		
		if name == "VirtualBrake" then

			gBrakeState = Call( "*:GetControlValue", "VirtualBrake", 0)
			Call( "*:SetControlValue", "TrainBrakeControl", 0, gBrakeState )
		end
		
		if name == "DSDPedal" then

			Call( "*:SetControlValue", "DSD", 0, 0 )
			gDSDStartCount = 0
		end
		
		--If the alarm is enabled DSD, while the countdown timer is stopped
		if name == "AWSReset" or name == "Horn" or name == "Bell" or name == "VirtualThrottle" or name == "VirtualReverser" then
			
			if Call( "*:GetControlValue", "DSD", 0) == 1 then
				if gDSDStartCount > DSDDELAY then
					gDSDStopCount = 0
				end
		
			elseif Call( "*:GetControlValue", "DSD", 0) == 0 then
				gDSDStartCount = 0
			end
		end
	end
	
	-- Engine Control
	if name == "EngineStart" then
		if value > 0.5 then
			Call( "*:SetControlValue", "Startup", 0, 1 )
		end
	end
	if name == "EngineStop" then
		if value > 0.5 then
			Call( "*:SetControlValue", "Startup", 0, -1 )
		end
	end
end

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

function Update ( time )

	gRunningTime = gRunningTime + time

	if Call( "GetIsPlayer" ) == 1 then
		isPlayerLoco = true
	else
		isPlayerLoco = false
	end

	if Call( "IsExpertMode" ) == 1 then
		isExpert = true	
	else
		isExpert = false
	end
	
	if isPlayerLoco and isExpert then
		DriverSafetyDevice (time)
	end

	-- Cab Lights/ Cab Lights for AI.
	if Call("*:GetControlValue", "CabLight", 0) == 1 then
		Call( "CabLight_Front_01:Activate", 1)
		Call( "CabLight_Front_02:Activate", 1)
		Call( "CabLight_Front_03:Activate", 1)
		Call( "CabLight_Rear_01:Activate", 1)
		Call( "CabLight_Rear_02:Activate", 1)
		Call( "CabLight_Rear_03:Activate", 1)
	else
		Call( "CabLight_Front_01:Activate", 0)
		Call( "CabLight_Front_02:Activate", 0)
		Call( "CabLight_Front_03:Activate", 0)
		Call( "CabLight_Rear_01:Activate", 0)
		Call( "CabLight_Rear_02:Activate", 0)
		Call( "CabLight_Rear_03:Activate", 0)
	end
	
	if isPlayerLoco == false then
		Call( "CabLight_Front_01:Activate", 0)
		Call( "CabLight_Front_02:Activate", 0)
		Call( "CabLight_Front_03:Activate", 0)
		Call( "CabLight_Rear_01:Activate", 0)
		Call( "CabLight_Rear_02:Activate", 0)
		Call( "CabLight_Rear_03:Activate", 0)
	end
	
	-- AWS Extended.
	if isExpert then
		local warncount = Call("GetControlValue", "AWSWarnCount", 0)
		local my_awsreset = Call("GetControlValue", "MyAWSReset", 0)
		local aws = Call("GetControlValue", "AWS", 0)
		local aws_warn = 0
		
		-- delay AWS horn.
		if warncount == 1 then
			aws_warn_time = aws_warn_time + time
			if aws_warn_time > 1 then
				aws_warn = 1
			else
				aws_warn = 0
			end
		else
			prev_aws = aws
			aws_warn_time = 0
			aws_warn = 0
		end
	
		Call("SetControlValue", "MyAWSWarnCount", 0, aws_warn)
		
		-- cancel AWS only on release of the button.
		if my_awsreset == 0 and prev_awsreset ~= 0 and aws_warn == 1 then
			Call("SetControlValue", "AWSReset", 0, 1)
		else
			Call("SetControlValue", "AWSReset", 0, 0)
		end
		prev_awsreset = my_awsreset

		-- AWS Self Test.
		if Call( "*:GetControlValue", "Reverser", 0) ~= 0 and gAWSReady == true then
			gAWSTesting = true

			Call("*:SetControlValue", "AWSWarnCount", 0, 1)
			Call("*:SetControlValue", "AWS", 0, 0)
			gAWSReady = false
		end

		if Call( "*:GetControlValue", "AWSReset", 0) > 0.9 and gAWSReady == false and gAWSTesting == true then
			Call("*:SetControlValue", "AWSWarnCount", 0, 0)
			Call("*:SetControlValue", "AWSClearCount", 0, 1)
			Call("*:SetControlValue", "AWS", 0, 1)
			gAWSTesting = false
		end
	end

-- Check for player train.

	if Call( "GetIsPlayer" ) == 1 then

-- Check if player is driving this engine.

		if ( Call( "GetIsEngineWithKey" ) == 1 ) then
			if gDriven == 0 then
				gDriven = 1
				Call( "*:SetControlValue", "Active", 0, 1 )
			end
		else
			if gDriven == 1 then
				gDriven = 0
				Call( "*:SetControlValue", "Active", 0, 0 )
			end
		end

-- Get tractive effort values for this vehicle.
		TractiveEffort = Call ( "GetTractiveEffort" )
		TractiveEffort = math.abs ( TractiveEffort )

	else -- This is an AI train.

-- Tractive effort doesn't work for AI, so use acceleration.

		Accel = Call( "GetAcceleration" )
		Speed = Call( "GetSpeed" )

-- Unfortunately acceleration is signed based on direction loco is facing (sic).
		if Speed < 0 then
			Accel = Accel * -1
		end

		if Accel > ACCELRATE then
			TractiveEffort = MAXTE
		elseif ( math.abs(Speed) > 1 ) and ( Accel > -0.1 ) then
			TractiveEffort = MAXTE/2
		else
			TractiveEffort = MAXTE/11
		end

	end


-- Get rpm value for this vehicle.
	rpm = Call( "*:GetControlValue", "RPM", 0 )


-- Adjust exhaust smoke based on tractive effort.

	if TractiveEffort < MAXTE/10 then
						
		gSmokeColourR = 0.8
		gSmokeColourG = 0.8
		gSmokeColourB = 0.8
		Call ( "Exhaust:SetEmitterColour", gSmokeColourR, gSmokeColourG, gSmokeColourB )
		Call ( "Exhaust:SetEmitterRate", gEmitRate )

	end
				
	if ( TractiveEffort <= MAXTE/2 ) and ( TractiveEffort >= MAXTE/10 ) then
				
		gSmokeColourR = 0.25
		gSmokeColourG = 0.25
		gSmokeColourB = 0.25
		Call ( "Exhaust:SetEmitterColour", gSmokeColourR, gSmokeColourG, gSmokeColourB )
		Call ( "Exhaust:SetEmitterRate", 0.01 )

	end
		
	if TractiveEffort > MAXTE/2 then 
	
		gSmokeColourR = 0.0
		gSmokeColourG = 0.0
		gSmokeColourB = 0.0
		Call ( "Exhaust:SetEmitterColour", gSmokeColourR, gSmokeColourG, gSmokeColourB )
		Call ( "Exhaust:SetEmitterRate", 0.005 )

	end


-- Vent animations.

	if rpm < 220 then
		if gFrontVent == 1 then
			if ( Call( "*:AddTime", "FrontVents", -time ) ~= 0 ) then
				gFrontVent = 0
			end
		end
		if gBackVent == 1 then
			if ( Call( "*:AddTime", "BackVents", -time ) ~= 0 ) then
				gBackVent = 0
			end
		end
	elseif ( rpm >= 220 ) and ( rpm <= 600 ) then
		if gFrontVent == 0 then
			if ( Call( "*:AddTime", "FrontVents", time ) ~= 0 ) then
				gFrontVent = 1
			end
		end
		if gBackVent == 1 then
			if ( Call( "*:AddTime", "BackVents", -time ) ~= 0 ) then
				gBackVent = 0
			end
		end
	else -- RPM must be greater than 600
		if gFrontVent == 0 then
			if ( Call( "*:AddTime", "FrontVents", time ) ~= 0 ) then
				gFrontVent = 1
			end
		end
		if gBackVent == 0 then
			if ( Call( "*:AddTime", "BackVents", time ) ~= 0 ) then
				gBackVent = 1
			end
		end
	end

end

function alert(title, str, time)
	SysCall("ScenarioManager:ShowAlertMessageExt", title, str, time, 1)
end

function DriverSafetyDevice (time)

	-- If the reverser is in neutral then disable DSD
	if Call( "*:GetControlValue", "Reverser", 0) == 0 then
		isDSDTriggered = false
		return
	end

	-- If DSD warning has been active for 5 seconds with no response then cut power and trigger emergency brake
	if gDSDStartCount > DSDDELAY + 5 and not isDSDTriggered and not isSafetyIsolated then
		isDSDTriggered = true
		Call( "*:SetControlValue", "EmergencyBrake", 0, 1 )
		Call( "*:SetControlValue", "Regulator", 0, 0 )
		Call( "*:SetControlValue", "Reverser", 0, 0 )

	-- If DSD timer has expired then sound DSD alarm
	elseif gDSDStartCount > DSDDELAY and not isSafetyIsolated then
		Call( "*:SetControlValue", "DSD", 0, 1 )
	end

	-- DSD alarm off when DSD isolated
	if isSafetyIsolated == true and Call( "*:GetControlValue", "DSD", 0) == 1 then
		Call( "*:SetControlValue", "DSD", 0, 0 )
	end

	-- Increment DSD timer
	gDSDStartCount = gDSDStartCount + time
end
*Train Simulator 2018*
Изображение
Аватара пользователя
pROssO
Ветеран
Сообщения: 3519
Зарегистрирован: 21 май 2012
Откуда: Минск
Репутация: 4859

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение pROssO »

Cross, думаю, нужно просто основной фрагмент этого когда сделать функцией.
Аватара пользователя
Света
Разработчик
Сообщения: 752
Зарегистрирован: 13 мар 2015
Репутация: 1470

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение Света »

pROssO
Можно обойтись одной переменной :) . А поломкам присвоить номера, причем повторяющимся - четные. Тогда, если поломка случилась, FaultOccured устанавливается в 1. При последующих поломках (если они возникнут) условие проверки статуса FaultOccured направит нас в ветку, где сгенерированный номер поломки разделится на 2. Таким образом, по второму кругу могут пойти только "многоразовые" поломки :) .
Сильные люди - это не те, у которых всё хорошо, а те, у которых всё хорошо несмотря ни на что.
Аватара пользователя
Cross
Разработчик
Сообщения: 6330
Зарегистрирован: 14 дек 2011
Откуда: Москва
Репутация: 2985

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение Cross »

pROssO
предлагаю постепенно подходить к вопросу. Чтобы ничего не усложнять для начала можно попробовать с DSD разобраться, потом ещё что-нибудь придумать
*Train Simulator 2018*
Изображение
Аватара пользователя
PseudoStalker
Ветеран
Сообщения: 3235
Зарегистрирован: 09 авг 2012
Репутация: 1811

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение PseudoStalker »

Если вы ищете куда бы применить знания, я могу подсказать за что все игроки в RW будут благодарны. Тифон ботам при проезде знака "подать звуковой сигнал". Знаки на маршрутах уже расставлены, но почти наверняка никак не связаны ни с чем, а являются просто декорацией.
Можно ли к ним прицепить функцию так, чтоб потом не надо было переделывать маршрут в редакторе - вот это еще одна задачка. А даже если и переделывать, подменим знаки на маршруте, не проблема, было бы на что и немного времени.
Аватара пользователя
Cross
Разработчик
Сообщения: 6330
Зарегистрирован: 14 дек 2011
Откуда: Москва
Репутация: 2985

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение Cross »

PseudoStalker
да запросто, только к знаку нужно привязать скрипт и сделать этот знак как отдельный типа "светофора", тогда и функцию можно завязать на нём. И ещё для этого всего придётся к каждому локомотиву дополнять код в скрипте. Сейчас другая задача стоит, её бы попробовать выполнить
*Train Simulator 2018*
Изображение
Аватара пользователя
Света
Разработчик
Сообщения: 752
Зарегистрирован: 13 мар 2015
Репутация: 1470

Re: Патчи для ПС, мини правки, замена сценариев на стандарт

Сообщение Света »

Cross
То я так понимаю, главная проблема DSD заключается в рассинхронизации реальных и виртуальных контролов?
Последний раз редактировалось Света 07 авг 2015, 19:23, всего редактировалось 1 раз.
Сильные люди - это не те, у которых всё хорошо, а те, у которых всё хорошо несмотря ни на что.
Ответить