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,361 @@
--------------------------------------------------------------------------------
-- 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