1
0
mirror of https://github.com/metrostroi-repo/MetrostroiAddon.git synced 2026-05-02 00:42:29 +00:00
Files
MetrostroiAddon/lua/metrostroi/systems/sys_sbpp.lua
g_brzhezinskiy 1d05caf866 init
2021-01-02 12:51:45 +03:00

362 lines
14 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
--------------------------------------------------------------------------------
-- SBPP autodrive receiver
--------------------------------------------------------------------------------
-- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o.
-- Contains proprietary code. See license.txt for additional information.
--------------------------------------------------------------------------------
Metrostroi.DefineSystem("SBPP")
TRAIN_SYSTEM.DontAccelerateSimulation = true
function TRAIN_SYSTEM:Initialize()
self.Count = 0
self.ProgrammX = 0
self.ProgrammBrake = 0
self.Path = 0
self.Station = 0
end
function TRAIN_SYSTEM:Outputs()
return {}
end
function TRAIN_SYSTEM:Inputs()
return {}
end
local DrawDebug
if SERVER then
CreateConVar("metrostroi_sbppdebug",0)
DrawDebug = GetConVar("metrostroi_sbppdebug")
end
function TRAIN_SYSTEM:Think(dT)
local Train = self.Train
function self:SetCommand(name,command)
if command then
Train.PUAV:TriggerInput(name,command)
if name == "CommandDrive" then
self.LastDrive = self.Drive
self.Drive = command
if command==-1 then self.LastBrake = false end
end
if name == "CommandBrake" then
self.LastBrake = self.Brake
self.Brake = command
if command and command~=0 and self.Drive and self.Drive>0 then self.LastDrive = self.Drive self.Drive = 0 end
end
else
Train.PUAV:TriggerInput(name,0)
end
end
local Sensor = Train.SBPPSensor
if not IsValid(Sensor) then return end
local ProgrammType
local Programm
for k,v in ipairs(Sensor.Commands) do
local isSBPP = v.PlateType==METROSTROI_SBPPSENSOR
local command = v.SBPPType
if isSBPP and Train:GetRight():Dot(v:GetUp())>0 then
if not ProgrammType then
Programm = v.Linked or v
ProgrammType = command
elseif ProgrammType ~= command then
Programm = false
end
end
end
if self.Programm ~= Programm then
self.Programm = Programm
self.LastProgramm = Programm or self.LastProgramm
end
local ProgramDoorLeft
local ProgramDoorRight
local ProgrammX
local ProgrammBrake = 0
local CurrProgramm = Programm and Programm.SBPPType
if CurrProgramm == 1 then
if self.StationState~=1 then
self.StationState = 1
self.Distance = Programm.DistanceToOPV+1.40
self.SensorDistance = self.Distance
end
elseif CurrProgramm == 2 then
if self.StationState~=4 then
self.StationState = 4
self.Distance = Programm.DistanceToOPV+1.40
self.SensorDistance = self.Distance
end
elseif CurrProgramm == 3 then
self.Path = Programm.StationPath or 0
self.Station = Programm.StationID or 0
local btime = Train.BoardTimer or 0
local wtime = Programm.WTime or 0
if not Programm.IsDeadlock and btime<8 or wtime==0 and Train.ALSCoil.Speed<0.2 and Programm.IsDeadlock then
ProgrammX = Programm.DriveMode or 0
if wtime>0 then self.DrivingTimer = CurTime()+wtime end
self.StationState = nil
end
ProgramDoorRight = Programm.RightDoors
ProgramDoorLeft = not ProgramDoorRight
elseif CurrProgramm == 5 then
local wtime = Programm.WTime or 0
if wtime>0 then self.DrivingTimer = CurTime()+wtime end
ProgrammX = 2
elseif CurrProgramm == 6 then
local wtime = Programm.WTime or 0
if wtime>0 then self.DrivingTimer = CurTime()+wtime end
ProgrammX = 3
elseif CurrProgramm == 7 then
local time = Programm.WTime or 0
local RK = Programm.RKPos or 1
if not self.BrakingRimer and time>0 then
self.BrakingTimer = CurTime()+time
else
self.BrakingTimer = true
end
self.BrakingPos = RK
end
local PUAV = Train.PUAV
if self.BrakingTimer then
if self.BrakingPos > 1 and (not PUAV.TargetKPRK or PUAV.TargetKPRK<self.BrakingPos) then
if self.LastBrakeTime then
ProgrammBrake = 0
else
self.LastBrakeTime = CurTime()
end
if CurTime()-self.LastBrakeTime<0.35 then
ProgrammBrake = 0
else
ProgrammBrake = 1
end
if CurTime()-self.LastBrakeTime > 0.4 then self.LastBrakeTime = CurTime() end--]]
else
ProgrammBrake = 1
end
if self.BrakingTimer~=true and CurTime()-self.BrakingTimer>0 then
CurrProgramm = 4
end
end
local pos = Metrostroi.TrainPositions[Train] pos = pos and pos[1]
local speedMpS = Train.ALSCoil.Speed/3600*1000
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
if self.Distance then
self.Distance = self.Distance-delta
if self.Distance-self.SensorDistance>5 or self.Distance < -5 then
self.Distance = false
self.StationState = false
end
end
if self.StationState then
ProgrammBrake = 1
if self.StationState==1 then
if self.LossDistance then ProgrammBrake = 0 end
if not self.LossDistance then
self.LossDistance = self.Distance
elseif self.LossDistance-self.Distance>20 then
self.LossDistance = false
self.StationState = 2
end
elseif self.StationState == 2 then
if math.min(((self.Distance-32)/66)^0.6*66-1,66) < Train.ALSCoil.Speed then
self:SetCommand("CommandBrakeElapsed",0)
self.StationState = 3
end
elseif self.StationState == 4 then
if math.min(((self.Distance-2)/12)^0.5*25-3,22) < Train.ALSCoil.Speed then
self:SetCommand("CommandBrakeElapsed",0)
self.StationState = 5
end
end
if self.StationState>=2 then
if not self.CrossTimer then self.CrossTimer = CurTime() end
if self.CrossTimer and CurTime()-self.CrossTimer>0.15 then
self.CrossTimer = CurTime()
self:SetCommand("CommandBrakeElapsed",self.StationState==3 and 3 or 1)
end
end
else
self.CrossTimer = false
self.LossDistance = false
end
if self.DrivingTimer and CurTime()-self.DrivingTimer > 0 then
CurrProgramm = 4
end
if CurrProgramm == 4 then
ProgrammX = -1
ProgrammBrake = 0
self.BrakingTimer = false
self.DrivingTimer = false
elseif not CurrProgramm and not self.BrakingTimer and not self.DrivingTimer then
ProgrammX = 0
end
if self.ProgrammX and self.ProgrammX>0 and ProgrammX==0 and not self.DriveTimer then self.DriveTimer = CurTime() end
if self.DriveTimer and not CurrProgramm and CurTime()-self.DriveTimer > 1.5 then self.DriveTimer = nil end
if self.ProgramDoorLeft ~= ProgramDoorLeft then
self:SetCommand("CommandDoorsLeft",ProgramDoorLeft and 1)
self.ProgramDoorLeft = ProgramDoorLeft
end
if self.ProgramDoorRight ~= ProgramDoorRight then
self:SetCommand("CommandDoorsRight",ProgramDoorRight and 1)
self.ProgramDoorRight = ProgramDoorRight
end
--if ProgrammBrake and not ProgrammBrake.BrakeCommandFounded then ProgrammBrake = nil end
if self.ProgrammBrake ~= ProgrammBrake then
self:SetCommand("CommandBrake",ProgrammBrake)
self.ProgrammBrake = ProgrammBrake
end
if self.ProgrammX ~= ProgrammX and(ProgrammX ~= 0 or not self.DriveTimer) then
if ProgrammX == 3 then self:SetCommand("CommandDrive",3) --X3
elseif ProgrammX == 2 then self:SetCommand("CommandDrive",2) --X2
elseif ProgrammX == -1 then self:SetCommand("CommandDrive",-1) --X2
elseif ProgrammX == 0 then self:SetCommand("CommandDrive",0) end
self.ProgrammX = ProgrammX
end
if DrawDebug:GetBool() then
Train:SetNW2Bool("SBPP:Debug",true)
local str1 = ""
local str2 = ""
local page = math.floor(CurTime()%1.25/1.25*2)
local cp = CurrProgramm or self.LastProgramm and self.LastProgramm.SBPPType
if page==0 and cp then
if CurrProgramm then
str1 = str1.."СБПП"
else
str1 = str1.."сбпп"
end
if cp == 1 then str2 = str2.."СТ1 "
elseif cp == 2 then str2 = str2.."СТ2 "
elseif cp == 3 then str2 = str2.."ОПВ "
elseif cp == 4 then str2 = str2.."ОД "
elseif cp == 5 then str2 = str2.."Х2 "
elseif cp == 6 then str2 = str2.."Х3 "
elseif cp == 7 then str2 = str2.."ТР " end
else
str1 = str1.."ПУАВ"
end
if CurrProgramm == 3 then
local btime = Train.BoardTimer or 0
local wtime = Programm.WTime or 0
ProgramDoorRight = Programm.RightDoors
ProgramDoorLeft = not ProgramDoorRight
if page==0 then
str1 = str1.." П"
str2 = str2.." "..self.Path
str1 = str1.." СТ "
str2 = str2..Format(" %03d",self.Station)
str1 = str1.." РСТ"
str2 = str2..Format(" %05.1f",(self.Distance or -1))
else
str1 = str1.." ОТП"
str2 = str2..Format(" %+03d",math.Clamp(btime,-99,99))
str1 = str1.." РЖ"
if Programm.DriveMode == 3 then
str2 = str2.." Х3"
elseif Programm.DriveMode == 2 then
str2 = str2.." Х2"
end
str1 = str1.." ВР"
if Programm.WTime and Programm.WTime ~= 0 then
str2 = str2..Format(" %04.1f",math.Clamp(wtime,0,120))
else
str2 = str2.." МАРК"
end
end
end
local PUAV = Train.PUAV
if self.BrakingTimer then
str1 = str1.." РК"
str2 = str2..Format(" %02d",self.BrakingPos)
if self.BrakingPos > Train.RheostatController.SelectedPosition then
str1 = str1.."<"
elseif self.BrakingPos < Train.RheostatController.SelectedPosition then
str1 = str1..">"
else
str1 = str1.."="
end
if page==0 then
str1 = str1.."кп"
str2 = str2..Format(" %02d",PUAV.TargetKPRK or -1)
else
str1 = str1.."рк"
str2 = str2..Format(" %02d",Train.RheostatController.SelectedPosition)
end
str1 = str1.." ВР"
if self.BrakingTimer~=true then
str2 = str2..Format(" %04.1f",math.Clamp(self.BrakingTimer-CurTime(),0,120))
else
str2 = str2.." МАРК"
end
end
if self.StationState then
str1 = str1.." РСТ"
str2 = str2..Format(" %05.1f",(self.Distance or -1))
if self.StationState == 2 then
str1 = str1.." РСК"
str2 = str2..Format(" %04.1f",math.min(((self.Distance-32)/66)^0.6*66-1,66))
elseif self.StationState == 4 then
if page==0 then
str1 = str1.." П"
str2 = str2.." "..self.Path
str1 = str1.." СТ "
str2 = str2..Format(" %03d",self.Station)
else
str1 = str1.." РСК"
str2 = str2..Format(" %04.1f",math.min(((self.Distance-2)/12)^0.5*20-3,22))
end
end
end
if self.DrivingTimer and not CurrProgramm then
str1 = str1.." ВР"
if self.DrivingTimer~=true then
str2 = str2..Format(" %04.1f",math.Clamp(self.DrivingTimer-CurTime(),0,120))
else
str2 = str2.." МАРК"
end
end
if self.DriveTimer and not CurrProgramm then
str1 = str1.." ХВР"
str2 = str2..Format(" %04.1f",math.Clamp(1.5-(CurTime()-self.DriveTimer),0,120))
end
str1 = str1..string.rep(" ",15-#{utf8.codepoint(str1,1,-1)})..page
if not cp or page==1 then
if ProgramDoorLeft and ProgramDoorRight then str2 = "ЛП"..str2
elseif ProgramDoorLeft then str2 = "Л-"..str2
elseif ProgramDoorRight then str2 = ""..str2
else str2 = "--"..str2 end
if self.Brake==1 then str2 = "КП"..str2
elseif self.Brake and self.Brake<0 then str2 = "Х3"..str2
elseif self.Drive==3 then str2 = "Х3"..str2
elseif self.Drive==2 then str2 = "Х2"..str2
elseif self.Drive==-1 then str2 = "ОД"..str2
elseif self.LastBrake==1 then str2 = "тп"..str2
elseif self.LastBrake and self.LastBrake<0 then str2 = "кп"..str2
elseif self.LastDrive==3 then str2 = "х3"..str2
elseif self.LastDrive==2 then str2 = "х2"..str2
elseif self.LastDrive==-1 then str2 = "од"..str2
else str2 = "--"..str2 end
end
Train:SetNW2String("SBPP:Str1",str1~="" and str1 or "No data")
Train:SetNW2String("SBPP:Str2",str2~="" and str2 or "No data")
else
Train:SetNW2Bool("SBPP:Debug",false)
end
end