1
0
mirror of https://github.com/metrostroi-repo/MetrostroiAddon.git synced 2026-05-02 00:42:29 +00:00
This commit is contained in:
g_brzhezinskiy
2021-01-02 12:51:45 +03:00
commit 1d05caf866
613 changed files with 337020 additions and 0 deletions

View File

@@ -0,0 +1,490 @@
--------------------------------------------------------------------------------
-- ПУАВ - Поездное Устройство АвтоВедения
--------------------------------------------------------------------------------
Metrostroi.DefineSystem("PUAV")
TRAIN_SYSTEM.DontAccelerateSimulation = true
function TRAIN_SYSTEM:Initialize()
self.Train:LoadSystem("IPAV")
self.Train:LoadSystem("KH","Relay","Switch",{ bass = true })
self.Train:LoadSystem("VAV","Relay","Switch",{ bass = true })
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.Train:LoadSystem("P1","Relay","Switch",{ bass = true })
self.Train:LoadSystem("P2","Relay","Switch",{ bass = true })
self.Train:LoadSystem("P3","Relay","Switch",{ bass = true })
self.Train:LoadSystem("P4","Relay","Switch",{ bass = true })
self.Train:LoadSystem("P5","Relay","Switch",{ bass = true })
self.Selected = true
self.LK16 = false
self.LAVT = false
self.LOS = false
self.ARS = false
self.LKI1 = false
self.LKI2 = false
self.LRSTimer = false
self["2"] = 0 --Вращение РК
self["3"] = 0 --Ход 3
self["8"] = 0 --Замещение электрического торможения
self["16"] = 0 --Закрытие дверей
self["17"] = 0 -- Разрешение восстановления реле перегрузки
self["19"] = 0 -- Разрешение замещения электрического торможения
self["20"] = 0 -- Включение двигателей
self["20X"] = 0 -- Разрешение включения двигателей в ходовые режимы
self["025"] = 0 -- Разрешение ручного торможения
self["25"] = 0 -- Ручное торможение
self["31"] = 0 --Разрешение открытия левых дверей
self["31O"] = 0 --Открытие левых дверей
self["32"] = 0 --Разрешение открытия правых дверей
self["32O"] = 0 --Открытие правых дверей
self["33"] = 0 --Включение ходового режима
self["033"] = 0 --Разрешение включения ходового режима
self["33G"] = 0 --Включение режима торможения
self["39"] = 0 --Включение вентиля замещения № 2
self["48"] = 0 --Включение вентиля замещения № 1
self.KRH = 0
self.KRT = 0
self.KGR = 0
self.KRR1 = 0
self.KRR2 = 0
self.KRR3 = 0
self.KD = 0
self.KPRK = 0
self.KOAT = 0
self.KET = 0
self.KSOT = 0
self.KDL = 0
self.KDP = 0
self.RK1 = 0
self.KRU = 0
self.KVARS = 0
self.KTARS = 0
self.VAB = 0
self.KH3 = 0
self.VZP = 0
self.KSZD = 0
self.KB = 0
self.RD = 0
self.Ring = false
self.State = -1
self.Stopped = false
self.DoorsOpen = false
self.Drive = 0
end
if TURBOSTROI then return end
function TRAIN_SYSTEM:Inputs()
return { "IPAVCommand" }
end
function TRAIN_SYSTEM:Outputs()
return { "31","32","31C","32C","16C"}
end
if CLIENT then
local function createFont(name,font,size)
surface.CreateFont("Metrostroi_"..name, {
font = font,
size = size,
weight = 500,
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("PUAV","Liquid Crystal Display",35,400)
function TRAIN_SYSTEM:ClientThink()
--RunConsoleCommand("say","президент!!!")
if not self.DrawTimer then
render.PushRenderTarget(self.Train.PUAV,0,0,512, 128)
render.Clear(0, 0, 0, 0)
render.PopRenderTarget()
end
if self.DrawTimer and CurTime()-self.DrawTimer < 0.1 then return end
self.DrawTimer = CurTime()
render.PushRenderTarget(self.Train.PUAV,0,0,512, 128)
--render.Clear(0, 0, 0, 0)
cam.Start2D()
self:PUAVScreen(self.Train)
cam.End2D()
render.PopRenderTarget()
end
function TRAIN_SYSTEM:PrintText(x,y,text,inverse)
local str = {utf8.codepoint(text,1,-1)}
for i=1,#str do
local char = utf8.char(str[i])
if inverse then
draw.SimpleText(string.char(0x7f),"Metrostroi_PUAV",(x+i)*27+15,y*50+30,Color(0,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
draw.SimpleText(char,"Metrostroi_PUAV",(x+i)*27+15,y*50+30,Color(140,190,0,150),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
else
draw.SimpleText(char,"Metrostroi_PUAV",(x+i)*27+15,y*50+30,Color(0,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
end
end
end
function TRAIN_SYSTEM:PUAVScreen(Train)
local State = Train:GetNW2Int("PUAV:State",-1)
if State ~= 0 then
surface.SetDrawColor(140*0.7,190*0.7,0,self.Warm and 130 or 255)
self.Warm = true
else
surface.SetDrawColor(20,50,0,230)
self.Warm = false
end
surface.DrawRect(0,0,512,128)
if State == 0 then
return
end
for i=1,6 do
self:PrintText(-2+i*2,0,Format("%02d",i))
self:PrintText(-2+i*2,1,Format("%02d",math.max(0,Train:GetNW2Int("PUAV:RK"..i,0))))
end
--self:PrintText(0,0,"010101010101")
--self:PrintText(1,1,Format("РК:%02d",Train:GetNW2Int("PUAV:RK",0)))
--self:PrintText(1,1,"(точнее криво)")
end
end
function TRAIN_SYSTEM:Trigger(name,nosnd)
end
function TRAIN_SYSTEM:SetAVPosition(pos)
if self.Train.KV.AutodrivePosition ~= pos then
self.Train.KV:TriggerInput("SetAutodrive",pos)
end
end
local IgnoreDoors = false
function TRAIN_SYSTEM:Think(dT)
if not self.Selected then return end
local Train = self.Train
local ALS = Train.ALSCoil
local ARS = Train.ALS_ARS
local EnableARS = ARS.EnableARS
local UOS = not EnableARS and Train.RC1.Value == 0
local LeftCoil,RightCoil = Train.LeftAutoCoil,Train.RightAutoCoil
local power = Train.VB.Value > 0.5 and Train.VAU.Value > 0.5 and Train.Panel["V1"] > 0.5
local KRUEnabled = Train.KRU and Train.KRU["14/1-B3"] > 0
local RVForward = power and (Train.KV["D4-15"] > 0 or KRUEnabled)
local KVT = Train.PB.Value > 0 or Train.KVT and Train.KVT.Value > 0
local speed = math.Round(ALS.Speed or 0,1)
if not power and self.State > -1 then self.State = -1 self.State2Timer = nil end
if not RVForward and self.State > 0 then self.State = 0 end
if RVForward and self.State == 0 then self.State = 2 end
if RVForward and self.State == -1 and not self.State2Timer then self.State = 1 self.State2Timer = CurTime() end
if RVForward and self.State == 1 and self.State2Timer and CurTime()-self.State2Timer > 2 then self.State = 2 self.State2Timer = nil end
if self.State > 0 then
self.NoFreq = ALS.NoFreq
self.F1 = ALS.F1*(1-self.NoFreq)
self.F2 = ALS.F2*(1-self.NoFreq)
self.F3 = ALS.F3*(1-self.NoFreq)
self.F4 = ALS.F4*(1-self.NoFreq)
self.F5 = ALS.F5*(1-self.NoFreq)
self.F6 = ALS.F6*(1-self.NoFreq)
self.RealF5 = self.F5*(1-(self.F4+self.F3+self.F2+self.F1))
self.NoFreq = self.NoFreq + (1-math.min(1,self.F5+self.F4+self.F3+self.F2+self.F1))
else
self.NoFreq = 0
self.F1 = 0
self.F2 = 0
self.F3 = 0
self.F4 = 0
self.F5 = 0
self.F6 = 0
self.NoFreq = 0
end
if self.State == 2 then
--Speed limit
local speedLimit = 20
if EnableARS and self.F4 > 0 then speedLimit = 40 end
if EnableARS and self.F3 > 0 then speedLimit = 60 end
if EnableARS and self.F2 > 0 then speedLimit = 70 end
if EnableARS and self.F1 > 0 then speedLimit = 80 end
local ProgrammX = false
local ProgramDoorLeft = IgnoreDoors
local ProgramDoorRight = IgnoreDoors
local ProgrammSBrake = false
self.LastBrakeProgramTimer = self.LastBrakeProgramTimer or CurTime()
self.LastBrakeProgram = self.LastBrakeProgram or false
local haveCommand = 0
for k,v in ipairs(LeftCoil.Commands) do
v.Power = true
local command = v.PlateType
ProgramDoorLeft = ProgramDoorLeft or command == METROSTROI_ACOIL_DOOR
ProgrammX = ProgrammX or command == METROSTROI_ACOIL_DRIVE and v.Power and v.Mode
ProgrammSBrake = ProgrammSBrake or command == METROSTROI_ACOIL_SBRAKE and LeftCoil
haveCommand = haveCommand + 1
end
for k,v in ipairs(RightCoil.Commands) do
v.Power = true
local command = v.PlateType
ProgramDoorRight = ProgramDoorRight or command == METROSTROI_ACOIL_DOOR
ProgrammX = ProgrammX or command == METROSTROI_ACOIL_DRIVE and v.Power and v.Mode
ProgrammSBrake = ProgrammSBrake or command == METROSTROI_ACOIL_SBRAKE and RightCoil
haveCommand = haveCommand + 1
end
if self.HaveCommand ~= haveCommand then
self.LRSTimer = CurTime()
self.HaveCommand = haveCommand
end
if self.DoorsOpen == true and (Train.Panel["SD"] <= 0 or Train:ReadTrainWire(16) > 0) then self.DoorsOpen = false end
if Train.VAV.Value > 0 and self.Stopped then
if Train.Panel["SD"] > 0 and not self.SDTimer then self.SDTimer = CurTime() end
if Train.Panel["SD"] <= 0 and self.SDTimer then
self.SDTimer = false
self.Autodrive = false
end
if self.SDTimer and (self.SDTimer == true or CurTime()-self.SDTimer > 0.2) then
self.SDTimer = true
self.Autodrive = self.Autodrive or Train.VZP.Value > 0
end
else
self.Autodrive = false
self.Stopped = false
end
if Train.VAV.Value > 0 and Train.Panel["SD"] <= 0 and not self.Stopped then self.Stopped = CurTime() end
if Train.VAV.Value > 0 and Train.Panel["SD"] > 0 and (self.Stopped and self.Stopped ~= true and CurTime()-self.Stopped >= 2) then self.Stopped = true end
if self.Stopped and (Train.VAV.Value == 0 or Train.Panel["SD"] > 0 and (self.Stopped ~= true and CurTime()-self.Stopped < 2)) then self.Stopped = false end
if not self.Autodrive then
self.Drive = 0
self.Brake = false
end
if ProgrammSBrake then
if self.RingArmed == nil then self.RingArmed = CurTime() + math.max(1,math.min(4,5-speed/15)) end
elseif not ProgrammSBrake and self.RingArmed ~= nil then self.RingArmed = nil end
if self.RingArmed and CurTime()-self.RingArmed <= 0 and Train:ReadTrainWire(6) > 0 then self.RingArmed = false end
if self.RingArmed and CurTime()-self.RingArmed > 4 then
self.RingArmed = false
end
local position = 0
if self.Autodrive and ProgrammSBrake then
if not self.Brake and ProgrammSBrake then self.Brake = 0 end
if self.Brake then position = speed > 55 and -2 or -1 end
local passed = ProgrammSBrake.BrakeProgrammPassed
local passednow = CurTime()-ProgrammSBrake.LastBrakeProgrammPassed
if self.Brake == 0 and passed < 1e9 then self.Brake = 1 end
if self.Brake == 1 and (passed < METROSTROI_ABRAKE_DIST or (passednow > self.Passed*4 and passednow > METROSTROI_ABRAKE_DIST*4)) then self.Brake = 2 end
if self.Brake == 2 and METROSTROI_ABRAKE_DIST*3 < passed and passed < 1e9 and speed<=25 then self.Brake = 3 end
if self.Brake == 3 and passed < METROSTROI_ABRAKE_DIST then self.Brake = 4 end
--if self.Brake == 2 and speed > 25 or self.Brake == 4 then position = -3 end
if self.Brake == 2 and Train.RheostatController.Position < 12 or self.Brake == 4 then position = -3 end
self.Passed = passed
elseif self.Autodrive then
--print(-1,Train,ProgrammSBrake)
if self.Brake then
position = -3
elseif ProgrammX and ProgrammX then
--X3
if ProgrammX == 2 or ProgrammX == 4 then self.Drive = 3 end --X3
if ProgrammX == 1 or ProgrammX == 3 then self.Drive = 2 end --X2
if ProgrammX == 5 or ProgrammX == 6 then self.Drive = 0 end --0
if ProgrammX == 7 then self.Drive = -1 end --T1
if ProgrammX == 8 then self.Drive = -2 end --T1a
end
if self.Brake and (self.Brake <= 1 or speed < 0.1) then
self.Brake = false
self.Stopped = false
if ProgramDoorLeft or ProgramDoorRight then
self.DoorsOpen = true
end
end
if position == 0 then position = self.Drive or 0 end
end
if position ~= 0 and not self.Starting then self.Starting = CurTime() end
if position == 0 and self.Starting then self.Starting = false end
if (position < -1 or position > 1) and self.Starting and CurTime()-self.Starting < 0.5 then
position = math.Clamp(position,-1,1)
end
if ARS["33D"]*self["33D"] == 0 and position > 0 then position = 0 end
--if Train.RheostatController.Position < 17.2 then print(Train.Electric.I13,Train.RheostatController.Position,speed,Train.Electric.ThyristorState,Train.Electric.ThyristorResistance,Train.ThyristorBU5_6.Value) end
self:SetAVPosition(position)
if ProgrammSBrake then ProgrammSBrake.BrakeProgrammPassed = 1e9 end
local zero = (self.NoFreq*(Train.ALS.Value+Train.VRD.Value)) > 0
--PUAV ARS logic
if not EnableARS then
self.Ringing = true
self.EBrake = true
end
if self.Ringing and KVT then self.Ringing = false end
if self.EBrake and KVT then self.EBrake = false end
if speed >= speedLimit and not ARS.ElectricBrake and not self.Pneumo then
self.Ringing = true
self.Pneumo = speed == speedLimit
self.EBrake = speed > speedLimit
end
if (speed < speedLimit or ARS.ElectricBrake) and EnableARS then
self.Pneumo = false
self.EBrake = false
end
local CloseDoors = (not ProgramDoorLeft and not ProgramDoorRight and not zero) or speed > 0.2 or Train.VAV.Value > 0 and Train.KSZD.Value > 0
local DoorLeftWork = Train:ReadTrainWire(16) == 0 and (ProgramDoorLeft or zero)
local DoorRightWork = Train:ReadTrainWire(16) == 0 and (ProgramDoorRight or zero)
self.LK16 = Train:ReadTrainWire(16) > 0
self.LAVT = Train.VAV.Value > 0
self.LOS = UOS
self.LRS =
not ProgramDoorLeft and not ProgramDoorRight and EnableARS
and Train.EK.Value > 0 and Train.EK1.Value > 0 and Train.SOT.Value > 0 and (not self.LRSTimer or CurTime()-self.LRSTimer > 0.2)
self.LKI1 = false
self.LKI2 = false
self["31"] = DoorLeftWork and self.DoorsOpen and 1 or 0
self["32"] = DoorRightWork and self.DoorsOpen and 1 or 0
self["31C"] = DoorLeftWork and 1 or 0
self["32C"] = DoorRightWork and 1 or 0
self["16C"] = CloseDoors and 1 or 0
--local zbrake = speedLimit <= 20 and not KVT
self["33D"] = (self.EBrake or zbrake) and 0 or 1
self["33G"] = (self.EBrake or zbrake) and 1 or 0
self["2"] = self["33G"]
self["20"] = self["33G"]
self["48"] = self.Pneumo and 1 or 0
self["8"] = self["33G"]
if Train.KV["U2-25"] > 0 or KVT and speedLimit == 20 then
self["8"] = -1
end
if (Train.KV["7G-33Yu"] > 0 or Train.KSZD.Value > 0) and self.KSZDRing then self.KSZDRing = false end
for i,train in ipairs(Train.WagonList) do
if train.RheostatController then
Train:SetNW2Int("PUAV:RK"..i,math.floor(train.RheostatController.Position+0.5))
end
end
self.Ring = (self.EBrake or self.Ringing) and CurTime()%2 > 1 or self.KSZDRing
elseif self.State == 1 then
self.LK16 = true
self.LAVT = true
self.LOS = true
self.LRS = true
self.LKI1 = true
self.LKI2 = true
self.Ring = CurTime()-self.State2Timer < 1
self.EBrake = true
self.Ringing = true
else
self.LK16 = false
self.LAVT = false
self.LOS = false
self.LRS = false
self.LKI1 = false
self.LKI2 = false
self["31"] = 0
self["32"] = 0
self["31C"] = 1
self["32C"] = 1
self["16C"] = 0
self["33D"] = 1
self["33G"] = 0
self["2"] = 0
self["20"] = 0
self["48"] = 0
self["8"] = 0
self.LRSTimer = false
self.HaveCommand = false
self.Ring = false
self.EBrake = true
self.Ringing = true
self.Pneumo = false
self.RingArmed = nil
self:SetAVPosition(0)
end
if EnableARS then
if (ARS.F5 > 0 or ARS.F6 > 0) then
if not self.ZeroTimer then
self.ZeroTimer = CurTime()+30
self.ZeroTimerState = true
end
if self.ZeroTimerState and self.ZeroTimer and CurTime()-self.ZeroTimer > 7.5 and Train.ALSCoil.Speed < 0.25 then
self.ZeroTimerState = false
self.ZeroTimer = CurTime()+30
end
elseif self.ZeroTimer ~= nil then
self.ZeroTimer = nil
end
else
self.ZeroTimer = nil
end
--[[
if self.Train.VZP.Value > 0.5 then
Train.Autodrive:Enable()
end
if Train.VAV.Value < 0.5 then
Train.Autodrive:Disable()
end
if self.Timer and CurTime() - self.Timer > 0 then
self.Timer = nil
self.Choose = 0
end
--self.FirstStation = Metrostroi.EndStations[Train.Announcer.AnnMap][self.Line] and Metrostroi.EndStations[Train.Announcer.AnnMap][self.Line][self.ChoosedFStation or 1] or 0
--self.LastStation = Metrostroi.EndStations[Train.Announcer.AnnMap][self.Line] and Metrostroi.EndStations[Train.Announcer.AnnMap][self.Line][self.ChoosedLStation or 1] or 0
if self.State ~= self.RealState then
self.RealState = self.State
self.TimeOverride = true
end
self.Time = self.Time or CurTime()
if (CurTime() - self.Time) > 0.1 or self.TimeOverride then
self.TimeOverride = nil
--print(1)
self.Time = CurTime()
Train:SetNW2Int("PUAV:Choose",self.Choose)
Train:SetNW2Int("PUAV:LastStation",self.LastStation or 1)
Train:SetNW2Int("PUAV:FirstStation",self.FirstStation or 1)
Train:SetNW2Int("PUAV:Line",self.Line or 1)
end
self.RouteNumber = string.gsub(Train.RouteNumber or "","^(0+)","")
self.Line = Train.UPO.Line
self.FirstStation = tostring(Train.UPO.FirstStation or "")
self.LastStation = tostring(Train.UPO.LastStation or "")
local pathID
if (Metrostroi.TrainPositions[self.Train] and Metrostroi.TrainPositions[self.Train][1]) then
PathID = Metrostroi.TrainPositions[self.Train][1].path.id
end
Train:SetPackedBool("LKI",self.Train.Autodrive.Commands[PathID] and self.Train.Autodrive.Commands[PathID][self.Train.UPO.Station] ~= nil)]]
end