mirror of
https://github.com/metrostroi-repo/MetrostroiAddon.git
synced 2026-05-02 00:42:29 +00:00
3415 lines
179 KiB
Lua
3415 lines
179 KiB
Lua
--------------------------------------------------------------------------------
|
||
-- 81-717 "PA" safety system
|
||
--------------------------------------------------------------------------------
|
||
-- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o.
|
||
-- Contains proprietary code. See license.txt for additional information.
|
||
--------------------------------------------------------------------------------
|
||
--[[
|
||
а) включение ПА-М и начальное тестирование:
|
||
V 1) включение ПА-М;
|
||
V 2) алгоритм определения положения реверсивной рукоятки (РР);
|
||
V 3) функции доступа к системе:
|
||
– вход в систему с кодом доступа электромеханика, тестовый контроль аппаратуры;
|
||
– вход в систему с кодом доступа машиниста и приемка состава;
|
||
4) алгоритм взаимодействия ПА-М и БАРС;
|
||
5) выход из депо, переход в режим «Работа»;
|
||
б) алгоритмы контроля пневматических систем поезда:
|
||
1) алгоритм контроля отпуска тормозов;
|
||
2) алгоритм контроля работы воздухораспределителей;
|
||
3) алгоритм контроля включения вентилей замещения В1 и В2;
|
||
4) алгоритм контроля отключения вентилей замещения В1 и В2;
|
||
в) алгоритмы регулирования скорости:
|
||
1) алгоритм формирования допустимой скорости движения по перегону;
|
||
2) регулирование скорости в режиме КС и ОС;
|
||
V 3) регулирование скорости в режиме КС при значении Vд = 0;
|
||
4) алгоритм контроля эффективности торможения;
|
||
г) алгоритм управления поездом на станции в режимах КС и ОС:
|
||
1) фиксация станции;
|
||
2) осаживание поезда;
|
||
3) процедура открытия/закрытия дверей на станции;
|
||
4) отправление со станции;
|
||
5) движение при переезде поездом зоны ОПВ на станции;
|
||
6) оборот на промежуточной станции;
|
||
д) проезд станции без остановки (транзитом);
|
||
е) алгоритм перехода на другую линию;
|
||
ж) управление поездом на перегоне:
|
||
1) управление поездом при потере контроля дверей на перегоне;
|
||
2) функция открытия дверей на перегоне по запросу машиниста;
|
||
|
||
з) алгоритм коррекции пройденного пути;
|
||
и) алгоритм коррекции значений коэффициентов (бандажа);
|
||
к) осаживание при пожаре;
|
||
л) алгоритм контроля скатывания поезда (режим КС);
|
||
м) алгоритм проверки «противоскатывания» поезда;
|
||
н) алгоритм движения по станционным путям;
|
||
о) алгоритм работы ПА-М в режиме резервного управления поездом;
|
||
п) организация работы терминала машиниста.
|
||
|
||
2.1.5 При обнаружении ПА-М пропадания сигнала КД она формирует команду ОХТ и ожидает запрос на разрешение движения без КД.
|
||
2.1.6 При пропадании сигнала КСОТ ПА-М автоматически переходит в режим ОС, дальнейшее движение поезда возможно при нажатой ПБ. При появлении сигнала КСОТ происходит автоматический переход в КС.
|
||
2.1.7 ПА-М не позволяет производить открытие дверей на перегоне, кроме случая выполнения машинистом запроса на открытие дверей только после полной остановки поезда.
|
||
2.1.8 ПА-М блокирует возможность движения состава при Vд = 0. Движение при Vд = 0 возможно со скоростью не более 20 км/ч при нажатой ПБ и включенном тумблере ВРД или введенном запросе машиниста «Движение при Vд = 0».
|
||
2.1.9 ПА-М не производит автоматического открытия дверей на станции при отсутствии радиосвязи с СА КСД.
|
||
2.1.10 ПА-М блокирует открытие дверей на станции со стороны, противоположной стороне платформы.
|
||
2.1.11 ПА-М запрещает осаживание поезда на станции открытого типа при проезде зоны ОПВ и разрешает на станции закрытого типа при проезде зоны ОПВ не более 3 м.
|
||
2.1.12 ПА-М запрещает движение со скоростью более 20 км/ч при нажатой ПБ независимо от значения Vд.
|
||
2.1.13 ПА-М в режимах КС и ОС блокирует возможность проследования станции без остановки, кроме случая введения машинистом запроса на проследование станции транзитом.
|
||
2.2.3.2 Перед включением ПА-М проверить включенное состояние переключателей РЦ1, РЦ2, автоматических выключателей А58, А59, А61 и включенное состояние выключателя ВАУ (положение «ВКЛ»).
|
||
|
||
2.3.3 Управление поездом при отсутствии кодирования (НЧ)
|
||
2.3.3.1 Функция формирования допустимой скорости движения:
|
||
а) При наезде на Vд = НЧ выдается значение предыдущей допустимой скорости, пока непройдет 0.8 секунды с момента наезда на Vд = НЧ и поезд не проедет 12 – 20 м (в зависимостиот скорости движения поезда);
|
||
б) При несовпадении данных полученных от двух плат ФФК или получении недостовер-ных данных по одной из них (при получении частот вне диапазона значений или двойных час-тот и т.д.) формируется Vд = НЧ через 1,5 секунды и после прохождения поездом 12 – 20 м(в зависимости от скорости движения поезда);
|
||
в) На стоящем поезде (при скорости менее 0.1 м/с), при пропадании частоты смена допус-тимой скорости производится через 2,5 с, не дожидаясь прохождения составом 12 м.2.3.3.2 Функция управления поездом при наезде на рельсовую цепь с отсутствием коди-рования (НЧ):
|
||
а) При наезде на рельсовую цепь с отсутствием кодирования (НЧ) выдается зуммер;
|
||
б) ПА М формирует последовательность команд ОХТ → Т2;
|
||
в) После нажатия ПБ зуммер отключается;
|
||
г) Торможение (Т2) продолжается до полной остановки, а после остановки поезда ПА-М формирует команду В1;
|
||
д) При отпущенной ПБ ПА-М формирует команду ОХТ + В1;
|
||
е) При установленном в положение «0» КВ и нажатой ПБ ПА-М формирует команду ОД;
|
||
ж) После перевода КВ в положение ХОД движение поезда возможно со скоростью не более 20 км/ч при нажатой ПБ.
|
||
2.3.4 Возможность проследования блок-участка с Vд = 0
|
||
2.3.4.1 При наезде на рельсовую цепь с Vд = 0 за 100 метров до станции с путевым разви- тием, разрешается дальнейшее движение без остановки со скоростью не более 20 км/ч при ус- ловии нажатой ПБ.
|
||
2.3.4.2 В остальных случаях при наезде на Vд = 0 происходит торможение до полной ос- тановки.
|
||
2.3.4.3 При смене допустимой скорости с Vд ≠ 0 на Vд = 0 ПА-М должна сформировать последовательность команд ОХТ → Т2 до остановки поезда, с выдачей зуммера.
|
||
2.3.4.4 После остановки поезда и нажатии ПБ команда Т2 + В1 меняется на ОХТ + В1.
|
||
2.3.4.5 При последующем отпуске ПБ, зуммер отключается.
|
||
2.3.4.6 При переводе КВ в положение ХОД назначение ходового режима запрещается, и на дисплее ТМ появляется подсказка «Движение при Vд = 0».
|
||
2.3.4.7 После остановки поезда возобновление движения со скоростью не более 20 км/ч возможно при условии нажатой ПБ и наличия сигнала ВРД (включен выключатель ВРД).
|
||
2.3.4.8 После остановки поезда возобновление движения со скоростью не более 20 км/ч возможно при условии нажатой ПБ и введения на блоке ТМ запроса «Движение при Vд = 0».
|
||
2.3.4.9 Для ввода запроса необходимо последовательно нажать на ТМ клавишу «F», за- тем выбрать пункт меню, нажав клавишу «5».
|
||
2.3.4.10 На дисплее ТМ появится «Запрос на разрешение продолжения движения при Vд = 0» (рисунок 11).
|
||
2.3.4.11 При нажатии клавиши «Esc» произойдет возврат к предыдущему кадру без раз- решения продолжения движения (режим ОХТ + В1).
|
||
2.3.4.12 При нажатии клавиши « ←⏐» ПА М разрешит продолжение движения при Vд = 0, а на ТМ произойдет возврат к предыдущему кадру и на время 7 секунд появится под- сказка «Разрешено движение при Vд = 0».
|
||
2.3.4.13 Режим ОХТ + В1 сменится на ОД + В1 при нажатой ПБ.
|
||
2.3.4.14 При появлении Vд ≠ 0 запрос «движение при Vд = 0» автоматически снимается.
|
||
]]
|
||
|
||
Metrostroi.DefineSystem("PAM")
|
||
TRAIN_SYSTEM.DontAccelerateSimulation = true
|
||
TRAIN_SYSTEM.TriggerNames = {
|
||
"PAM7",
|
||
"PAM8",
|
||
"PAM9",
|
||
"PAMLeft",
|
||
"PAMRight",
|
||
"PAM4",
|
||
"PAM5",
|
||
"PAM6",
|
||
"PAMUp",
|
||
"PAM1",
|
||
"PAM2",
|
||
"PAM3",
|
||
"PAMDown",
|
||
"PAM0",
|
||
"PAMEnter",
|
||
"PAMEsc",
|
||
"PAMF",
|
||
"PAMM",
|
||
"PAMP",
|
||
"PAMKeyB",
|
||
}
|
||
|
||
function TRAIN_SYSTEM:Initialize()
|
||
self.Train:LoadSystem("PAM_VV")
|
||
self.Train:LoadSystem("KSD_R","Relay")
|
||
self.Train:LoadSystem("KSD_VAU","Relay",nil,{close_time=0.1})
|
||
--self.Train:LoadSystem("KSZD","Relay","Switch",{ bass = true })
|
||
--self.Train:LoadSystem("VZP","Relay","Switch",{ bass = true })
|
||
--self.Train:LoadSystem("VAU","Relay","Switch",{ bass = true, normally_closed = true })
|
||
--self.Train:LoadSystem("RC2","Relay","Switch",{ bass = true, normally_closed = true })
|
||
|
||
|
||
self.Triggers = {}
|
||
self.Touches = {}
|
||
for k,v in pairs(self.TriggerNames) do
|
||
self.Train:LoadSystem(v,"Relay","Switch",{ bass = true })
|
||
self.Triggers[k] = false
|
||
self.Touches[k] = false
|
||
end
|
||
|
||
self.NoFreq = 0
|
||
self.F6 = 0
|
||
self.F5 = 0
|
||
self.F4 = 0
|
||
self.F3 = 0
|
||
self.F2 = 0
|
||
self.F1 = 0
|
||
|
||
self["2"] = 0 --Вращение РК
|
||
self["3"] = 0 --Ход 3
|
||
self["8"] = 0 --Замещение электрического торможения
|
||
self["16"] = 0 --Закрытие дверей
|
||
self["68"] = 0 --Открытие правых дверей хвостового вагона
|
||
self["17"] = 0 -- Разрешение восстановления реле перегрузки
|
||
self["19"] = 0 -- Разрешение замещения электрического торможения
|
||
self["20"] = 0 -- Включение двигателей
|
||
self["20X"] = 0 -- Разрешение включения двигателей в ходовые режимы
|
||
self["025"] = 0 -- Разрешение ручного торможения
|
||
self["25"] = 0 -- Ручное торможение
|
||
self["31"] = 0 --Открытие открытия левых дверей
|
||
self["32"] = 0 --Открытие правых дверей
|
||
self["33"] = 0 --Включение ходового режима
|
||
self["033"] = 0 --Разрешение включения ходового режима
|
||
self["33G"] = 0 --Включение режима торможения
|
||
self["39"] = 0 --Включение вентиля замещения № 2
|
||
self["7GA"] = 0 --Включение вентиля замещения № 2
|
||
self["48"] = 0 --Включение вентиля замещения № 1
|
||
self.EPK = 0
|
||
|
||
|
||
self.Ring = 0
|
||
|
||
self.State = 0
|
||
self.Selected = 1
|
||
|
||
self.Keyboard = false
|
||
|
||
self.Station = ""
|
||
self.Path = ""
|
||
self.RouteNumber = ""
|
||
self.DriverNumber = ""
|
||
--self:SetDriveMode = "Zero"
|
||
--self.CurrentDoorMode = "DO"
|
||
--self.CurrentPneumoMode = "NT"
|
||
self.Speed = 0
|
||
self.SpeedLimit = 0
|
||
self.Acceleration = 0
|
||
self.Brightness = 0.6
|
||
self.ErrorTimers = {}
|
||
self.Timers = {}
|
||
end
|
||
|
||
|
||
--if TURBOSTROI then return end
|
||
function TRAIN_SYSTEM:Inputs()
|
||
return { "KSDMode" }
|
||
end
|
||
function TRAIN_SYSTEM:Outputs()
|
||
return {
|
||
"2","3","8","16","68","17","19","20","20X","025","25","31","32","33","033","33G","39","7GA","48","EPK",
|
||
"Ring", "NoFreq", "F5", "F4", "F3", "F2", "F1"
|
||
}
|
||
end
|
||
|
||
if CLIENT then
|
||
local function createFont(name,font,size)
|
||
surface.CreateFont("Metrostroi_"..name, {
|
||
font = font,
|
||
size = size,
|
||
weight = 800,
|
||
blursize = false,
|
||
antialias = true,
|
||
underline = false,
|
||
italic = false,
|
||
strikeout = false,
|
||
symbol = false,
|
||
rotary = false,
|
||
shadow = false,
|
||
additive = false,
|
||
outline = false,
|
||
extended = true,
|
||
scanlines = false,
|
||
})
|
||
end
|
||
createFont("PAM15","Arial",15)
|
||
createFont("PAM19","Arial",19)
|
||
createFont("PAM20","Arial",20)
|
||
createFont("PAM21","Arial",21)
|
||
createFont("PAM24","Arial",24)
|
||
createFont("PAM25","Arial",25)
|
||
createFont("PAM26","Arial",26)
|
||
createFont("PAM27","Arial",27)
|
||
createFont("PAM28","Arial",28)
|
||
createFont("PAM29","Arial",29)
|
||
createFont("PAM30","Arial",30)
|
||
createFont("PAM31","Arial",31)
|
||
createFont("PAM35","Arial",35)
|
||
createFont("PAM45","Arial",45)
|
||
createFont("PAM60","Arial",60)
|
||
function TRAIN_SYSTEM:ClientThink()
|
||
if not self.Train:ShouldDrawPanel("PAMScreen") then return end
|
||
if self.FilterMag then
|
||
render.PopFilterMag()
|
||
render.PopFilterMin()
|
||
end
|
||
|
||
self.FilterMag = true
|
||
|
||
render.PushRenderTarget(self.Train.PAM,0,0,1024, 512)
|
||
render.Clear(0, 0, 0, 0)
|
||
cam.Start2D()
|
||
render.SetScissorRect(0, 0, 640, 480, true)
|
||
render.PushFilterMag( TEXFILTER.POINT )
|
||
render.PushFilterMin( TEXFILTER.POINT )
|
||
surface.SetDrawColor(0,0,0)
|
||
surface.DrawRect(0,0,640,480)
|
||
if true then self:PAMScreen(self.Train) end
|
||
render.SetScissorRect(0, 0, 0, 0, false)
|
||
render.PopFilterMag()
|
||
render.PopFilterMin()
|
||
cam.End2D()
|
||
render.PopRenderTarget()
|
||
self.FilterMag = false
|
||
end
|
||
|
||
local button = {"button_lt","button_lc","button_lb","button_ct","button_cc","button_cb"}
|
||
local button_p = {"button_p_lt","button_p_lc","button_p_lb","button_p_ct","button_p_cc","button_p_cb"}
|
||
local button_s = {"button_s_lt","button_s_lc","button_s_lb","button_s_ct","button_s_cc","button_s_cb"}
|
||
|
||
local textbox = {
|
||
"textbox_corner_tl","textbox_corner_t","textbox_corner_tr",
|
||
"textbox_corner_l","textbox_corner_r",
|
||
"textbox_corner_bl","textbox_corner_b","textbox_corner_br",
|
||
}
|
||
local speed = {
|
||
"speed_tl","speed_t","speed_tr",
|
||
"speed_l","speed_c","speed_r",
|
||
"speed_bl","speed_b","speed_br",
|
||
}
|
||
local window = {
|
||
"window_tl","window_tc","window_tr",
|
||
"window_cl","window_cc","window_cr",
|
||
"window_bl","window_bc","window_br",
|
||
}
|
||
local function replaceNames(tbl,path)
|
||
for k,v in pairs(tbl) do tbl[k] = surface.GetTextureID((path or "models/metrostroi_train/81-717/screens/pa/buttons/")..v) end
|
||
end
|
||
replaceNames(button)
|
||
replaceNames(button_p)
|
||
replaceNames(button_s)
|
||
replaceNames(textbox)
|
||
replaceNames(speed)
|
||
replaceNames(window,"models/metrostroi_train/81-717/screens/pa/window/")
|
||
local function drawButton(x,y,w,h,button,color)
|
||
--[[ surface.SetDrawColor(255,0,0)
|
||
surface.DrawLine(x,y,x+w,y)
|
||
surface.DrawLine(x+w,y,x+w,y+h)
|
||
surface.DrawLine(x,y+h,x+w,y+h)
|
||
surface.DrawLine(x,y,x,y+h)--]]
|
||
if not button then return end
|
||
w = math.max(w-16,0)
|
||
h = math.max(h-16,0)
|
||
surface.SetDrawColor(color or Color(255,255,255))
|
||
surface.SetTexture(button[1])
|
||
surface.DrawTexturedRect(x,y,8,8)
|
||
surface.DrawTexturedRectUV(x+w+8,y,8,8,1,0,0,1)
|
||
if h > 0 then
|
||
surface.SetTexture(button[2])
|
||
surface.DrawTexturedRect(x,y+8,8,h)
|
||
surface.SetTexture(button[2])
|
||
surface.DrawTexturedRectUV(x+w+8,y+8,8,h,1,0,0,1)
|
||
--surface.DrawTexturedRectUV(x+8,y,w,h,0,0,1*(w/8),1)
|
||
end
|
||
if w > 0 then
|
||
surface.SetTexture(button[4])
|
||
surface.DrawTexturedRectUV(x+8,y,w,8,0,0,1*(w/8),1)
|
||
surface.SetTexture(button[5])
|
||
surface.DrawTexturedRect(x+8,y+8,w,h)
|
||
surface.SetTexture(button[6])
|
||
surface.DrawTexturedRectUV(x+8,y+h+8,w,8,0,0,1*(w/8),1)
|
||
end
|
||
surface.SetTexture(button[3])
|
||
surface.DrawTexturedRect(x,y+h+8,8,8)
|
||
surface.DrawTexturedRectUV(x+w+8,y+h+8,8,8,1,0,0,1)
|
||
--surface.SetTexture(button[3])
|
||
--surface.DrawTexturedRect(x+w+8,y,8,h,0)
|
||
end
|
||
local function drawWindow(x,y,w,h,text)
|
||
w = math.max(w-16,0)
|
||
h = math.max(h-40,0)
|
||
--Color(74,95,148)
|
||
surface.SetDrawColor(color or Color(255,255,255))
|
||
--surface.DrawRect(x+4,y+4,w,h)
|
||
surface.SetTexture(window[1])
|
||
surface.DrawTexturedRect(x,y,8,32)
|
||
surface.SetTexture(window[2])
|
||
surface.DrawTexturedRect(x+8,y,w,32)
|
||
surface.SetTexture(window[3])
|
||
surface.DrawTexturedRect(x+w+8,y,8,32)
|
||
draw.SimpleText(text,"Metrostroi_PAM19",x+8+w/2,y+18, Color(28,35,53),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(text,"Metrostroi_PAM19",x+8+w/2,y+16, col or Color(255,255,255),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
|
||
surface.SetDrawColor(color or Color(255,255,255))
|
||
surface.SetTexture(window[4])
|
||
surface.DrawTexturedRect(x,y+32,8,h)
|
||
surface.SetTexture(window[5])
|
||
surface.DrawTexturedRect(x+8,y+32,w,h)
|
||
surface.SetTexture(window[6])
|
||
surface.DrawTexturedRect(x+w+8,y+32,8,h)
|
||
|
||
surface.SetTexture(window[7])
|
||
surface.DrawTexturedRect(x,y+h+32,8,4)
|
||
surface.SetTexture(window[8])
|
||
surface.DrawTexturedRect(x+8,y+h+32,w,4)
|
||
surface.SetTexture(window[9])
|
||
surface.DrawTexturedRect(x+w+8,y+h+32,8,4)
|
||
|
||
--draw.SimpleText(text,font,x+w/2+4,y+h/2+4, Color(0,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
--surface.SetTexture(button[3])
|
||
--surface.DrawTexturedRect(x+w+8,y,8,h,0)
|
||
end
|
||
local function drawTextBox(x,y,w,h,text,font,color)
|
||
--[[ surface.SetDrawColor(255,0,0)
|
||
surface.DrawLine(x,y,x+w,y)
|
||
surface.DrawLine(x+w,y,x+w,y+h)
|
||
surface.DrawLine(x,y+h,x+w,y+h)
|
||
surface.DrawLine(x,y,x,y+h)--]]
|
||
|
||
w = math.max(w-8,0)
|
||
h = math.max(h-8,0)
|
||
surface.SetDrawColor(color or Color(255,255,255))
|
||
surface.DrawRect(x+4,y+4,w,h)
|
||
surface.SetTexture(textbox[1])
|
||
surface.DrawTexturedRect(x,y,4,4)
|
||
surface.SetTexture(textbox[2])
|
||
surface.DrawTexturedRect(x+4,y,w,4)
|
||
surface.SetTexture(textbox[3])
|
||
surface.DrawTexturedRect(x+w+4,y,4,4)
|
||
|
||
surface.SetTexture(textbox[4])
|
||
surface.DrawTexturedRect(x,y+4,4,h)
|
||
surface.SetTexture(textbox[5])
|
||
surface.DrawTexturedRect(x+w+4,y+4,4,h)
|
||
|
||
surface.SetTexture(textbox[6])
|
||
surface.DrawTexturedRect(x,y+h+4,4,4)
|
||
surface.SetTexture(textbox[7])
|
||
surface.DrawTexturedRect(x+4,y+h+4,w,4)
|
||
surface.SetTexture(textbox[8])
|
||
surface.DrawTexturedRect(x+w+4,y+h+4,4,4)
|
||
|
||
draw.SimpleText(text,font,x+w/2+4,y+h/2+4, Color(0,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
end
|
||
local function drawSpeed(x,y,w,h,color)
|
||
--[[
|
||
surface.SetDrawColor(255,0,0)
|
||
surface.DrawLine(x,y,x+w,y)
|
||
surface.DrawLine(x+w,y,x+w,y+h)
|
||
surface.DrawLine(x,y+h,x+w,y+h)
|
||
surface.DrawLine(x,y,x,y+h)--]]
|
||
--w = math.max(w-8,0)
|
||
h = math.max(h-8,0)
|
||
if w < -4 then return end
|
||
surface.SetDrawColor(color or Color(255,255,255))
|
||
--surface.DrawRect(x+4,y+4,w,h)
|
||
surface.SetTexture(speed[1])
|
||
surface.DrawTexturedRect(x,y,4,4)
|
||
surface.SetTexture(speed[2])
|
||
surface.DrawTexturedRect(x+4,y,w,4)
|
||
surface.SetTexture(speed[3])
|
||
surface.DrawTexturedRect(x+w+4,y,4,4)
|
||
|
||
surface.SetTexture(speed[4])
|
||
surface.DrawTexturedRect(x,y+4,4,h)
|
||
surface.SetTexture(speed[5])
|
||
surface.DrawTexturedRectUV(x+4,y+4,w,h,0,0,1*(w/19),1)
|
||
surface.SetTexture(speed[6])
|
||
surface.DrawTexturedRect(x+w+4,y+4,4,h)
|
||
|
||
surface.SetTexture(speed[7])
|
||
surface.DrawTexturedRect(x,y+h+4,4,4)
|
||
surface.SetTexture(speed[8])
|
||
surface.DrawTexturedRect(x+4,y+h+4,w,4)
|
||
surface.SetTexture(speed[9])
|
||
surface.DrawTexturedRect(x+w+4,y+h+4,4,4)
|
||
end
|
||
local function buttonWTextC(x,y,w,h,text,font,color,button,buttoncolor)
|
||
drawButton(x,y,w,h,button,buttoncolor)
|
||
draw.SimpleText(text,font,x+w/2,y+h/2, color,TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
end
|
||
|
||
function drawFrame(tex,x,y,w,h,alpha)
|
||
x,y,w,h = x or 0,y or 0,w or 1024,h or 512
|
||
surface.SetTexture(tex)
|
||
surface.SetDrawColor(255,255,255,alpha)
|
||
surface.DrawTexturedRect(x,y,w,h)
|
||
--surface.DrawTexturedRectRotated(x+w/2,y+h/2,w,h,0)
|
||
end
|
||
|
||
function stateDebug(Train)
|
||
draw.SimpleText(Format("St = %.02f",Train:GetNW2Float("PAM:TrackS",-1)),"Metrostroi_PAM30",5,20, Color(255,255,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("S = %.02f",Train:GetNW2Float("PAM:S",-1)),"Metrostroi_PAM30",5,20+20*1, Color(255,255,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("Sd = %.02f",Train:GetNW2Float("PAM:Sd",-1)),"Metrostroi_PAM30",5,20+20*2, Color(255,255,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("S2 = %.02f",Train:GetNW2Float("PAM:S2",-1)),"Metrostroi_PAM30",5,20+20*3, Color(255,255,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("S2d = %.02f",Train:GetNW2Float("PAM:S2d",-1)),"Metrostroi_PAM30",5,20+20*4, Color(255,255,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("SSd = %.02f",Train:GetNW2Float("PAM:S",-1)-Train:GetNW2Float("PAM:S2",-1)),"Metrostroi_PAM30",5,20+20*5, Color(255,255,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
|
||
draw.SimpleText(Format("SensID = %0.1f",Train:GetNW2Float("PAM:LastSensorDist",-1)),"Metrostroi_PAM30",5,20+20*7, Color(255,255,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("SensD = %0.1f",Train:GetNW2Float("PAM:SensorDist",-1)),"Metrostroi_PAM30",5,20+20*8, Color(255,255,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("SensT = %0.1f",Train:GetNW2Float("PAM:LastSensorTime",-1)),"Metrostroi_PAM30",5,20+20*9, Color(255,255,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("SensD1 = %0.3f",Train:GetNW2Float("PAM:LastSensorDiff",-1)),"Metrostroi_PAM30",5,20+20*10, Color(255,255,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("SensD2 = %0.3f",Train:GetNW2Float("PAM:LastSensorDiff2",-1)),"Metrostroi_PAM30",5,20+20*11, Color(255,255,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
|
||
draw.SimpleText(Format("Sig = %s",Train:GetNW2String("PAM:Signal","n\\a")),"Metrostroi_PAM30",5,20+20*13, Color(255,255,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
|
||
draw.SimpleText(Format("ST = %d",Train:GetNW2Int("PAM:Station",-1)),"Metrostroi_PAM30",5,20+20*15, Color(255,255,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("STd = %0.2f",Train:GetNW2Float("PAM:StationS",-1)),"Metrostroi_PAM30",5,20+20*16, Color(255,255,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("STD = %0.1f",Train:GetNW2Float("PAM:StationD",-1)),"Metrostroi_PAM30",5,20+20*17, Color(255,255,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
end
|
||
|
||
local state1_nkr = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/state1_nkr")
|
||
local state1_kr = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/state1_kr")
|
||
local function State1(Train)
|
||
local reverser = Train:GetNW2Bool("PAM:Reverser")
|
||
local xmin = reverser and 36 or 0
|
||
drawFrame(reverser and state1_kr or state1_nkr)
|
||
local Stest,SSetup,SBack = Train:GetNW2Bool("PAM:GoodTest"),Train:GetNW2Bool("PAM:GoodSetup"),Train:GetNW2Int("PAM:GoodBack",0)
|
||
if Stest then
|
||
draw.SimpleText("НОРМА","Metrostroi_PAM28",431,163+38*0-xmin, Color(0,165,13),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText("НЕ НОРМА","Metrostroi_PAM28",431,163+38*0-xmin, Color(213,18,8),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
end
|
||
if SSetup then
|
||
draw.SimpleText("НОРМА","Metrostroi_PAM28",431,163+38*1-xmin, Color(0,165,13),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText("НЕ НОРМА","Metrostroi_PAM28",431,163+38*1-xmin, Color(213,18,8),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
end
|
||
if SBack==1 then
|
||
draw.SimpleText("НОРМА","Metrostroi_PAM28",431,163+38*2-xmin, Color(0,165,13),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
elseif SBack==-1 then
|
||
draw.SimpleText("НЕ НОРМА","Metrostroi_PAM28",431,163+38*2-xmin, Color(213,18,8),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText("НЕТ СВЯЗИ","Metrostroi_PAM28",431,163+38*2-xmin, Color(125,125,125),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
end
|
||
draw.SimpleText("2.2","Metrostroi_PAM28",431-5,163+38*3-xmin, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
|
||
|
||
draw.SimpleText("ПСР не подключен","Metrostroi_PAM27",315,318-xmin, Color(213,18,8),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
|
||
buttonWTextC(542,352-xmin,77,51,"Esc","Metrostroi_PAM30",Color(0,0,0), Train:GetNW2Bool("PAM:KeyEsc") and button_p or button)
|
||
if reverser then
|
||
buttonWTextC(320-55,410,110,51,"Enter","Metrostroi_PAM30", Color(0,0,0), Train:GetNW2Bool("PAM:KeyEnter") and button_p or button)
|
||
--buttonWTextC(320-55,410,110,51,"Enter","Metrostroi_PAM30", SSetup and Color(0,0,0) or Color(124,124,124), (SSetup and Train:GetNW2Bool("PAM:KeyEnter")) and button_p or button)
|
||
end
|
||
end
|
||
local state1_errs = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/state1_errs")
|
||
local function State1_5(Train)
|
||
drawFrame(state1_errs)
|
||
local backPA = Train:GetNW2Int("PAM:GoodBack",0)
|
||
for i=0,7 do
|
||
if i~=4 or Train:GetNW2Bool("PAM:GoodSetup") then
|
||
draw.SimpleText("НОРМА","Metrostroi_PAM28",302,164+31*i, Color(0,165,13),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText("НЕ НОРМА","Metrostroi_PAM28",302,164+31*i, Color(213,18,8),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
end
|
||
if backPA ==0 then
|
||
draw.SimpleText("НЕТ СВЯЗИ","Metrostroi_PAM28",471,164+31*i, Color(125,125,125),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
elseif i==4 and backPA == -1 then
|
||
draw.SimpleText("НЕ НОРМА","Metrostroi_PAM28",471,164+31*i, Color(213,18,8),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText("НОРМА","Metrostroi_PAM28",471,164+31*i, Color(0,165,13),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
end
|
||
end
|
||
buttonWTextC(320-82,408,164,51,"Закрыть","Metrostroi_PAM30",Color(0,0,0), Train:GetNW2Bool("PAM:KeyEsc") and button_p or button)
|
||
end
|
||
local state2 = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/state2")
|
||
local tbl = {
|
||
1,"Выход на линию",
|
||
2,"Перезапуск",
|
||
false,"Назад",
|
||
"M","Технологическое меню",
|
||
}
|
||
local function State2(Train)
|
||
drawFrame(state2)
|
||
local sel = Train:GetNW2Int("PAM:Selected",1)
|
||
for i=1,#tbl/2 do
|
||
local color = i==sel and Color(255,255,255) or Color(0,0,0)
|
||
local y = 121+59*(i-1)+25
|
||
if i~=2 or Train:GetNW2Bool("PAM:HaveRestart") then
|
||
if i==4 then y=y+69 end
|
||
drawButton(320-298,y-25,596,50, i==sel and button_s or button)
|
||
draw.SimpleText(tbl[i*2],"Metrostroi_PAM28",320-98,y, color,TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
if tbl[i*2-1] then
|
||
draw.SimpleText(tbl[i*2-1],"Metrostroi_PAM28",320-292,y, color,TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
if i==4 then
|
||
Metrostroi.DrawLine(320-290,y+13,320-272,y+13,color,3)
|
||
else
|
||
Metrostroi.DrawLine(320-290,y+13,320-277,y+13,color,3)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
local keyboard_na = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/keyboard_na")
|
||
local keyboard = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/keyboard")
|
||
local keys = {
|
||
"P",
|
||
"F" , "Up" , "M",
|
||
"Left","Down","Right",
|
||
"1" , "2" , "3",
|
||
"4" , "5" , "6",
|
||
"7" , "8" , "9",
|
||
"Esc" , "0" ,"Enter",
|
||
}
|
||
local keysConv = {Up="▲",Left="◄",Down="▼",Right="►",}
|
||
local function drawKeyboard(Train,x,y)
|
||
local selected = Train:GetNW2String("PAM:Touching","") ~= ""
|
||
drawFrame(selected and keyboard or keyboard_na,x,y,256,512)
|
||
local colors = Color(0,0,0,255*0.3)
|
||
for i,keyName in ipairs(keys) do
|
||
local touched = not selected and Train:GetNW2String("PAM:LastToucn") == keyName
|
||
local touching = Train:GetNW2String("PAM:Touching") == keyName
|
||
local col = Color(255,255,255,colors.a)
|
||
if touching then col = Color(245,46,18) end
|
||
if touched then
|
||
col = Color(255,255,255)
|
||
end
|
||
local key = i+1
|
||
local xp = key%3
|
||
local yp = math.floor(key/3)
|
||
buttonWTextC(x+5+60*xp,y+32+49*yp,60,49,keysConv[keyName] or keyName,"Metrostroi_PAM27",Color(0,0,0), Train:GetNW2Bool("PAM:Key"..keyName) and button_p or button,col)
|
||
end
|
||
end
|
||
local combobox = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/combobox")
|
||
local combobox_g = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/combobox_g")
|
||
local function comboBox(Train,x,y)
|
||
local count = Train:GetNW2Int("PAM:ElemCount",0)
|
||
if count <= 0 then return end
|
||
local w,h = 260,163
|
||
drawFrame(combobox,x,y,256,256)
|
||
for i=1,Train:GetNW2String("PAM:ElemCount",0) do
|
||
local text = Train:GetNW2String("PAM:Elem"..i)
|
||
local tab = text:find("\t")
|
||
if tab then
|
||
draw.SimpleText(text:sub(1,tab-1),"Metrostroi_PAM20",x+13,y+27-10+18*(i-1), Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(text:sub(tab+1,-1),"Metrostroi_PAM20",x+13+35,y+27-10+18*(i-1), Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText(text,"Metrostroi_PAM20",x+13,y+27-5+18*(i-1), Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
end
|
||
--x+28+18*i Train:SetNW2String("PAM:Elem"..iS,id.."\t"..(name or id))
|
||
end
|
||
--[[ surface.SetDrawColor(Color(255,0,0))
|
||
surface.DrawLine(x+219,y+5,x+219+31,y+5)
|
||
surface.DrawLine(x+219,y+5,x+219,y+5+15)
|
||
surface.DrawLine(x+219,y+5+15,x+219+31,y+5+15)
|
||
surface.DrawLine(x+219+31,y+5,x+219+31,y+5+15)
|
||
|
||
surface.SetDrawColor(Color(0,255,0))
|
||
surface.DrawLine(x+219,y+128,x+219+31,y+128)
|
||
surface.DrawLine(x+219,y+128,x+219,y+128+14)
|
||
surface.DrawLine(x+219,y+128+14,x+219+31,y+128+14)
|
||
surface.DrawLine(x+219+31,y+128,x+219+31,y+128+14)
|
||
|
||
surface.SetDrawColor(Color(0,0,255))
|
||
surface.DrawLine(x+219,y+143,x+219+31,y+143)
|
||
surface.DrawLine(x+219,y+143,x+219,y+143+14)
|
||
surface.DrawLine(x+219,y+143+14,x+219+31,y+143+14)
|
||
surface.DrawLine(x+219+31,y+143,x+219+31,y+143+14)--]]
|
||
|
||
end
|
||
local state3 = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/state3")
|
||
local state3k = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/state3k")
|
||
local keyb_icon = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/buttons/keyb_icon")
|
||
local function State3(Train)
|
||
local selected = Train:GetNW2String("PAM:Touching") ~= ""
|
||
local keyboard = Train:GetNW2Bool("PAM:Keyboard")
|
||
if keyboard then drawFrame(state3k,640-512,nil,512) else drawFrame(state3) end
|
||
local sel = Train:GetNW2Int("PAM:Selected",1)
|
||
local xadd = keyboard and 1 or 0
|
||
drawTextBox(374,103+35*0,210,35,Train:GetNW2String("PAM:StationS",""),"Metrostroi_PAM30",not selected and sel == 1 and Color(79,252,246))
|
||
drawTextBox(374,103+35*1,210,35,Train:GetNW2String("PAM:PathS",""),"Metrostroi_PAM30",not selected and sel == 2 and Color(79,252,246))
|
||
drawTextBox(374,103+35*2,210,35,Train:GetNW2String("PAM:RouteNumber",""),"Metrostroi_PAM30",not selected and sel == 3 and Color(79,252,246))
|
||
drawTextBox(374,103+35*3,210,35,Train:GetNW2String("PAM:DriverNumber",""),"Metrostroi_PAM30",not selected and sel == 4 and Color(79,252,246))
|
||
drawTextBox(374,103+35*4,210,35,os.date("!%d.%m.%y %H:%M:%S",Metrostroi.GetSyncTime()),"Metrostroi_PAM30",sel == 5 and Color(79,252,246))
|
||
if sel==1 then comboBox(Train,374,103+35*1) end
|
||
local err = Train:GetNW2String("PAM:EnterError","")
|
||
if err ~= "" then draw.SimpleText(err,"Metrostroi_PAM30",320+xadd*90,300, Color(213,18,8),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER) end
|
||
local currStation = Train:GetNW2String("PAM:CurrentStationS")
|
||
if currStation ~= "" then draw.SimpleText(currStation,"Metrostroi_PAM30",320+xadd*90,330, Color(0,165,13),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER) end
|
||
buttonWTextC(156+xadd*127,369,120,51,"Ввод","Metrostroi_PAM30",Color(0,0,0), Train:GetNW2Bool("PAM:KeyEnter") and button_p or button)
|
||
buttonWTextC(286+xadd*127,369,120,51,"Назад","Metrostroi_PAM30",Color(0,0,0), Train:GetNW2Bool("PAM:KeyEsc") and button_p or button)
|
||
if Train:GetNW2Bool("PAM:KeyKeyB") or keyboard then drawButton(443+xadd*100,369,40,51, keyboard and button_p or button) end
|
||
surface.SetDrawColor(255,255,255)
|
||
surface.SetTexture(keyb_icon)
|
||
surface.DrawTexturedRect(447+xadd*100,363,32,64)
|
||
if keyboard then drawKeyboard(Train,22,47) end
|
||
end
|
||
local state35 = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/state35")
|
||
local state35k = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/state35k")
|
||
local function State35(Train)
|
||
local selected = Train:GetNW2String("PAM:Touching") ~= ""
|
||
local keyboard = Train:GetNW2Bool("PAM:Keyboard")
|
||
|
||
if keyboard then drawFrame(state35k,640-512,nil,512) else drawFrame(state35) end
|
||
local sel = Train:GetNW2Int("PAM:Selected",1)
|
||
local xadd = keyboard and 1 or 0
|
||
drawTextBox(374,103+35*0,210,35,Train:GetNW2String("PAM:StationS",""),"Metrostroi_PAM30",not selected and sel == 1 and Color(79,252,246))
|
||
drawTextBox(374,103+35*1,210,35,Train:GetNW2String("PAM:PathS",""),"Metrostroi_PAM30",not selected and sel == 2 and Color(79,252,246))
|
||
if sel==1 then comboBox(Train,374,103+35*1) end
|
||
local err = Train:GetNW2String("PAM:EnterError","")
|
||
if err ~= "" then draw.SimpleText(err,"Metrostroi_PAM30",320+xadd*90,260, Color(213,18,8),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER) end
|
||
local currStation = Train:GetNW2String("PAM:CurrentStationS")
|
||
if currStation ~= "" then draw.SimpleText(currStation,"Metrostroi_PAM30",320+xadd*90,330, Color(0,165,13),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER) end
|
||
|
||
buttonWTextC(156+xadd*127,369,120,51,"Ввод","Metrostroi_PAM30",Color(0,0,0), Train:GetNW2Bool("PAM:KeyEnter") and button_p or button)
|
||
buttonWTextC(286+xadd*127,369,120,51,"Назад","Metrostroi_PAM30",Color(0,0,0), Train:GetNW2Bool("PAM:KeyEsc") and button_p or button)
|
||
|
||
if Train:GetNW2Bool("PAM:KeyKeyB") or keyboard then drawButton(443+xadd*100,369,40,51, keyboard and button_p or button) end
|
||
surface.SetDrawColor(255,255,255)
|
||
surface.SetTexture(keyb_icon)
|
||
surface.DrawTexturedRect(447+xadd*100,363,32,64)
|
||
|
||
if keyboard then drawKeyboard(Train,22,47,selected) end
|
||
end
|
||
|
||
local state4 = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/state4")
|
||
local function State4(Train)
|
||
drawFrame(state4)
|
||
buttonWTextC(320-19,278,76,38,"Ввод","Metrostroi_PAM30",Color(0,0,0), Train:GetNW2Bool("PAM:KeyEnter") and button_p or button)
|
||
end
|
||
|
||
local function drawText2(x,y,text,state,col)
|
||
if state then
|
||
draw.SimpleText(text,"Metrostroi_PAM30",x,y, col or Color(0,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText(text,"Metrostroi_PAM30",x+1,y+1, Color(173,178,172),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(text,"Metrostroi_PAM30",x,y, col or Color(142,147,146),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
end
|
||
end
|
||
local driveModes = {
|
||
[0]="?",
|
||
"ОС",
|
||
"КС",
|
||
"АВ",
|
||
"ОР",
|
||
"КР",
|
||
}
|
||
|
||
local KVModes = {
|
||
[-4]="Т2",
|
||
[-3]="Т1а",
|
||
[-2]="Т1",
|
||
[-1]="ОХТ",
|
||
[0]="ОД",
|
||
[1]="Х1",
|
||
[2]="Х2",
|
||
[3]="Х3",
|
||
}
|
||
local menus = {
|
||
{"Проверка","скатывания"},
|
||
{"Движение","без КД"},
|
||
"Смена линии",
|
||
{"Движение","транзитом"},
|
||
{"Движение"," при Vд=0"},
|
||
{"Открытие дверей","на перегоне"},
|
||
{"Движение","без контроля ЛПТ"},
|
||
{"Зонный","оборот"},
|
||
{"Фиксация","станции"},
|
||
[12]="Закрыть"
|
||
}
|
||
local acceptions = {
|
||
[-7] = "Подтверди переход на другую линию",
|
||
[-6] = "Подтверди осаживание при пожаре",
|
||
[-4] = {"Подтверди движение по станционным","путям"},
|
||
[-3] = "Подтверди переход в ОС",
|
||
[-2] = "Подтверди переход в КС",
|
||
[-1] = "Подтверди переход в АВ",
|
||
"Подтвердите проверку скатывания",
|
||
"Подтвердите движение без КД",
|
||
"Подтвердите смену линии",
|
||
"Подтвердите движение транзитом",
|
||
"Подтвердите движение при Vд = 0",
|
||
"Подтвердите открытие дверей на перегоне",
|
||
"Подтвердите движение без контроля ЛПТ",
|
||
"Подтвердите зонный оборот",
|
||
[11]="Подтвердите отмену проверки скатывания",
|
||
[12]="Подтвердите отмену движения без КД",
|
||
[13]="Подтвердите отмену смены линии",
|
||
[14]="Подтвердите отмену движения транзитом",
|
||
[15]="Подтвердите отмену движения при Vд = 0",
|
||
[16]={"Подтвердите отмену открытия дверей на","перегоне"},
|
||
[17]="Подтвердите восстановление контроля ЛПТ",
|
||
[18]="Подтвердите отмену зонного оборота",
|
||
}
|
||
local menusReset = {
|
||
{"Проверка","скатывания"},
|
||
{"Движение","без КД"},
|
||
"Смена линии",
|
||
"Транзит",
|
||
{"Движение"," при Vд=0"},
|
||
{"Открытие дверей","на перегоне"},
|
||
{"Движение","без контроля ЛПТ"},
|
||
"Оборот",
|
||
[11]="Закрыть"
|
||
}
|
||
|
||
local errors = {
|
||
"Открой правые двери",
|
||
"Открой левые двери",
|
||
"Переведи РР вперед",
|
||
"Нет контроля открытия дверей",
|
||
"Нет контроля закрытия дверей",
|
||
"Нет блокировки дверей",
|
||
"Разблокируй двери",
|
||
"Не открыл двери! Подтвердись ПБ",
|
||
"Несработка ДКП! Зафиксируйте станцию",
|
||
"Отпусти пневмотормоз",
|
||
"Выключите тумблер ВЗП",
|
||
"Движение при Vд=0",
|
||
"Нет набора скорости",
|
||
"Для перехода сбросьте с хода",
|
||
"Доложи диспетчеру Vд=0",
|
||
"Выход на линию",
|
||
"Установи реверсивную рукоятку",
|
||
"Необходимо дополнительное включение",
|
||
"РР в другой голове",
|
||
"Переход в ОС",
|
||
"Переход в КС",
|
||
"Постоянное электропитание на КДЛ/КДП",
|
||
"Введён транзит",
|
||
"Отсутствует КСОТ",
|
||
"Оборот",
|
||
"Режим ОС",
|
||
"Открой двери станции",
|
||
"Перейди в КС",
|
||
"Нет питания на 34 проводе(ЛКТ)",
|
||
"Есть питание на 34 проводе",
|
||
|
||
[51]={"Контроль дверей отменён"},
|
||
[52]={"Контроль дверей восстановлен"},
|
||
[53]={"Движение по станционным","путям запрещено",true},
|
||
[54]={"Разрешено движение","при Vд = 0"},
|
||
[55]={"Движение по станционным","путям разрешено"},
|
||
[56]={"Открытие дверей на","перегоне разрешено"},
|
||
[57]={"Открытие дверей на","перегоне запрещено",true},
|
||
[58]={"Контроль ЛПТ отменён"},
|
||
[59]={"Контроль ЛПТ","восстановлен"},
|
||
[60]={"Движение под оборот","разрешено"},
|
||
[61]={"Движение под оборот","запрещено",true},
|
||
[62]={"Оборот отменён"},
|
||
[63]={"Транзит разрешён"},
|
||
[64]={"Транзит запрещён",true},
|
||
[65]={"Транзит отменён"},
|
||
[66]={"Осаживание при пожаре","разрешено"},
|
||
[67]={"Осаживание при пожаре","запрещено",true},
|
||
[68] = {"Режим КС разрешён"},
|
||
[69] = {"Режим КС запрещён",true},
|
||
[70] = {"Режим ОС разрешён"},
|
||
[71] = {"Движение по станционным","путям",true},
|
||
[72] = {"Проверка скатывания","запрещена",true}
|
||
}
|
||
local state5 = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/state5_main")
|
||
local state5k = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/state5k_main")
|
||
local state5b = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/state5b_main")
|
||
local state5kb = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/state5kb_main")
|
||
local question = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/question")
|
||
local slider = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/buttons/slider")
|
||
local function State5(Train,isARS)
|
||
local speed = Train:GetNW2Int("PAM:Vf")
|
||
local mode = Train:GetNW2Int("PAM:Mode",0)
|
||
local currentStation = Train:GetNW2String("PAM:CurrentStation")
|
||
local targetStation = Train:GetNW2String("PAM:TargetStation")
|
||
local speedLimit = Train:GetNW2Int("PAM:SpeedLimit")
|
||
|
||
local driveMode = Train:GetNW2Int("PAM:DriveMode",0)
|
||
local KVMode = Train:GetNW2Int("PAM:KVMode",0)
|
||
|
||
local state = Train:GetNW2Int("PAM:State5",-100)
|
||
local stateAcc = Train:GetNW2Int("PAM:State5Accept",0)
|
||
local sel = Train:GetNW2Int("PAM:Selected",1)
|
||
local block = state~=-100 or stateAcc~=0
|
||
|
||
local ksd = Train:GetNW2Bool("PAM:KSD")
|
||
|
||
surface.SetDrawColor(1,54,2)
|
||
surface.DrawRect(2,70,541,35)
|
||
if Train:GetNW2Bool("PAM:OXT") then
|
||
drawSpeed(3,71,542/100*speed-5,33,Color(240,240,40))
|
||
else
|
||
drawSpeed(3,71,542/100*speed-5,33,Color(40,220,40))
|
||
end
|
||
if block then
|
||
drawFrame(ksd and state5kb or state5b)
|
||
else
|
||
drawFrame(ksd and state5k or state5)
|
||
end
|
||
|
||
|
||
local date = Metrostroi.GetSyncTime()
|
||
draw.SimpleText(os.date("!%d.%m.%y",date),"Metrostroi_PAM24",57,11, Color(199,199,199),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(os.date("!%H:%M:%S",date),"Metrostroi_PAM28",59,32, Color(199,199,199),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
|
||
--Train:GetNW2Int("PAM:Vf")
|
||
--Train:GetNW2Int("PAM:Vd")
|
||
--Train:GetNW2String("PAM:RC")
|
||
--Train:GetNW2Float("PAM:S")
|
||
--Линия
|
||
draw.SimpleText(isARS and "?" or Train:GetNW2String("PAM:Line"),"Metrostroi_PAM28",239,13, Color(222,234,58),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
--Путь
|
||
draw.SimpleText(isARS and "?" or Train:GetNW2String("PAM:Path"),"Metrostroi_PAM28",371,13, Color(222,234,58),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
|
||
--Текущая
|
||
draw.SimpleText(speed,"Metrostroi_PAM45",605,67, Color(20,239,32),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
--Ограничение
|
||
if speedLimit == -1 then
|
||
draw.SimpleText("НЧ","Metrostroi_PAM45",605,104, Color(232,13,12),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
elseif speedLimit <= 20 then
|
||
draw.SimpleText(speedLimit,"Metrostroi_PAM45",605,104, Color(232,13,12),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText(speedLimit,"Metrostroi_PAM45",605,104, Color(246,242,0),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
end
|
||
|
||
if Train:GetNW2Bool("PAM:State5_5") then draw.SimpleText("Vд=0","Metrostroi_PAM28",145,70, Color(225,235,110),TEXT_ALIGN_CENTER,TEXT_ALIGN_BOTTOM) end
|
||
if Train:GetNW2Bool("PAM:State5_2") then draw.SimpleText("КД","Metrostroi_PAM28",195,70, Color(225,235,110),TEXT_ALIGN_CENTER,TEXT_ALIGN_BOTTOM) end
|
||
if Train:GetNW2Bool("PAM:State5_4") then draw.SimpleText("ТР","Metrostroi_PAM28",235,70, Color(225,235,110),TEXT_ALIGN_CENTER,TEXT_ALIGN_BOTTOM) end
|
||
if Train:GetNW2Bool("PAM:State5_8") then draw.SimpleText("ОБ","Metrostroi_PAM28",275,70, Color(225,235,110),TEXT_ALIGN_CENTER,TEXT_ALIGN_BOTTOM) end
|
||
if Train:GetNW2Bool("PAM:State5_3") then draw.SimpleText("СЛ","Metrostroi_PAM28",315,70, Color(225,235,110),TEXT_ALIGN_CENTER,TEXT_ALIGN_BOTTOM) end
|
||
if Train:GetNW2Bool("PAM:State5_7") then draw.SimpleText("ЛПТ","Metrostroi_PAM28",365,70, Color(225,235,110),TEXT_ALIGN_CENTER,TEXT_ALIGN_BOTTOM) end
|
||
if Train:GetNW2Bool("PAM:State5_6") then draw.SimpleText("ДП","Metrostroi_PAM28",420,70, Color(225,235,110),TEXT_ALIGN_CENTER,TEXT_ALIGN_BOTTOM) end
|
||
|
||
if speedLimit == -1 then
|
||
draw.SimpleText("НЧ","Metrostroi_PAM24",5,122, Color(232,13,12),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(6,68,6,107,Color(246,242,0),3)
|
||
elseif speedLimit == 0 then
|
||
draw.SimpleText(0,"Metrostroi_PAM24",5,122, Color(232,13,12),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(6,68,6,107,Color(246,242,0),3)
|
||
elseif speedLimit <= 20 then
|
||
draw.SimpleText(0,"Metrostroi_PAM24",5+5.42*20,122, Color(232,13,12),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(6+5.42*20,68,6+5.42*20,107,Color(246,242,0),3)
|
||
else
|
||
draw.SimpleText(speedLimit,"Metrostroi_PAM24",5+5.42*speedLimit,122, Color(246,242,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(6+5.42*speedLimit,68,6+5.42*speedLimit,107,Color(246,242,0),3)
|
||
end
|
||
local mess = Train:GetNW2Int("PAM:CurrentMessage",0)
|
||
if mode == 6 then
|
||
if mess==0 then mess = 21 end
|
||
elseif mode == 3 then
|
||
draw.SimpleText("T = 00:00:00","Metrostroi_PAM31",0,412, Color(20,239,32),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText("пр","Metrostroi_PAM15",20,416, Color(20,239,32),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("Нагон= 0 с"),"Metrostroi_PAM28",175,411, Color(20,239,32),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("T ="),"Metrostroi_PAM28",355,411, Color(20,239,32),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText("ост","Metrostroi_PAM15",374,416, Color(20,239,32),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(math.Clamp(Train:GetNW2Int("PAM:BoardTime",0),-999,999),"Metrostroi_PAM28",443,411, Color(20,239,32),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText("с","Metrostroi_PAM28",470+3,411, Color(20,239,32),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("S=%.2fм",Train:GetNW2Float("PAM:S")),"Metrostroi_PAM31",639,412, Color(20,239,32),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
|
||
if not Train:GetNW2Bool("PAM:Shunt") then
|
||
if mess == 0 then
|
||
draw.SimpleText(currentStation,"Metrostroi_PAM35",320,222, Color(20,239,32),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("%d путь",Train:GetNW2String("PAM:Path")),"Metrostroi_PAM35",320,258, Color(20,239,32),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
end
|
||
if targetStation=="оборот" then
|
||
draw.SimpleText("оборот","Metrostroi_PAM26",639,11, Color(154,154,154),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText(Format("до %s",targetStation),"Metrostroi_PAM26",639,11, Color(154,154,154),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
end
|
||
draw.SimpleText(currentStation,"Metrostroi_PAM25",639,34, Color(20,239,32),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
end
|
||
|
||
elseif mode == 2 then
|
||
draw.SimpleText(Format("РЦ= %s",Train:GetNW2String("PAM:RC")),"Metrostroi_PAM31",0,412, Color(27,234,30),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
--draw.SimpleText(Format("Пикет="),"Metrostroi_PAM28",141,411, Color(27,234,30),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("Уклон= %d",Train:GetNW2Int("PAM:Slope",0)),"Metrostroi_PAM28",349,411, Color(27,234,30),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("S=%.2fм",Train:GetNW2Float("PAM:S")),"Metrostroi_PAM31",639,412, Color(27,234,30),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("до %s",targetStation),"Metrostroi_PAM26",639,11, Color(154,154,154),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(currentStation,"Metrostroi_PAM25",639,34, Color(154,154,154),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
elseif mode == 4 or mode == 5 then
|
||
draw.SimpleText("РЦ= ","Metrostroi_PAM31",0,412, Color(27,234,30),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
--draw.SimpleText(Format("Пикет="),"Metrostroi_PAM28",141,411, Color(27,234,30),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText("Уклон=","Metrostroi_PAM28",349,411, Color(27,234,30),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("S=%.2fм",Train:GetNW2Float("PAM:S")),"Metrostroi_PAM31",639,412, Color(27,234,30),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(mode == 5 and "депо" or "оборот","Metrostroi_PAM26",639,11, Color(154,154,154),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(currentStation,"Metrostroi_PAM25",639,34, Color(154,154,154),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
elseif not isARS then
|
||
draw.SimpleText("РЦ=","Metrostroi_PAM31",0,412, Color(27,234,30),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
--draw.SimpleText("Пикет=","Metrostroi_PAM28",141,411, Color(27,234,30),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText("Уклон=","Metrostroi_PAM28",349,411, Color(27,234,30),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(Format("S=%.2fм",Train:GetNW2Float("PAM:S")),"Metrostroi_PAM31",639,412, Color(27,234,30),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText("выход на линию","Metrostroi_PAM26",639,11, Color(154,154,154),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(currentStation,"Metrostroi_PAM25",639,34, Color(154,154,154),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText("Режим АРС","Metrostroi_PAM60",320,200, Color(238,129,31),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
end
|
||
if mess>0 then
|
||
local mess = errors[50+mess]
|
||
if #mess == 1 or #mess==2 and mess[2]==true then
|
||
draw.SimpleText(mess[1],"Metrostroi_PAM35",320,isARS and 280 or 240, mess[2] and Color(238,129,31) or Color(20,239,32),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText(mess[1],"Metrostroi_PAM35",320,isARS and 262 or 222, mess[3] and Color(238,129,31) or Color(20,239,32),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(mess[2],"Metrostroi_PAM35",320,isARS and 298 or 258, mess[3] and Color(238,129,31) or Color(20,239,32),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
end
|
||
end
|
||
local err = Train:GetNW2Int("PAM:CurrentError",0)
|
||
if err>0 then
|
||
draw.SimpleText(errors[err],"Metrostroi_PAM31",10,385, Color(225,235,110),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
end
|
||
|
||
--local function draw
|
||
draw.SimpleText("1 АВ","Metrostroi_PAM29",3,173, Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(4,173+14,16,173+14,Color(206,206,206),3)
|
||
draw.SimpleText("1 АВ","Metrostroi_PAM29",2,172, Color(140,140,140),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(3,172+14,15,172+14,Color(140,140,140),3)
|
||
draw.SimpleText("7 Лин","Metrostroi_PAM29",570+1,262+1, Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(571,262+14+1,584,262+14+1,Color(206,206,206),3)
|
||
draw.SimpleText("7 Лин","Metrostroi_PAM29",570,262, Color(140,140,140),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(570,262+14,583,262+14,Color(140,140,140),3)
|
||
if isARS then
|
||
draw.SimpleText("P Маш","Metrostroi_PAM29",3,306, Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(4,305+14,18,305+14,Color(206,206,206),3)
|
||
draw.SimpleText("P Маш","Metrostroi_PAM29",2,305, Color(140,140,140),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(3,304+14,17,304+14,Color(140,140,140),3)
|
||
|
||
draw.SimpleText("4 СтП","Metrostroi_PAM29",571,171, Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(571,171+14,584,171+14,Color(206,206,206),3)
|
||
draw.SimpleText("4 СтП","Metrostroi_PAM29",570,170, Color(140,140,140),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(570,170+14,583,170+14,Color(140,140,140),3)
|
||
|
||
draw.SimpleText("6 Пож","Metrostroi_PAM29",571,217, Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(571,216+15,584,216+15,Color(206,206,206),3)
|
||
draw.SimpleText("6 Пож","Metrostroi_PAM29",570,216, Color(140,140,140),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(570,216+14,583,216+14,Color(140,140,140),3)
|
||
draw.SimpleText("8 Отм","Metrostroi_PAM29",571,309, Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(571,308+15,584,308+15,Color(206,206,206),3)
|
||
draw.SimpleText("8 Отм","Metrostroi_PAM29",570,308, Color(140,140,140),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(570,308+14,583,308+14,Color(140,140,140),3)
|
||
draw.SimpleText("9 ФСт","Metrostroi_PAM29",571,355, Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(571,354+15,584,354+15,Color(206,206,206),3)
|
||
draw.SimpleText("9 ФСт","Metrostroi_PAM29",570,354, Color(140,140,140),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(570,354+14,583,354+14,Color(140,140,140),3)
|
||
for i=block and 1 or 0,0,-1 do
|
||
local blocked = i==0 and block
|
||
draw.SimpleText("2 КС","Metrostroi_PAM29",2+i,218+i, ((driveMode==2 or driveMode==4) and i==0) and Color(85,75,225) or blocked and Color(140,140,140) or Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(3+i,218+14+i,15+i,218+14+i,((driveMode==2 or driveMode==4) and i==0) and Color(85,75,225) or blocked and Color(140,140,140) or Color(206,206,206),3)
|
||
if ksd then
|
||
draw.SimpleText("3 ОС","Metrostroi_PAM29",2+i,264+i, ((driveMode==1 or driveMode==5) and i==0) and Color(85,75,225) or blocked and Color(140,140,140) or Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(3+i,264+14+i,15+i,264+14+i,((driveMode==1 or driveMode==5) and i==0) and Color(85,75,225) or blocked and Color(140,140,140) or Color(206,206,206),3)
|
||
end
|
||
draw.SimpleText("8 Отм","Metrostroi_PAM29",570+i,308+i, blocked and Color(140,140,140) or Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(570+i,308+14+i,583+i,308+14+i,blocked and Color(140,140,140) or Color(206,206,206),3)
|
||
end
|
||
else
|
||
for i=block and 1 or 0,0,-1 do
|
||
local blocked = i==0 and block
|
||
draw.SimpleText("2 КС","Metrostroi_PAM29",2+i,218+i, ((driveMode==2 or driveMode==4) and i==0) and Color(85,75,225) or blocked and Color(140,140,140) or Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(3+i,218+14+i,15+i,218+14+i,((driveMode==2 or driveMode==4) and i==0) and Color(85,75,225) or blocked and Color(140,140,140) or Color(206,206,206),3)
|
||
if ksd then
|
||
draw.SimpleText("3 ОС","Metrostroi_PAM29",2+i,264+i, ((driveMode==1 or driveMode==5) and i==0) and Color(85,75,225) or blocked and Color(140,140,140) or Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(3+i,264+14+i,15+i,264+14+i,((driveMode==1 or driveMode==5) and i==0) and Color(85,75,225) or blocked and Color(140,140,140) or Color(206,206,206),3)
|
||
end
|
||
draw.SimpleText("P Маш","Metrostroi_PAM29",2+i,305+i, blocked and Color(140,140,140) or Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(3+i,304+14+i,17+i,304+14+i,blocked and Color(140,140,140) or Color(206,206,206),3)
|
||
|
||
|
||
draw.SimpleText("4 СтП","Metrostroi_PAM29",570+i,170+i, blocked and Color(140,140,140) or Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(570+i,170+14+i,583+i,170+14+i,blocked and Color(140,140,140) or Color(206,206,206),3)
|
||
draw.SimpleText("6 Пож","Metrostroi_PAM29",570+i,216+i, (Train:GetNW2Bool("PAM:State5_-6") and i==0) and Color(85,75,225) or blocked and Color(140,140,140) or Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(570+i,216+14+i,583+i,216+14+i,(Train:GetNW2Bool("PAM:State5_-6") and i==0) and Color(85,75,225) or blocked and Color(140,140,140) or Color(206,206,206),3)
|
||
--draw.SimpleText("7 Лин","Metrostroi_PAM29",570+i,262+i, blocked and Color(140,140,140) or Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
--Metrostroi.DrawLine(570+i,262+14+i,583,262+14+i,blocked and Color(140,140,140) or Color(206,206,206),3)
|
||
draw.SimpleText("8 Отм","Metrostroi_PAM29",570+i,308+i, blocked and Color(140,140,140) or Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(570+i,308+14+i,583+i,308+14+i,blocked and Color(140,140,140) or Color(206,206,206),3)
|
||
draw.SimpleText("9 ФСт","Metrostroi_PAM29",570+i,354+i, (mode == 3 and i==0) and Color(85,75,225) or blocked and Color(140,140,140) or Color(206,206,206),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(570+i,354+14+i,583+i,354+14+i,(mode == 3 and i==0) and Color(85,75,225) or blocked and Color(140,140,140) or Color(206,206,206),3)
|
||
end
|
||
end
|
||
if state==0 then
|
||
surface.SetDrawColor(192,192,192,255)
|
||
surface.DrawRect(0,119,636,248,0)
|
||
for i,text in pairs(menus) do
|
||
local color = (i==3 or isARS and (i==3 or i==4 or i==8 or i==9)) and Color(113,113,113) or i==sel and Color(255,255,255) or Color(0,0,0)
|
||
|
||
local x,y = 212*((i-1)%3),119+(math.ceil(i/3)-1)*62
|
||
drawButton(x,y,212,62, i==sel and button_s or button)
|
||
if type(text)=="table" then
|
||
draw.SimpleText(text[1],"Metrostroi_PAM21",x+106+10,y+31-12, color,TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(text[2],"Metrostroi_PAM21",x+106+10,y+31+12, color,TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText(text,"Metrostroi_PAM21",x+106+10,y+31, color,TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
end
|
||
if i<12 then
|
||
draw.SimpleText(i%10,"Metrostroi_PAM35",x+17,y+31, color,TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(x+10,y+48,x+24,y+48,color,3)
|
||
end
|
||
end
|
||
elseif state==-1 then
|
||
drawWindow(146,146, 357,201,"Регулировка яркости")
|
||
buttonWTextC(161,192,75,34,"<","Metrostroi_PAM25",Color(0,0,0),Train:GetNW2Bool("PAM:KeyLeft") and button_p or button)
|
||
buttonWTextC(413,192,75,34,">","Metrostroi_PAM25",Color(0,0,0),Train:GetNW2Bool("PAM:KeyRight") and button_p or button)
|
||
buttonWTextC(277,277,95,50,"Закрыть","Metrostroi_PAM25",Color(0,0,0),(Train:GetNW2Bool("PAM:KeyEsc") or Train:GetNW2Bool("PAM:KeyEnter")) and button_p or button)
|
||
Metrostroi.DrawRectOL(246,203,157,4,Color(113,113,113),1,Color(200,200,200))
|
||
for i=0,10 do
|
||
Metrostroi.DrawLine(251+i*15,216,251+i*15,220,Color(113,113,113),2)
|
||
end
|
||
draw.SimpleText("Яркость:","Metrostroi_PAM25",246,251, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
drawTextBox(340,237,63,29,Format("%d%%",Train:GetNW2Float("PAM:Brightness",1)*100),"Metrostroi_PAM25")
|
||
surface.SetDrawColor(255,255,255)
|
||
surface.SetTexture(slider)
|
||
surface.DrawTexturedRect(251-5+Train:GetNW2Float("PAM:Brightness",1)*150,216-17,16,16)
|
||
|
||
elseif state==8 then
|
||
drawWindow(0,120, 640,241,"Зонный оборот")
|
||
local count = Train:GetNW2Int("PAM:ElemCount",0)
|
||
for i=1,math.min(9,Train:GetNW2String("PAM:ElemCount",0)) do
|
||
local selected = i==sel
|
||
local color = selected and Color(255,255,255) or Color(0,0,0)
|
||
|
||
local x,y = 4+210*((i-1)%3),152+(math.ceil(i/3)-1)*50
|
||
drawButton(x,y,210,50, selected and button_s or button)
|
||
local text = Train:GetNW2String("PAM:Elem"..i)
|
||
draw.SimpleText(text:sub(1,-2),selected and "Metrostroi_PAM20" or "Metrostroi_PAM21",x+106+10,y+24-10, color,TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
if text[#text]=="1" then
|
||
draw.SimpleText("(непр) оборот",selected and "Metrostroi_PAM20" or "Metrostroi_PAM21",x+106+10,y+24+10, color,TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText("оборот",selected and "Metrostroi_PAM20" or "Metrostroi_PAM21",x+106+10,y+24+10, color,TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
end
|
||
draw.SimpleText(i%10,"Metrostroi_PAM31",x+17,y+24, color,TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(x+10,y+37,x+24,y+37,color,2)
|
||
--x+28+18*i Train:SetNW2String("PAM:Elem"..iS,id.."\t"..(name or id))
|
||
end
|
||
buttonWTextC(4+210*1.5-145,152+3*50,140,50,"Да - Enter","Metrostroi_PAM25",Color(0,0,0),Train:GetNW2Bool("PAM:KeyEnter") and button_p or button)
|
||
buttonWTextC(4+210*1.5+5,152+3*50,140,50,"Нет - Esc","Metrostroi_PAM25",Color(0,0,0),Train:GetNW2Bool("PAM:KeyEsc") and button_p or button)
|
||
if Train:GetNW2Bool("PAM:ElemCountStart") then
|
||
buttonWTextC(4+210*0,152+3*50,80,50,"◄","Metrostroi_PAM25",Color(0,0,0),Train:GetNW2Bool("PAM:KeyLeft") and button_p or button)
|
||
end
|
||
if Train:GetNW2Bool("PAM:ElemCountEnd") then
|
||
buttonWTextC(4+210*3-80,152+3*50,80,50,"►","Metrostroi_PAM25",Color(0,0,0),Train:GetNW2Bool("PAM:KeyRight") and button_p or button)
|
||
end
|
||
elseif state==-8 then
|
||
drawWindow(0,120, 640,241,"Введенные запросы")
|
||
for i,text in pairs(menusReset) do
|
||
if Train:GetNW2Bool("PAM:State5_"..i) or i==11 then
|
||
local selected = i==sel
|
||
local disabled = i==5 or i==6
|
||
local color = disabled and Color(113,113,113) or selected and Color(255,255,255) or Color(0,0,0)
|
||
|
||
local x,y = 4+210*((i-1)%3),152+(math.ceil(i/3)-1)*50
|
||
drawButton(x,y,209,49, selected and button_s or button)
|
||
if type(text)=="table" then
|
||
draw.SimpleText(text[1],selected and "Metrostroi_PAM20" or "Metrostroi_PAM21",x+106+10,y+24-10, color,TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(text[2],selected and "Metrostroi_PAM20" or "Metrostroi_PAM21",x+106+10,y+24+10, color,TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText(text,selected and "Metrostroi_PAM20" or "Metrostroi_PAM21",x+106+10,y+24, color,TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
end
|
||
if i<11 and not disabled then
|
||
draw.SimpleText(i%10,"Metrostroi_PAM31",x+17,y+24, color,TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||
Metrostroi.DrawLine(x+10,y+37,x+24,y+37,color,2)
|
||
end
|
||
end
|
||
end
|
||
Metrostroi.DrawLine(4,202,640-8,202,Color(113,113,113),2)
|
||
Metrostroi.DrawLine(4,252,640-8,252,Color(113,113,113),2)
|
||
Metrostroi.DrawLine(4,302,640-8,302,Color(113,113,113),2)
|
||
Metrostroi.DrawLine(214,154,214,351,Color(113,113,113),2)
|
||
Metrostroi.DrawLine(424,154,424,351,Color(113,113,113),2)
|
||
elseif state==1 then
|
||
drawWindow(82,160, 484,180,"Режим проверки скатывания")
|
||
buttonWTextC(139,270,370,50,"Завершить скатывание (Esc)","Metrostroi_PAM30",Color(0,0,0), Train:GetNW2Bool("PAM:KeyEsc") and button_p or button)
|
||
local dist = Train:GetNW2Float("PAM:RollDist",0)
|
||
draw.SimpleText("Скатывание на","Metrostroi_PAM30",110,225, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
|
||
draw.SimpleText(Format("%.2f",dist),"Metrostroi_PAM35",380,225, Color(0,0,0),TEXT_ALIGN_RIGHT,TEXT_ALIGN_CENTER)
|
||
|
||
draw.SimpleText("м","Metrostroi_PAM30",395,225, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
if dist >= 0 then
|
||
draw.SimpleText("вперед","Metrostroi_PAM30",440,225, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText("назад","Metrostroi_PAM30",440,225, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
end
|
||
elseif state==-5 then
|
||
local selected = Train:GetNW2String("PAM:Touching") ~= ""
|
||
local keyboard = Train:GetNW2Bool("PAM:Keyboard")
|
||
|
||
drawWindow(keyboard and 80+112 or 80,145,keyboard and 480-(112-79) or 480,261,"Смена машиниста")
|
||
local sel = Train:GetNW2Int("PAM:Selected",1)
|
||
local xadd = keyboard and 1 or 0
|
||
if keyboard then
|
||
draw.SimpleText("Номер маршрута","Metrostroi_PAM27",99+112-10,201, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText("Табельный номер","Metrostroi_PAM27",99+112-10,201+39, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText("Номер маршрута","Metrostroi_PAM27",99,201, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText("Табельный номер","Metrostroi_PAM27",99,201+39, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
end
|
||
drawTextBox(320+102*xadd,190+39*0,225-15*xadd,31,Train:GetNW2String("PAM:RouteNumber",""),"Metrostroi_PAM30",not selected and sel == 1 and Color(79,252,246))
|
||
drawTextBox(320+102*xadd,190+39*1,225-15*xadd,31,Train:GetNW2String("PAM:DriverNumber",""),"Metrostroi_PAM30",not selected and sel == 2 and Color(79,252,246))
|
||
local err = Train:GetNW2String("PAM:EnterError","")
|
||
if err ~= "" then draw.SimpleText(err,"Metrostroi_PAM30",325+xadd*90,275, Color(213,18,8),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER) end
|
||
|
||
buttonWTextC(190+xadd*79,320,75+1*65,50,"Ввод","Metrostroi_PAM30",Color(0,0,0), Train:GetNW2Bool("PAM:KeyEnter") and button_p or button)
|
||
buttonWTextC(288+42+10+xadd*79,320,120+1*20,50,"Закрыть","Metrostroi_PAM30",Color(0,0,0), Train:GetNW2Bool("PAM:KeyEsc") and button_p or button)
|
||
|
||
if Train:GetNW2Bool("PAM:KeyKeyB") or keyboard then drawButton(501+xadd*79,320,40,51, keyboard and button_p or button) end
|
||
surface.SetDrawColor(255,255,255)
|
||
surface.SetTexture(keyb_icon)
|
||
surface.DrawTexturedRect(505+xadd*79,314,32,64)
|
||
|
||
if keyboard then drawKeyboard(Train,0,47,selected) end
|
||
elseif state==9 then
|
||
local selected = Train:GetNW2String("PAM:Touching") ~= ""
|
||
local keyboard = Train:GetNW2Bool("PAM:Keyboard")
|
||
|
||
drawWindow(keyboard and 82+130 or 82,145,keyboard and 484-(130-40) or 484,261,"Фиксация станции")
|
||
local sel = Train:GetNW2Int("PAM:Selected",1)
|
||
local xadd = keyboard and 1 or 0
|
||
if keyboard then
|
||
draw.SimpleText("Станция","Metrostroi_PAM27",99+130,201, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText("Путь","Metrostroi_PAM27",99+130,201+39, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText("Код станции","Metrostroi_PAM27",99,201, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText("Номер пути","Metrostroi_PAM27",99,201+39, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
end
|
||
drawTextBox(322+40*xadd,190+39*0,229,31,Train:GetNW2String("PAM:StationS",""),"Metrostroi_PAM30",not selected and sel == 1 and Color(79,252,246))
|
||
drawTextBox(322+40*xadd,190+39*1,229,31,Train:GetNW2String("PAM:PathS",""),"Metrostroi_PAM30",not selected and sel == 2 and Color(79,252,246))
|
||
local err = Train:GetNW2String("PAM:EnterError","")
|
||
if err ~= "" then draw.SimpleText(err,"Metrostroi_PAM30",325+xadd*90,275, Color(213,18,8),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER) end
|
||
local currStation = Train:GetNW2String("PAM:CurrentStationS")
|
||
if currStation ~= "" then draw.SimpleText(currStation,"Metrostroi_PAM30",325+xadd*90,301, Color(0,165,13),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER) end
|
||
|
||
buttonWTextC(190+xadd*39,320,75+xadd*65,50,"Ввод","Metrostroi_PAM30",Color(0,0,0), Train:GetNW2Bool("PAM:KeyEnter") and button_p or button)
|
||
buttonWTextC(288+xadd*(42+39+10),320,120+xadd*20,50,"Закрыть","Metrostroi_PAM30",Color(0,0,0), Train:GetNW2Bool("PAM:KeyEsc") and button_p or button)
|
||
|
||
if Train:GetNW2Bool("PAM:KeyKeyB") or keyboard then drawButton(501+xadd*40,320,40,51, keyboard and button_p or button) end
|
||
surface.SetDrawColor(255,255,255)
|
||
surface.SetTexture(keyb_icon)
|
||
surface.DrawTexturedRect(505+xadd*40,314,32,64)
|
||
|
||
if sel==1 then comboBox(Train,320+40*xadd,200+29*1) end
|
||
if keyboard then drawKeyboard(Train,10,47,selected) end
|
||
end
|
||
if stateAcc ~= 0 then
|
||
local text = acceptions[stateAcc]
|
||
surface.SetFont("Metrostroi_PAM21")
|
||
local y,x=21
|
||
if type(text) == "table" then
|
||
x = surface.GetTextSize(text[1])
|
||
y=42
|
||
else x = surface.GetTextSize(text) end
|
||
drawWindow(320-x/2-36,240-72-16,x+72,128+y+16,"Подтверждение")
|
||
surface.SetTexture(question)
|
||
surface.DrawTexturedRect(296-x/2,200,32,32)
|
||
if type(text) == "table" then
|
||
draw.SimpleText(text[1],"Metrostroi_PAM21",336-x/2,210, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
draw.SimpleText(text[2],"Metrostroi_PAM21",336-x/2,210+21, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.SimpleText(text,"Metrostroi_PAM21",336-x/2,210, Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||
end
|
||
|
||
buttonWTextC(194,219+y,120,50,"Да - Enter","Metrostroi_PAM21",Color(0,0,0), Train:GetNW2Bool("PAM:KeyEnter") and button_p or button)
|
||
buttonWTextC(326,219+y,120,50,"Нет - Esc","Metrostroi_PAM21",Color(0,0,0), Train:GetNW2Bool("PAM:KeyEsc") and button_p or button)
|
||
end
|
||
|
||
|
||
drawText2(201,441,Format("%s = %s",driveModes[driveMode],KVModes[KVMode]),true)
|
||
|
||
local VZ = Train:GetNW2Int("PAM:V",0)
|
||
if VZ > 0 then
|
||
drawText2(307,441,"В"..VZ,true)
|
||
elseif VZ==-1 then
|
||
drawText2(307,441,"ЭПК",true)
|
||
else
|
||
drawText2(307,441,"В",false)
|
||
end
|
||
|
||
drawText2(386,441,"ЛПТ",Train:GetNW2Bool("PAM:LPT"))
|
||
local KD = Train:GetNW2Int("PAM:KD",2)
|
||
if KD == 2 then
|
||
drawText2(465,441,"КД",true,Color(213,15,15))
|
||
elseif KD==1 then
|
||
drawText2(465-1,441-1,"КД",false,Color(238,129,31))
|
||
else
|
||
drawText2(465,441,"КД",true,Color(0,0,0))
|
||
end
|
||
|
||
if ksd then
|
||
drawText2(320,467,"Зона ОПВ",Train:GetNW2Bool("PAM:OPV"))
|
||
else
|
||
drawText2(181.5,467,"АРС",Train:GetNW2Bool("PAM:KVARS"))
|
||
drawText2(273.5,467,"ПСР",false)
|
||
drawText2(365.5,467,"ВРД",Train:GetNW2Bool("PAM:VRD"))
|
||
drawText2(458,467,"ОПВ",Train:GetNW2Bool("PAM:OPV"))
|
||
end
|
||
end
|
||
local function drawBlink_(x,y) if CurTime()%0.4 > 0.2 then draw.SimpleText("_","Metrostroi_PAM30",x, y,Color(150,150,150),TEXT_ALIGN_LEFT,TEXT_ALIGN_BOTTOM) end end
|
||
local bios_splash = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/bios_splash")
|
||
local splash = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/splash")
|
||
local splash_egg = surface.GetTextureID("models/metrostroi_train/81-717/screens/pa/splash_egg")
|
||
local snds = {
|
||
[-3] = "http://pollitto.ru/other/files/NEW/shit/apdisco.wav",
|
||
[-2] = "http://pollitto.ru/other/files/NEW/shit/master_warning.wav",
|
||
[-1] = "http://pollitto.ru/other/files/NEW/shit/terrain_n.wav",
|
||
[-0.01] = "http://pollitto.ru/other/files/NEW/shit/mini.wav",
|
||
[1.02] = "http://pollitto.ru/other/files/NEW/shit/5ft.wav",
|
||
[3.05] = "http://pollitto.ru/other/files/NEW/shit/10ft.wav",
|
||
[6.10] = "http://pollitto.ru/other/files/NEW/shit/20ft.wav",
|
||
[9.14] = "http://pollitto.ru/other/files/NEW/shit/30ft.wav",
|
||
[12.19] = "http://pollitto.ru/other/files/NEW/shit/40ft.wav",
|
||
[15.24] = "http://pollitto.ru/other/files/NEW/shit/50ft.wav",
|
||
[30.48] = "http://pollitto.ru/other/files/NEW/shit/100ft.wav",
|
||
[60.96] = "http://pollitto.ru/other/files/NEW/shit/200ft.wav",
|
||
[91.44] = "http://pollitto.ru/other/files/NEW/shit/300ft.wav",
|
||
[100] = "http://pollitto.ru/other/files/NEW/shit/alt_alert.wav",
|
||
[121.92] = "http://pollitto.ru/other/files/NEW/shit/400ft.wav",
|
||
[152.40] = "http://pollitto.ru/other/files/NEW/shit/500ft.wav",
|
||
[304.80] = "http://pollitto.ru/other/files/NEW/shit/1000ft.wav",
|
||
[762] = "http://pollitto.ru/other/files/NEW/shit/2500ft.wav",
|
||
["caution"] = "http://pollitto.ru/other/files/NEW/shit/toconfigwarn.wav",
|
||
["belts"] = "http://pollitto.ru/other/files/NEW/shit/belts.wav",
|
||
["smoking"] = "http://pollitto.ru/other/files/NEW/shit/smoking.wav",
|
||
["pullup"] = "http://pollitto.ru/other/files/NEW/shit/whoopwhoop.wav",
|
||
["tl_flaps"] = "http://pollitto.ru/other/files/NEW/shit/too_low_flaps.wav",
|
||
["tl_terrain"] = "http://pollitto.ru/other/files/NEW/shit/too_low_terrain.wav",
|
||
}
|
||
|
||
local UPD = 10
|
||
function TRAIN_SYSTEM:PAMScreen(Train)
|
||
--surface.SetTexture(splash_egg)
|
||
--surface.SetDrawColor(255,255,255)
|
||
--surface.DrawTexturedRectRotated(512,256,1024,512,0)
|
||
|
||
local state = Train:GetNW2Float("PAM:State",0)
|
||
|
||
if state ~= 0 and state ~= -1 and state ~= -0.5 then
|
||
surface.SetDrawColor(50,50,50,100)
|
||
surface.DrawRect(0,0,640,480,0)
|
||
if state == -100 then stateDebug(Train) end
|
||
if state < 0 then
|
||
local time = Train:GetNW2Float("PAM:StartTimer",0)
|
||
if state == -2 then
|
||
if time > 0.4 then drawBlink_(620,440) else drawBlink_(5,20) end
|
||
end
|
||
if state == -3 then drawFrame(bios_splash) end
|
||
if state == -4 then
|
||
if time > 0.5 then drawBlink_(5,40) else drawBlink_(5,20) end
|
||
end
|
||
if state == -5 then drawFrame(splash) end
|
||
end
|
||
|
||
if state == 1 then State1(Train) end
|
||
if state == 1.5 then State1_5(Train) end
|
||
if state == 2 then State2(Train) end
|
||
if state == 3 then State3(Train) end
|
||
if state == 3.5 then State35(Train) end
|
||
if state == 4 then State4(Train) end
|
||
if state == 5 then
|
||
--[[
|
||
if LocalPlayer():GetName() ~= "MrMeowpestMan" then
|
||
if not self.Sounds or self.SoundsTemp ~= UPD then
|
||
if self.Sounds then for i,snd in pairs(self.Sounds) do snd:Stop() end end
|
||
self.Sounds = {}
|
||
for i, sndU in pairs(snds) do
|
||
sound.PlayURL ( sndU, "3d noplay noblock", function( snd )
|
||
if ( IsValid( snd ) ) then
|
||
self.Sounds[i] = snd
|
||
print(snd)
|
||
else
|
||
print("???")
|
||
end
|
||
end )
|
||
end
|
||
self.SoundsTemp = UPD
|
||
end
|
||
for i,snd in pairs(self.Sounds) do
|
||
if IsValid(snd) then
|
||
snd:SetPos(self.Train:LocalToWorld(Vector(450,22,0)))
|
||
end
|
||
end
|
||
local sndId
|
||
local s = Train:GetNW2Float("PAM:S")--/0.3048
|
||
for i,snd in pairs(self.Sounds) do
|
||
if type(i) == "number" and s <= i and (not sndId or sndId > i) then sndId = i end
|
||
end
|
||
if self.CurrentSound ~= sndId then
|
||
if sndId then
|
||
print(self.Sounds[sndId])
|
||
self.Sounds[sndId]:SetTime(0)
|
||
self.Sounds[sndId]:Play()
|
||
end
|
||
self.CurrentSound = sndId
|
||
end
|
||
if self.Sounds.caution and not self.Caution and self.Train:GetNW2Bool("PAM:OXT") then
|
||
self.Sounds.caution:SetTime(0)
|
||
self.Sounds.caution:Play()
|
||
self.Caution = CurTime()
|
||
elseif self.Caution and CurTime()-self.Caution > 2 then
|
||
self.Caution = false
|
||
end
|
||
|
||
if self.Sounds.pullup and not self.PullUp and Train:GetNW2Int("PAM:Vf") > 1 then
|
||
self.Sounds.pullup:SetTime(0)
|
||
self.Sounds.pullup:Play()
|
||
self.PullUp = true
|
||
elseif self.PullUp and Train:GetNW2Int("PAM:Vf") == 0 then
|
||
self.PullUp = false
|
||
end
|
||
self.SpeedLimitSmoking = self.SpeedLimitSmoking or Train:GetNW2Int("PAM:SpeedLimit")
|
||
if self.Sounds.smoking and Train:GetNW2Int("PAM:SpeedLimit") ~= self.SpeedLimitSmoking then
|
||
if Train:GetNW2Int("PAM:SpeedLimit") > self.SpeedLimitSmoking then
|
||
self.Sounds.smoking:SetTime(0)
|
||
self.Sounds.smoking:Play()
|
||
else
|
||
self.Sounds.belts:SetTime(0)
|
||
self.Sounds.belts:Play()
|
||
end
|
||
self.SpeedLimitSmoking = Train:GetNW2Int("PAM:SpeedLimit")
|
||
end
|
||
local canPlayTLFlaps = Train:GetNW2Int("PAM:KVMode") >= -1 and Train:GetNW2Int("PAM:Vf") > 0 and not Train:GetNW2Bool("PAM:LPT")
|
||
if self.Sounds.tl_flaps and not self.TLFlaps and (50 <= s and s <= 100) and canPlayTLFlaps then
|
||
self.Sounds.tl_flaps:SetTime(0)
|
||
self.Sounds.tl_flaps:Play()
|
||
self.TLFlaps = CurTime()
|
||
elseif self.Sounds.tl_terrain and not self.TLFlaps and s < 50 and canPlayTLFlaps then
|
||
self.Sounds.tl_terrain:SetTime(0)
|
||
self.Sounds.tl_terrain:Play()
|
||
self.TLFlaps = CurTime()
|
||
elseif self.TLFlaps and CurTime()-self.TLFlaps > 1.5 then
|
||
self.TLFlaps = false
|
||
end
|
||
end
|
||
--]]
|
||
|
||
State5(Train)
|
||
end
|
||
if state == 6 then State5(Train,true) end
|
||
--surface.SetDrawColor(0,0,0,150)
|
||
surface.SetAlphaMultiplier(0.9-Train:GetNW2Float("PAM:Brightness",0)*0.5)
|
||
surface.SetDrawColor(Color(20,20,20))
|
||
surface.DrawRect(0,0,640,480,0)
|
||
surface.SetAlphaMultiplier(1)
|
||
end
|
||
end
|
||
return
|
||
end
|
||
|
||
function TRAIN_SYSTEM:TriggerInput(name,value)
|
||
if name == "KSDMode" then
|
||
self.PAKSD = value>0
|
||
self.Train:SetNW2Bool("PAM:KSD",self.PAKSD)
|
||
end
|
||
end
|
||
|
||
function TRAIN_SYSTEM:UpdateStationList(entered,id)
|
||
local Train = self.Train
|
||
if not entered or #entered < 1 or #entered > 2 then
|
||
Train:SetNW2Int("PAM:ElemCount",0)
|
||
self.ScrollCount = 0
|
||
self.Scroll = 0
|
||
return
|
||
end
|
||
local iS = 0
|
||
if #entered < 3 then
|
||
local line = tonumber(entered[1])
|
||
local tbl = Metrostroi.PAMStations[line]
|
||
if id then
|
||
if tbl then
|
||
for k,station in ipairs(tbl) do
|
||
if string.find(tostring(station.id),"^"..entered) then
|
||
if iS < 8+self.Scroll and iS >= self.Scroll and (iS+1-self.Scroll)==id then
|
||
return station.id
|
||
end
|
||
iS = iS + 1
|
||
end
|
||
end
|
||
end
|
||
return
|
||
else
|
||
self.LineS = line
|
||
if tbl then
|
||
for k,station in ipairs(tbl) do
|
||
if string.find(tostring(station.id),"^"..entered) then
|
||
if iS < 8+self.Scroll and iS >= self.Scroll then
|
||
local id,name = station.id,station.name
|
||
Train:SetNW2String("PAM:Elem"..(iS+1-self.Scroll),id.."\t"..(name or id))
|
||
end
|
||
iS = iS + 1
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
Train:SetNW2Int("PAM:ElemCount",math.min(8,iS))
|
||
self.ScrollCount = iS
|
||
self.Scroll = math.Clamp(self.Scroll,0,math.max(0,self.ScrollCount-8))
|
||
--end
|
||
end
|
||
function TRAIN_SYSTEM:UpdateLastStationList()
|
||
local Train = self.Train
|
||
local iS = 0
|
||
local dist = self.Distance
|
||
local line = self.Line
|
||
local path = tonumber(self.Path)
|
||
local tbl = Metrostroi.PAMConfTest and Metrostroi.PAMConfTest[line] and Metrostroi.PAMConfTest[line][path]
|
||
if not tbl then return end
|
||
self.Scroll = math.Clamp(self.Scroll,0,math.max(0,math.ceil(((self.ScrollCount or 0)-9)/9)*9))
|
||
self.DeadlockS = nil
|
||
local curr
|
||
if self.Mode==2 or self.Mode==3 and not self.Shunt then
|
||
for i,stat in ipairs(tbl[1].stations) do
|
||
if i<#tbl[1].stations then
|
||
if not curr and tostring(self.Station)==tostring(stat.id) then
|
||
curr=i
|
||
end
|
||
if curr and i>=curr and stat.isLast then
|
||
if iS < 9+self.Scroll and iS >= self.Scroll then
|
||
local id = (iS+1-self.Scroll)
|
||
Train:SetNW2String("PAM:Elem"..id,stat.name..(stat.isInWrong and 1 or 0))
|
||
if self.Selected == id then self.DeadlockS = stat end
|
||
end
|
||
iS = iS + 1
|
||
end
|
||
end
|
||
end
|
||
end
|
||
if self.Selected>0 and self.DeadlockS == nil then self.Selected = 0 end
|
||
Train:SetNW2Int("PAM:ElemCount",math.min(10,iS-self.Scroll))
|
||
Train:SetNW2Bool("PAM:ElemCountStart",self.Scroll>=9)
|
||
Train:SetNW2Bool("PAM:ElemCountEnd",(iS-self.Scroll)>9)
|
||
self.ScrollCount = iS
|
||
self.Scroll = math.Clamp(self.Scroll,0,math.max(0,math.ceil((self.ScrollCount-9)/9)*9))
|
||
--end
|
||
end
|
||
function TRAIN_SYSTEM:Trigger(name,value,press)
|
||
local Train = self.Train
|
||
Train:SetNW2Bool("PAM:Key"..name,value)
|
||
if name == "F" and value and not self.SoundTimer then self.SoundTimer = CurTime() end
|
||
if name == "F" and not value and self.SoundTimer ~= nil then
|
||
local oldST = self.SoundTimer
|
||
self.SoundTimer = nil
|
||
if not oldST then return end
|
||
end
|
||
if press and value and self.Sound then
|
||
self.Train:PlayOnce("pa_"..name:lower(),"bass",1)
|
||
end
|
||
if name == "KeyB" and not value then self.Keyboard = not self.Keyboard end
|
||
if self.State == 1 and not value then
|
||
if name == "Esc" then self:SetState(1.5,0.1) end
|
||
if name == "Enter" and self.ReverserWrench then
|
||
if self.GoodSetup then
|
||
self:SetState(2,0.1)
|
||
else
|
||
self:SetState(6,0.1)
|
||
end
|
||
end
|
||
elseif self.State == 1.5 and name == "Esc" and not value then
|
||
self:SetState(1,0.1)
|
||
elseif self.State == 2 then
|
||
if name == "Down" and value then
|
||
self.Selected = self.Selected < 4 and self.Selected+1 or 1
|
||
if not self.HaveRestart and self.Selected == 2 then self.Selected = 3 end
|
||
end
|
||
if name == "Up" and value then
|
||
self.Selected = self.Selected > 1 and self.Selected-1 or 4
|
||
if not self.HaveRestart and self.Selected == 2 then self.Selected = 1 end
|
||
end
|
||
if name == "1" and value then self.Selected = 1 end
|
||
if name == "2" and self.HaveRestart and value then self.Selected = 2 end
|
||
if name == "Esc" and value then self.Selected = 3 end
|
||
if name == "M" and value then self.Selected = 4 end
|
||
if (name == "Esc" or name == "Enter") and not value and self.Selected == 3 then self:SetState(1,0.1) end
|
||
if (name == "1" or name == "Enter") and not value and self.Selected == 1 then self:SetState(3,0.1) end
|
||
if self.HaveRestart and (name == "2" or name == "Enter") and not value and self.Selected == 2 then self:SetState(3.5,0.1) end
|
||
if (name == "M" or name == "Enter") and not value and self.Selected == 4 then self:SetState(2,0.1) end
|
||
elseif self.State == 3 then
|
||
if name == "Down" and value then self.Selected = self.Selected < 4 and self.Selected+1 or 1 end
|
||
if name == "Up" and value then self.Selected = self.Selected > 1 and self.Selected-1 or 4 end
|
||
local num = tonumber(name)
|
||
if num and value then
|
||
if self.Selected == 1 and #self.StationS < 3 then
|
||
self.StationS = self.StationS..num
|
||
self.Scroll = 0
|
||
self:UpdateStationList(self.StationS)
|
||
end
|
||
if self.Selected == 2 and #self.PathS < #tostring(Metrostroi.LineCount) then self.PathS = self.PathS..num end
|
||
if self.Selected == 3 and #self.RouteNumberS < 3 then self.RouteNumberS = self.RouteNumberS..num end
|
||
if self.Selected == 4 and #self.DriverNumberS < 4 then self.DriverNumberS = self.DriverNumberS..num end
|
||
end
|
||
if name == "Left" and value then
|
||
if self.Selected == 1 then
|
||
self.StationS = self.StationS:sub(1,-2)
|
||
self.Scroll = 0
|
||
self:UpdateStationList(self.StationS)
|
||
end
|
||
if self.Selected == 2 then self.PathS = self.PathS:sub(1,-2) end
|
||
if self.Selected == 3 then self.RouteNumberS = self.RouteNumberS:sub(1,-2) end
|
||
if self.Selected == 4 then self.DriverNumberS = self.DriverNumberS:sub(1,-2) end
|
||
end
|
||
if name == "Esc" and not value then self:SetState(2,0.1) end
|
||
if name == "Enter" and not value then
|
||
if #self.StationS < 3 or not Metrostroi.PAMStations[self.LineS] or not Metrostroi.PAMStations[self.LineS][tonumber(self.StationS)] then
|
||
Train:SetNW2String("PAM:EnterError","Неверный номер станции")
|
||
elseif #self.PathS < #tostring(Metrostroi.LineCount) or not Metrostroi.PAMConfTest[self.LineS][tonumber(self.PathS)] then
|
||
Train:SetNW2String("PAM:EnterError","Неверный номер пути")
|
||
elseif #self.RouteNumberS < 3 then
|
||
Train:SetNW2String("PAM:EnterError","Неверный номер маршрута")
|
||
elseif #self.DriverNumberS < 4 then
|
||
Train:SetNW2String("PAM:EnterError","Неверный табельный номер")
|
||
else
|
||
self:SetState(4,0.1)
|
||
end
|
||
end
|
||
elseif self.State == 3.5 then
|
||
if name == "Down" and value then self.Selected = self.Selected < 2 and self.Selected+1 or 1 end
|
||
if name == "Up" and value then self.Selected = self.Selected > 1 and self.Selected-1 or 2 end
|
||
local num = tonumber(name)
|
||
if num and value then
|
||
if self.Selected == 1 and #self.StationS < 3 then
|
||
self.StationS = self.StationS..num
|
||
self.Scroll = 0
|
||
self:UpdateStationList(self.StationS)
|
||
end
|
||
if self.Selected == 2 and #self.PathS < 1 then self.PathS = self.PathS..num end
|
||
end
|
||
if name == "Left" and value then
|
||
if self.Selected == 1 then
|
||
self.StationS = self.StationS:sub(1,-2)
|
||
self.Scroll = 0
|
||
self:UpdateStationList(self.StationS)
|
||
end
|
||
if self.Selected == 2 then self.PathS = self.PathS:sub(1,-2) end
|
||
end
|
||
if name == "Esc" and not value then self:SetState(2,0.1) end
|
||
if name == "Enter" and not value then
|
||
if #self.StationS < 3 or not Metrostroi.PAMStations[self.LineS] or not Metrostroi.PAMStations[self.LineS][tonumber(self.StationS)] then
|
||
Train:SetNW2String("PAM:EnterError","Неверный номер станции")
|
||
elseif #self.PathS < #tostring(Metrostroi.LineCount) or not Metrostroi.PAMConfTest[self.Line][tonumber(self.PathS)] then
|
||
Train:SetNW2String("PAM:EnterError","Неверный номер пути")
|
||
else
|
||
self:SetState(5,0.1)
|
||
end
|
||
end
|
||
elseif self.State == 4 and not self.Stopping and name == "Enter" and not value then
|
||
self:SetState(5,0.1)
|
||
elseif self.State >= 5 then
|
||
local char = tonumber(name)
|
||
--if char and not value and self.Selected == char then self.State5 = char+1 end
|
||
if self.State5Accept then
|
||
local PAM_VV = Train.PAM_VV
|
||
if name == "Enter" and not value then
|
||
if self.State5Accept == 1 then
|
||
if PAM_VV.KD < 1 and not self.NoKD and PAM_VV.KRU == 0 then
|
||
self:Message(22)
|
||
else
|
||
self.State5 = 1
|
||
end
|
||
elseif self.State5Accept == 2 then
|
||
self.NoKD = true
|
||
self:Message(1)
|
||
elseif self.State5Accept == 4 then
|
||
if self.State == 5 and (self.Mode == 2 or self.Mode == 3) then
|
||
self.Transit = true
|
||
self:Message(13)
|
||
else
|
||
self:Message(14)
|
||
end
|
||
elseif self.State5Accept == 5 and self.ZeroStopped then
|
||
self.Vd0 = true
|
||
self:Message(4)
|
||
elseif self.State5Accept == 6 then
|
||
if self.Speed<2.5 and (PAM_VV.LPT>0 or self.NoLPT or PAM_VV.V1>0) then
|
||
self.OpenDoors = true
|
||
self:Message(6)
|
||
else
|
||
self.OpenDoors = false
|
||
self:Message(7)
|
||
end
|
||
elseif self.State5Accept == -6 then
|
||
local prev = self:FindPrevStation()
|
||
if self.State == 5 and (self.StationTable and (prev and self.Distance-prev.pos < 120 or self.Distance-self.StationTable.pos<120) and self.Speed<0.2) then
|
||
self.FireBack = prev
|
||
self:Message(16)
|
||
else
|
||
self.FireBack = false
|
||
self:Message(17)
|
||
end
|
||
elseif self.State5Accept == -1 then
|
||
--AV
|
||
elseif self.State5Accept == -2 then
|
||
if PAM_VV.KSOT == 0 or not self.ControlMode2 then
|
||
self:Error(24,true,7,true)
|
||
self:Message(19)
|
||
else
|
||
self.ControlMode=2
|
||
self.ControlModeAuto = false
|
||
self:Message(18)
|
||
end
|
||
elseif self.State5Accept == -3 then
|
||
self.ControlMode=1
|
||
self.ControlModeAuto = false
|
||
self:Message(20)
|
||
elseif self.State5Accept == -4 then
|
||
if self.State == 5 and (self.Speed<0.2 and (self.StationTable.isLast or self.StationTable.hasSwitches)) then
|
||
self:Message(5)
|
||
self.Shunt = true
|
||
else
|
||
self:Message(3)
|
||
end
|
||
elseif self.State5Accept == 7 then
|
||
self.NoLPT = true
|
||
self:Message(8)
|
||
elseif self.State5Accept == 12 then
|
||
self.NoKD = false
|
||
self:Message(2)
|
||
elseif self.State5Accept == 14 then
|
||
self.Transit = false
|
||
self:Message(15)
|
||
elseif self.State5Accept == 15 then self.Vd0 = false
|
||
elseif self.State5Accept == 16 then self.OpenDoors = false
|
||
elseif self.State5Accept == 17 then
|
||
self.NoLPT = false
|
||
self:Message(9)
|
||
elseif self.State5Accept == 18 then
|
||
self.Deadlock = nil
|
||
self:Message(12)
|
||
else
|
||
self.State5 = self.State5Accept
|
||
if self.State5 == 8 then
|
||
self.Selected = 0
|
||
self.Scroll = 0
|
||
self:UpdateLastStationList()
|
||
end
|
||
end
|
||
self.State5Accept = nil
|
||
end
|
||
if name == "Esc" and not value then self.State5 = nil self.State5Accept = nil end
|
||
elseif self.State5 == 0 then
|
||
if char and value and char ~= 3 and (self.State == 5 or (char==1 or char==2 or 5<=char and char<=7)) then self.Selected = char end
|
||
if char and not value and char==self.Selected then
|
||
self.State5 = nil
|
||
if char == 9 and self.State == 5 then
|
||
self:Trigger("9",true)
|
||
self:Trigger("9",false)
|
||
else
|
||
self.State5Accept = char
|
||
end
|
||
end
|
||
if name == "Esc" and value then self.Selected = 12 end
|
||
if name == "Esc" and not value and self.Selected == 12 then self.State5 = nil end
|
||
elseif self.State5 == 8 then
|
||
if name == "Esc" and not value then
|
||
self.State5 = nil
|
||
self.DeadlockS = nil
|
||
end
|
||
if name == "Enter" and not value then
|
||
self.State5 = nil
|
||
if true or not self.Transit then
|
||
self.Deadlock = self.DeadlockS
|
||
self:Message(10)
|
||
else
|
||
self:Message(11)
|
||
end
|
||
end
|
||
if (name == "Left" or name == "Right") and not value then
|
||
self.Scroll = name == "Right" and self.Scroll+9 or math.max(self.Scroll-9,0)
|
||
self.Selected = 0
|
||
self:UpdateLastStationList()
|
||
end
|
||
if char and value then
|
||
self.Selected = char
|
||
self:UpdateLastStationList()
|
||
end
|
||
elseif self.State5 == -8 then
|
||
local charAccept = char and Train:GetNW2Bool("PAM:State5_"..char)
|
||
if charAccept and value and (char~=5 and char~=6) then self.Selected = char end
|
||
if charAccept and not value and char==self.Selected then
|
||
self.State5 = nil
|
||
self.State5Accept = 10+char
|
||
end
|
||
if name == "Esc" and value then self.Selected = 11 end
|
||
if name == "Esc" and not value and self.Selected == 11 then self.State5 = nil end
|
||
elseif self.State5 == -1 then
|
||
if name == "Left" and value then self.Brightness = math.max(0,self.Brightness-0.1) end
|
||
if name == "Right" and value then self.Brightness = math.min(1,self.Brightness+0.1) end
|
||
if (name == "Esc" or name == "Enter") and not value then self.State5 = nil end
|
||
elseif self.State5 == 1 then
|
||
if name == "Esc" and not value then
|
||
self.State5 = nil
|
||
Train:SetNW2Float("PAM:RollDist",0)
|
||
end
|
||
elseif self.State5 == -5 then
|
||
if name == "Down" and value then self.Selected = self.Selected < 2 and self.Selected+1 or 1 end
|
||
if name == "Up" and value then self.Selected = self.Selected > 1 and self.Selected-1 or 2 end
|
||
local num = tonumber(name)
|
||
if num and value then
|
||
if self.Selected == 1 and #self.RouteNumberS < 3 then self.RouteNumberS = self.RouteNumberS..num end
|
||
if self.Selected == 2 and #self.DriverNumberS < 4 then self.DriverNumberS = self.DriverNumberS..num end
|
||
end
|
||
if name == "Left" and value then
|
||
if self.Selected == 1 then self.RouteNumberS = self.RouteNumberS:sub(1,-2) end
|
||
if self.Selected == 2 then self.DriverNumberS = self.DriverNumberS:sub(1,-2) end
|
||
end
|
||
if name == "Esc" and not value then self.State5 = nil end
|
||
if name == "Enter" and not value then
|
||
if #self.RouteNumberS < 3 then
|
||
Train:SetNW2String("PAM:EnterError","Неверный номер маршрута")
|
||
elseif #self.DriverNumberS < 4 then
|
||
Train:SetNW2String("PAM:EnterError","Неверный табельный номер")
|
||
else
|
||
self.RouteNumber = self.RouteNumberS
|
||
self.DriverNumber = self.DriverNumberS
|
||
self.RouteNumberS = nil
|
||
self.DriverNumberS = nil
|
||
self.State5 = nil
|
||
end
|
||
end
|
||
elseif self.State5 == 9 then
|
||
if name == "Down" and value then self.Selected = self.Selected < 2 and self.Selected+1 or 1 end
|
||
if name == "Up" and value then self.Selected = self.Selected > 1 and self.Selected-1 or 2 end
|
||
local num = tonumber(name)
|
||
if num and value then
|
||
if self.Selected == 1 and #self.StationS < 3 then
|
||
self.StationS = self.StationS..num
|
||
self.Scroll = 0
|
||
self:UpdateStationList(self.StationS)
|
||
end
|
||
if self.Selected == 2 and #self.PathS < 1 then self.PathS = self.PathS..num end
|
||
end
|
||
if name == "Left" and value then
|
||
if self.Selected == 1 then
|
||
self.StationS = self.StationS:sub(1,-2)
|
||
self.Scroll = 0
|
||
self:UpdateStationList(self.StationS)
|
||
end
|
||
if self.Selected == 2 then self.PathS = self.PathS:sub(1,-2) end
|
||
end
|
||
if name == "Esc" and not value then
|
||
self.State5 = nil
|
||
end
|
||
if name == "Enter" and not value then
|
||
if #self.StationS < 3 or not Metrostroi.PAMStations[self.Line] or not Metrostroi.PAMStations[self.Line][tonumber(self.StationS)] then
|
||
Train:SetNW2String("PAM:EnterError","Неверный номер станции")
|
||
elseif #self.PathS < #tostring(Metrostroi.LineCount) or not Metrostroi.PAMConfTest[self.Line][tonumber(self.PathS)] then
|
||
Train:SetNW2String("PAM:EnterError","Неверный номер пути")
|
||
else
|
||
if self.Speed < 2.5 then
|
||
self.Station = self.StationS
|
||
self.Path = self.PathS
|
||
self:SetMode(1)
|
||
self.Distance = self.StationTable.pos+0.001
|
||
self:SetMode(3)
|
||
self:FindSensor(self.Distance,true)
|
||
end
|
||
self.StationS = nil
|
||
self.PathS = nil
|
||
self.State5 = nil
|
||
end
|
||
end
|
||
else
|
||
if name == "F" and not value then
|
||
self.State5 = 0
|
||
self.Selected = 1
|
||
end
|
||
|
||
--if name == "1" and value then self.State5Accept=-1 end
|
||
if name == "2" and value then self.State5Accept=-2 end
|
||
if name == "3" and self.PAKSD and value then self.State5Accept=-3 end
|
||
if name == "8" and value then self.State5=-8 self.Selected = 0 end
|
||
if name == "Left" or name == "Right" and value then
|
||
if name == "Right" then
|
||
self.Brightness = math.min(1,self.Brightness+0.1)
|
||
else
|
||
self.Brightness = math.max(0,self.Brightness-0.1)
|
||
end
|
||
self.State5 = -1
|
||
end
|
||
if self.State==5 then
|
||
if name == "P" and value then
|
||
self.State5 = -5
|
||
self.Selected = 1
|
||
self.RouteNumberS = ""
|
||
self.DriverNumberS = ""
|
||
self.KeyboardX,self.KeyboardY = 0,47
|
||
Train:SetNW2String("PAM:EnterError","")
|
||
end
|
||
if name == "4" and value then self.State5Accept=-4 end
|
||
if name == "6" and value then self.State5Accept=-6 end
|
||
--if name == "7" and value then self.State5Accept=-7 end
|
||
if name == "9" and value then
|
||
self.State5=9
|
||
self.Selected = 1
|
||
self.StationS = ""--tostring(self.Station)
|
||
self.PathS = ""--tostring(self.Path)
|
||
self.KeyboardX,self.KeyboardY = 10,47
|
||
Train:SetNW2String("PAM:EnterError","")
|
||
self:UpdateStationList(self.StationS)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
local keys = {
|
||
"P",
|
||
"F" , "Up" , "M",
|
||
"Left","Down","Right",
|
||
"1" , "2" , "3",
|
||
"4" , "5" , "6",
|
||
"7" , "8" , "9",
|
||
"Esc" , "0" ,"Enter",
|
||
}
|
||
local acceptions = {
|
||
[-7] = 1,
|
||
[-6] = 1,
|
||
[-4] = 2,
|
||
[-3] = 1,
|
||
[-2] = 1,
|
||
[-1] = 1,
|
||
1,1,1,1,1,1,1,1,
|
||
[11]=1,
|
||
[12]=1,
|
||
[13]=1,
|
||
[14]=1,
|
||
[15]=1,
|
||
[16]=2,
|
||
[17]=1,
|
||
[18]=1,
|
||
}
|
||
local acceptionsReset = {
|
||
1,1,1,1,1,2,1,1,
|
||
}
|
||
function TRAIN_SYSTEM:Touch(value,x,y)
|
||
local Train = self.Train
|
||
Train:SetNW2String("PAM:Touching","")
|
||
if self.Keyboard and (self.State==3 or self.State==3.5 or self.State==5 and self.State5==9) then
|
||
for i,keyName in ipairs(keys) do
|
||
local key = i+1
|
||
local xp = key%3
|
||
local yp = math.floor(key/3)
|
||
if math.InRangeXYR(x,y,self.KeyboardX+5+60*xp,self.KeyboardY+33+49*yp,60,49) then
|
||
self.Touches[keyName] = true
|
||
Train:SetNW2String("PAM:LastToucn",keyName)
|
||
if value then Train:SetNW2String("PAM:Touching",keyName) end
|
||
break
|
||
end
|
||
end
|
||
end
|
||
if not value then
|
||
for k in pairs(self.Touches) do self.Touches[k] = false end
|
||
return
|
||
end
|
||
if self.State == 1 then
|
||
if value and math.InRangeXYR(x,y,542,self.ReverserWrench and 316 or 352,77,51) then self.Touches["Esc"] = true return end
|
||
if value and math.InRangeXYR(x,y,265,410,110,51) then self.Touches["Enter"] = true return end
|
||
elseif self.State == 1.5 then
|
||
if value and math.InRangeXYR(x,y,238,408,164,51) then self.Touches["Esc"] = true return end
|
||
elseif self.State == 2 then
|
||
if math.InRangeXYR(x,y,320-298,121+59*0,596,50) then self.Touches["1"] = true return end
|
||
if math.InRangeXYR(x,y,320-298,121+59*1,596,50) then self.Touches["2"] = true return end
|
||
if math.InRangeXYR(x,y,320-298,121+59*2,596,50) then self.Touches["Esc"] = true return end
|
||
if math.InRangeXYR(x,y,320-298,121+59*4+10,596,50) then self.Touches["M"] = true return end
|
||
elseif self.State == 3 or self.State == 3.5 then
|
||
if self.Selected==1 and self.ScrollCount and self.ScrollCount > 0 then
|
||
local xa,ya = 374,103+35*1
|
||
if math.InRangeXYR(x,y,xa+219,ya+5,31,15) or math.InRangeXYR(x,y,xa+219,ya+128,31,14) then
|
||
self.Scroll = math.max(self.Scroll-1,0)
|
||
self:UpdateStationList(self.StationS)
|
||
return
|
||
elseif math.InRangeXYR(x,y,xa+219,ya+143,31,14) then
|
||
self.Scroll = math.Clamp(self.Scroll+1,0,math.max(0,self.ScrollCount-8))
|
||
self:UpdateStationList(self.StationS)
|
||
return
|
||
end
|
||
|
||
for i=1,math.min(8,self.ScrollCount) do
|
||
if math.InRangeXYR(x,y,xa+13,ya+27-10+18*(i-1)-9,200,17) then
|
||
local st = self:UpdateStationList(self.StationS,i)
|
||
self.StationS = st and tostring(st) or self.StationS
|
||
self:UpdateStationList(self.StationS)
|
||
return
|
||
end
|
||
end
|
||
else
|
||
for i=0,self.State==3.5 and 1 or 3 do
|
||
if math.InRangeXYR(x,y,374,103+35*i,210,35) then self.Selected = i+1 return end
|
||
end
|
||
end
|
||
if self.Keyboard then
|
||
if math.InRangeXYR(x,y,156+127,369,120,51) then self.Touches["Enter"] = true return end
|
||
if math.InRangeXYR(x,y,286+127,369,120,51) then self.Touches["Esc"] = true return end
|
||
if math.InRangeXYR(x,y,443+100,369,40,51) then self.Touches["KeyB"] = true return end
|
||
else
|
||
if math.InRangeXYR(x,y,156,369,120,51) then self.Touches["Enter"] = true return end
|
||
if math.InRangeXYR(x,y,286,369,120,51) then self.Touches["Esc"] = true return end
|
||
if math.InRangeXYR(x,y,443,369,40,51) then self.Touches["KeyB"] = true return end
|
||
end
|
||
elseif self.State == 4 and math.InRangeXYR(x,y,320-19,278,76,38) then
|
||
self.Touches["Enter"] = true
|
||
return
|
||
elseif self.State >= 5 then
|
||
if self.State5Accept and self.State5Accept ~= 0 then
|
||
local ya = acceptions[self.State5Accept]*21
|
||
if math.InRangeXYR(x,y,194,219+ya,120,50) then self.Touches["Enter"] = true return end
|
||
if math.InRangeXYR(x,y,326,219+ya,120,50) then self.Touches["Esc"] = true return end
|
||
elseif self.State5==0 then
|
||
for i=1,10 do
|
||
if i==10 then i=12 end
|
||
if math.InRangeXYR(x,y,212*((i-1)%3),119+(math.ceil(i/3)-1)*62,212,62) then
|
||
if i==12 then
|
||
self.Touches["Esc"] = true
|
||
return
|
||
else
|
||
self.Touches[tostring(i%10)] = true
|
||
return
|
||
end
|
||
end
|
||
end
|
||
elseif self.State5 == -1 then
|
||
if math.InRangeXYR(x,y,161,192,75,34) then self.Touches["Left"] = true return end
|
||
if math.InRangeXYR(x,y,413,192,75,34) then self.Touches["Right"] = true return end
|
||
if math.InRangeXYR(x,y,277,277,95,50) then self.Touches["Enter"] = true return end
|
||
if math.InRangeXYR(x,y,246,196,157,25) then self.Brightness = math.Clamp(math.Round((x-251)/147,2),0,1) return end
|
||
elseif self.State5==-8 then
|
||
for i=1,9 do
|
||
if i==9 then i=11 end
|
||
if math.InRangeXYR(x,y,4+210*((i-1)%3),152+(math.ceil(i/3)-1)*50,209,49) then
|
||
if i==11 then
|
||
self.Touches["Esc"] = true
|
||
return
|
||
else
|
||
self.Touches[tostring(i%10)] = true
|
||
return
|
||
end
|
||
end
|
||
end
|
||
elseif self.State5 == 1 then
|
||
if math.InRangeXYR(x,y,139,270,370,50) then self.Touches["Esc"] = true return end
|
||
elseif self.State5 == 8 then
|
||
if self.ScrollCount and self.ScrollCount > 0 then
|
||
for i=1,math.min(9,Train:GetNW2String("PAM:ElemCount",0)) do
|
||
if math.InRangeXYR(x,y,4+210*((i-1)%3),152+(math.ceil(i/3)-1)*50,210,50) then self.Touches[tostring(i)] = true return end
|
||
end
|
||
if math.InRangeXYR(x,y,4+210*0,152+3*50,80,50) then self.Touches["Left"] = true return end
|
||
if math.InRangeXYR(x,y,4+210*3-80,152+3*50,80,50) then self.Touches["Right"] = true return end
|
||
end
|
||
if math.InRangeXYR(x,y,4+210*1.5-145,152+3*50,140,50) then self.Touches["Enter"] = true return end
|
||
if math.InRangeXYR(x,y,4+210*1.5+5,152+3*50,140,50) then self.Touches["Esc"] = true return end
|
||
elseif self.State5 == -5 then
|
||
local xadd = (self.Keyboard and 1 or 0)
|
||
for i=0,1 do
|
||
if math.InRangeXYR(x,y,320+102*(self.Keyboard and 1 or 0),190+39*i,225-15*xadd,31) then self.Selected = i+1 return end
|
||
end
|
||
if math.InRangeXYR(x,y,190+xadd*79,320,140,50) then self.Touches["Enter"] = true return end
|
||
if math.InRangeXYR(x,y,340+xadd*79,320,140,50) then self.Touches["Esc"] = true return end
|
||
if math.InRangeXYR(x,y,501+xadd*79,320,40,51) then self.Touches["KeyB"] = true return end
|
||
elseif self.State5 == 9 then
|
||
if self.Selected==1 and self.ScrollCount and self.ScrollCount > 0 then
|
||
local xa,ya = 320+40*(self.Keyboard and 1 or 0),229
|
||
if math.InRangeXYR(x,y,xa+219,ya+5,31,15) or math.InRangeXYR(x,y,xa+219,ya+128,31,14) then
|
||
self.Scroll = math.max(self.Scroll-1,0)
|
||
self:UpdateStationList(self.StationS)
|
||
return
|
||
elseif math.InRangeXYR(x,y,xa+219,ya+143,31,14) then
|
||
self.Scroll = math.Clamp(self.Scroll+1,0,self.ScrollCount-8)
|
||
self:UpdateStationList(self.StationS)
|
||
return
|
||
end
|
||
|
||
for i=1,math.min(8,self.ScrollCount) do
|
||
if math.InRangeXYR(x,y,xa+13,ya+27-10+18*(i-1)-9,200,17) then
|
||
local st = self:UpdateStationList(self.StationS,i)
|
||
self.StationS = st and tostring(st) or self.StationS
|
||
self:UpdateStationList(self.StationS)
|
||
return
|
||
end
|
||
end
|
||
else
|
||
for i=0,1 do
|
||
if math.InRangeXYR(x,y,322+40*(self.Keyboard and 1 or 0),190+39*i,229,31) then self.Selected = i+1 return end
|
||
end
|
||
end
|
||
if self.Keyboard then
|
||
if math.InRangeXYR(x,y,190+1*39,320,75+1*65,50) then self.Touches["Enter"] = true return end
|
||
if math.InRangeXYR(x,y,288+1*(42+39+10),320,120+1*20,50) then self.Touches["Esc"] = true return end
|
||
if math.InRangeXYR(x,y,501+1*40,320,40,51) then self.Touches["KeyB"] = true return end
|
||
else
|
||
if math.InRangeXYR(x,y,190+0*39,320,75+0*65,50) then self.Touches["Enter"] = true return end
|
||
if math.InRangeXYR(x,y,288+0*(42+39+10),320,120+0*20,50) then self.Touches["Esc"] = true return end
|
||
if math.InRangeXYR(x,y,501+0*40,320,40,51) then self.Touches["KeyB"] = true return end
|
||
end
|
||
else
|
||
if math.InRangeXYR(x,y,0,429,136,51) then self.Touches["F"] = true return end
|
||
if math.InRangeXYR(x,y,3,289,80,35) then self.Touches["P"] = true return end
|
||
|
||
for i=0,2 do
|
||
if math.InRangeXYR(x,y,2,157+i*46,70,35) then self.Touches[tostring(i+1)] = true end
|
||
end
|
||
for i=0,4 do
|
||
if math.InRangeXYR(x,y,570,155+i*46,70,35) then self.Touches[i==0 and "4" or tostring(i+5)] = true end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
TRAIN_SYSTEM.DriveModesConv = {
|
||
AT = -4,
|
||
AT1 = -4,
|
||
VPR = -3,
|
||
ST = -2,
|
||
OXT = -1,
|
||
OD = 0,
|
||
X1 = 1,
|
||
X2 = 2,
|
||
X3 = 3,
|
||
}
|
||
TRAIN_SYSTEM.DriveModes = {
|
||
--Priority 2 3 8 017 19 20 20X 25 025 33 033 33G
|
||
X3 = {1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0},
|
||
X2 = {2, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0},
|
||
X1 = {3, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0},
|
||
OD = {4, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0},
|
||
OXT = {5, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0},
|
||
ST = {6, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1},
|
||
VPR = {7, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1},
|
||
AT1 = {8, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1},
|
||
AT = {9, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1},
|
||
Zero = {10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||
}
|
||
function TRAIN_SYSTEM:SetDriveMode(curMode,override)
|
||
local mode = self.DriveModes[curMode]
|
||
if mode and mode[1] > self.CurrentDriveModePriority then
|
||
self.CurrentDriveMode = mode
|
||
self.CurrentDriveModePriority = mode[1]
|
||
self.DriveMode = curMode
|
||
end
|
||
end
|
||
TRAIN_SYSTEM.PneumoModes = {
|
||
--Priority 39 48
|
||
NT = {1, 0, 0,},
|
||
V1 = {2, 0, 1,},
|
||
V2 = {3, 1, 0,},
|
||
V12 = {4, 1, 1,},
|
||
}
|
||
function TRAIN_SYSTEM:SetDoorMode(curMode,override)
|
||
local mode = self.DoorModes[curMode]
|
||
self.CurrentDoorMode = mode
|
||
self.DoorMode = curMode
|
||
end
|
||
TRAIN_SYSTEM.DoorModes = {
|
||
-- 16 31 32 68
|
||
ZD = {1, 0, 0, 0,},
|
||
DL = {0, 1, 0, 0,},
|
||
DP = {0, 0, 1, 0,},
|
||
DB = {0, 0, 0, 1,},
|
||
DO = {0, 0, 0, 0,},
|
||
}
|
||
function TRAIN_SYSTEM:SetPneumoMode(curMode,override)
|
||
if self.CurrentPneumoModePriority==2 and curMode=="V2" then
|
||
curMode = "V12"
|
||
end
|
||
if self.CurrentPneumoModePriority==3 and curMode=="V1" then
|
||
curMode = "V12"
|
||
end
|
||
local mode = self.PneumoModes[curMode]
|
||
if mode and (override or mode[1] > self.CurrentPneumoModePriority) then
|
||
self.CurrentPneumoMode = mode
|
||
self.CurrentPneumoModePriority = mode[1]
|
||
self.PneumoMode = curMode
|
||
end
|
||
end
|
||
|
||
function TRAIN_SYSTEM:TriggerSensor(coil,plate)
|
||
if self.SensorEnabled then
|
||
--self.Distance = plate.TrackX
|
||
local line = self.Line
|
||
local path = tonumber(self.Path)
|
||
local tbl = Metrostroi.PAMConfTest and Metrostroi.PAMConfTest[line] and Metrostroi.PAMConfTest[line][path]
|
||
if not tbl then return end
|
||
if self.Mode == 1 then
|
||
--Ищем позицию нашей станции
|
||
--[[ local pos
|
||
for i,stat in ipairs(tbl[1].stations) do
|
||
if stat.id == tonumber(self.Station) then
|
||
pos = stat.pos
|
||
break
|
||
end
|
||
end--]]
|
||
--Ищем ближайший датчик на станции в районе 200м
|
||
--[[ for i,sensor in ipairs(tbl[1].sensors) do
|
||
if pos-sensor<200 then
|
||
sensorDist = sensor
|
||
break
|
||
end
|
||
end--]]
|
||
self:FindSensor(self.StationTable.linkedSensor or false)
|
||
if self.NextSensorDist then
|
||
--print(Format("SENSOR: New pos: %.2fm",self.NextSensorDist))
|
||
self.Distance = self.NextSensorDist
|
||
self.SensorError = false
|
||
self:SetMode(2)
|
||
self:FindSensor()
|
||
else
|
||
--print(Format("SENSOR: Error! Can't find good detector near station %s",self.Station))
|
||
end
|
||
self.AlwaysSensor = false
|
||
else
|
||
--Ищем ближайший сенсор от нас для коррекции пути
|
||
--[[ local nearest,sensorDist
|
||
for i,sensor in ipairs(tbl[1].sensors) do
|
||
if not nearest or math.abs(sensor-self.Distance)<nearest then
|
||
nearest = math.abs(sensor-self.Distance)
|
||
sensorDist = sensor
|
||
end
|
||
end--]]
|
||
if self.NextSensorDist then
|
||
--print(Format("SENSOR:Old pos: %.2fm, New pos: %.2fm, delta:%.2fm",self.Distance,self.NextSensorDist,self.NextSensorDist-self.Distance))
|
||
self.Distance = self.NextSensorDist--sensorDist
|
||
self.SensorError = false
|
||
self:FindSensor()
|
||
else
|
||
--print("SENSOR: Unknown error in sensors database")
|
||
end
|
||
self.AlwaysSensor = false
|
||
end
|
||
end
|
||
end
|
||
|
||
function TRAIN_SYSTEM:FindSensor(sens,nearest)
|
||
local line = self.Line
|
||
local path = tonumber(self.Path)
|
||
local tbl = Metrostroi.PAMConfTest and Metrostroi.PAMConfTest[line] and Metrostroi.PAMConfTest[line][path]
|
||
if not tbl then return end
|
||
if nearest then
|
||
local dist = self.Distance
|
||
for i,sens in ipairs(tbl[1].sensors) do
|
||
if sens > dist then
|
||
self.NextSensor = i
|
||
break
|
||
end
|
||
end
|
||
elseif sens~=nil then
|
||
self.NextSensor = sens
|
||
else
|
||
self.NextSensor = self.NextSensor + 1
|
||
end
|
||
self.NextSensorDist = tbl[1].sensors[self.NextSensor]
|
||
end
|
||
|
||
function TRAIN_SYSTEM:FindNextSignal()
|
||
local dist = self.Distance
|
||
local line = self.Line
|
||
local path = tonumber(self.Path)
|
||
local tbl = Metrostroi.PAMConfTest and Metrostroi.PAMConfTest[line] and Metrostroi.PAMConfTest[line][path]
|
||
if not tbl then return end
|
||
for i,sig in ipairs(tbl[1].signals) do
|
||
if sig[2] > dist then
|
||
return sig[1]
|
||
end
|
||
end
|
||
end
|
||
|
||
function TRAIN_SYSTEM:FindNextSlope()
|
||
local dist = self.Distance
|
||
local line = self.Line
|
||
local path = tonumber(self.Path)
|
||
local tbl = Metrostroi.PAMConfTest and Metrostroi.PAMConfTest[line] and Metrostroi.PAMConfTest[line][path]
|
||
if not tbl then return 0 end
|
||
local stbl = tbl[1].slopes
|
||
if not stbl then return 0 end
|
||
for i,slp in ipairs(stbl) do
|
||
if slp[2] > dist then
|
||
return stbl[i-1] and stbl[i-1][1] or 0
|
||
end
|
||
end
|
||
end
|
||
|
||
function TRAIN_SYSTEM:FindNextStation()
|
||
local dist = self.Distance
|
||
local line = self.Line
|
||
local path = tonumber(self.Path)
|
||
local tbl = Metrostroi.PAMConfTest and Metrostroi.PAMConfTest[line] and Metrostroi.PAMConfTest[line][path]
|
||
if not tbl then return end
|
||
for i,stat in ipairs(tbl[1].stations) do
|
||
if stat.pos-10 > dist then
|
||
return stat,tbl[1].stations[i-1]
|
||
end
|
||
end
|
||
end
|
||
function TRAIN_SYSTEM:FindPrevStation()
|
||
local dist = self.Distance
|
||
local line = self.Line
|
||
local path = tonumber(self.Path)
|
||
local tbl = Metrostroi.PAMConfTest and Metrostroi.PAMConfTest[line] and Metrostroi.PAMConfTest[line][path]
|
||
if not tbl then return end
|
||
for i,stat in ipairs(tbl[1].stations) do
|
||
if stat.pos+120 > dist then
|
||
return stat
|
||
end
|
||
end
|
||
end
|
||
function TRAIN_SYSTEM:FindStation(line,path,stationIndex)
|
||
local tbl = Metrostroi.PAMConfTest and Metrostroi.PAMConfTest[line] and Metrostroi.PAMConfTest[line][tonumber(path) or 1]
|
||
if not tbl then return end
|
||
for i,v in ipairs(tbl[1].stations) do
|
||
if v.id == tonumber(stationIndex) then return v,tbl[1].stations[i-1] end
|
||
end
|
||
return station and station.id
|
||
end
|
||
function TRAIN_SYSTEM:FindFirstStation()
|
||
local dist = self.Distance
|
||
local line = self.Line
|
||
local path = tonumber(self.Path)
|
||
local tbl = Metrostroi.PAMConfTest and Metrostroi.PAMConfTest[line] and Metrostroi.PAMConfTest[line][path]
|
||
if not tbl then return end
|
||
return tbl[1].stations[1].id
|
||
end
|
||
function TRAIN_SYSTEM:FindLastStation()
|
||
local dist = self.Distance
|
||
local line = self.Line
|
||
local path = tonumber(self.Path)
|
||
local tbl = Metrostroi.PAMConfTest and Metrostroi.PAMConfTest[line] and Metrostroi.PAMConfTest[line][path]
|
||
if not tbl then return end
|
||
return tbl[1].stations[#tbl[1].stations]
|
||
end
|
||
function TRAIN_SYSTEM:Message(id)
|
||
self.CurrentMessage = id
|
||
self.MessageTimer = CurTime()
|
||
end
|
||
local errorsRing = {
|
||
true ,true ,nil ,false,nil ,nil ,true ,true ,
|
||
true ,nil ,nil ,nil ,false,nil ,false,nil ,
|
||
nil ,nil ,nil ,nil ,nil ,true ,nil ,false,
|
||
nil ,nil ,false,nil ,nil ,false,nil ,nil ,
|
||
}
|
||
function TRAIN_SYSTEM:Error(id,state,time,removeOnTimer)
|
||
if (state or removeOnTimer and self.ErrorTimers[id] and CurTime()-self.ErrorTimers[id]<time) and (not self.ErrorTimers[self.CurrentError] or not self.ErrorTimers[id] and (not time or CurTime()-self.ErrorTimers[self.CurrentError]<time) or self.ErrorTimers[id] and self.ErrorTimers[self.CurrentError] <= self.ErrorTimers[id]) then
|
||
if not self.ErrorTimers[id] then
|
||
self.ErrorTimers[id] = CurTime()
|
||
end
|
||
if not time or CurTime()-self.ErrorTimers[id]<time then
|
||
self.CurrentError = id
|
||
end
|
||
elseif not state and self.ErrorTimers[id] then
|
||
self.ErrorTimers[id] = nil
|
||
end
|
||
end
|
||
function TRAIN_SYSTEM:SetWaitTimer(time)
|
||
self.ChangeTimer = CurTime()+time
|
||
end
|
||
function TRAIN_SYSTEM:SetState(state,time)
|
||
if state>=2 then
|
||
self.Selected = 1
|
||
end
|
||
if state == 2 then
|
||
self.LineS = self.Line or self.LineS
|
||
self.PathS = tostring(self.Path) or self.PathS
|
||
self.StationS = tostring(self.Station) or self.StationS
|
||
self.RouteNumberS = self.RouteNumber or self.RouteNumberS
|
||
self.DriverNumberS = self.DriverNumber or self.DriverNumberS
|
||
|
||
self.HaveRestart = self.DriverNumber and #self.DriverNumber == 4 and self.RouteNumber and #self.RouteNumber == 3
|
||
and Metrostroi.PAMConfTest[self.LineS]
|
||
and Metrostroi.PAMConfTest[self.LineS][tonumber(self.PathS)]
|
||
and Metrostroi.PAMStations[self.LineS][tonumber(self.StationS)]
|
||
self.Train:SetNW2Bool("PAM:HaveRestart",self.HaveRestart)
|
||
elseif state == 3 or state == 3.5 then
|
||
self.KeyboardX,self.KeyboardY = 22,47
|
||
|
||
if state == 3 then
|
||
self.StationS = ""
|
||
self.PathS = ""
|
||
self.RouteNumberS = ""
|
||
self.DriverNumberS = ""
|
||
end
|
||
|
||
self:UpdateStationList(self.StationS)
|
||
self.Train:SetNW2String("PAM:EnterError","")
|
||
elseif (state == 4 or state == 5) and self.LineS then
|
||
if state == 4 then self.CheckRing = true end
|
||
--elseif state == 5 then
|
||
self.Line = tonumber(self.LineS)
|
||
self.Station = tonumber(self.StationS)
|
||
self.Path = tonumber(self.PathS)
|
||
self.RouteNumber = self.RouteNumberS
|
||
self.DriverNumber = self.DriverNumberS
|
||
self.LineS = nil
|
||
self.StationS = nil
|
||
self.PathS = nil
|
||
self.RouteNumberS = nil
|
||
self.DriverNumberS = nil
|
||
|
||
self:SetMode(1)
|
||
self.EPKActive = true
|
||
self.ControlMode = 2
|
||
self.State5 = nil
|
||
self.CloseDoors = true
|
||
elseif state == 6 then
|
||
self:SetMode(0)
|
||
self.EPKActive = true
|
||
self.ControlMode = 2
|
||
self.State5 = nil
|
||
self.CloseDoors = true
|
||
end
|
||
self.State = state
|
||
if time then self.ChangeTimer = CurTime()+time end
|
||
end
|
||
|
||
function TRAIN_SYSTEM:SetMode(mode)
|
||
self.Mode = mode
|
||
if mode==0 then
|
||
self.Transit = false
|
||
self.FireBack = false
|
||
self.Shunt = false
|
||
self.AntiMiss = false
|
||
elseif mode==1 then
|
||
self.Distance = 0
|
||
self.StationTable,self.PrevStationTable = self:FindStation(self.Line,self.Path,self.Station)
|
||
self.LastStationTable = self:FindLastStation()
|
||
self.SensorError = false
|
||
self.Deadlock = nil
|
||
self.FireBack = false
|
||
self.Shunt = false
|
||
self.AntiMiss = false
|
||
elseif mode == 2 then
|
||
self.AntiMiss = false
|
||
self.FireBack = false
|
||
elseif mode == 3 then
|
||
self.Transit = false
|
||
self.FireBack = false
|
||
self.Shunt = false
|
||
self.AntiMiss = false
|
||
elseif mode == 6 then
|
||
self.Shunt = false
|
||
end
|
||
end
|
||
|
||
function TRAIN_SYSTEM:CANReceive(source,sourceid,target,targetid,textdata,numdata)
|
||
if self.CANIgnore and CurTime()-self.CANIgnore < 2 then return end
|
||
if sourceid == self.Train:GetWagonNumber() then return end
|
||
if self.State == 0 then return end
|
||
if textdata == "Check" then
|
||
self:CANWrite("Answer",{
|
||
Errors = not self.GoodSetup,
|
||
State=self.State,
|
||
Mode = self.Mode,
|
||
Line = self.Line,
|
||
Path = self.Path,
|
||
Station = self.Station,
|
||
RouteNumber = self.RouteNumber,
|
||
DriverNumber = self.DriverNumber,
|
||
Deadlock = self.Deadlock and self.Deadlock.id,
|
||
RR = self.ReverserWrench,
|
||
})
|
||
elseif textdata == "Answer" then
|
||
if not self.BackPA then
|
||
self.BackPA = {
|
||
id=sourceid,
|
||
LastAnswer = CurTime(),
|
||
state = numdata
|
||
}
|
||
elseif self.BackPA.id ~= sourceid then
|
||
self.BackPA = nil
|
||
self.CANIgnore = CurTime()
|
||
else
|
||
self.BackPA.LastAnswer = CurTime()
|
||
self.BackPA.state = numdata
|
||
end
|
||
local back = self.BackPA and self.BackPA.state
|
||
if back and back.RR and self.State>0 then
|
||
local tbl = Metrostroi.PAMConfTest and Metrostroi.PAMConfTest[back.Line] and Metrostroi.PAMConfTest[back.Line][(back.Path=="2" or back.Path==2) and 1 or 2]
|
||
if not tbl then return end
|
||
if self.State<4 and back.State==4 then
|
||
self.LineS = back.Line
|
||
self.PathS = (back.Path=="2" or back.Path==2) and "1" or "2"
|
||
self.RouteNumberS = back.RouteNumber
|
||
self.DriverNumberS = back.DriverNumber
|
||
self.StationS = back.Station
|
||
|
||
self:SetState(4)
|
||
end
|
||
if self.State<5 and back.State==5 then self.EPKActive = true self.State = 5 self.ControlMode = 2 end
|
||
if self.State==5 then
|
||
self.Line = back.Line
|
||
self.Path = (back.Path=="2" or back.Path==2) and "1" or "2"
|
||
self.RouteNumber = back.RouteNumber
|
||
self.DriverNumber = back.DriverNumber
|
||
self.Deadlock = self.Mode==4 and self.Deadlock or nil
|
||
self.Shunt = back.Shunt
|
||
if self.Station ~= back.Station or not self.BackRR or self.BackMode~=back.Mode then
|
||
local line = self.Line
|
||
local path = tonumber(self.Path)
|
||
for k,v in ipairs(tbl[1].stations) do
|
||
if v.id == tonumber(back.Station) then
|
||
self.Station = back.Station
|
||
self.StationTable = v
|
||
self.Distance = v.pos
|
||
self.PrevStationTable = tbl[1].stations[k-1]
|
||
self.LastStationTable = self:FindLastStation()
|
||
self.AlwaysSensor = true
|
||
self:FindSensor(self.StationTable.linkedSensor or false)
|
||
self.AddDistance = 100+math.random()*50
|
||
end
|
||
end
|
||
self.BackMode = back.Mode
|
||
end
|
||
|
||
local deadlock
|
||
if back.Deadlock and not self.Deadlock then
|
||
local line = self.Line
|
||
local path = tonumber(self.Path)
|
||
local tbl = Metrostroi.PAMConfTest and Metrostroi.PAMConfTest[line] and Metrostroi.PAMConfTest[line][path]
|
||
for k,v in ipairs(tbl[1].stations) do
|
||
if back.Deadlock and v.id == back.Deadlock and tonumber(back.Station) == back.Deadlock and not self.StationTable.isInWrong then
|
||
self.Deadlock = v
|
||
self.Mode = 4
|
||
self.AddDistance = false
|
||
self.AntiMiss = false
|
||
deadlock = true
|
||
end
|
||
end
|
||
end
|
||
if back.Mode<=4 and (not self.Deadlock or self.StationTable.isInWrong) then
|
||
self.Mode = math.min(2,back.Mode)
|
||
self.AntiMiss = false
|
||
end
|
||
if (back.Mode==5 or back.Mode==1) and self.Mode~=1 then self:SetMode(1) end
|
||
if back.Mode==6 then
|
||
self:SetMode(1)
|
||
self:SetMode(6)
|
||
end
|
||
end
|
||
end
|
||
self.BackRR = back and back.RR
|
||
end
|
||
|
||
end
|
||
function TRAIN_SYSTEM:CANWrite(name,value,number)
|
||
if self.State == 0 then return end
|
||
if self.CANIgnore and CurTime()-self.CANIgnore < 1 then return end
|
||
local source = self.Train:GetWagonNumber()
|
||
self.Train:CANWrite("PAM",source,"PAM",number,name,value)
|
||
end
|
||
function TRAIN_SYSTEM:Think(dT)
|
||
local Train = self.Train
|
||
if Train.Electric.Type < 4 then return end
|
||
self.OldDriveModePriority = self.CurrentDriveModePriority or 0
|
||
self.CurrentDriveModePriority = 0
|
||
self.CurrentPneumoModePriority = 0
|
||
|
||
local PAM_VV = Train.PAM_VV
|
||
local Power = PAM_VV.Power > 0
|
||
local ALS = Train.ALSCoil
|
||
local BackReverser = PAM_VV.KRR2 > 0
|
||
local BackActive = PAM_VV.KRR1 > 0
|
||
local RR = (PAM_VV.KRR > 0 or PAM_VV.KRU > 0) and not BackActive
|
||
if RR and self.AddDistance then
|
||
if not self.Deadlock then self.Distance = self.Distance-self.AddDistance end
|
||
self.AddDistance = false
|
||
end
|
||
if Power and self.State == 0 then
|
||
self.State = -0.5
|
||
self.StartTimer = CurTime()
|
||
end
|
||
if not Power and self.State ~= 0 then
|
||
self.State = 0
|
||
for k,v in pairs(self.TriggerNames) do
|
||
self.Triggers[v] = false
|
||
self.Touches[v:sub(4,-1)] = false
|
||
end
|
||
self.BackCheckTimer = false
|
||
self.BackPA = nil
|
||
self.Brightness = 0.6
|
||
self.Sound = true
|
||
self.SoundTimer = false
|
||
end
|
||
if self.State == -0.5 and CurTime()-self.StartTimer > 0.05 then self.State = -1 self.StartTimer = CurTime() end
|
||
if self.State == -1 and CurTime()-self.StartTimer > 5 then self.State = -2 self.StartTimer = CurTime() self:SetWaitTimer(0.2) end
|
||
if self.State == -2 and CurTime()-self.StartTimer > 0.8 then self.State = -3 self.StartTimer = CurTime() self:SetWaitTimer(1) end
|
||
if self.State == -3 and CurTime()-self.StartTimer > 3 then self.State = -4 self.StartTimer = CurTime() end
|
||
if self.State == -4 and CurTime()-self.StartTimer > 2 then self.State = -5 self.StartTimer = CurTime() self:SetWaitTimer(1) end
|
||
if self.State == -4 and CurTime()-self.StartTimer > 2 then self.State = -5 self.StartTimer = CurTime() self:SetWaitTimer(1) end
|
||
if self.State == -5 and CurTime()-self.StartTimer > 5 then self.State = 1 self.StartTimer = CurTime() self:SetWaitTimer(0.2) end
|
||
if self.State == -5 and PAM_VV.LPT > 0 then
|
||
if PAM_VV.KGR==0 and self.WaitingX==nil then
|
||
self.WaitingX = false
|
||
elseif PAM_VV.KGR>0 and self.WaitingX==false then
|
||
self.WaitingX = true
|
||
elseif PAM_VV.KGR==0 and self.WaitingX then
|
||
self:SetState(6,0.1)
|
||
end
|
||
else
|
||
self.WaitingX = nil
|
||
end
|
||
if self.ChangeTimer and CurTime()-self.ChangeTimer > 0 then self.ChangeTimer = nil end
|
||
|
||
local ALSOn = (self.State>0) and 1 or 0
|
||
if self.PAKSD and ALSOn ~= ALS.Enabled then
|
||
ALS:TriggerInput("Enable",ALSOn)
|
||
end
|
||
|
||
self.Speed = ALS.Speed--math.Round(ALS.Speed or 0,1)
|
||
local speed = self.Speed
|
||
local speedMpS = speed/3600*1000
|
||
local speedMpSSigned = speedMpS*ALS.SpeedSign
|
||
local accel = ALS.Acceleration
|
||
if ALSOn>0--[[self.State > 0 or self.State<-3]] then
|
||
for k,v in pairs(self.TriggerNames) do
|
||
local name = v:sub(4,-1)
|
||
local val = Train[v].Value > 0.5
|
||
if (self.Touches[name] or val) ~= self.Triggers[v] then
|
||
self.Triggers[v] = self.Touches[name] or val
|
||
self:Trigger(name,self.Triggers[v],val == self.Triggers[v])
|
||
end
|
||
|
||
if self.SoundTimer and self.SoundTimer > 0 and CurTime()-self.SoundTimer > 0.5 then
|
||
self.SoundTimer = -CurTime()
|
||
self.Sound = not self.Sound
|
||
Train:PlayOnce("pa_f","bass",1)
|
||
end
|
||
if self.SoundTimer and self.SoundTimer < 0 and CurTime()+self.SoundTimer > 0.25 then
|
||
self.SoundTimer = false
|
||
Train:PlayOnce("pa_f","bass",1)
|
||
end
|
||
end
|
||
if (not self.BackCheckTimer or CurTime()-self.BackCheckTimer > 1) then
|
||
self:CANWrite("Check")
|
||
self.BackCheckTimer = CurTime()
|
||
end
|
||
if self.BackPA and CurTime()-self.BackPA.LastAnswer > 2 then
|
||
self.BackPA = nil
|
||
end
|
||
|
||
local ALSSh = self.PAKSD and 0 or (1-Train.ALS.Value)*Train.VRD.Value --ALS Shunt
|
||
local Vd = -1
|
||
if ALS.F5*(1-ALSSh) > 0 then Vd = 0 end
|
||
if ALS.F4*(1-ALSSh) > 0 then Vd = 40 end
|
||
if ALS.F3*(1-ALSSh) > 0 then Vd = 60 end
|
||
if ALS.F2*(1-ALSSh) > 0 then Vd = 70 end
|
||
if ALS.F1*(1-ALSSh) > 0 then Vd = 80 end
|
||
if Vd ~= self.SpeedLimit then
|
||
if Vd == -1 and not self.FQChagneTimer then
|
||
self.FQChagneTimer = CurTime()
|
||
end
|
||
if Vd ~= -1 or self.FQChagneTimer and (speedMpS <= 0.1 and CurTime()-self.FQChagneTimer > 2.5 or speedMpS >= 0.1 and CurTime()-self.FQChagneTimer > 0.8) then
|
||
self.SpeedLimit = Vd
|
||
self.FQChagneTimer = nil
|
||
end
|
||
end
|
||
if self.PAKSD then --ALS outputs for KSD
|
||
self.F5 = self.SpeedLimit==0 and 1 or 0
|
||
self.F4 = self.SpeedLimit==40 and 1 or 0
|
||
self.F3 = self.SpeedLimit==60 and 1 or 0
|
||
self.F2 = self.SpeedLimit==70 and 1 or 0
|
||
self.F1 = self.SpeedLimit==80 and 1 or 0
|
||
self.F6 = self.SpeedLimit>-1 and ALS.F6 or 0
|
||
end
|
||
self.NoFreq = self.SpeedLimit==-1 and 1 or 0
|
||
elseif self.State==-0.5 then
|
||
self.NoFreq = 1
|
||
self.F6 = 1
|
||
self.F5 = 1
|
||
self.F4 = 1
|
||
self.F3 = 1
|
||
self.F2 = 1
|
||
self.F1 = 1
|
||
else
|
||
self.NoFreq = 0
|
||
self.F6 = 0
|
||
self.F5 = 0
|
||
self.F4 = 0
|
||
self.F3 = 0
|
||
self.F2 = 0
|
||
self.F1 = 0
|
||
end
|
||
Train:SetNW2Float("PAM:State",self.ChangeTimer and -10 or self.State)
|
||
Train:SetNW2Float("PAM:Brightness",self.Brightness)
|
||
if self.StartTimer then Train:SetNW2Float("PAM:StartTimer",CurTime()-self.StartTimer) end
|
||
|
||
--if self.WorkTimer and CurTime()- self.WorkTimer < 0.1 then return end
|
||
--self.WorkTimer = CurTime() --CHECK
|
||
local Ring = false
|
||
if self.State <= 0 then
|
||
self["2"] = 0
|
||
self["3"] = 0
|
||
self["8"] = 0
|
||
self["17"] = 0
|
||
self["19"] = 0
|
||
self["20"] = 0
|
||
self["20X"] = 0
|
||
self["25"] = 0
|
||
self["025"] = 0
|
||
self["33"] = 0
|
||
self["033"] = 0
|
||
self["33G"] = 0
|
||
self["16"] = 0
|
||
self["31"] = 0
|
||
self["32"] = 0
|
||
self["68"] = 0
|
||
self["39"] = 0
|
||
self["7GA"] = 0
|
||
self["48"] = 0
|
||
self.EPK = 0
|
||
|
||
self.Ring = self.State==-0.5 and 1 or 0
|
||
self.Mode = 0
|
||
self.SensorEnabled = false
|
||
return
|
||
end
|
||
self.GoodSetup = not not Metrostroi.PAMConfTest
|
||
self.ReverserWrench = PAM_VV.KRR > 0
|
||
self.CurrentError = 0
|
||
|
||
if self.State == 1 or self.State == 1.5 then
|
||
Train:SetNW2Bool("PAM:GoodTest",true)
|
||
Train:SetNW2Bool("PAM:GoodSetup",self.GoodSetup)
|
||
Train:SetNW2Int("PAM:GoodBack",self.BackPA~=nil and (self.BackPA.state.Errors and -1 or 1) or 0 )
|
||
|
||
end
|
||
if self.State == 3 or self.State==5 and self.State5 == -5 then
|
||
Train:SetNW2String("PAM:RouteNumber",self.RouteNumberS)
|
||
Train:SetNW2String("PAM:DriverNumber",self.DriverNumberS)
|
||
end
|
||
if self.State == 3 or self.State == 3.5 or self.State==5 and self.State5 == 9 then
|
||
if self.StationS ~= "" then
|
||
local st = self:FindStation(self.LineS,self.PathS,self.StationS)
|
||
Train:SetNW2String("PAM:CurrentStationS",st and (st.name or st.id) or "")
|
||
else
|
||
Train:SetNW2String("PAM:CurrentStationS", "")
|
||
end
|
||
Train:SetNW2String("PAM:StationS",self.StationS)
|
||
Train:SetNW2String("PAM:LineS",self.LineS)
|
||
Train:SetNW2String("PAM:PathS",self.PathS)
|
||
end
|
||
if self.State < 4 then
|
||
self:SetDriveMode("OXT")
|
||
self:SetDoorMode("DO")
|
||
self:SetPneumoMode("NT")
|
||
self["7GA"] = 0
|
||
--[[ if PAM_VV.KB==0 then
|
||
self:SetPneumoMode("V2")
|
||
else
|
||
self:SetPneumoMode("NT")
|
||
end--]]
|
||
self.SensorEnabled = false
|
||
if (not self.ReverserWrench or not self.GoodSetup) and self.State >= 2 then
|
||
self:SetState(1,0.1)
|
||
end
|
||
else
|
||
self["7GA"] = PAM_VV.KSOT+PAM_VV.KB
|
||
if self.CheckRing and PAM_VV.KB > 0 then self.CheckRing = false end
|
||
end
|
||
if self.State == 4 then
|
||
self.SensorEnabled = false
|
||
Ring = self.CheckRing
|
||
|
||
self:SetDriveMode("OD")
|
||
self:SetPneumoMode("NT")
|
||
self:SetDoorMode("DO")
|
||
if RR then
|
||
self:SetDoorMode(PAM_VV.KDP>0 and "DP"or PAM_VV.KDL > 0 and "DL" or "DO")
|
||
if speed>0.2 then self.Stopping = true end
|
||
if speed<=0.2 and PAM_VV.KGR>0 and PAM_VV.KB>0 then self.Stopping = false end
|
||
if self.Stopping then
|
||
self:SetDriveMode("AT")
|
||
self:SetPneumoMode("V2")
|
||
end
|
||
end
|
||
else
|
||
self.Stopping = false
|
||
end
|
||
if self.State >= 5 then
|
||
self:Error(17,not RR and not BackActive)
|
||
self:Error(19,BackActive)
|
||
--Drive block after drive reset
|
||
if self.OldDriveModePriority>4 and PAM_VV.KGR==0 then
|
||
self:SetDriveMode("OXT")
|
||
else
|
||
self:SetDriveMode("OD")
|
||
end
|
||
self:SetDoorMode("DO")
|
||
|
||
if not RR and not BackActive then
|
||
self:SetPneumoMode("V1")
|
||
else
|
||
self:SetPneumoMode("NT")
|
||
end
|
||
|
||
|
||
local stationLast = ""
|
||
local station = ""
|
||
local signal = ""
|
||
local slope = 0
|
||
local dist = 1337
|
||
local opv = false
|
||
--Distance count
|
||
if not self.Distance and self.State == 5 then self.Distance = self.StationTable and self.StationTable.pos or 0 end
|
||
|
||
if self.Mode~=6 and self.Distance then
|
||
local pos = Metrostroi.TrainPositions[Train];pos = pos and pos[1]
|
||
local delta = speedMpS*dT
|
||
if pos and pos.path ~= self.OldPath then
|
||
self.OldPath = pos.path
|
||
self.OldPos = pos.x+Train.PosX
|
||
delta = speedMpS*dT
|
||
elseif pos then
|
||
local x = pos.x+Train.PosX
|
||
delta = (x-self.OldPos)*(Metrostroi.TrainDirections[Train] and 1 or -1)
|
||
self.OldPos = x
|
||
end
|
||
self.Distance = self.Distance + delta
|
||
end
|
||
if self.Mode == 1 or (0 < self.Mode and self.Mode < 6) and not self.StationTable then
|
||
stationLast = "выход на линию"
|
||
if self.StationTable then station = self.StationTable.name end
|
||
dist = 3072-self.Distance
|
||
elseif self.Mode == 2 or self.Mode == 3 then
|
||
local lasttbl = self.Deadlock or self.LastStationTable
|
||
if self.Mode == 3 and lasttbl and lasttbl.id==self.StationTable.id then
|
||
stationLast = "оборот"
|
||
else
|
||
stationLast = lasttbl and lasttbl.name_last or "?"
|
||
end
|
||
dist = self.StationTable.pos-self.Distance
|
||
station = self.StationTable.name
|
||
signal = self:FindNextSignal()
|
||
slope = self:FindNextSlope()
|
||
if self.PrevStationTable then
|
||
local dist = self.PrevStationTable.pos-self.Distance
|
||
local opvDist = self.PrevStationTable.isHorlift and 0.45 or 3
|
||
opv = -opvDist < dist and dist < opvDist
|
||
end
|
||
if not opv then
|
||
local opvDist = self.StationTable.isHorlift and 0.45 or 3
|
||
opv = -opvDist < dist and dist < opvDist
|
||
end
|
||
elseif self.Mode == 4 or self.Mode == 5 then
|
||
stationLast = "оборот"
|
||
station = self.StationTable.name
|
||
if self.Mode == 5 then
|
||
dist = 3072-self.Distance
|
||
opv = true
|
||
else
|
||
dist = self.StationTable.dist_last_end-self.Distance
|
||
local opvDist = self.StationTable.isHorlift and 0.45 or 3
|
||
opv = self.Distance > self.StationTable.dist_last_start
|
||
if not opv then
|
||
local dist = self.StationTable.pos-self.Distance
|
||
local opvDist = self.StationTable.isHorlift and 0.45 or 3
|
||
opv = -opvDist < dist and dist < opvDist
|
||
end
|
||
end
|
||
end
|
||
|
||
local OXT = false
|
||
if RR then
|
||
if (self.Mode~=2 and self.Mode~=3) or self.NextSensorDist and math.abs(self.Distance-self.NextSensorDist)<=20 or self.AlwaysSensor then
|
||
self.SensorEnabled =true
|
||
elseif self.SensorEnabled then
|
||
if self.Mode==2 and self.SensorError==nil then
|
||
self.SensorError = true
|
||
end
|
||
self.SensorEnabled = nil
|
||
end
|
||
|
||
if self.State~=6 and ((self.Mode==2 or self.Mode==3) and (dist < -3 and (self.Transit or not self.AntiMiss)) or self.OpenControl == false and speed > 0.2 or self.Mode == 4 and dist<0) then
|
||
local oldSt = self.StationTable
|
||
if not self.Shunt then self.StationTable,self.PrevStationTable = self:FindNextStation() end
|
||
|
||
if self.Mode == 4 and dist<0 then
|
||
self.Mode = 5
|
||
|
||
self.StationTable = oldSt
|
||
elseif self.StationTable then
|
||
if self.Shunt then
|
||
self:SetMode(6)
|
||
elseif self.Deadlock and oldSt.id == self.Deadlock.id then
|
||
self.Mode=4
|
||
|
||
self.StationTable=self.Deadlock
|
||
self.Deadlock = nil
|
||
elseif self.Mode == 3 then
|
||
self:SetMode(2)
|
||
end
|
||
elseif oldSt and oldSt.isLast and oldSt.dist_last_end then
|
||
self.Mode = 4
|
||
self.StationTable = oldSt
|
||
else
|
||
self.Station = self:FindFirstStation()
|
||
self:SetMode(1)
|
||
end
|
||
self.Station = self.StationTable.id
|
||
self.OpenControl = nil
|
||
end
|
||
|
||
if self.Mode==2 and dist<=200 then
|
||
local line = self.Line
|
||
local path = tonumber(self.Path)
|
||
local tbl = Metrostroi.PAMConfTest and Metrostroi.PAMConfTest[line] and Metrostroi.PAMConfTest[line][path]
|
||
if self.StationBrakeRing==nil and tbl and tbl[1].sensors[self.StationTable.linkedSensor] and tbl[1].sensors[self.StationTable.linkedSensor]<self.Distance then
|
||
self.StationBrakeRing = PAM_VV.KRT==0 and PAM_VV.KET==0 and CurTime()
|
||
elseif self.StationBrakeRing and CurTime()-self.StationBrakeRing>0.2 then self.StationBrakeRing = false end
|
||
elseif self.StationBrakeRing==false or self.StationBrakeRing and CurTime()-self.StationBrakeRing > 0.5 then
|
||
self.StationBrakeRing = nil
|
||
end
|
||
local CanOpen = not self.CloseDoors and PAM_VV.KRH==0 and (PAM_VV.LPT > 0 or self.NoLPT and PAM_VV.V1>0)
|
||
if ((opv or self.Mode==5) and speed < 0.5 or (self.OpenDoors and speed < 2.5 or not self.GoodSetup)) and CanOpen then
|
||
self:SetDoorMode((not self.OpenControl and (PAM_VV.ZD>0 or self.DoorMode=="ZD")) and "ZD" or "DO")
|
||
local err
|
||
if (self.Mode > 3 or self.OpenDoors or not self.GoodSetup) then
|
||
local Open = PAM_VV.KDL > 0 or PAM_VV.KDP > 0
|
||
if Open and PAM_VV.ZD == 0 then
|
||
self:SetDoorMode(PAM_VV.KDP > 0 and "DP"or "DL")
|
||
if not self.OpenControl then self.OpenControl = CurTime() end
|
||
if not self.OpeningTimer and PAM_VV.KD>0 then self.OpeningTimer = CurTime() end
|
||
end
|
||
if Open and PAM_VV.ZD>0 and not self.OpenTimer then
|
||
self.OpenTimer = CurTime()
|
||
elseif (not Open or PAM_VV.ZD==0) and self.OpenTimer then
|
||
self.OpenTimer = nil
|
||
end
|
||
--TODO: При открытии контроль 16 провода, через 0.7с при наличии 16 провода сообщение "Разблокируйте двери"
|
||
--TODO: При нажатии на кнопку>2.5с и не пропадании КД подсказка "Нет контроля открытия дверей
|
||
elseif self.Mode<=3 then
|
||
local stationTable = dist>10 and self.PrevStationTable or self.StationTable
|
||
local Open = PAM_VV.KDL > 0 or PAM_VV.KDP > 0 or PAM_VV.OPD > 0
|
||
local CanOpen = not self.Transit and (PAM_VV.KDL > 0 and not stationTable.rightDoors or (PAM_VV.KDP > 0 or PAM_VV.OPD > 0) and stationTable.rightDoors)
|
||
if PAM_VV.ZD==0 and CanOpen then
|
||
self:SetDoorMode(stationTable.rightDoors and (PAM_VV.OPD > 0 and "DB" or "DP")or "DL")
|
||
if opv and (stationTable==self.StationTable or self.FireBack) then
|
||
self:SetMode(3)
|
||
end
|
||
if not self.OpenControl then self.OpenControl = CurTime() end
|
||
if not self.OpeningTimer and PAM_VV.KD>0 then self.OpeningTimer = CurTime() end
|
||
else
|
||
self.OpeningTimer = false
|
||
self:Error(1,Open and not CanOpen and not self.Transit and stationTable.rightDoors and PAM_VV.OPD == 0)
|
||
self:Error(2,Open and not CanOpen and not self.Transit and not stationTable.rightDoors and PAM_VV.OPD == 0)
|
||
self:Error(23,Open and not CanOpen and self.Transit)
|
||
end
|
||
if CanOpen and PAM_VV.ZD>0 and not self.OpenTimer then
|
||
self.OpenTimer = CurTime()
|
||
elseif (not CanOpen or PAM_VV.ZD==0) and self.OpenTimer then
|
||
self.OpenTimer = nil
|
||
end
|
||
--TODO: При открытии контроль 16 провода, через 0.7с при наличии 16 провода сообщение "Разблокируйте двери"
|
||
--TODO: При нажатии на кнопку>2.5с и не пропадании КД подсказка "Нет контроля открытия дверей
|
||
end
|
||
if self.OpeningTimer and (CurTime()-self.OpeningTimer>2.7 and PAM_VV.KD==0 or not RR) then self.OpeningTimer = false end
|
||
self:Error(4,self.OpeningTimer and CurTime()-self.OpeningTimer>2.7)
|
||
--TODO: Для режима "3" на станции закрытого типа сообщение "Откройте двери станции" при отсутствии КД(контроллируемом) и наличии частоты
|
||
-- Отмена сообщения на КБ либо появлении 0(с отменой ходового режима)
|
||
else
|
||
if not CanOpen or PAM_VV.ZD>0 or self.DoorMode=="ZD" then self:SetDoorMode("ZD") end
|
||
self.OpenDoors = false
|
||
self.OpenTimer = false
|
||
self.OpeningTimer = false
|
||
end
|
||
if self.CloseDoors then
|
||
if self.DoorMode=="ZD" then self.CloseDoors = false end
|
||
self:SetDoorMode("ZD")
|
||
end
|
||
|
||
if self.OpenControl and self.Mode==3 and self.StationTable.isHorlift and self.SpeedLimit~=0 then
|
||
if not self.StationDoorsTimer then self.StationDoorsTimer = CurTime() end
|
||
if PAM_VV.KB>0 and self.StationDoorsTimer~=true and self.StationDoorsTimer>2.5 then self.StationDoorsTimer = true end
|
||
else
|
||
self.StationDoorsTimer = nil
|
||
end
|
||
--self:Error(10,self.KDTimer and not self.OpenControl,7,true)
|
||
self:Error(5,self.KDTimer and not self.OpenControl)
|
||
self:Error(27,self.StationDoorsTimer and self.StationDoorsTimer~=true and CurTime()-self.StationDoorsTimer>2.5)
|
||
|
||
self:Error(7,self.OpenTimer and CurTime()-self.OpenTimer>0.7)
|
||
self:Error(9,self.SensorError and PAM_VV.ZD==0 and (PAM_VV.KDL>0 or PAM_VV.KDP>0))
|
||
if PAM_VV.KDL>0 or PAM_VV.KDP>0 then
|
||
if not self.KDLPTimer then self.KDLPTimer = CurTime() end
|
||
elseif self.KDLPTimer then self.KDLPTimer = nil end
|
||
self:Error(22,self.KDLPTimer and CurTime()-self.KDLPTimer>10)
|
||
|
||
--Disable NoKD if we got KD
|
||
if self.NoKD and PAM_VV.KD>0 and not self.KDOnTime then self.KDOnTime = CurTime() end
|
||
if self.NoKD or PAM_VV.KSZD>0 then self:SetDoorMode("ZD") end
|
||
if self.KDOnTime and PAM_VV.KD>0 and CurTime()-self.KDOnTime>5 then self.KDOnTime = false self.NoKD = false end
|
||
if self.KDOnTime and PAM_VV.KD==0 then self.KDOnTime = false end
|
||
if PAM_VV.KRU>0 and PAM_VV.ZD==0 then self:SetPneumoMode("V2") end
|
||
|
||
--Movement block by 64tw
|
||
if PAM_VV.I33*PAM_VV.LPT>0 and not self.NoLPT then
|
||
if not self.LPTTimer then self.LPTTimer = CurTime() end
|
||
elseif self.LPTTimer and (PAM_VV.KGR>0 or self.NoLPT or CurTime()-self.LPTTimer<=6.5) then
|
||
self.LPTTimer = nil
|
||
end
|
||
self:Error(10,self.LPTTimer and CurTime()-self.LPTTimer > 6.5)
|
||
|
||
|
||
local speedLimit = math.max(21,self.SpeedLimit+1)
|
||
--[[if self.SpeedLimit == -1 and (self.Mode == 1 or self.Mode == 5) then
|
||
speedLimit = 16
|
||
else]]if self.ControlMode == 1 then
|
||
speedLimit = (self.SpeedLimit > 40 and 36 or 21)*PAM_VV.KB
|
||
elseif PAM_VV.KB>0 then
|
||
speedLimit=21
|
||
elseif self.Mode==6 then
|
||
speedLimit = math.min(41,speedLimit)
|
||
end
|
||
--KS Mode
|
||
if self.SpeedLimit <= 20 then
|
||
if not self.ZeroStopped and speed <= 0.2 then
|
||
self.ZeroStopped = true
|
||
end
|
||
local station = (self.Mode==1 or self.Mode==2) and dist<=100
|
||
if self.ZeroStopped == nil and speed > 0.2 then
|
||
self.ZeroStopped = self.Mode>3 or station and not self.Transit
|
||
end
|
||
if self.ZeroStopped and PAM_VV.KB == 0 or self.SpeedLimit~=-1 and ((ALS.F6==0 and not station or self.Transit) and not self.Vd0) then
|
||
self:SetDriveMode("OXT")
|
||
OXT = true
|
||
speedLimit=0
|
||
end
|
||
if not self.ZeroStopped or speed > 0.2 and PAM_VV.KB == 0 then speedLimit = 0 end
|
||
if self.SpeedLimit~=-1 then
|
||
if not self.ZeroTimer then self.ZeroTimer = CurTime() end
|
||
else
|
||
self.ZeroTimer = nil
|
||
end
|
||
self:Error(12,self.SpeedLimit==0 and PAM_VV.KGR==0 and OXT and PAM_VV.KB>0)
|
||
self:Error(15,self.ZeroTimer and CurTime()-self.ZeroTimer>30,7,true)
|
||
else
|
||
self.ZeroStopped = nil
|
||
self.ZeroTimer = nil
|
||
end
|
||
|
||
self:Error(26,self.ControlMode==1 and PAM_VV.KB==0 and PAM_VV.KGR==0)
|
||
|
||
if self.SpeedLimit>20 or self.SpeedLimit == -1 then self.Vd0 = false end
|
||
if not self.PAKSD and self.SpeedLimit==20 and PAM_VV.VRD>0 then self.Vd0 = true end
|
||
|
||
local speedLimitMpS = speedLimit/3600*1000
|
||
local timeAdd = (1-PAM_VV.I33G*1+PAM_VV.I33*1)
|
||
|
||
self.Acceleration = self.Acceleration+(accel-self.Acceleration)*dT*1
|
||
if speedMpS+self.Acceleration*timeAdd > speedLimitMpS and speed>0.2 or self.STTimer then
|
||
local ST,AT = false,false
|
||
if not self.OXTTimer then self.OXTTimer = CurTime() end
|
||
if speed > speedLimit or self.OXTTimer and CurTime()-self.OXTTimer > 1.5 then
|
||
ST = true
|
||
if not self.STTimer then
|
||
self.STTimer = CurTime()
|
||
self.RingArmed = PAM_VV.KRT==0 and CurTime()
|
||
self.STV1Timer = PAM_VV.KRT==0 and CurTime()
|
||
end
|
||
end
|
||
if speed > speedLimit or self.STTimer and CurTime()-self.STTimer > 1 then
|
||
AT = true
|
||
end
|
||
if self.STV1Timer and CurTime()-self.STV1Timer < 0.7 then self:SetPneumoMode("V1") end
|
||
if AT then
|
||
self:SetDriveMode("AT")
|
||
elseif ST then
|
||
self:SetDriveMode("ST")
|
||
else
|
||
self:SetDriveMode("OXT")
|
||
end
|
||
if speed < speedLimit-2 and not self.RingArmed then self.STTimer = false end
|
||
|
||
if (AT or ST) and (accel>-0.7 and PAM_VV.KET == 0) then
|
||
if not self.EKTimer then self.EKTimer = CurTime() end
|
||
elseif self.EKTimer then
|
||
self.EKTimer = false
|
||
end
|
||
if self.EKTimer and CurTime()-self.EKTimer > ((10<speed and speed<30) and 5.5 or 3.3) then self.EPKActive=false end
|
||
OXT = true
|
||
else
|
||
self.STTimer = false
|
||
self.OXTTimer = false
|
||
self.STV1Timer = nil
|
||
self.EKTimer = false
|
||
end
|
||
|
||
if not self.RollingCheckRolled and (speed < 2.5 or self.Stopped) and PAM_VV.KRH == 0 and (self.NoFreq==0 or PAM_VV.KB==0) then
|
||
self:SetPneumoMode("V1")
|
||
if not self.V1Stop and PAM_VV.KET==0 then self.V1Stop = CurTime() end
|
||
if PAM_VV.KET>0 and self.V1Stop then
|
||
if not self.V1StopTimer then self.V1StopTimer = CurTime() end
|
||
if self.V1StopTimer and CurTime()-self.V1StopTimer>1 then
|
||
self.V1StopTimer = nil
|
||
self.V1Stop = nil
|
||
end
|
||
end
|
||
if not self.Stopped then self.Stopped = true end
|
||
if self.Stopped and speed>5.5 then
|
||
self.Stopped = 1
|
||
end
|
||
if self.Stopped==1 then self:SetPneumoMode("V2") end
|
||
self.Starting = (speed>0.2 or PAM_VV.KRH>0 or PAM_VV.KGR==0) and self.Starting
|
||
elseif not self.RollingCheckRolled then
|
||
if self.Stopped then
|
||
self.Stopped = false
|
||
self.Starting = self.NoFreq==0 and CurTime()
|
||
end
|
||
if self.Starting and CurTime()-self.Starting<4.5 and speed>0.5 then self.Starting = nil end
|
||
end
|
||
|
||
if self.Starting and CurTime()-self.Starting>=4.5 then self:SetDriveMode("AT") end
|
||
if not self.Stopped then self.V1Stop = nil end
|
||
self:Error(13,self.Starting and CurTime()-self.Starting>=4.5)
|
||
|
||
if speedMpSSigned < -0.01 and not self.Rolling and not self.FireBack and self.GoodSetup then self.Rolling = 0 end
|
||
if self.Rolling and self.Rolling < 0 then self.Rolling = false end
|
||
if self.Rolling then
|
||
local rolled = -speedMpSSigned*dT
|
||
if math.abs(rolled) >0.001 then
|
||
self.Rolling = self.Rolling + rolled
|
||
end
|
||
end
|
||
if not self.Rolled and self.Rolling and self.Rolling > 0.5+PAM_VV.KRH*2.5 then
|
||
self.Rolled = PAM_VV.KRH
|
||
end
|
||
if self.Rolled then
|
||
if self.Rolled>0 then
|
||
self:SetDriveMode("OXT")
|
||
end
|
||
if self.Rolled == 0 and PAM_VV.KRH > 0 then
|
||
self.Rolled = false
|
||
self.Rolling = false
|
||
end
|
||
if PAM_VV.KRH == 0 then self.Rolled = 0 end
|
||
self:SetPneumoMode("V2")
|
||
end
|
||
|
||
if self.Transit and self.Mode == 2 then
|
||
local lasttbl = self.Deadlock or self.LastStationTable
|
||
local last = lasttbl and lasttbl.id==self.StationTable.id
|
||
if last and (dist-10) < (speedMpS^2-3.8*speedMpS)/2.2 and speed>14 or not last and (dist-10)<(speedMpS^2-8.3*speedMpS)/2.2 and speed>30 then
|
||
self.TransitBraking = last and 10 or 30
|
||
end
|
||
if self.TransitBraking and speed>self.TransitBraking and dist<120 then
|
||
self:SetDriveMode("AT")
|
||
elseif self.TransitBraking then
|
||
self.TransitBraking = false
|
||
end
|
||
end
|
||
--[[ if (self.Mode==2 or self.Mode==3) then
|
||
if self.AntiMiss == nil then
|
||
local SchemeEngageDistance,_ACCEL,_ACCEL2
|
||
local currA = -math.min(0,Train.Acceleration)
|
||
_ACCEL = 1.61
|
||
_ACCEL2 = _ACCEL*2
|
||
local _SCHTime
|
||
if PAM_VV.KRT>0 then
|
||
--local speed = 45
|
||
--local speedMpS = speed/3600*1000
|
||
_SCHTime = (
|
||
(
|
||
math.Clamp(((18-PAM_VV.KPRK)/17)^1.5*(55-(speed-5))/55,0,1)^1.1
|
||
f )*2.2-math.Clamp(PAM_VV.KPRK-14,0,4)/4*3.3*math.Clamp((16-(speed-3))/16,0,1)^2.2
|
||
)*math.Clamp((0.5-currA),0,1)
|
||
--_SCHTime = ((math.Clamp((PAM_VV.KPRK-1)/17*(55-(10-5))/55,0,1)^1.1)*2.2-math.Clamp(PAM_VV.KPRK-12,0,6)/6*3-3.5*math.Clamp((16-(10-3))/16,0,1)^2.2)*math.Clamp((0.8-currA)/0.8,0.2,1)
|
||
SchemeEngageDistance = speedMpS*_SCHTime+(_ACCEL*(_SCHTime^2))/2-(2.0)*math.Clamp((7-(speed-3))/7,0,1)
|
||
else
|
||
_SCHTime = ((math.Clamp((55-(speed-5))/55,0,1)^1.2)*1.85+1-3.5*math.Clamp((16-(speed-3))/16,0,1)^1.7)*math.Clamp((_ACCEL-currA)/_ACCEL,0,1)
|
||
SchemeEngageDistance = speedMpS*_SCHTime+(_ACCEL*(_SCHTime^2))/2
|
||
end
|
||
--SchemeEngageDistance = speedMS*_SCHTime+(_ACCEL*(_SCHTime^2))/2
|
||
if not self.Transit and speed>0.2 and (dist-SchemeEngageDistance) < (speedMpS^2)/_ACCEL2 and not self.AntiMiss then
|
||
self.AntiMiss = opv and 2 or 1
|
||
print("ENGAGED "..dist)
|
||
elseif self.Transit then
|
||
local lasttbl = self.Deadlock or self.LastStationTable
|
||
local last = (lasttbl and lasttbl.id==self.StationTable.id) and 10 or 30
|
||
if (dist-SchemeEngageDistance) < (speedMpS^2-(last/3600*1000)*speedMpS)/_ACCEL2 and not self.AntiMiss then
|
||
self.AntiMiss = opv and 2 or 1
|
||
print("ENGAGED "..dist)
|
||
end
|
||
end
|
||
end--]]
|
||
if (opv or dist<0) and speed<=0.2 then
|
||
self.AntiMissStation = true
|
||
elseif dist>0 and not opv then
|
||
self.AntiMissStation = false
|
||
end
|
||
if not self.Transit and (self.Mode==2 or self.Mode==3) and not BackReverser then
|
||
if self.AntiMiss == nil or self.AntiMiss==1 then
|
||
local SchemeEngageDistance,_ACCEL,_ACCEL2
|
||
local currA = -math.min(0,Train.Acceleration)
|
||
_ACCEL = 1.61
|
||
_ACCEL2 = _ACCEL*2
|
||
local _SCHTime
|
||
if PAM_VV.KRT>0 or PAM_VV.LPT>0 or speed<6 then
|
||
--local speed = 45
|
||
--local speedMpS = speed/3600*1000
|
||
_SCHTime = (
|
||
(
|
||
math.Clamp(((18-PAM_VV.KPRK)/17)^1.5*(55-(speed-5))/55,0,1)^1.1
|
||
)*2.2-math.Clamp(PAM_VV.KPRK-14,0,4)/4*3.3*math.Clamp((16-(speed-3))/16,0,1)^2.2
|
||
)*math.Clamp((0.5-currA),0,1)
|
||
--_SCHTime = ((math.Clamp((PAM_VV.KPRK-1)/17*(55-(10-5))/55,0,1)^1.1)*2.2-math.Clamp(PAM_VV.KPRK-12,0,6)/6*3-3.5*math.Clamp((16-(10-3))/16,0,1)^2.2)*math.Clamp((0.8-currA)/0.8,0.2,1)
|
||
SchemeEngageDistance = speedMpS*_SCHTime+(_ACCEL*(_SCHTime^2))/2-(2.0)*math.Clamp((7-(speed-3))/7,0,1)
|
||
|
||
if dist<20 and speed<23 then
|
||
SchemeEngageDistance = SchemeEngageDistance-math.Clamp((dist-3)/17,0,1)*2
|
||
end
|
||
else
|
||
_SCHTime = ((math.Clamp((55-(speed-5))/55,0,1)^1.2)*1.85+1-3.5*math.Clamp((16-(speed-3))/16,0,1)^1.7)*math.Clamp((_ACCEL-currA)/_ACCEL,0,1)
|
||
SchemeEngageDistance = speedMpS*_SCHTime+(_ACCEL*(_SCHTime^2))/2
|
||
end
|
||
--SchemeEngageDistance = speedMS*_SCHTime+(_ACCEL*(_SCHTime^2))/2
|
||
local badAccel = (dist-SchemeEngageDistance) < (speedMpS^2)/_ACCEL2
|
||
if speed>0.2 and badAccel and self.AntiMiss==nil then
|
||
self.AntiMiss = self.AntiMissStation and 2 or 1
|
||
self.AntiMissBlock = CurTime()
|
||
end
|
||
if self.AntiMiss and not badAccel and CurTime()-self.AntiMissBlock>0.8 and PAM_VV.KB>0 then
|
||
self.AntiMiss = nil
|
||
end
|
||
end
|
||
if self.AntiMiss then
|
||
self:SetDriveMode("AT")
|
||
self:SetPneumoMode("V1")
|
||
if speed<6 then
|
||
self:SetPneumoMode("V2")
|
||
end
|
||
if speed < 0.2 and ((self.AntiMiss==2 or -3<=dist) and PAM_VV.KB>0 or self.AntiMiss==1) then
|
||
self.AntiMiss = self.AntiMiss==1 and nil
|
||
end
|
||
end
|
||
if self.AntiMiss==false and self.Mode==2 and dist > 150 then self.AntiMiss = nil end
|
||
elseif self.AntiMiss then
|
||
self.AntiMiss = nil
|
||
end
|
||
else
|
||
self.LPTTimer = nil
|
||
|
||
self.StationBrakeRing = nil
|
||
self.SensorEnabled = nil
|
||
|
||
self.OpenTimer = false
|
||
self.OpeningTimer = false
|
||
|
||
self.KDTimer = nil
|
||
self.OpenDoors = false
|
||
|
||
self.StationDoorsTimer = nil
|
||
|
||
self.ZeroStopped = nil
|
||
self.ZeroTimer = nil
|
||
|
||
self.STTimer = false
|
||
self.OXTTimer = false
|
||
self.STV1Timer = nil
|
||
|
||
self.Starting = nil
|
||
self.Stopped = false
|
||
self.Rolled = false
|
||
self.Rolling = false
|
||
if self.AntiMiss then self.AntiMiss = nil end
|
||
end
|
||
|
||
if (self.OpenControl~=true or PAM_VV.K16>0) and PAM_VV.KD==0 then
|
||
if not self.KDTimer then self.KDTimer = CurTime() end
|
||
if self.KDTimer and CurTime()-self.KDTimer>5 then self.OpenControl = false end
|
||
else
|
||
self.KDTimer = nil
|
||
end
|
||
if self.OpenControl and self.OpenControl~=true and PAM_VV.KD > 0 then self.OpenControl = CurTime() end
|
||
if self.OpenControl==true and PAM_VV.KD > 0 then self.OpenControl = false end
|
||
if self.OpenControl and self.OpenControl ~= true and CurTime()-self.OpenControl > 1 then self.OpenControl = true end
|
||
|
||
Train:SetNW2Int("PAM:Mode",self.Mode)
|
||
self:Error(8,self.State==5 and RR and (self.AntiMiss==2 or dist<-3 and self.AntiMiss))
|
||
Train:SetNW2Bool("PAM:Shunt",self.Shunt)
|
||
-- DO: Движение по станционным путям
|
||
-- Включается на станциях с путевым развитием при фактической скорости 0 или нахождении в зоне ОПВ
|
||
-- Автоматически вводится после передачи управления при отсутствии связи между головой и хвостом
|
||
-- Не контролирует пройденный путь и отменяется при фиксации
|
||
-- Разрешает движение со скоростью не более 40, а при ограничении 20 не делает предварительную остановку
|
||
|
||
--TODO: Смена линии
|
||
-- Возможно назначить в любой момент до отправления со станции с передаточной ветвью
|
||
-- Видны все станции по ходу движения, имеющие передаточную ветвь
|
||
-- Автмоатическая фиксация станции
|
||
-- При ограничении 20 не делает предварительную остановку
|
||
|
||
-- DO: Транзит
|
||
-- Ограничение скорости проезда ОПВ 29км\\ч и 10 на конечных
|
||
-- При запрещающем показании светофора у выходных светофоров торможенеи до полной остановки
|
||
|
||
--Block door open without all conditions
|
||
-- DO: При наличии 16 провода и отсутвии 15го в течении 5 секунд подсказка "Нет контроля закрытия дверей"
|
||
|
||
|
||
--if PAM_VV.K16>0 and PAM_VV.KD==0 and not self.KDTimer then self.KDTimer = CurTime() end
|
||
--if (PAM_VV.K16==0 or PAM_VV.KD>0) and self.KDTimer then self.KDTimer = nil end
|
||
|
||
--Get controller state
|
||
local driveModeKV = 0
|
||
if PAM_VV.KGR == 0 then
|
||
driveModeKV = 1+PAM_VV.I2+PAM_VV.I3
|
||
elseif PAM_VV.I33G > 0 then
|
||
driveModeKV = -2-PAM_VV.I2*2+PAM_VV.I25
|
||
end
|
||
|
||
--Fire rolling back logic
|
||
if self.FireBack then
|
||
local opvDist = self.FireBack.isHorlift and -0.45 or -1
|
||
if self.FireBack.pos-self.Distance>opvDist then
|
||
self.StationTable=self.FireBack
|
||
self:SetDriveMode("OXT")
|
||
self:SetPneumoMode("V1")
|
||
if speed>5.4 then self:SetPneumoMode("V2") end
|
||
if speed<0.2 then self.FireBack = false end
|
||
end
|
||
end
|
||
|
||
local No34 = self.V1Stop and CurTime()-self.V1Stop > 4
|
||
self.ControlMode2 = (PAM_VV.KVARS > 0 or self.PAKSD) and not No34 and PAM_VV.KSOT > 0
|
||
local mode = self.ControlMode2 and 2 or 1
|
||
|
||
if self.ControlMode~=mode and (mode==1 or self.ControlModeAuto) then
|
||
self.ControlMode = mode
|
||
self.ControlModeAuto = true
|
||
end
|
||
if RR then
|
||
self:Error(20,self.ControlModeAuto and self.ControlMode==1,No34 and 14 or 7,true)
|
||
self:Error(21,self.ControlModeAuto and self.ControlMode==2,7,true)
|
||
self:Error(29,No34,7,true)
|
||
self:Error(30,self.No34 and not No34,7,true)
|
||
self.No34 = No34
|
||
end
|
||
|
||
self:Error(24,false,7,true)
|
||
|
||
local BlockBack = self.State==6 and self.GoodSetup or not self.FireBack and self.Mode>2 and (not self.StationTable.isHorlift or dist > -.45 or dist < -6 or speed>=3.6)
|
||
if (driveModeKV>=0 or PAM_VV.KRU > 0) and (
|
||
--TODO аппаратура отменяет ходвоой режим и назначает ВЗ№1 при подезде к рейке
|
||
not RR or
|
||
BackReverser and BlockBack
|
||
or self.FireBack and speed>10
|
||
or self.LPTTimer and CurTime()-self.LPTTimer>6.5
|
||
or self.ControlMode==1 and PAM_VV.KB==0
|
||
or PAM_VV.KD < 1 and not self.NoKD and PAM_VV.KRU == 0
|
||
or PAM_VV.KTARS > 0) then
|
||
self:SetDriveMode("OXT")
|
||
end
|
||
self:Error(3,BackReverser and BlockBack and not BackActive)
|
||
|
||
--Rolling check
|
||
if self.State5==1 then
|
||
if not self.RollingCheckRolled then self.RollingCheckRolled = 0 end
|
||
local rolled = speedMpSSigned*dT
|
||
if math.abs(rolled) >0.001 then
|
||
self.RollingCheckRolled = self.RollingCheckRolled + rolled
|
||
Train:SetNW2Float("PAM:RollDist",self.RollingCheckRolled)
|
||
end
|
||
if self.RollingCheckRolled > 2.5 or self.RollingCheckRolled < -0.3 then
|
||
self.Stopped = true
|
||
self.RollingCheckRolled = false
|
||
self.State5 = nil
|
||
Train:SetNW2Float("PAM:RollDist",0)
|
||
end
|
||
if self.NoFreq>0 and PAM_VV.KB==0 then
|
||
self:SetPneumoMode("V2")
|
||
end
|
||
else
|
||
self.RollingCheckRolled = false
|
||
end
|
||
|
||
--if RR and self.ControlMode==1 and PAM_VV.KB==0 then self:SetPneumoMode("V2") end
|
||
if self.PneumoMode == "V1" or self.PneumoMode == "V12" then
|
||
if PAM_VV.V1==0 and not self.V1Timer then self.V1Timer = CurTime() end
|
||
if PAM_VV.V1>0 then
|
||
if self.V1Timer then self.V1Timer = nil end
|
||
if PAM_VV.LPT==0 and not self.V1ETimer then self.V1ETimer = CurTime() end
|
||
if PAM_VV.LPT>0 and PAM_VV.V2==0 and self.V1ETimer then self.V1ETimer = nil end
|
||
end
|
||
else
|
||
self.V1Timer = nil
|
||
self.V1ETimer = nil
|
||
end
|
||
if self.V1Timer and CurTime()-self.V1Timer > 2 then self:SetPneumoMode("V2") end
|
||
if self.V1ETimer and CurTime()-self.V1ETimer > 2.5 then self:SetPneumoMode("V2") end
|
||
|
||
if self.PneumoMode == "V2" or self.PneumoMode == "V12" then
|
||
if PAM_VV.V2==0 and not self.V2Timer then self.V2ETimer = CurTime() end
|
||
if PAM_VV.V2>0 then
|
||
if self.V2Timer then self.V2Timer = nil end
|
||
if PAM_VV.LPT==0 and not self.V2ETimer then self.V2ETimer = CurTime() end
|
||
if PAM_VV.LPT>0 and self.V2ETimer then self.V2ETimer = nil end
|
||
end
|
||
else
|
||
self.V2Timer = nil
|
||
self.V2ETimer = nil
|
||
end
|
||
if speed<2.5 and (PAM_VV.KB > 0 or not RR) then self.EPKActive = true end
|
||
if self.RingArmed and CurTime()-self.RingArmed>3 then self.EPKActive = false end
|
||
if self.V2ETimer and CurTime()-self.V2ETimer>2 then self.EPKActive = false end
|
||
|
||
if self.Mode==3 then
|
||
if self.BoardRing==nil and Train.BoardTimer and Train.BoardTimer<-2 and PAM_VV.KD==0 then self.BoardRing = CurTime() end
|
||
if self.BoardRing and (PAM_VV.KB>0 or PAM_VV.KD>0 or CurTime()-self.BoardRing>2) then self.BoardRing = false end
|
||
else
|
||
self.BoardRing = nil
|
||
end
|
||
|
||
if self.RingArmed and PAM_VV.KB > 0 then self.RingArmed = false end
|
||
if self.CurrentErrorR ~= self.CurrentError then
|
||
self.CurrentErrorR = self.CurrentError
|
||
self.CurrentErrorRing = errorsRing[self.CurrentError]==false and CurTime()
|
||
end
|
||
Ring = self.RingArmed or self.BoardRing or self.StationBrakeRing or errorsRing[self.CurrentError] or self.CurrentErrorRing and CurTime()-self.CurrentErrorRing<1.5 or self.CheckRing
|
||
Train:SetNW2Int("PAM:DriveMode",self.ControlMode+PAM_VV.KRU*3)
|
||
local driveMode = self.DriveModesConv[self.DriveMode]
|
||
Train:SetNW2Int("PAM:KVMode",driveMode>0 and math.max(driveMode,driveModeKV) or driveMode<0 and math.min(driveMode,driveModeKV) or driveModeKV)
|
||
Train:SetNW2String("PAM:CurrentStation",station)
|
||
Train:SetNW2String("PAM:TargetStation",stationLast)
|
||
Train:SetNW2Int("PAM:BoardTime",Train.BoardTimer or 0)
|
||
Train:SetNW2Int("PAM:CurrentError",self.CurrentError or 0)
|
||
|
||
if self.MessageTimer and CurTime()-self.MessageTimer > 4 then
|
||
self.CurrentMessage = 0
|
||
self.MessageTimer = false
|
||
end
|
||
Train:SetNW2Int("PAM:CurrentMessage",self.CurrentMessage or 0)
|
||
|
||
Train:SetNW2Bool("PAM:OXT",OXT)
|
||
Train:SetNW2Int("PAM:Vf",speed)
|
||
Train:SetNW2Int("PAM:SpeedLimit",self.SpeedLimit)
|
||
Train:SetNW2String("PAM:RC",signal)
|
||
Train:SetNW2Int("PAM:Slope",slope)
|
||
Train:SetNW2Float("PAM:S",dist)
|
||
Train:SetNW2Int("PAM:V",not self.EPKActive and -1 or PAM_VV.V2 > 0 and 2 or PAM_VV.V1 > 0 and (false and 2 or 1) or 0)
|
||
Train:SetNW2Bool("PAM:LPT",PAM_VV.LPT > 0)
|
||
Train:SetNW2Bool("PAM:KD",self.OpenControl==true and 1 or PAM_VV.KD <= 0 and 2 or 0)
|
||
Train:SetNW2Bool("PAM:KVARS",PAM_VV.KVARS > 0)
|
||
Train:SetNW2Bool("PAM:VRD",PAM_VV.VRD > 0)
|
||
Train:SetNW2Bool("PAM:OPV",opv)
|
||
Train:SetNW2Bool("PAM:State5_-6",not not self.FireBack) --Vд=0
|
||
Train:SetNW2Bool("PAM:State5_5",self.Vd0) --Vд=0
|
||
Train:SetNW2Bool("PAM:State5_2",self.NoKD) --КД
|
||
Train:SetNW2Bool("PAM:State5_4",self.Transit) --ТР
|
||
Train:SetNW2Bool("PAM:State5_8",not not self.Deadlock) --ОБ
|
||
--Train:SetNW2Bool("PAM:State5_3") --СЛ
|
||
Train:SetNW2Bool("PAM:State5_7",self.NoLPT) --ЛПТ
|
||
Train:SetNW2Bool("PAM:State5_6",self.OpenDoors) --ОДП
|
||
end
|
||
if self.CurrentDriveMode then
|
||
self["2"] = self.CurrentDriveMode[2]
|
||
self["3"] = self.CurrentDriveMode[3]
|
||
local pr8 = self.CurrentDriveMode[4]
|
||
if pr8 ~= self.Target8 then
|
||
if pr8 == 0 or self.pr8Timer and CurTime()-self.pr8Timer > 1.5 then
|
||
self.Target8 = pr8
|
||
self.pr8Timer = nil
|
||
end
|
||
if pr8 > 0 and not self.pr8Timer then self.pr8Timer = CurTime() end
|
||
end
|
||
if pr8 == 0 and self.pr8Timer then self.pr8Timer = CurTime() end
|
||
self["8"] = self.Target8+self.CurrentDriveMode[13]*(PAM_VV.KRU+self.NoFreq)
|
||
self["17"] = self.CurrentDriveMode[5]
|
||
self["19"] = self.CurrentDriveMode[6]
|
||
self["20"] = self.CurrentDriveMode[7]
|
||
self["20X"] = self.CurrentDriveMode[8]
|
||
self["25"] = self.CurrentDriveMode[9]
|
||
self["025"] = self.CurrentDriveMode[10]
|
||
self["33"] = self.CurrentDriveMode[11]
|
||
self["033"] = self.CurrentDriveMode[12]
|
||
self["33G"] = self.CurrentDriveMode[13]*(1-PAM_VV.KRU)
|
||
end
|
||
if self.CurrentDoorMode then
|
||
self["16"] = self.CurrentDoorMode[1]
|
||
self["31"] = self.CurrentDoorMode[2]
|
||
self["32"] = self.CurrentDoorMode[3]
|
||
self["68"] = self.CurrentDoorMode[4]
|
||
end
|
||
if self.CurrentPneumoMode then
|
||
self["39"] = self.CurrentPneumoMode[2]
|
||
self["48"] = self.CurrentPneumoMode[3]
|
||
end
|
||
self.EPK = (self.State==4 or (self.State==5 or self.State==6) and RR and self.EPKActive) and 1 or 0
|
||
self.Ring = (Ring) and 1 or 0
|
||
Train:SetNW2String("PAM:Station",self.Station)
|
||
Train:SetNW2String("PAM:Line",self.Line)
|
||
Train:SetNW2String("PAM:Path",self.Path)
|
||
Train:SetNW2Bool("PAM:Reverser",self.ReverserWrench)
|
||
Train:SetNW2Bool("PAM:Keyboard",self.Keyboard)
|
||
Train:SetNW2Bool("PAM:Selected",self.Selected)
|
||
Train:SetNW2Int("PAM:State5",self.State5)
|
||
Train:SetNW2Int("PAM:State5Accept",self.State5Accept)
|
||
end |