diff --git a/lua/entities/gmod_subway_81-714_lvz/cl_init.lua b/lua/entities/gmod_subway_81-714_lvz/cl_init.lua index 81e3445d..7457f493 100644 --- a/lua/entities/gmod_subway_81-714_lvz/cl_init.lua +++ b/lua/entities/gmod_subway_81-714_lvz/cl_init.lua @@ -407,6 +407,31 @@ for i,button in pairs(ENT.ButtonMap.AV_T.buttons) do } button.ID = "1:"..button.ID end +-- ДВР() +ENT.ButtonMap["DVR_87"] = { + pos = Vector(448,-53,-28), + ang = Angle(0,180,-5), + width = 1000, + height = 300, + scale = 0.0625, + hide=0.8, + + buttons = { + {ID = "DVRDisconnectToggle", x=0, y=0, w=1000, h=300, tooltip="", model = { + var="DVRDisconnect",sndid="disconnect_valve",--"brake_disconnect", + sndvol = 1, snd = function(val) return "disconnect_valve" end, + sndmin = 90, sndmax = 1e3, sndang = Angle(-90,0,0),} + }, + } +} +ENT.ClientSounds["DVRDisconnect"] = {{"DVR_disconnect",function() return "disconnect_valve" end,1,1,50,1e3,Angle(-90,0,0)}} + +ENT.ClientProps["DVR_disconnect"] = { + model = "models/metrostroi_train/81-707/cran1.mdl", + pos = Vector(431.15,-43.5,-24.7), + ang = Angle(-90,0,-90), + hideseat=0.2, +} ENT.ButtonMap["DriverValveBLTLDisconnect"] = { pos = Vector(-466,44,-18), @@ -430,6 +455,12 @@ ENT.ButtonMap["DriverValveBLTLDisconnect"] = { }}, } } +ENT.ClientProps["cran_dooropen_int"] = { + model = "models/metrostroi_train/door_crans/cran_dooropen_int.mdl", + pos = Vector(-19,-0.2,1.2), + ang = Angle(0,90,0), + hide = 1, +} ENT.ClientProps["brake_disconnect"] = { model = "models/metrostroi_train/81-707/cran1.mdl", @@ -571,6 +602,341 @@ ENT.ClientProps["door2"] = { ang = Angle(0,-90,0), hide=2, } +--Выключение дверей () +ENT.ButtonMap["Doors1_2_left"] = { + pos = Vector(-387,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod4Set",x=304,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd4Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr1_2_lft"] = { + pos = Vector(-317.5,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + --hide = 1 + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK4Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK4",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors3_4_left"] = { + pos = Vector(-156.5,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod3Set",x=300,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd3Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr3_4_lft"] = { + pos = Vector(-87.4,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + --hide = 0.8 + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK3Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK3",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors5_6_left"] = { + pos = Vector(73,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod2Set",x=304,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd2Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr5_6_lft"] = { + pos = Vector(142.7,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + --hide = 0.8 + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK2Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK2",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors7_8_left"] = { + pos = Vector(302,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod1Set",x=312,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd1Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr7_8_lft"] = { + pos = Vector(372.8,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + --hide = 0.8 + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK1Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK1",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors1_2_right"] = { + pos = Vector(-389,62,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod5Set",x=324,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd5Set",x=0,y=0,w= 100,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr1_2_rgh"] = { + pos = Vector(-317.5,64.45,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK5Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK5",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors3_4_right"] = { + pos = Vector(-156.6,62,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod6Set",x=298,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd6Set",x=0,y=0,w= 100,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr3_4_rgh"] = { + pos = Vector(-87.5,64.45,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK6Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK6",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors5_6_right"] = { + pos = Vector(72,62,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod7Set",x=312,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd7Set",x=0,y=0,w= 100,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr5_6_rgh"] = { + pos = Vector(142.56,64.5,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK7Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK7",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors7_8_right"] = { + pos = Vector(302,62,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod8Set",x=314,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd8Set",x=0,y=0,w= 100,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr7_8_rgh"] = { + pos = Vector(372.7,64.5,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK8Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK8",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["DoorReleaseRight"] = { + pos = Vector(284,-62,15), + ang = Angle(0,180,90), + width = 100, + height = 160, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "DoorReleaseRightToggle",x=0,y=0,w= 100,h = 40,tooltip="",model = { + var="DoorReleaseRight",sndid="doorsmanual_r", + sndvol = 1,snd = function(val) return "disconnect_valve" end, + sndmin = 90,sndmax = 1e3,sndang = Angle(-90,0,0),}}, + } +} +ENT.ClientProps["doorsmanual_r"] = { + model = "models/metrostroi_train/81-717/stop_mvm.mdl", + pos = Vector(282,-62.5,13.5), + ang = Angle(180,180,0), + hideseat=0.2, +} +ENT.ClientSounds["DoorReleaseRight"] = {{"doorsmanual_r",function() return "disconnect_valve" end,1,1,50,1e3,Angle(-90,0,0)}} + + +ENT.ButtonMap["DoorReleaseLeft"] = { + pos = Vector(274,62,15), + ang = Angle(0,0,90), + width = 100, + height = 160, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "DoorReleaseLeftToggle",x=0,y=0,w= 100,h = 40,tooltip="",model = { + var="DoorReleaseLeft",sndid="doorsmanual_l", + sndvol = 1,snd = function(val) return "disconnect_valve" end, + sndmin = 90,sndmax = 1e3,sndang = Angle(-90,0,0),}}, + } +} +ENT.ClientProps["doorsmanual_l"] = { + model = "models/metrostroi_train/81-717/stop_mvm.mdl", + pos = Vector(282,62,12.5), + ang = Angle(0,0,0), + hideseat=0.2, +} +ENT.ClientSounds["DoorReleaseLeft"] = {{"doorsmanual_l",function() return "disconnect_valve" end,1,1,50,1e3,Angle(-90,0,0)}} -------------------------------------------------------------------------------- ENT.ClientPropsInitialized = false @@ -906,6 +1272,12 @@ function ENT:Think() self.ClientEnts.seats_new_cap:SetSubMaterial(0,self.NewBlueSeats and "models/metrostroi_train/81-717/interior_kvr_blue" or "") end end + --() + local DrawDVR = self:GetPackedBool("CouchCap") + self:ShowHide("DVR_disconnect",DrawDVR) + self:HidePanel("DVR_87",not DrawDVR) + self:Animate("DVR_disconnect",self:GetPackedBool("DVRDisconnect") and 1 or 0,0.25,0, 4,false) + --() local Bortlamp_w = self:Animate("Bortlamp_w",self:GetPackedBool("DoorsW") and 1 or 0,0,1,16,false) local Bortlamp_g = self:Animate("Bortlamp_g",self:GetPackedBool("GRP") and 1 or 0,0,1,16,false) @@ -1007,6 +1379,8 @@ function ENT:Think() self:Animate("RearBrake", self:GetNW2Bool("RbI") and 0 or 1,0,1, 3, false) self:Animate("RearTrain", self:GetNW2Bool("RtI") and 1 or 0,0,1, 3, false) self:Animate("ParkingBrake", self:GetPackedBool("ParkingBrake") and 1 or 0,1,0, 3, false) + self:Animate("doorsmanual_r", self:GetNW2Bool("DoorReleaseRight") and 0 or 1, 0.25,0, 128, 3,false) + self:Animate("doorsmanual_l", self:GetNW2Bool("DoorReleaseLeft") and 0 or 1, 0.25,0, 128, 3,false) -- Main switch if self.LastGVValue ~= self:GetPackedBool("GV") then @@ -1018,42 +1392,46 @@ function ENT:Think() if not self.DoorStates then self.DoorStates = {} end if not self.DoorLoopStates then self.DoorLoopStates = {} end + if not self.DSprev then self.DSprev = {{1,1},{1,1},{1,1},{1,1}} end + if not self.DoorDelta then self.DoorDelta = {{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0}} end for i=0,3 do for k=0,1 do local st = k==1 and "DoorL" or "DoorR" - local doorstate = self:GetPackedBool(st) local id,sid = st..(i+1),"door"..i.."x"..k local state = self:GetPackedRatio(id) - --print(state,self.DoorStates[state]) - if (state ~= 1 and state ~= 0) ~= self.DoorStates[id] then - if doorstate and state < 1 or not doorstate and state > 0 then - else - if state > 0 then - self:PlayOnce(sid.."o","",1,math.Rand(0.8,1.2)) - else - self:PlayOnce(sid.."c","",1,math.Rand(0.8,1.2)) - end - end - self.DoorStates[id] = (state ~= 1 and state ~= 0) - end - if (state ~= 1 and state ~= 0) then + local prevstate = self.DSprev[i+1][k+1] + if math.abs(prevstate - state) > 0.01 then self.DoorLoopStates[id] = math.Clamp((self.DoorLoopStates[id] or 0) + 2*self.DeltaTime,0,1) - else - self.DoorLoopStates[id] = math.Clamp((self.DoorLoopStates[id] or 0) - 6*self.DeltaTime,0,1) - end + self.DoorDelta[i+1][k+1] = 0.0 + else + if self.DoorDelta[i+1][k+1] < 0.2 then + self.DoorDelta[i+1][k+1] = self.DoorDelta[i+1][k+1] + self.DeltaTime + else + self.DoorLoopStates[id] = math.Clamp((self.DoorLoopStates[id] or 0) - 1.2*self.DeltaTime,0,1) + end + end + self.DSprev[i+1][k+1] = state self:SetSoundState(sid.."r",self.DoorLoopStates[id],0.8+self.DoorLoopStates[id]*0.2) - local n_l = "door"..i.."x"..k--.."a" - --local n_r = "door"..i.."x"..k.."b" + local n_l = "door"..i.."x"..k local dlo = 1 - --local dro = 1 + local drcsing = state-(self.Anims[n_l] and self.Anims[n_l].oldival or 0) < 0 if self.Anims[n_l] then dlo = math.abs(state-(self.Anims[n_l] and self.Anims[n_l].oldival or 0)) if dlo <= 0 and self.Anims[n_l].oldspeed then dlo = self.Anims[n_l].oldspeed/14 end end - self:Animate(n_l,state,0,0.95, dlo*14,false)--0.8 + (-0.2+0.4*math.random()),0) - --self:Animate(n_r,state,0,1, dlo*14,false)--0.8 + (-0.2+0.4*math.random()),0) + local retval = self:Animate(n_l,state,0,0.95, math.max(0.15, drcsing and state < 0.03 and dlo > 0 and 1 or dlo*14),false) + if (retval ~= 0.95 and retval ~= 0) ~= self.DoorStates[id] then + if retval == 0.95 then + self:PlayOnce(sid.."o","",1,math.Rand(0.8,1.2)) + elseif retval == 0 then + self:PlayOnce(sid.."c","",1,math.Rand(0.8,1.2)) + end + self.DoorStates[id] = (retval ~= 0.95 and retval ~= 0) + end end end + self:SetSoundState("releasedr",-0.5*(self:GetPackedRatio("RightDoorCloseCylPressure_dPdT",0) + 0.8),1) + self:SetSoundState("releasedl",-0.5*(self:GetPackedRatio("LeftDoorCloseCylPressure_dPdT",0) + 0.8),1) local dT = self.DeltaTime --self.TunnelCoeff = 0.8 diff --git a/lua/entities/gmod_subway_81-714_lvz/init.lua b/lua/entities/gmod_subway_81-714_lvz/init.lua index d8256442..22437589 100644 --- a/lua/entities/gmod_subway_81-714_lvz/init.lua +++ b/lua/entities/gmod_subway_81-714_lvz/init.lua @@ -6,8 +6,8 @@ ENT.BogeyDistance = 650 -- Needed for gm trainspawner ENT.SyncTable = { "A53","A56","A54","A24","A39","A23","A14","A13","A31","A32","A16","A12","A49","A15","A27","A50","A8","A52","A19","A10","A22","A30","A1","A2","A3","A4","A5","A6","A72","A38","A20","A25","A37","A55","A45","A66","A51","A65","A28", "A70","A81","A80","A18", - "VB","GV", - "DriverValveBLDisconnect","DriverValveTLDisconnect","ParkingBrake", + "VB","GV","IDLK1","IDLK2","IDLK3","IDLK4","IDLK5","IDLK6","IDLK7","IDLK8", + "DriverValveBLDisconnect","DriverValveTLDisconnect","ParkingBrake","DVRDisconnect","DoorReleaseLeft","DoorReleaseRight", "A84","BPSNon","ConverterProtection","L_1","Start","VozvratRP","EmergencyBrakeValve" } @@ -145,6 +145,22 @@ function ENT:Initialize() self:SetNW2Int("BPSNType",self.BPSNType) self.OldTexture = 0 + self.OldPedestrianCount = 0 + + self.d_slow_speeds = { + {0.4, 0.8}, + --{0.3, 0.4}, + --{0.2, 0.3}, + --{0.3, 0.4}, + --{0.2, 0.3}, + } + self.d_fast_speeds = { + {1.2, 1.8}, + --{1.7, 1.8}, + --{1.8, 1.9}, + --{1.7, 1.8}, + --{2.1, 2.2}, + } self.Lamps = { broken = {}, } @@ -226,6 +242,22 @@ end function ENT:TrainSpawnerUpdate() local typ = self:GetNW2Int("Type") local num = self.WagonNumber + + local offs = math.random(1,3) + if self:GetNW2Int("RetainerLoad",1) == 5 then self:SetNW2Int("RetainerLoad",math.random(1,4)) end + self.Pneumatic:TriggerInput("KM013offset",5.0 + 0.1*(offs-1)) + self.Pneumatic:TriggerInput("KM013Over",math.random()>0.92) + self.Pneumatic:TriggerInput("VZ1Offset",0.8) + self.Pneumatic:TriggerInput("VZ2Offset",2.4) + self.CompressorEfficiency = math.random()*0.05 + 0.02 + self.AirConsumeRatio = math.random()*0.04 + 0.06 + self.AirLeakRatio = math.random()*0.002 + 0.001 + self.DVRLag = math.random()*0.5 + self.DVRHiss = math.random(2,5) + self.d_speeds = nil + self.DoorSpeedsDone = false + self.StuckSet = nil + math.randomseed(num+817171) local kvr=false local passtex = "Def_717SPBWhite" @@ -355,7 +387,29 @@ function ENT:Think() (Pneumatic.RightDoorState[3] > 0.5) or (Pneumatic.RightDoorState[4] > 0.5) - --self:SetPackedRatio("Crane", Pneumatic.RealDriverValvePosition) + if self.Speed > 1 and not self.LeftDoorsOpen and not self.RightDoorsOpen and not self.PedChecked then + self.OldPedestrianCount = self:GetNW2Float("PassengerCount") + self.PedChecked = true + self.left_side = nil + self.StuckSet = false + end + if not self.StuckSet then + local passenger_count = self:GetNW2Float("PassengerCount") + if self.Speed < 1 and math.abs(self.OldPedestrianCount - passenger_count) >= 1 and self.left_side == nil then + self.OldPedestrianCount = self:GetNW2Float("PassengerCount") + self.left_side = self.Pneumatic.DoorLeft or false + self.PedChecked = false + end + if self.left_side ~= nil then + if not (self.Pneumatic.DoorLeft or self.Pneumatic.DoorRight) then + local luava = math.random() + self["CanStuckPassenger"..(self.left_side and "Left" or "Right")] = (1-passenger_count/200) < luava and luava < 1 and 1--0.912 < luava and luava < 0.987 + self.StuckSet = true + if self.CanStuckPassengerLeft or self.CanStuckPassengerRight then print(self,"passenger to be caught! :D") end + end + end + end + --self:SetPackedRatio("Crane", Pneumatic.RealDriverValvePosition) --self:SetPackedRatio("Controller", (self.KV.ControllerPosition+3)/7) if Pneumatic.ValveType == 1 then self:SetPackedRatio("BLPressure", Pneumatic.ReservoirPressure/16.0) @@ -448,7 +502,7 @@ function ENT:OnButtonPress(button,ply) if self.CouchCap and self.Pneumatic.DriverValvePosition>2 then return end self.CouchCap = not self.CouchCap end - if not self.CouchCap and (not button:find("VB") and not button:find("GV") and not button:find("Isolation") and not button:find("Parking") and not button:find("Air")) then return true end + --if not self.CouchCap and (not button:find("VB") and not button:find("GV") and not button:find("Isolation") and not button:find("Parking") and not button:find("Air")) then return true end if button == "DriverValveDisconnect" then if self.DriverValveBLDisconnect.Value == 0 or self.DriverValveTLDisconnect.Value == 0 then diff --git a/lua/entities/gmod_subway_81-714_lvz/shared.lua b/lua/entities/gmod_subway_81-714_lvz/shared.lua index fdd6eec1..2a4242d1 100644 --- a/lua/entities/gmod_subway_81-714_lvz/shared.lua +++ b/lua/entities/gmod_subway_81-714_lvz/shared.lua @@ -196,6 +196,16 @@ function ENT:InitializeSounds() self.SoundNames["release2"] = {loop=true,"subway_trains/common/pneumatic/release_low.wav"} self.SoundPositions["release2"] = {350,1e9,Vector(-183,0,-70),0.4} + self.SoundNames["releasedl"] = {loop=true,"subway_trains/717/door_cyl/vdo_on.mp3"} + self.SoundPositions["releasedl"] = {150,20,Vector(282,62,12.5),1.5} + self.SoundNames["releasedr"] = {loop=true,"subway_trains/717/door_cyl/vdo2_on.mp3"} + self.SoundPositions["releasedr"] = {150,20,Vector(281,-62,12.8),1.5} + + self.SoundNames["dcyl_op_exh"] = "subway_trains/common/pneumatic/parking_brake_stop2.mp3" + self.SoundNames["dcyl_cl_exh"] = self.SoundNames["dcyl_op_exh"] + self.SoundPositions["dcyl_op_exh"] = {480,1e9,Vector(-420,45,-30),0.4} + self.SoundPositions["dcyl_cl_exh"] = {480,1e9,Vector(-420,45,-30),1.2} + self.SoundNames["parking_brake"] = {loop=true,"subway_trains/common/pneumatic/parking_brake.wav"} self.SoundNames["parking_brake_en"] = "subway_trains/common/pneumatic/parking_brake_stop.mp3" self.SoundNames["parking_brake_rel"] = "subway_trains/common/pneumatic/parking_brake_stop2.mp3" @@ -343,7 +353,7 @@ function ENT:InitializeSystems() -- Панель управления 81-710 self:LoadSystem("Panel","81_714_Panel") -- Пневмосистема 81-710 - self:LoadSystem("Pneumatic","81_717_Pneumatic",{br013_1 = true}) + self:LoadSystem("Pneumatic","81_714_NewPneumatic",{br013_1 = true}) -- Everything else self:LoadSystem("Battery") self:LoadSystem("PowerSupply","BPSN") diff --git a/lua/entities/gmod_subway_81-714_mvm/cl_init.lua b/lua/entities/gmod_subway_81-714_mvm/cl_init.lua index 974d47cb..f0ee77dd 100644 --- a/lua/entities/gmod_subway_81-714_mvm/cl_init.lua +++ b/lua/entities/gmod_subway_81-714_mvm/cl_init.lua @@ -410,6 +410,31 @@ for i,button in pairs(ENT.ButtonMap.AV_T.buttons) do } button.ID = "1:"..button.ID end +-- ДВР() +ENT.ButtonMap["DVR_87"] = { + pos = Vector(448,-53,-28), + ang = Angle(0,180,-5), + width = 1000, + height = 300, + scale = 0.0625, + hide=0.8, + + buttons = { + {ID = "DVRDisconnectToggle", x=0, y=0, w=1000, h=300, tooltip="", model = { + var="DVRDisconnect",sndid="disconnect_valve",--"brake_disconnect", + sndvol = 1, snd = function(val) return "disconnect_valve" end, + sndmin = 90, sndmax = 1e3, sndang = Angle(-90,0,0),} + }, + } +} +ENT.ClientSounds["DVRDisconnect"] = {{"DVR_disconnect",function() return "disconnect_valve" end,1,1,50,1e3,Angle(-90,0,0)}} + +ENT.ClientProps["DVR_disconnect"] = { + model = "models/metrostroi_train/81-707/cran1.mdl", + pos = Vector(431.15,-43.5,-24.7), + ang = Angle(-90,0,-90), + hideseat=0.2, +} ENT.ButtonMap["DriverValveBLTLDisconnect"] = { pos = Vector(-466,44,-18), @@ -433,6 +458,12 @@ ENT.ButtonMap["DriverValveBLTLDisconnect"] = { }}, } } +ENT.ClientProps["cran_dooropen_int"] = { + model = "models/metrostroi_train/door_crans/cran_dooropen_int.mdl", + pos = Vector(-19,-0.2,1.2), + ang = Angle(0,90,0), + hide = 1, +} ENT.ClientProps["brake_disconnect"] = { model = "models/metrostroi_train/81-707/cran1.mdl", @@ -580,6 +611,342 @@ ENT.ClientProps["door2"] = { hide=2, } +--Выключение дверей () +ENT.ButtonMap["Doors1_2_left"] = { + pos = Vector(-387,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod4Set",x=304,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd4Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr1_2_lft"] = { + pos = Vector(-317.5,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + --hide = 1 + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK4Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK4",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors3_4_left"] = { + pos = Vector(-156.5,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod3Set",x=300,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd3Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr3_4_lft"] = { + pos = Vector(-87.4,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + --hide = 0.8 + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK3Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK3",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors5_6_left"] = { + pos = Vector(73,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod2Set",x=304,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd2Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr5_6_lft"] = { + pos = Vector(142.7,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + --hide = 0.8 + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK2Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK2",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors7_8_left"] = { + pos = Vector(302,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod1Set",x=312,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd1Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr7_8_lft"] = { + pos = Vector(372.8,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + --hide = 0.8 + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK1Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK1",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors1_2_right"] = { + pos = Vector(-389,62,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod5Set",x=324,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd5Set",x=0,y=0,w= 100,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr1_2_rgh"] = { + pos = Vector(-317.5,64.45,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK5Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK5",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors3_4_right"] = { + pos = Vector(-156.6,62,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod6Set",x=298,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd6Set",x=0,y=0,w= 100,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr3_4_rgh"] = { + pos = Vector(-87.5,64.45,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK6Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK6",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors5_6_right"] = { + pos = Vector(72,62,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod7Set",x=312,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd7Set",x=0,y=0,w= 100,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr5_6_rgh"] = { + pos = Vector(142.56,64.5,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK7Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK7",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors7_8_right"] = { + pos = Vector(302,62,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "iod8Set",x=314,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "icd8Set",x=0,y=0,w= 100,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr7_8_rgh"] = { + pos = Vector(372.7,64.5,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "IDLK8Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="IDLK8",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["DoorReleaseRight"] = { + pos = Vector(284,-62,15), + ang = Angle(0,180,90), + width = 100, + height = 160, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "DoorReleaseRightToggle",x=0,y=0,w= 100,h = 40,tooltip="",model = { + var="DoorReleaseRight",sndid="doorsmanual_r", + sndvol = 1,snd = function(val) return "disconnect_valve" end, + sndmin = 90,sndmax = 1e3,sndang = Angle(-90,0,0),}}, + } +} +ENT.ClientProps["doorsmanual_r"] = { + model = "models/metrostroi_train/81-717/stop_mvm.mdl", + pos = Vector(282,-62.5,13.5), + ang = Angle(180,180,0), + hideseat=0.2, +} +ENT.ClientSounds["DoorReleaseRight"] = {{"doorsmanual_r",function() return "disconnect_valve" end,1,1,50,1e3,Angle(-90,0,0)}} + + +ENT.ButtonMap["DoorReleaseLeft"] = { + pos = Vector(274,62,15), + ang = Angle(0,0,90), + width = 100, + height = 160, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "DoorReleaseLeftToggle",x=0,y=0,w= 100,h = 40,tooltip="",model = { + var="DoorReleaseLeft",sndid="doorsmanual_l", + sndvol = 1,snd = function(val) return "disconnect_valve" end, + sndmin = 90,sndmax = 1e3,sndang = Angle(-90,0,0),}}, + } +} +ENT.ClientProps["doorsmanual_l"] = { + model = "models/metrostroi_train/81-717/stop_mvm.mdl", + pos = Vector(282,62,12.5), + ang = Angle(0,0,0), + hideseat=0.2, +} +ENT.ClientSounds["DoorReleaseLeft"] = {{"doorsmanual_l",function() return "disconnect_valve" end,1,1,50,1e3,Angle(-90,0,0)}} + -------------------------------------------------------------------------------- ENT.ClientPropsInitialized = false @@ -934,6 +1301,12 @@ function ENT:Think() self.ClientEnts.schemes:SetSubMaterial(1,scheme and scheme[1]) self.PassSchemesDone = true end + --() + local DrawDVR = self:GetPackedBool("CouchCap") + self:ShowHide("DVR_disconnect",DrawDVR) + self:HidePanel("DVR_87",not DrawDVR) + self:Animate("DVR_disconnect",self:GetPackedBool("DVRDisconnect") and 1 or 0,0.25,0, 4,false) + --() local Bortlamp_w = self:Animate("Bortlamp_w",self:GetPackedBool("DoorsW") and 1 or 0,0,1,16,false) local Bortlamp_g = self:Animate("Bortlamp_g",self:GetPackedBool("GRP") and 1 or 0,0,1,16,false) @@ -1053,13 +1426,13 @@ function ENT:Think() self:PlayOnce("door2","bass",self.Door2 and 1 or 0) end - - self:Animate("FrontBrake", self:GetNW2Bool("FbI") and 0 or 1,0,1, 3, false) self:Animate("FrontTrain", self:GetNW2Bool("FtI") and 1 or 0,0,1, 3, false) self:Animate("RearBrake", self:GetNW2Bool("RbI") and 0 or 1,0,1, 3, false) self:Animate("RearTrain", self:GetNW2Bool("RtI") and 1 or 0,0,1, 3, false) self:Animate("ParkingBrake", self:GetPackedBool("ParkingBrake") and 1 or 0,1,0, 3, false) + self:Animate("doorsmanual_r", self:GetNW2Bool("DoorReleaseRight") and 0 or 1, 0.25,0, 128, 3,false) + self:Animate("doorsmanual_l", self:GetNW2Bool("DoorReleaseLeft") and 0 or 1, 0.25,0, 128, 3,false) -- Main switch if self.LastGVValue ~= self:GetPackedBool("GV") then @@ -1071,42 +1444,46 @@ function ENT:Think() if not self.DoorStates then self.DoorStates = {} end if not self.DoorLoopStates then self.DoorLoopStates = {} end + if not self.DSprev then self.DSprev = {{1,1},{1,1},{1,1},{1,1}} end + if not self.DoorDelta then self.DoorDelta = {{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0}} end for i=0,3 do for k=0,1 do local st = k==1 and "DoorL" or "DoorR" - local doorstate = self:GetPackedBool(st) local id,sid = st..(i+1),"door"..i.."x"..k local state = self:GetPackedRatio(id) - --print(state,self.DoorStates[state]) - if (state ~= 1 and state ~= 0) ~= self.DoorStates[id] then - if doorstate and state < 1 or not doorstate and state > 0 then - else - if state > 0 then - self:PlayOnce(sid.."o","",1,math.Rand(0.8,1.2)) - else - self:PlayOnce(sid.."c","",1,math.Rand(0.8,1.2)) - end - end - self.DoorStates[id] = (state ~= 1 and state ~= 0) - end - if (state ~= 1 and state ~= 0) then + local prevstate = self.DSprev[i+1][k+1] + if math.abs(prevstate - state) > 0.01 then self.DoorLoopStates[id] = math.Clamp((self.DoorLoopStates[id] or 0) + 2*self.DeltaTime,0,1) - else - self.DoorLoopStates[id] = math.Clamp((self.DoorLoopStates[id] or 0) - 6*self.DeltaTime,0,1) - end + self.DoorDelta[i+1][k+1] = 0.0 + else + if self.DoorDelta[i+1][k+1] < 0.2 then + self.DoorDelta[i+1][k+1] = self.DoorDelta[i+1][k+1] + self.DeltaTime + else + self.DoorLoopStates[id] = math.Clamp((self.DoorLoopStates[id] or 0) - 1.2*self.DeltaTime,0,1) + end + end + self.DSprev[i+1][k+1] = state self:SetSoundState(sid.."r",self.DoorLoopStates[id],0.8+self.DoorLoopStates[id]*0.2) - local n_l = "door"..i.."x"..k--.."a" - --local n_r = "door"..i.."x"..k.."b" + local n_l = "door"..i.."x"..k local dlo = 1 - --local dro = 1 + local drcsing = state-(self.Anims[n_l] and self.Anims[n_l].oldival or 0) < 0 if self.Anims[n_l] then dlo = math.abs(state-(self.Anims[n_l] and self.Anims[n_l].oldival or 0)) if dlo <= 0 and self.Anims[n_l].oldspeed then dlo = self.Anims[n_l].oldspeed/14 end end - self:Animate(n_l,state,0,0.95, dlo*14,false)--0.8 + (-0.2+0.4*math.random()),0) - --self:Animate(n_r,state,0,1, dlo*14,false)--0.8 + (-0.2+0.4*math.random()),0) + local retval = self:Animate(n_l,state,0,0.95, math.max(0.15, drcsing and state < 0.03 and dlo > 0 and 1 or dlo*14),false) + if (retval ~= 0.95 and retval ~= 0) ~= self.DoorStates[id] then + if retval == 0.95 then + self:PlayOnce(sid.."o","",1,math.Rand(0.8,1.2)) + elseif retval == 0 then + self:PlayOnce(sid.."c","",1,math.Rand(0.8,1.2)) + end + self.DoorStates[id] = (retval ~= 0.95 and retval ~= 0) + end end end + self:SetSoundState("releasedr",-0.5*(self:GetPackedRatio("RightDoorCloseCylPressure_dPdT",0) + 0.8),1) + self:SetSoundState("releasedl",-0.5*(self:GetPackedRatio("LeftDoorCloseCylPressure_dPdT",0) + 0.8),1) local dT = self.DeltaTime local rollingi = math.min(1,self.TunnelCoeff+math.Clamp((self.StreetCoeff-0.82)/0.3,0,1)) diff --git a/lua/entities/gmod_subway_81-714_mvm/init.lua b/lua/entities/gmod_subway_81-714_mvm/init.lua index e444f6ac..ceccdf47 100644 --- a/lua/entities/gmod_subway_81-714_mvm/init.lua +++ b/lua/entities/gmod_subway_81-714_mvm/init.lua @@ -9,8 +9,8 @@ ENT.SyncTable = { "A22","A30","A1","A2","A3","A4","A5","A6","A72","A38","A20", "A25","A37","A55","A45","A66","A51","A65","A28","A70","AV2", "AV3","AV4","AV5","A81","AV6","A80","A18", - "VB","GV", - "DriverValveBLDisconnect","DriverValveTLDisconnect","ParkingBrake", + "VB","GV","IDLK1","IDLK2","IDLK3","IDLK4","IDLK5","IDLK6","IDLK7","IDLK8", + "DriverValveBLDisconnect","DriverValveTLDisconnect","ParkingBrake","DVRDisconnect","DoorReleaseLeft","DoorReleaseRight", "A84","BPSNon","ConverterProtection","L_1","OtklBV","Start","VozvratRP","EmergencyBrakeValve" } @@ -142,9 +142,25 @@ function ENT:Initialize() [31] = 32, -- Doors L<->R } + self.OldPedestrianCount = 0 + self.Lamps = { broken = {}, } + self.d_slow_speeds = { + {0.4, 0.8}, + --{0.3, 0.4}, + --{0.2, 0.3}, + --{0.3, 0.4}, + --{0.2, 0.3}, + } + self.d_fast_speeds = { + {1.2, 1.8}, + --{1.7, 1.8}, + --{1.8, 1.9}, + --{1.7, 1.8}, + --{2.1, 2.2}, + } local rand = math.random() > 0.8 and 1 or math.random(0.95,0.99) for i = 1,27 do if math.random() > rand then self.Lamps.broken[i] = math.random() > 0.5 end @@ -230,6 +246,20 @@ function ENT:TrainSpawnerUpdate() self:SetNW2Bool("Custom",self.CustomSettings) local num = self.WagonNumber math.randomseed(num+817171) + + local offs = math.random(1,3) + if self:GetNW2Int("RetainerLoad",1) == 5 then self:SetNW2Int("RetainerLoad",math.random(1,4)) end + self.Pneumatic:TriggerInput("KM013offset",5.0 + 0.1*(offs-1)) + self.Pneumatic:TriggerInput("KM013Over",math.random()>0.92) + self.Pneumatic:TriggerInput("VZ1Offset",0.8) + self.Pneumatic:TriggerInput("VZ2Offset",2.4) + self.CompressorEfficiency = math.random()*0.05 + 0.02 + self.AirConsumeRatio = math.random()*0.04 + 0.06 + self.AirLeakRatio = math.random()*0.002 + 0.001 + self.DVRLag = math.random()*0.5 + self.DVRHiss = math.random(2,5) + self.d_speeds = nil + if self.CustomSettings then local dot5 = self:GetNW2Int("Type")==2 local typ = self:GetNW2Int("BodyType") @@ -286,6 +316,9 @@ function ENT:TrainSpawnerUpdate() self.Pneumatic.ValveType = self:GetNW2Int("Crane",1) self.Announcer.AnnouncerType = self:GetNW2Int("Announcer",1) + self.DoorSpeedsDone = false + self.StuckSet = nil + self.WorkingLights = 6 self:SetPackedBool("Crane013",self.Pneumatic.ValveType == 2) self:UpdateTextures() @@ -346,6 +379,28 @@ function ENT:Think() (Pneumatic.RightDoorState[3] > 0.5) or (Pneumatic.RightDoorState[4] > 0.5) + if self.Speed > 1 and not self.LeftDoorsOpen and not self.RightDoorsOpen and not self.PedChecked then + self.OldPedestrianCount = self:GetNW2Float("PassengerCount") + self.PedChecked = true + self.left_side = nil + self.StuckSet = false + end + if not self.StuckSet then + local passenger_count = self:GetNW2Float("PassengerCount") + if self.Speed < 1 and math.abs(self.OldPedestrianCount - passenger_count) >= 1 and self.left_side == nil then + self.OldPedestrianCount = self:GetNW2Float("PassengerCount") + self.left_side = self.Pneumatic.DoorLeft or false + self.PedChecked = false + end + if self.left_side ~= nil then + if not (self.Pneumatic.DoorLeft or self.Pneumatic.DoorRight) then + local luava = math.random() + self["CanStuckPassenger"..(self.left_side and "Left" or "Right")] = (1-passenger_count/200) < luava and luava < 1 and 1--0.912 < luava and luava < 0.987 + self.StuckSet = true + if self.CanStuckPassengerLeft or self.CanStuckPassengerRight then print(self,"passenger to be caught! :D") end + end + end + end --self:SetPackedRatio("Crane", Pneumatic.RealDriverValvePosition) --self:SetPackedRatio("Controller", (self.KV.ControllerPosition+3)/7) if Pneumatic.ValveType == 1 then @@ -475,7 +530,7 @@ function ENT:OnButtonPress(button,ply) if self.CouchCap and self.Pneumatic.DriverValvePosition>2 then return end self.CouchCap = not self.CouchCap end - if not self.CouchCap and (not button:find("VB") and not button:find("GV") and not button:find("Isolation") and not button:find("Parking") and not button:find("Air")) then return true end + --if not self.CouchCap and (not button:find("VB") and not button:find("GV") and not button:find("Isolation") and not button:find("Parking") and not button:find("Air")) then return true end if button == "DriverValveDisconnect" then if self.DriverValveBLDisconnect.Value == 0 or self.DriverValveTLDisconnect.Value == 0 then diff --git a/lua/entities/gmod_subway_81-714_mvm/shared.lua b/lua/entities/gmod_subway_81-714_mvm/shared.lua index 8255f54d..9afa4a95 100644 --- a/lua/entities/gmod_subway_81-714_mvm/shared.lua +++ b/lua/entities/gmod_subway_81-714_mvm/shared.lua @@ -216,6 +216,16 @@ function ENT:InitializeSounds() self.SoundNames["release2"] = {loop=true,"subway_trains/common/pneumatic/release_low.wav"} self.SoundPositions["release2"] = {350,1e9,Vector(-183,0,-70),0.4} + self.SoundNames["releasedl"] = {loop=true,"subway_trains/717/door_cyl/vdo_on.mp3"} + self.SoundPositions["releasedl"] = {150,20,Vector(282,62,12.5),1.5} + self.SoundNames["releasedr"] = {loop=true,"subway_trains/717/door_cyl/vdo2_on.mp3"} + self.SoundPositions["releasedr"] = {150,20,Vector(281,-62,12.8),1.5} + + self.SoundNames["dcyl_op_exh"] = "subway_trains/common/pneumatic/parking_brake_stop2.mp3" + self.SoundNames["dcyl_cl_exh"] = self.SoundNames["dcyl_op_exh"] + self.SoundPositions["dcyl_op_exh"] = {480,1e9,Vector(-420,45,-30),0.4} + self.SoundPositions["dcyl_cl_exh"] = {480,1e9,Vector(-420,45,-30),1.2} + self.SoundNames["parking_brake"] = {loop=true,"subway_trains/common/pneumatic/parking_brake.wav"} self.SoundNames["parking_brake_en"] = "subway_trains/common/pneumatic/parking_brake_stop.mp3" self.SoundNames["parking_brake_rel"] = "subway_trains/common/pneumatic/parking_brake_stop2.mp3" @@ -360,7 +370,7 @@ function ENT:InitializeSystems() -- Панель управления 81-710 self:LoadSystem("Panel","81_714_Panel") -- Пневмосистема 81-710 - self:LoadSystem("Pneumatic","81_717_Pneumatic",{br013_1 = true}) + self:LoadSystem("Pneumatic","81_714_NewPneumatic",{br013_1 = true}) -- Everything else self:LoadSystem("Battery") self:LoadSystem("PowerSupply","BPSN") diff --git a/lua/entities/gmod_subway_81-717_lvz/cl_init.lua b/lua/entities/gmod_subway_81-717_lvz/cl_init.lua index f49cdcb3..bc3b4d6a 100644 --- a/lua/entities/gmod_subway_81-717_lvz/cl_init.lua +++ b/lua/entities/gmod_subway_81-717_lvz/cl_init.lua @@ -2393,6 +2393,12 @@ ENT.ClientProps["gv_wrench"] = { hide = 0.5, } +ENT.ClientProps["cran_dooropen_head"] = { + model = "models/metrostroi_train/door_crans/cran_dooropen_head.mdl", + pos = Vector(5,0.15,1), + ang = Angle(0,-90,0), + hide = 1, +} ENT.ClientProps["parking_brake"] = { model = "models/metrostroi_train/81-707/cran3.mdl", @@ -2417,6 +2423,46 @@ ENT.ButtonMap["AirDistributor"] = { } } +ENT.ButtonMap["AutostopValve"] = { + pos = Vector(365.8,-67.6,-56), + ang = Angle(0,0,90), + width = 130, + height = 40, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "AutostopValveSet",x=0,y=0,w= 130,h = 40,tooltip=""}, + } +} +-- ДВР () +ENT.ButtonMap["DVR_87"] = { + pos = Vector(-398,35,-28), + ang = Angle(0,180,5), + width = 1000, + height = 300, + scale = 0.0625, + hide=0.8, + + buttons = { + {ID = "DVRDisconnectToggle", x=0, y=0, w=1000, h=300, tooltip="", model = { + var="DVRDisconnect",sndid="disconnect_valve",--"brake_disconnect", + sndvol = 1, snd = function(val) return "disconnect_valve" end, + sndmin = 90, sndmax = 1e3, sndang = Angle(-90,0,0),} + }, + } +} +ENT.ClientSounds["DVRDisconnect"] = {{"DVR_disconnect",function() return "disconnect_valve" end,1,1,50,1e3,Angle(-90,0,0)}} + +ENT.ClientProps["DVR_disconnect"] = { + model = "models/metrostroi_train/81-707/cran1.mdl", + pos = Vector(-451.15,43.5,-24.7), + ang = Angle(-90,-180,-90), + hideseat=0.2, +} + for i=0,4 do ENT.ClientProps["TrainNumberL"..i] = { model = "models/metrostroi_train/common/bort_numbers.mdl", @@ -2851,6 +2897,378 @@ for i = 0,11 do hideseat = 1.1, } end + +ENT.ButtonMap["Doors7_8_right"] = { + pos = Vector(-386,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod4Set",x=298,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd4Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr7_8_rgh"] = { + pos = Vector(-317.5,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK4Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK4",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors5_6_right"] = { + pos = Vector(-157,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod3Set",x=306,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd3Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr5_6_rgh"] = { + pos = Vector(-87.5,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK3Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK3",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors3_4_right"] = { + pos = Vector(73,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod2Set",x=302,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd2Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr3_4_rgh"] = { + pos = Vector(142.6,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK2Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK2",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors1_2_right"] = { + pos = Vector(300,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod1Set",x=334,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd1Set",x=15,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["Doors1_2_right_outer"] = { + pos = Vector(332.5,-66,47), + ang = Angle(0,0,90), + width = 120, + height = 952, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "outerhod1Set",x=10,y=0,w= 100,h = 952,tooltip=""}, + } +} +ENT.ButtonMap["bldr1_2_rgh"] = { + pos = Vector(372.8,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK1Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK1",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + +ENT.ButtonMap["Doors7_8_left"] = { + pos = Vector(-386,62,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod5Set",x=294,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd5Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr7_8_lft"] = { + pos = Vector(-317.58,64.45,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK5Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK5",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors5_6_left"] = { + pos = Vector(-158,62.8,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod6Set",x=314,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd6Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr5_6_lft"] = { + pos = Vector(-87.5,64.45,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK6Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK6",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors3_4_left"] = { + pos = Vector(74,62,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod7Set",x=294,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd7Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr3_4_lft"] = { + pos = Vector(142.56,64.5,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK7Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK7",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors1_2_left"] = { + pos = Vector(303,62,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod8Set",x=306,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd8Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr1_2_lft"] = { + pos = Vector(372.7,64.5,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK8Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK8",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + +ENT.ButtonMap["DoorReleaseExtra"] = { + pos = Vector(278,-62,-2), + ang = Angle(0,0,-90), + width = 100, + height = 160, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "DoorReleaseExtraToggle",x=0,y=130,w= 100,h = 30,tooltip="", model = { + var="DoorReleaseExtra",sndid="disconnect_valve",--"brake_disconnect", + sndvol = 1, snd = function(val) return "disconnect_valve" end, + sndmin = 90, sndmax = 1e3, sndang = Angle(-90,0,0),} + }, + } +} +ENT.ClientProps["doorsmanual_e"] = { + model = "models/metrostroi_train/81-717/stop_mvm.mdl", + pos = Vector(281,-62.3,12.3), + ang = Angle(0,180,0), + hideseat=0.2, +} +ENT.ClientSounds["DoorReleaseExtra"] = {{"DoorReleaseExtra",function() return "disconnect_valve" end,1,1,50,1e3,Angle(-90,0,0)}} + + +ENT.ButtonMap["DoorReleaseRight"] = { + pos = Vector(-290,-62,14.5), + ang = Angle(0,180,90), + width = 100, + height = 160, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "DoorReleaseRightToggle",x=0,y=0,w= 100,h = 30,tooltip="", model = { + var="DoorReleaseRight",sndid="disconnect_valve",--"brake_disconnect", + sndvol = 1, snd = function(val) return "disconnect_valve" end, + sndmin = 90, sndmax = 1e3, sndang = Angle(-90,0,0),} + }, + } +} +ENT.ClientProps["doorsmanual_r"] = { + model = "models/metrostroi_train/81-717/stop_mvm.mdl", + pos = Vector(-296,-62.13,12.5), + ang = Angle(0,180,0), + hideseat=0.2, +} +ENT.ClientSounds["DoorReleaseRight"] = {{"doorsmanual_r",function() return "disconnect_valve" end,1,1,50,1e3,Angle(-90,0,0)}} + + +ENT.ButtonMap["DoorReleaseLeft"] = { + pos = Vector(-298,62,14.5), + ang = Angle(0,0,90), + width = 100, + height = 160, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "DoorReleaseLeftToggle",x=0,y=0,w= 100,h = 30,tooltip="", model = { + var="DoorReleaseLeft",sndid="disconnect_valve",--"brake_disconnect", + sndvol = 50, snd = function(val) return "disconnect_valve" end, + sndmin = 90, sndmax = 1e3, sndang = Angle(-90,0,0),} + }, + } +} +ENT.ClientProps["doorsmanual_l"] = { + model = "models/metrostroi_train/81-717/stop_mvm.mdl", + pos = Vector(-295.9,62.5,13.59), + ang = Angle(180,0,0), + hideseat=0.2, +} +ENT.ClientSounds["DoorReleaseLeft"] = {{"doorsmanual_l",function() return "disconnect_valve" end,1,1,50,1e3,Angle(-90,90,0)}} --[[ local pos = Vector(454.3,-28.3,12+3.5) local ang = Angle(60,-30,180) @@ -3125,9 +3543,14 @@ function ENT:Think() self:Animate("voltmeter2",self:GetPackedRatio("EnginesVoltage"),0.398-0.002,0.648+0.002,nil,nil)--,256,2,0.01) self:Animate("ampermeter2",self:GetPackedRatio("EnginesCurrent"),0.398-0.009,0.648+0.008,nil,nil,256,2,0.01) self:Animate("volt1",self:GetPackedRatio("BatteryVoltage"),0.625,0.376,256,0.2,false) + ----------------- + self:Animate("doorsmanual_e", self:GetNW2Bool("DoorReleaseExtra") and 0 or 1, 0.25,0, 128, 3,false) + self:Animate("doorsmanual_r", self:GetNW2Bool("DoorReleaseRight") and 0 or 1, 0.25,0, 128, 3,false) + self:Animate("doorsmanual_l", self:GetNW2Bool("DoorReleaseLeft") and 0 or 1, 0.25,0, 128, 3,false) + ----------------- --self:Animate("voltmeter",0.5 or self:GetPackedRatio("EnginesVoltage"),0.396,0.658,nil,nil)--,256,2,0.01) --self:Animate("ampermeter",0.5 or self:GetPackedRatio("EnginesCurrent"),0.39,0.655,nil,nil,256,2,0.01) - self:Animate("stopkran", self:GetPackedBool("EmergencyBrakeValve") and 0 or 1, 0.25,0, 128, 3,false) + --self:Animate("stopkran", self:GetPackedBool("EmergencyBrakeValve") and 0 or 1, 0.25,0, 128, 3,false) self:ShowHide("SSpeed1",self:GetPackedBool("LUDS")) self:ShowHide("SSpeed2",self:GetPackedBool("LUDS")) @@ -3361,6 +3784,11 @@ function ENT:Think() self:ShowHide("EPV_disconnect",c013) self:HidePanel("EPVDisconnect",not c013) self:HidePanel("DriverValveDisconnect",not c013) + + local DrawDVR = self:GetPackedBool("ShowDVR") + self:ShowHide("DVR_disconnect",DrawDVR) + self:HidePanel("DVR_87",not DrawDVR) + self:Animate("DVR_disconnect",self:GetPackedBool("DVRDisconnect") and 1 or 0,0.25,0, 4,false) --[[ -- Animate AV switches for i in ipairs(self.Panel.AVMap) do local value = self:GetPackedBool(64+(i-1)) and 1 or 0 @@ -3376,43 +3804,54 @@ function ENT:Think() self:Animate("gv_wrench",self.LastGVValue and 1 or 0,0.5,0.9,128,1,false) self:ShowHideSmooth("gv_wrench", CurTime() < self.ResetTime and 1 or 0.1) --self:InitializeSounds() + -- reworked doors animation and sounds + local dT = self.DeltaTime if not self.DoorStates then self.DoorStates = {} end if not self.DoorLoopStates then self.DoorLoopStates = {} end - for i=0,3 do + if not self.DSprev then self.DSprev = {{1,1},{1,1},{1,1},{1,1}} end + if not self.DoorDelta then self.DoorDelta = {{0,0},{0,0},{0,0},{0,0}} end + for i=0,3 do for k=0,1 do local st = k==1 and "DoorL" or "DoorR" - local doorstate = self:GetPackedBool(st) local id,sid = st..(i+1),"door"..i.."x"..k local state = self:GetPackedRatio(id) - --print(state,self.DoorStates[state]) - if (state ~= 1 and state ~= 0) ~= self.DoorStates[id] then - if doorstate and state < 1 or not doorstate and state > 0 then - else - if state > 0 then - self:PlayOnce(sid.."o","",1,math.Rand(0.8,1.2)) - else - self:PlayOnce(sid.."c","",1,math.Rand(0.8,1.2)) - end - end - self.DoorStates[id] = (state ~= 1 and state ~= 0) - end - if (state ~= 1 and state ~= 0) then + local prevstate = self.DSprev[i+1][k+1] + + if math.abs(prevstate - state) > 0.01 then self.DoorLoopStates[id] = math.Clamp((self.DoorLoopStates[id] or 0) + 2*self.DeltaTime,0,1) - else - self.DoorLoopStates[id] = math.Clamp((self.DoorLoopStates[id] or 0) - 6*self.DeltaTime,0,1) - end - self:SetSoundState(sid.."r",self.DoorLoopStates[id],0.8+self.DoorLoopStates[id]*0.2) - local n_l = "door"..i.."x"..k--.."a" + self.DoorDelta[i+1][k+1] = 0.0 + else + if self.DoorDelta[i+1][k+1] < 0.2 then + self.DoorDelta[i+1][k+1] = self.DoorDelta[i+1][k+1] + self.DeltaTime + else --was 6 + self.DoorLoopStates[id] = math.Clamp((self.DoorLoopStates[id] or 0) - 1*self.DeltaTime,0,1) + end + end + self.DSprev[i+1][k+1] = state + self:SetSoundState(sid.."r",self.DoorLoopStates[id],0.8+self.DoorLoopStates[id]*0.2) + local n_l = "door"..i.."x"..k--.."a" --local n_r = "door"..i.."x"..k.."b" local dlo = 1 + local drcsing = state-(self.Anims[n_l] and self.Anims[n_l].oldival or 0) < 0 if self.Anims[n_l] then dlo = math.abs(state-(self.Anims[n_l] and self.Anims[n_l].oldival or 0)) if dlo <= 0 and self.Anims[n_l].oldspeed then dlo = self.Anims[n_l].oldspeed/14 end end - self:Animate(n_l,state,0,0.95,dlo*14,false)--0.8 + (-0.2+0.4*math.random()),0) - --self:Animate(n_r,state,0,1,dlo*14,false)--0.8 + (-0.2+0.4*math.random()),0) + + local retval = self:Animate(n_l,state,0,0.95,math.max(0.15, drcsing and state < 0.03 and dlo > 0 and 1 or dlo*14),false) + if (retval ~= 0.95 and retval ~= 0) ~= self.DoorStates[id] then + if retval == 0.95 then -- was state > 0 + self:PlayOnce(sid.."o","",1,math.Rand(0.8,1.2)) + elseif retval == 0 then -- was else + self:PlayOnce(sid.."c","",1,math.Rand(0.8,1.2)) + end + self.DoorStates[id] = (retval ~= 0.95 and retval ~= 0) + end end end + self:SetSoundState("releasedr",-0.5*(self:GetPackedRatio("RightDoorCloseCylPressure_dPdT",0) + 0.8),1) + self:SetSoundState("releasedl",-0.5*(self:GetPackedRatio("LeftDoorCloseCylPressure_dPdT",0) + 0.8),1) + self:SetSoundState("releasede",-0.3*(self:GetPackedRatio("_1stRightDoorCloseCylPressure_dPdT",0) + 1.2),2) --[[local dT = self.DeltaTime --self.TunnelCoeff = 0.8 @@ -3687,6 +4126,9 @@ function ENT:DrawPost() self:DrawOnPanel("AirDistributor",function() draw.DrawText(self:GetNW2Bool("AD") and "Air Distributor ON" or "Air Distributor OFF","Trebuchet24",0,0,Color(0,0,0,255)) end) + self:DrawOnPanel("AutostopValve",function() + draw.DrawText("Autostop Valve", "Trebuchet24",0,6,Color(0,0,0,255)) + end) end function ENT:OnButtonPressed(button) diff --git a/lua/entities/gmod_subway_81-717_lvz/init.lua b/lua/entities/gmod_subway_81-717_lvz/init.lua index 9c0de180..894ca9cd 100644 --- a/lua/entities/gmod_subway_81-717_lvz/init.lua +++ b/lua/entities/gmod_subway_81-717_lvz/init.lua @@ -17,7 +17,7 @@ ENT.SyncTable = { "A58","A59","A61","A15","A66", "RC1","VB","VRD","PB", "UAVA","UAVAC", "DriverValveBLDisconnect","DriverValveTLDisconnect","DriverValveDisconnect","ParkingBrake","EPK", - "VUD2","VDL","VOPD","Wiper", "GV", "RC2","VAU", + "VUD2","VDL","VOPD","Wiper", "GV", "RC2","VAU", "HDLK1","HDLK2","HDLK3","HDLK4","HDLK5","HDLK6","HDLK7","HDLK8","DVRDisconnect","DoorReleaseLeft","DoorReleaseRight","DoorReleaseExtra", "KH","VAV","KSZD","VZP","VSOSD", "PAM7","PAM8","PAM9","PAMLeft","PAMRight","PAM4","PAM5","PAM6","PAMUp","PAM1","PAM2","PAM3","PAMDown","PAM0","PAMEnter","PAMEsc","PAMF","PAMM","PAMP", } @@ -224,6 +224,10 @@ function ENT:Initialize() ID = "AirDistributorDisconnectToggle", Pos = Vector(-177, -66, -50), Radius = 20, }, + { + ID = "AutostopValveToggle", + Pos = Vector(377, -66, -50), Radius = 20, + }, } -- Cross connections in train wires @@ -244,9 +248,25 @@ function ENT:Initialize() self.OtsekDoor1 = false self.OtsekDoor2 = false + self.OldPedestrianCount = 0 + self.Lamps = { broken = {}, } + self.d_slow_speeds = { + {0.4, 0.8}, + --{0.3, 0.4}, + --{0.2, 0.3}, + --{0.3, 0.4}, + --{0.2, 0.3}, + } + self.d_fast_speeds = { + {1.2, 1.8}, + --{1.7, 1.8}, + --{1.8, 1.9}, + --{1.7, 1.8}, + --{2.1, 2.2}, + } local rand = math.random() > 0.95 and 1 or math.random(0.95,0.99) for i = 1,12 do if math.random() > rand then self.Lamps.broken[i] = math.random() > 0.7 end @@ -342,6 +362,20 @@ function ENT:TrainSpawnerUpdate() local cabtex = "Def_PUAV" local ring,puring = math.ceil(math.random()*4) self:SetNW2Int("RingType",ring) + + local offs = math.random(1,3) + if self:GetNW2Int("RetainerLoad",1) == 5 then self:SetNW2Int("RetainerLoad",math.random(1,4)) end + self.Pneumatic:TriggerInput("KM013offset",5.0 + 0.1*(offs-1)) + self.Pneumatic:TriggerInput("KM013Over",math.random()>0.92) + self.Pneumatic:TriggerInput("VZ1Offset",0.9) + self.Pneumatic:TriggerInput("VZ2Offset",2.5) + self.CompressorEfficiency = math.random()*0.05 + 0.02 + self.AirConsumeRatio = math.random()*0.04 + 0.06 + self.AirLeakRatio = math.random()*0.002 + 0.001 + self.DVRLag = math.random()*0.5 + self.DVRHiss = math.random(2,5) + self.d_speeds = nil + if typ == 1 then --PAKSDM self.Electric:TriggerInput("X2PS",0) self.Electric:TriggerInput("Type",self.Electric.LVZ_4) @@ -436,6 +470,8 @@ function ENT:TrainSpawnerUpdate() self:SetNW2Bool("NewSeats",self:GetNW2Int("SeatType") == 4 or self:GetNW2Int("SeatType") == 3 or self:GetNW2Int("SeatType") == 1 and math.random()>0.5)--(kvr or seats)) self:SetNW2Bool("NewSeatsBlue",self:GetNW2Int("SeatType") == 4 or self:GetNW2Bool("NewSeats") and self:GetNW2Int("SeatType") == 1 and math.random()>0.5) end + self.StuckSet = nil + self.DoorSpeedsDone = false self.Pneumatic.ValveType = self:GetNW2Int("Crane",1)+1 self.Announcer.AnnouncerType = self:GetNW2Int("Announcer",1) self:UpdateTextures() @@ -507,6 +543,7 @@ function ENT:Think() self:SetPackedBool("RedLights",Panel.RedLight2 > 0) self:SetPackedBool("CabLights",Panel.CabLights>0) self:SetPackedBool("EqLights",Panel.EqLights>0) + self:SetPackedBool("ShowDVR",self.OtsekDoor1) self:SetPackedBool("PanelLights",Panel.PanelLights > 0.5) --[[if not self.KEKTimer or CurTime()-self.KEKTimer > 3 then @@ -588,6 +625,35 @@ function ENT:Think() (self.Pneumatic.RightDoorState[3] > 0.5) or (self.Pneumatic.RightDoorState[4] > 0.5) + if #self.WagonList == self.CarCount and not self.d_speeds then + local d_spd_type = math.random() + for k,v in ipairs(self.WagonList) do + v.d_speeds = d_spd_type < 0.5 and v.d_fast_speeds or v.d_slow_speeds + end + end + + if self.Speed > 1 and not self.LeftDoorsOpen and not self.RightDoorsOpen and not self.PedChecked then + self.OldPedestrianCount = self:GetNW2Float("PassengerCount") + self.PedChecked = true + self.left_side = nil + self.StuckSet = false + end + if not self.StuckSet then + local passenger_count = self:GetNW2Float("PassengerCount") + if self.Speed < 1 and math.abs(self.OldPedestrianCount - passenger_count) >= 1 and self.left_side == nil then + self.OldPedestrianCount = self:GetNW2Float("PassengerCount") + self.left_side = self.Pneumatic.DoorLeft or false + end + if self.left_side ~= nil then + if not (self.Pneumatic.DoorLeft or self.Pneumatic.DoorRight) then + local luava = math.random() + self["CanStuckPassenger"..(self.left_side and "Left" or "Right")] = (1-passenger_count/200)*0.8 < luava and luava < 1 and 1--0.912 < luava and luava < 0.987 + self.StuckSet = true + --if self.CanStuckPassengerLeft or self.CanStuckPassengerRight then print(self,"passenger to be caught! :D") end + end + end + end + -- DIP/power self:SetPackedBool("LUDS",Panel.LUDS > 0.5) diff --git a/lua/entities/gmod_subway_81-717_lvz/shared.lua b/lua/entities/gmod_subway_81-717_lvz/shared.lua index 5ec9bde4..f3696cf6 100644 --- a/lua/entities/gmod_subway_81-717_lvz/shared.lua +++ b/lua/entities/gmod_subway_81-717_lvz/shared.lua @@ -405,6 +405,17 @@ function ENT:InitializeSounds() self.SoundNames["release2"] = {loop=true,"subway_trains/common/pneumatic/release_low.wav"} self.SoundPositions["release2"] = {350,1e9,Vector(-183,0,-70),0.4} + self.SoundNames["releasedl"] = {loop=true,"subway_trains/717/door_cyl/vdo_on.mp3"} + self.SoundPositions["releasedl"] = {150,20,Vector(282,62,12.5),1.5} + self.SoundNames["releasedr"] = {loop=true,"subway_trains/717/door_cyl/vdo2_on.mp3"} + self.SoundPositions["releasedr"] = {150,20,Vector(281,-62,12.8),1.5} + self.SoundNames["releasede"] = {loop=true,"subway_trains/717/door_cyl/vdo3_on.mp3"} + self.SoundPositions["releasede"] = {150,20,Vector(278,-62,-2),1.5} + + self.SoundNames["dcyl_op_exh"] = "subway_trains/common/pneumatic/parking_brake_stop2.mp3" + self.SoundNames["dcyl_cl_exh"] = self.SoundNames["dcyl_op_exh"] + self.SoundPositions["dcyl_op_exh"] = {480,1e9,Vector(-420,45,-30),0.4} + self.SoundPositions["dcyl_cl_exh"] = {480,1e9,Vector(-420,45,-30),1.2} self.SoundNames["parking_brake"] = {loop=true,"subway_trains/common/pneumatic/parking_brake.wav"} self.SoundNames["parking_brake_en"] = "subway_trains/common/pneumatic/parking_brake_stop.mp3" self.SoundNames["parking_brake_rel"] = "subway_trains/common/pneumatic/parking_brake_stop2.mp3" @@ -832,7 +843,7 @@ function ENT:InitializeSystems() self:LoadSystem("PR_14X_Panels") -- Пневмосистема 81-710 - self:LoadSystem("Pneumatic","81_717_Pneumatic") + self:LoadSystem("Pneumatic","81_717_NewPneumatic") -- Панель управления 81-710 self:LoadSystem("Panel","81_717LVZ_Panel") -- Everything else @@ -970,6 +981,16 @@ ENT.Spawner = { train.NumberRangesID = typ end end, + postfunc = function(cartable,wagnum) + for k,v in ipairs(cartable) do + local val = v._Settings.SpawnMode + v.CarCount = wagnum + v.InitIsoCountNeeded = true + v.Pneumatic.TrainLinePressure = val==3 and math.random()*4 or val==2 and 4.5+math.random()*3 or 7.6+math.random()*0.6 + v.Pneumatic.WorkingChamberPressure = val==3 and math.random()*1.0 or val==2 and 4.0+math.random()*1.0 or 5.2 + v.Pneumatic.BrakeLinePressure = val==4 and 5.2 or 2.3 + end + end, wagfunc = function(ent,i,num) end, --Metrostroi.Skins.GetTable("Texture","Spawner.Texture",false,"train"), @@ -992,6 +1013,14 @@ ENT.Spawner = { if ent._SpawnerStarted~=val then ent.VB:TriggerInput("Set",val<=2 and 1 or 0) ent.ParkingBrake:TriggerInput("Set",val==3 and 1 or 0) + ent.Pneumatic.LeftDoorState = val ~= 4 and {1,1,1,1} or {0,0,0,0} + ent.Pneumatic.RightDoorState = val ~= 4 and {1,1,1,1} or {0,0,0,0} + for _i = 1,4 do + ent.Pneumatic.DSprev[_i][1] = ent.Pneumatic.RightDoorState[_i] + ent.Pneumatic.DSprev[_i][2] = ent.Pneumatic.LeftDoorState[_i] + end + ent.Pneumatic.DoorLeft = val == 4 and true or false + ent.Pneumatic.DoorRight = val == 4 and true or false if ent.AR63 then local first = i==1 or _LastSpawner~=CurTime() ent.OhrSig:TriggerInput("Set",val<4 and 1 or 0) diff --git a/lua/entities/gmod_subway_81-717_lvz_custom.lua b/lua/entities/gmod_subway_81-717_lvz_custom.lua index e973c6cd..47904169 100644 --- a/lua/entities/gmod_subway_81-717_lvz_custom.lua +++ b/lua/entities/gmod_subway_81-717_lvz_custom.lua @@ -46,6 +46,16 @@ ENT.Spawner = { train.NumberRangesID = typ end end, + postfunc = function(cartable,wagnum) + for k,v in ipairs(cartable) do + local val = v._Settings.SpawnMode + v.CarCount = wagnum + v.InitIsoCountNeeded = true + v.Pneumatic.TrainLinePressure = val==3 and math.random()*4 or val==2 and 4.5+math.random()*3 or 7.6+math.random()*0.6 + v.Pneumatic.WorkingChamberPressure = val==3 and math.random()*1.0 or val==2 and 4.0+math.random()*1.0 or 5.2 + v.Pneumatic.BrakeLinePressure = val==4 and 5.2 or 2.3 + end + end, {"Type","Spawner.717.Type","List",{"Spawner.717.Type.Line2","Spawner.717.Type.Line4","Spawner.717.Type.Line5"}}, {"Scheme","Spawner.717.Schemes","List",function() local Schemes = {} @@ -59,11 +69,20 @@ ENT.Spawner = { {}, {"SeatType","Spawner.717.SeatType","List",{"Spawner.717.Common.Random","Spawner.717.Common.Old","Spawner.717.Common.New","Spawner.717.Common.NewBlue"}}, {}, + {"RetainerLoad","Spawner.717.RetainerLoad","List",{"Spawner.717.RetainerLoad.1","Spawner.717.RetainerLoad.2","Spawner.717.RetainerLoad.3","Spawner.717.RetainerLoad.4","Spawner.717.Common.Random"}}, {"SpawnMode","Spawner.717.SpawnMode","List",{"Spawner.717.SpawnMode.Full","Spawner.717.SpawnMode.Deadlock","Spawner.717.SpawnMode.NightDeadlock","Spawner.717.SpawnMode.Depot"}, nil,function(ent,val,rot,i,wagnum,rclk) if rclk then return end if ent._SpawnerStarted~=val then ent.VB:TriggerInput("Set",val<=2 and 1 or 0) ent.ParkingBrake:TriggerInput("Set",val==3 and 1 or 0) + ent.Pneumatic.LeftDoorState = val ~= 4 and {1,1,1,1} or {0,0,0,0} + ent.Pneumatic.RightDoorState = val ~= 4 and {1,1,1,1} or {0,0,0,0} + for _i = 1,4 do + ent.Pneumatic.DSprev[_i][1] = ent.Pneumatic.RightDoorState[_i] + ent.Pneumatic.DSprev[_i][2] = ent.Pneumatic.LeftDoorState[_i] + end + ent.Pneumatic.DoorLeft = val == 4 and true or false + ent.Pneumatic.DoorRight = val == 4 and true or false if ent.AR63 then local first = i==1 or _LastSpawner~=CurTime() ent.OhrSig:TriggerInput("Set",val<4 and 1 or 0) diff --git a/lua/entities/gmod_subway_81-717_mvm/cl_init.lua b/lua/entities/gmod_subway_81-717_mvm/cl_init.lua index afe5a49b..dd15526b 100644 --- a/lua/entities/gmod_subway_81-717_mvm/cl_init.lua +++ b/lua/entities/gmod_subway_81-717_mvm/cl_init.lua @@ -2048,9 +2048,34 @@ ENT.ButtonMap["AutostopValve"] = { screenHide = true, buttons = { - {ID = "AutostopValveSet",x=0,y=0,w= 130,h = 40,tooltip="Сорвать срывной клапан"}, + {ID = "AutostopValveSet",x=0,y=0,w= 130,h = 40,tooltip=""}, } } +-- ДВР () +ENT.ButtonMap["DVR_87"] = { + pos = Vector(-398,35,-28), + ang = Angle(0,180,5), + width = 1000, + height = 300, + scale = 0.0625, + hide=0.8, + + buttons = { + {ID = "DVRDisconnectToggle", x=0, y=0, w=1000, h=300, tooltip="", model = { + var="DVRDisconnect",sndid="disconnect_valve",--"brake_disconnect", + sndvol = 1, snd = function(val) return "disconnect_valve" end, + sndmin = 90, sndmax = 1e3, sndang = Angle(-90,0,0),} + }, + } +} +ENT.ClientSounds["DVRDisconnect"] = {{"DVR_disconnect",function() return "disconnect_valve" end,1,1,50,1e3,Angle(-90,0,0)}} + +ENT.ClientProps["DVR_disconnect"] = { + model = "models/metrostroi_train/81-707/cran1.mdl", + pos = Vector(-451.15,43.5,-24.7), + ang = Angle(-90,-180,-90), + hideseat=0.2, +} for i=0,4 do ENT.ClientProps["TrainNumberL"..i] = { @@ -2116,6 +2141,13 @@ ENT.ClientProps["route2"] = { end, } +ENT.ClientProps["cran_dooropen_head"] = { + model = "models/metrostroi_train/door_crans/cran_dooropen_head.mdl", + pos = Vector(5,0.15,1), + ang = Angle(0,-90,0), + hide = 1, +} + ENT.ButtonMap["CabinDoor"] = { pos = Vector(414.5,64,56.7), ang = Angle(0,0,90), @@ -2555,6 +2587,378 @@ for i = 0,24 do hideseat = 1.1, } end + +ENT.ButtonMap["Doors7_8_right"] = { + pos = Vector(-386,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod4Set",x=298,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd4Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr7_8_rgh"] = { + pos = Vector(-317.5,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK4Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK4",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors5_6_right"] = { + pos = Vector(-157,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod3Set",x=306,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd3Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr5_6_rgh"] = { + pos = Vector(-87.5,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK3Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK3",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors3_4_right"] = { + pos = Vector(73,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod2Set",x=302,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd2Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr3_4_rgh"] = { + pos = Vector(142.6,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK2Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK2",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors1_2_right"] = { + pos = Vector(300,-62,-50), + ang = Angle(0,0,-90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod1Set",x=334,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd1Set",x=15,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["Doors1_2_right_outer"] = { + pos = Vector(332.5,-66,47), + ang = Angle(0,0,90), + width = 120, + height = 952, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "outerhod1Set",x=10,y=0,w= 100,h = 952,tooltip=""}, + } +} +ENT.ButtonMap["bldr1_2_rgh"] = { + pos = Vector(372.8,-64.48,-50), + ang = Angle(0,90,-90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK1Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK1",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + +ENT.ButtonMap["Doors7_8_left"] = { + pos = Vector(-386,62,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod5Set",x=294,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd5Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr7_8_lft"] = { + pos = Vector(-317.58,64.45,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK5Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK5",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors5_6_left"] = { + pos = Vector(-158,62.8,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod6Set",x=314,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd6Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr5_6_lft"] = { + pos = Vector(-87.5,64.45,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK6Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK6",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors3_4_left"] = { + pos = Vector(74,62,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod7Set",x=294,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd7Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr3_4_lft"] = { + pos = Vector(142.56,64.5,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK7Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK7",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + + +ENT.ButtonMap["Doors1_2_left"] = { + pos = Vector(303,62,50), + ang = Angle(0,0,90), + width = 520, + height = 1000, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "hod8Set",x=306,y=0,w= 100,h = 1000,tooltip=""}, + {ID = "hcd8Set",x=0,y=0,w= 60,h = 1000,tooltip=""}, + } +} +ENT.ButtonMap["bldr1_2_lft"] = { + pos = Vector(372.7,64.5,0), + ang = Angle(0,-90,90), + width = 20, + height = 450, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "HDLK8Toggle", x=0, y=180, w=20, h=100, tooltip="", model = { + model = "models/metrostroi_train/81-717/battery_enabler.mdl", + var="HDLK8",speed=0.5,vmin=1,vmax=0.8, + sndvol = 0.8, snd = function(val) return val and "pak_on" or "pak_off" end,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0), + }}, + } +} + +ENT.ButtonMap["DoorReleaseExtra"] = { + pos = Vector(278,-62,-2), + ang = Angle(0,0,-90), + width = 100, + height = 160, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "DoorReleaseExtraToggle",x=0,y=130,w= 100,h = 30,tooltip="", model = { + var="DoorReleaseExtra",sndid="disconnect_valve",--"brake_disconnect", + sndvol = 1, snd = function(val) return "disconnect_valve" end, + sndmin = 90, sndmax = 1e3, sndang = Angle(-90,0,0),} + }, + } +} +ENT.ClientProps["doorsmanual_e"] = { + model = "models/metrostroi_train/81-717/stop_mvm.mdl", + pos = Vector(281,-62.3,12.3), + ang = Angle(0,180,0), + hideseat=0.2, +} +ENT.ClientSounds["DoorReleaseExtra"] = {{"DoorReleaseExtra",function() return "disconnect_valve" end,1,1,50,1e3,Angle(-90,0,0)}} + + +ENT.ButtonMap["DoorReleaseRight"] = { + pos = Vector(-290,-62,14.5), + ang = Angle(0,180,90), + width = 100, + height = 160, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "DoorReleaseRightToggle",x=0,y=0,w= 100,h = 30,tooltip="", model = { + var="DoorReleaseRight",sndid="disconnect_valve",--"brake_disconnect", + sndvol = 1, snd = function(val) return "disconnect_valve" end, + sndmin = 90, sndmax = 1e3, sndang = Angle(-90,0,0),} + }, + } +} +ENT.ClientProps["doorsmanual_r"] = { + model = "models/metrostroi_train/81-717/stop_mvm.mdl", + pos = Vector(-296,-62.13,12.5), + ang = Angle(0,180,0), + hideseat=0.2, +} +ENT.ClientSounds["DoorReleaseRight"] = {{"doorsmanual_r",function() return "disconnect_valve" end,1,1,50,1e3,Angle(-90,0,0)}} + + +ENT.ButtonMap["DoorReleaseLeft"] = { + pos = Vector(-298,62,14.5), + ang = Angle(0,0,90), + width = 100, + height = 160, + scale = 0.1, + hideseat=0.1, + hide=true, + screenHide = true, + + buttons = { + {ID = "DoorReleaseLeftToggle",x=0,y=0,w= 100,h = 30,tooltip="", model = { + var="DoorReleaseLeft",sndid="disconnect_valve",--"brake_disconnect", + sndvol = 50, snd = function(val) return "disconnect_valve" end, + sndmin = 90, sndmax = 1e3, sndang = Angle(-90,0,0),} + }, + } +} +ENT.ClientProps["doorsmanual_l"] = { + model = "models/metrostroi_train/81-717/stop_mvm.mdl", + pos = Vector(-295.9,62.5,13.59), + ang = Angle(180,0,0), + hideseat=0.2, +} +ENT.ClientSounds["DoorReleaseLeft"] = {{"doorsmanual_l",function() return "disconnect_valve" end,1,1,50,1e3,Angle(-90,90,0)}} --[[ local pos = Vector(450.273468,-32.306019,13.236823) @@ -2810,6 +3214,11 @@ function ENT:Think() self:HidePanel("DriverValveBLDisconnect",self:GetPackedBool("Crane013")) self:HidePanel("DriverValveTLDisconnect",self:GetPackedBool("Crane013")) + local DrawDVR = self:GetPackedBool("ShowDVR") + self:ShowHide("DVR_disconnect",DrawDVR) + self:HidePanel("DVR_87",not DrawDVR) + self:Animate("DVR_disconnect",self:GetPackedBool("DVRDisconnect") and 1 or 0,0.25,0, 4,false) + self:Animate("brake334",self:GetPackedRatio("CranePosition")/5,0.35,0.65,256,24) self:Animate("brake013", Cpos[self:GetPackedRatio("CranePosition")] or 0, 0.03, 0.458, 256,24) @@ -2944,6 +3353,11 @@ function ENT:Think() self:Animate("train_disconnect",self:GetPackedBool("DriverValveTLDisconnect") and 1 or 0,0.25,0, 4,false) self:Animate("valve_disconnect",self:GetPackedBool("DriverValveDisconnect") and 1 or 0,0.25,0, 4,false) self:Animate("stopkran", self:GetPackedBool("EmergencyBrakeValve") and 0 or 1, 0.25,0, 128, 3,false) + ----------------- + self:Animate("doorsmanual_e", self:GetNW2Bool("DoorReleaseExtra") and 0 or 1, 0.25,0, 128, 3,false) + self:Animate("doorsmanual_r", self:GetNW2Bool("DoorReleaseRight") and 0 or 1, 0.25,0, 128, 3,false) + self:Animate("doorsmanual_l", self:GetNW2Bool("DoorReleaseLeft") and 0 or 1, 0.25,0, 128, 3,false) + ----------------- local c013 = self:GetNW2Int("Crane",1)==2 self:ShowHide("brake_valve_334",not c013) @@ -3060,41 +3474,61 @@ function ENT:Think() self:ShowHideSmooth("gv_wrench", CurTime() < self.ResetTime and 1 or 0.1) --self:InitializeSounds() - for i=0,3 do + -- reworked doors animation and sounds + local dT = self.DeltaTime + if not self.DoorStates then self.DoorStates = {} end + if not self.DoorLoopStates then self.DoorLoopStates = {} end + if not self.DSprev then self.DSprev = {{1,1},{1,1},{1,1},{1,1}} end + if not self.DoorDelta then self.DoorDelta = {{0,0},{0,0},{0,0},{0,0}} end + for i=0,3 do for k=0,1 do local st = k==1 and "DoorL" or "DoorR" - local doorstate = self:GetPackedBool(st) local id,sid = st..(i+1),"door"..i.."x"..k local state = self:GetPackedRatio(id) - if (state ~= 1 and state ~= 0) ~= self.DoorStates[id] then - if doorstate and state < 1 or not doorstate and state > 0 then - else - if state > 0 then - self:PlayOnce(sid.."o","",1,math.Rand(0.8,1.2)) - else - self:PlayOnce(sid.."c","",1,math.Rand(0.8,1.2)) - end - end - self.DoorStates[id] = (state ~= 1 and state ~= 0) - end - if (state ~= 1 and state ~= 0) then + local prevstate = self.DSprev[i+1][k+1] + + if math.abs(prevstate - state) > 0.01 then self.DoorLoopStates[id] = math.Clamp((self.DoorLoopStates[id] or 0) + 2*self.DeltaTime,0,1) - else - self.DoorLoopStates[id] = math.Clamp((self.DoorLoopStates[id] or 0) - 6*self.DeltaTime,0,1) - end - self:SetSoundState(sid.."r",self.DoorLoopStates[id],0.8+self.DoorLoopStates[id]*0.2) - local n_l = "door"..i.."x"..k--.."a" + self.DoorDelta[i+1][k+1] = 0.0 + else + if self.DoorDelta[i+1][k+1] < 0.2 then + self.DoorDelta[i+1][k+1] = self.DoorDelta[i+1][k+1] + self.DeltaTime + else --was 6 + self.DoorLoopStates[id] = math.Clamp((self.DoorLoopStates[id] or 0) - 1*self.DeltaTime,0,1) + end + end + self.DSprev[i+1][k+1] = state + self:SetSoundState(sid.."r",self.DoorLoopStates[id],0.8+self.DoorLoopStates[id]*0.2) + local n_l = "door"..i.."x"..k--.."a" --local n_r = "door"..i.."x"..k.."b" local dlo = 1 + local drcsing = state-(self.Anims[n_l] and self.Anims[n_l].oldival or 0) < 0 if self.Anims[n_l] then dlo = math.abs(state-(self.Anims[n_l] and self.Anims[n_l].oldival or 0)) if dlo <= 0 and self.Anims[n_l].oldspeed then dlo = self.Anims[n_l].oldspeed/14 end end - self:Animate(n_l,state,0,0.95,dlo*14,false)--0.8 + (-0.2+0.4*math.random()),0) - --self:Animate(n_r,state,0,1,dlo*14,false)--0.8 + (-0.2+0.4*math.random()),0) + local retval = self:Animate(n_l,state,0,0.95,math.max(0.15, drcsing and state < 0.03 and dlo > 0 and 1 or dlo*14),false) + --Заменил в условии "серверное" положение створок на возвращаемое из функции Animate, чтобы хлопок не раздавался раньше фактического смыкания створок + --UPD: зато он стал раздаваться после прихода КД :D (исправил это другим костылем, а именно: принудительным захлопыванием створок на максимальной скорости, если сервер + -- говорит, что двери закрыты, а на клиенте они еще нет) + if (retval ~= 0.95 and retval ~= 0) ~= self.DoorStates[id] then + --if doorstate and state < 1 or not doorstate and state > 0 then Закомментил, чтобы хлопанье раздавалось даже при + --else открытии-закрытии дверей руками + if retval == 0.95 then -- was state > 0 + self:PlayOnce(sid.."o","",1,math.Rand(0.8,1.2)) + elseif retval == 0 then -- was else + self:PlayOnce(sid.."c","",1,math.Rand(0.8,1.2)) + end + --end + --self.DoorStates[id] = (state ~= 1 and state ~= 0) + self.DoorStates[id] = (retval ~= 0.95 and retval ~= 0) + end end end + self:SetSoundState("releasedr",-0.5*(self:GetPackedRatio("RightDoorCloseCylPressure_dPdT",0) + 0.8),1) + self:SetSoundState("releasedl",-0.5*(self:GetPackedRatio("LeftDoorCloseCylPressure_dPdT",0) + 0.8),1) + self:SetSoundState("releasede",-0.3*(self:GetPackedRatio("_1stRightDoorCloseCylPressure_dPdT",0) + 1.2),2) local dT = self.DeltaTime local rollingi = math.min(1,self.TunnelCoeff+math.Clamp((self.StreetCoeff-0.82)/0.3,0,1)) diff --git a/lua/entities/gmod_subway_81-717_mvm/init.lua b/lua/entities/gmod_subway_81-717_mvm/init.lua index 3ed1da5a..95e810a0 100644 --- a/lua/entities/gmod_subway_81-717_mvm/init.lua +++ b/lua/entities/gmod_subway_81-717_mvm/init.lua @@ -18,7 +18,7 @@ ENT.SyncTable = { "AIS","A15","A81","A68","A80", "RC1","VB","BPS","UOS", "PB", "UAVA","UAVAC", "DriverValveBLDisconnect","DriverValveTLDisconnect","DriverValveDisconnect","ParkingBrake","EPK","EmergencyBrakeValve", - "VUD2","VDL","Wiper", "GV", + "VUD2","VDL","Wiper", "GV", "HDLK1","HDLK2","HDLK3","HDLK4","HDLK5","HDLK6","HDLK7","HDLK8","DVRDisconnect","DoorReleaseLeft","DoorReleaseRight","DoorReleaseExtra", "R_ASNPMenu","R_ASNPUp","R_ASNPDown","R_ASNPOn" , "ALSFreq","Ring","VBD", "V11","V12","V13","UPPS_On","SAB1" @@ -224,9 +224,25 @@ function ENT:Initialize() self.OtsekDoor1 = false self.OtsekDoor2 = false + self.OldPedestrianCount = 0 + self.Lamps = { broken = {}, } + self.d_slow_speeds = { + {0.4, 0.8}, + --{0.3, 0.4}, + --{0.2, 0.3}, + --{0.3, 0.4}, + --{0.2, 0.3}, + } + self.d_fast_speeds = { + {1.2, 1.8}, + --{1.7, 1.8}, + --{1.8, 1.9}, + --{1.7, 1.8}, + --{2.1, 2.2}, + } local rand = math.random() > 0.8 and 1 or math.random(0.95,0.99) for i = 1,25 do if math.random() > rand then self.Lamps.broken[i] = math.random() > 0.5 end @@ -379,6 +395,19 @@ function ENT:TrainSpawnerUpdate() end--]] --self:SetNW2String("PassTexture","Def_717MSKBlue") -- + local offs = math.random(1,3) + if self:GetNW2Int("RetainerLoad",1) == 5 then self:SetNW2Int("RetainerLoad",math.random(1,4)) end + self.Pneumatic:TriggerInput("KM013offset",5.0 + 0.1*(offs-1)) + self.Pneumatic:TriggerInput("KM013Over",math.random()>0.92) + self.Pneumatic:TriggerInput("VZ1Offset",0.9) + self.Pneumatic:TriggerInput("VZ2Offset",2.5) + self.CompressorEfficiency = math.random()*0.05 + 0.02 + self.AirConsumeRatio = math.random()*0.04 + 0.06 + self.AirLeakRatio = math.random()*0.002 + 0.001 + self.DVRLag = math.random()*0.5 + self.DVRHiss = math.random(2,5) + self.d_speeds = nil + local num = self.WagonNumber self:SetNW2Bool("Custom",self.CustomSettings) math.randomseed(num+817171) @@ -504,6 +533,8 @@ function ENT:TrainSpawnerUpdate() self.Lights[31][2] = Vector(465,45 , -23.5) self.Lights[32][2] = Vector(465,0 , 52) end]] + self.StuckSet = nil + self.DoorSpeedsDone = false self.Announcer.AnnouncerType = self:GetNW2Int("Announcer",1) self.LampType = self:GetNW2Int("LampType",1) self.Pneumatic.ValveType = self:GetNW2Int("Crane",1) @@ -568,6 +599,7 @@ function ENT:Think() self:SetPackedBool("RedLights",Panel.RedLight2 > 0) self:SetPackedBool("CabLights",Panel.CabLights>0) self:SetPackedBool("EqLights",Panel.EqLights>0) + self:SetPackedBool("ShowDVR",self.OtsekDoor1) self:SetPackedBool("PanelLights",Panel.PanelLights > 0.5) @@ -615,6 +647,35 @@ function ENT:Think() self.LeftDoorsOpen = (Pneumatic.LeftDoorState[1] > 0.5) or (Pneumatic.LeftDoorState[2] > 0.5) or (Pneumatic.LeftDoorState[3] > 0.5) or (Pneumatic.LeftDoorState[4] > 0.5) self.RightDoorsOpen = (Pneumatic.RightDoorState[1] > 0.5) or (Pneumatic.RightDoorState[2] > 0.5) or (Pneumatic.RightDoorState[3] > 0.5) or (Pneumatic.RightDoorState[4] > 0.5) + if #self.WagonList == self.CarCount and not self.d_speeds then + local d_spd_type = math.random() + for k,v in ipairs(self.WagonList) do + v.d_speeds = d_spd_type < 0.5 and v.d_fast_speeds or v.d_slow_speeds + end + end + + if self.Speed > 1 and not self.LeftDoorsOpen and not self.RightDoorsOpen and not self.PedChecked then + self.OldPedestrianCount = self:GetNW2Float("PassengerCount") + self.PedChecked = true + self.left_side = nil + self.StuckSet = false + end + if not self.StuckSet then + local passenger_count = self:GetNW2Float("PassengerCount") + if self.Speed < 1 and math.abs(self.OldPedestrianCount - passenger_count) >= 1 and self.left_side == nil then + self.OldPedestrianCount = self:GetNW2Float("PassengerCount") + self.left_side = self.Pneumatic.DoorLeft or false + end + if self.left_side ~= nil then + if not (self.Pneumatic.DoorLeft or self.Pneumatic.DoorRight) then + local luava = math.random() + self["CanStuckPassenger"..(self.left_side and "Left" or "Right")] = (1-passenger_count/200)*0.8 < luava and luava < 1 and 1--0.912 < luava and luava < 0.987 + self.StuckSet = true + --if self.CanStuckPassengerLeft or self.CanStuckPassengerRight then print(self,"passenger to be caught! :D") end + end + end + end + -- DIP/power self:SetPackedBool("LUDS",Panel.LUDS > 0.5) diff --git a/lua/entities/gmod_subway_81-717_mvm/shared.lua b/lua/entities/gmod_subway_81-717_mvm/shared.lua index 3b921046..29d43c76 100644 --- a/lua/entities/gmod_subway_81-717_mvm/shared.lua +++ b/lua/entities/gmod_subway_81-717_mvm/shared.lua @@ -429,6 +429,18 @@ function ENT:InitializeSounds() self.SoundNames["release2"] = {loop=true,"subway_trains/common/pneumatic/release_low.wav"} self.SoundPositions["release2"] = {350,1e9,Vector(-183,0,-70),0.4} + self.SoundNames["releasedl"] = {loop=true,"subway_trains/717/door_cyl/vdo_on.mp3"} + self.SoundPositions["releasedl"] = {150,20,Vector(282,62,12.5),1.5} + self.SoundNames["releasedr"] = {loop=true,"subway_trains/717/door_cyl/vdo2_on.mp3"} + self.SoundPositions["releasedr"] = {150,20,Vector(281,-62,12.8),1.5} + self.SoundNames["releasede"] = {loop=true,"subway_trains/717/door_cyl/vdo3_on.mp3"} + self.SoundPositions["releasede"] = {150,20,Vector(278,-62,-2),1.5} + + self.SoundNames["dcyl_op_exh"] = "subway_trains/common/pneumatic/parking_brake_stop2.mp3" + self.SoundNames["dcyl_cl_exh"] = self.SoundNames["dcyl_op_exh"] + self.SoundPositions["dcyl_op_exh"] = {480,1e9,Vector(-420,45,-30),0.4} + self.SoundPositions["dcyl_cl_exh"] = {480,1e9,Vector(-420,45,-30),1.2} + self.SoundNames["parking_brake"] = {loop=true,"subway_trains/common/pneumatic/parking_brake.wav"} self.SoundNames["parking_brake_en"] = "subway_trains/common/pneumatic/parking_brake_stop.mp3" self.SoundNames["parking_brake_rel"] = "subway_trains/common/pneumatic/parking_brake_stop2.mp3" @@ -823,7 +835,7 @@ function ENT:InitializeSystems() self:LoadSystem("PR_14X_Panels") -- Пневмосистема 81-710 - self:LoadSystem("Pneumatic","81_717_Pneumatic") + self:LoadSystem("Pneumatic","81_717_NewPneumatic") -- Панель управления 81-710 self:LoadSystem("Panel","81_717_Panel") -- Everything else @@ -948,6 +960,16 @@ ENT.Spawner = { --Metrostroi.Skins.GetTable("Texture","Spawner.Texture",false,"train"), --Metrostroi.Skins.GetTable("PassTexture","Spawner.PassTexture",false,"pass"), --Metrostroi.Skins.GetTable("CabTexture","Spawner.CabTexture",false,"cab"), + postfunc = function(cartable,wagnum) + for k,v in ipairs(cartable) do + local val = v._Settings.SpawnMode + v.CarCount = wagnum + v.InitIsoCountNeeded = true + v.Pneumatic.TrainLinePressure = val==3 and math.random()*4 or val==2 and 4.5+math.random()*3 or 7.6+math.random()*0.6 + v.Pneumatic.WorkingChamberPressure = val==3 and math.random()*1.0 or val==2 and 4.0+math.random()*1.0 or 5.2 + v.Pneumatic.BrakeLinePressure = val==4 and 5.2 or 2.3 + end + end, {"Announcer","Spawner.717.Announcer","List",function() local Announcer = {} for k,v in pairs(Metrostroi.AnnouncementsASNP or {}) do if not v.riu then Announcer[k] = v.name or k end end @@ -963,6 +985,14 @@ ENT.Spawner = { if ent._SpawnerStarted~=val then ent.VB:TriggerInput("Set",val<=2 and 1 or 0) ent.ParkingBrake:TriggerInput("Set",val==3 and 1 or 0) + ent.Pneumatic.LeftDoorState = val ~= 4 and {1,1,1,1} or {0,0,0,0} + ent.Pneumatic.RightDoorState = val ~= 4 and {1,1,1,1} or {0,0,0,0} + for _i = 1,4 do + ent.Pneumatic.DSprev[_i][1] = ent.Pneumatic.RightDoorState[_i] + ent.Pneumatic.DSprev[_i][2] = ent.Pneumatic.LeftDoorState[_i] + end + ent.Pneumatic.DoorLeft = val == 4 and true or false + ent.Pneumatic.DoorRight = val == 4 and true or false if ent.AR63 then local first = i==1 or _LastSpawner~=CurTime() ent.A53:TriggerInput("Set",val<=2 and 1 or 0) diff --git a/lua/entities/gmod_subway_81-717_mvm_custom.lua b/lua/entities/gmod_subway_81-717_mvm_custom.lua index 843d2be7..383137e9 100644 --- a/lua/entities/gmod_subway_81-717_mvm_custom.lua +++ b/lua/entities/gmod_subway_81-717_mvm_custom.lua @@ -47,6 +47,16 @@ ENT.Spawner = { train.NumberRangesID = body>1 and (math.random()>0.5 and 6 or 7) or (math.random()>0.5 and 4 or 5) end end, + postfunc = function(cartable,wagnum) + for k,v in ipairs(cartable) do + local val = v._Settings.SpawnMode + v.CarCount = wagnum + v.InitIsoCountNeeded = true + v.Pneumatic.TrainLinePressure = val==3 and math.random()*4 or val==2 and 4.5+math.random()*3 or 7.6+math.random()*0.6 + v.Pneumatic.WorkingChamberPressure = val==3 and math.random()*1.0 or val==2 and 4.0+math.random()*1.0 or 5.2 + v.Pneumatic.BrakeLinePressure = val==4 and 5.2 or 2.3 + end + end, {"Type","Spawner.717.Type","List",{"81-717","81-717.5"}}, {"BodyType","Spawner.717.BodyType","List",{"Spawner.717.Type.MVM","Spawner.717.Type.LVZ"}}, {"Scheme","Spawner.717.Schemes","List",function() @@ -72,11 +82,20 @@ ENT.Spawner = { {"RingType","Spawner.717.RingType","List",{"Spawner.717.Common.Random","Spawner.717.RingType.1","Spawner.717.RingType.2","Spawner.717.RingType.3","Spawner.717.RingType.4","Spawner.717.RingType.5","Spawner.717.RingType.6","Spawner.717.RingType.7","Spawner.717.RingType.8"}}, {"BPSNType","Spawner.717.BPSNType","List",{"Spawner.717.Common.Random","Spawner.717.BPSNType.1","Spawner.717.BPSNType.2","Spawner.717.BPSNType.3","Spawner.717.BPSNType.4","Spawner.717.BPSNType.5","Spawner.717.BPSNType.6","Spawner.717.BPSNType.7","Spawner.717.BPSNType.8","Spawner.717.BPSNType.9","Spawner.717.BPSNType.10","Spawner.717.BPSNType.11","Spawner.717.BPSNType.12","Spawner.717.BPSNType.13"}}, {}, + {"RetainerLoad","Spawner.717.RetainerLoad","List",{"Spawner.717.RetainerLoad.1","Spawner.717.RetainerLoad.2","Spawner.717.RetainerLoad.3","Spawner.717.RetainerLoad.4","Spawner.717.Common.Random"}}, {"SpawnMode","Spawner.717.SpawnMode","List",{"Spawner.717.SpawnMode.Full","Spawner.717.SpawnMode.Deadlock","Spawner.717.SpawnMode.NightDeadlock","Spawner.717.SpawnMode.Depot"}, nil,function(ent,val,rot,i,wagnum,rclk) if rclk then return end if ent._SpawnerStarted~=val then ent.VB:TriggerInput("Set",val<=2 and 1 or 0) ent.ParkingBrake:TriggerInput("Set",val==3 and 1 or 0) + ent.Pneumatic.LeftDoorState = val ~= 4 and {1,1,1,1} or {0,0,0,0} + ent.Pneumatic.RightDoorState = val ~= 4 and {1,1,1,1} or {0,0,0,0} + for _i = 1,4 do + ent.Pneumatic.DSprev[_i][1] = ent.Pneumatic.RightDoorState[_i] + ent.Pneumatic.DSprev[_i][2] = ent.Pneumatic.LeftDoorState[_i] + end + ent.Pneumatic.DoorLeft = val == 4 and true or false + ent.Pneumatic.DoorRight = val == 4 and true or false if ent.AR63 then local first = i==1 or _LastSpawner~=CurTime() ent.A53:TriggerInput("Set",val<=2 and 1 or 0) diff --git a/lua/entities/gmod_subway_base/init.lua b/lua/entities/gmod_subway_base/init.lua index 67595f72..cd8ea425 100644 --- a/lua/entities/gmod_subway_base/init.lua +++ b/lua/entities/gmod_subway_base/init.lua @@ -276,6 +276,10 @@ function ENT:Initialize() self.PrevRightDoorsOpening = false self.RightDoorsOpening = false + self.BrakeLineConnectedCarsCounter = 1 + self.TrainLineConnectedCarsCounter = 1 + self.CarCount = false + -- Get default train mass if IsValid(self:GetPhysicsObject()) then self.NormalMass = self:GetPhysicsObject():GetMass() @@ -551,6 +555,48 @@ function ENT:GetWagonCount() return #self.WagonList end +function ENT:UpdateIsolation(wagnum) + if not self.IsoCountTimer and (self.InitIsoCountNeeded or self.RepeatIsoUpdate) then + self.IsoCountTimer = CurTime() + end + if (self.InitIsoCountNeeded or self.RepeatIsoUpdate) and (CurTime() - self.IsoCountTimer > 2) then + self:UpdateIsolationConnectedCarCounter("Brake") + self:UpdateIsolationConnectedCarCounter("Train") + if self:GetBLConnectedWagonCount() == wagnum and self:GetTLConnectedWagonCount() == wagnum or self.RepeatIsoUpdate then + self.InitIsoCountNeeded = false + self.RepeatIsoUpdate = nil + end + self.IsoCountTimer = nil + end +end + +function ENT:UpdateIsolationConnectedCarCounter(line) + self[line.."LineConnectedCarsCounter"] = 1 + local checked = {} + local function count(this) + checked[this] = true + if this.FrontTrain and not checked[this.FrontTrain] and this["Front"..line.."LineIsolation"].Value == 0 then + if this.FrontTrain.FrontTrain == this and this.FrontTrain["Front"..line.."LineIsolation"].Value == 0 or this.FrontTrain.RearTrain == this and this.FrontTrain["Rear"..line.."LineIsolation"].Value == 0 then count(this.FrontTrain) end + end + if this.RearTrain and not checked[this.RearTrain] and this["Rear"..line.."LineIsolation"].Value == 0 then + if this.RearTrain.FrontTrain == this and this.RearTrain["Front"..line.."LineIsolation"].Value == 0 or this.RearTrain.RearTrain == this and this.RearTrain["Rear"..line.."LineIsolation"].Value == 0 then count(this.RearTrain) end + end + end + count(self) + local b = 0 + for k,v in pairs(checked) do b = b + 1 end + for k,v in pairs(checked) do k[line.."LineConnectedCarsCounter"] = b end + --PrintMessage(HUD_PRINTTALK, Format("Вагон %u; line: %s; cars: %u",self:GetWagonNumber(), line, self[line.."LineConnectedCarsCounter"])) +end + +function ENT:GetBLConnectedWagonCount() + return self.BrakeLineConnectedCarsCounter +end + +function ENT:GetTLConnectedWagonCount() + return self.TrainLineConnectedCarsCounter +end + function ENT:ReadCell(Address) if Address < 0 then return nil end if Address == 0 then @@ -1991,6 +2037,8 @@ function ENT:Think() self:SetNW2Float("Accel",math.Round((self.OldSpeed or 0) - (self.Speed or 0)*(self.SpeedSign or 0),2)) self:SetNW2Float("TrainSpeed",self.Speed) self.OldSpeed = (self.Speed or 0)*(self.SpeedSign or 0) + + if self.InitIsoCountNeeded or self.RepeatIsoUpdate then self:UpdateIsolation(self.CarCount) end for k,v in pairs(self.CustomThinks) do if k ~= "BaseClass" then v(self) end end self:NextThink(CurTime()+0.05) @@ -2162,6 +2210,7 @@ function ENT:ButtonEvent(button,state,ply) if ShouldFireEvents(self.ButtonBuffer[button],state) then if state == false and not self:OnButtonRelease(button,ply) then self:TriggerInput(button,0.0) + if button:match("LineIsolationToggle") and self.CarCount then self:UpdateIsolationConnectedCarCounter(button:sub(-24,-20)) end elseif state ~= false and not self:OnButtonPress(button,ply) then self:TriggerInput(button,1.0) if self.Plombs and button:sub(-2,-1) == "Pl" and self.Plombs[button:sub(1,-3)] then diff --git a/lua/entities/gmod_train_couple/init.lua b/lua/entities/gmod_train_couple/init.lua index 414688cc..1dbffeae 100644 --- a/lua/entities/gmod_train_couple/init.lua +++ b/lua/entities/gmod_train_couple/init.lua @@ -209,6 +209,8 @@ net.Receive("metrostroi-coupler-menu",function(_,ply) ftrain.FrontBrakeLineIsolation:TriggerInput("Set",state and 0 or 1) ftrain.FrontTrainLineIsolation:TriggerInput("Set",state and 0 or 1) end + train.RepeatIsoUpdate = true + ftrain.RepeatIsoUpdate = true end elseif not isfront and train.RearBrakeLineIsolation and train.RearTrainLineIsolation then local state = train.RearBrakeLineIsolation.Value>0 or train.RearTrainLineIsolation.Value>0 @@ -223,6 +225,8 @@ net.Receive("metrostroi-coupler-menu",function(_,ply) rtrain.FrontBrakeLineIsolation:TriggerInput("Set",state and 0 or 1) rtrain.FrontTrainLineIsolation:TriggerInput("Set",state and 0 or 1) end + train.RepeatIsoUpdate = true + rtrain.RepeatIsoUpdate = true end end end diff --git a/lua/metrostroi/systems/sys_81_714_new_pneumatic.lua b/lua/metrostroi/systems/sys_81_714_new_pneumatic.lua new file mode 100644 index 00000000..69b83582 --- /dev/null +++ b/lua/metrostroi/systems/sys_81_714_new_pneumatic.lua @@ -0,0 +1,899 @@ +-------------------------------------------------------------------------------- +-- 81-714 pneumatic system +-------------------------------------------------------------------------------- +-- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o. +-- Contains proprietary code. See license.txt for additional information. +-------------------------------------------------------------------------------- +Metrostroi.DefineSystem("81_714_NewPneumatic") +TRAIN_SYSTEM.DontAccelerateSimulation = true + +function TRAIN_SYSTEM:Initialize(parameters) + self.ValveType = 1 + -- Position of the train drivers valve + -- Type 1 (334) + -- 1 Accelerated charge + -- 2 Normal charge (brake release) + -- 3 Closed + -- 4 Service application + -- 5 Emergency application + -- + -- Type 2 (013) + -- 1 Accelerated charge + -- 2 Normal charge (brake release) + -- 3 Closed + -- 4 Service application + -- 5 Emergency application + self.DriverValvePosition = 2 + self.RealDriverValvePosition = self.DriverValvePosition + + + -- Pressure in reservoir + self.ParkingBrakePressure = 0 + self.ReservoirPressure = 0.0 -- atm + -- Pressure in trains feed line + self.TrainLinePressure = 8.0 -- atm + -- Pressure in trains brake line + self.BrakeLinePressure = 3.0 -- atm + -- Pressure in brake cylinder + self.BrakeCylinderPressure = 0.0 -- atm + -- Pressure in the door line + self.DoorLinePressure = 0.0 -- atm + self.LeftDoorCloseCylPressure = 0.0 + self.LeftDoorOpenCylPressure = 0.0 + self.RightDoorCloseCylPressure = 0.0 + self.RightDoorOpenCylPressure = 0.0 + self.LeftExhausted = false + self.RightExhausted = false + + self.OldBrakeLinePressure = 0.0 + self.BCPressure = 0 + -- Air distrubutor part + self.WorkingChamberPressure = 5.2 + -- Disconnected KM 334 vessels (trainline and brakeline parts between disconnect valve and KM itself) emulation + self.TLDisconnectPressure = 0.0 + self.BLDisconnectPressure = 0.0 + self.WCChargeValve = false + self.PN1 = 0 + self.PN2 = 0 + self.cranPres = 0 + self.KM013offset = 5.2 + self.km013_overcharge = false + + --DKPT + self.Train:LoadSystem("DKPT","Relay","R-52B") -- + -- Valve #1 + self.Train:LoadSystem("PneumaticNo1","Relay") + -- Valve #2 + self.Train:LoadSystem("PneumaticNo2","Relay") + -- Автоматический выключатель торможения (АВТ) + self.Train:LoadSystem("AVT","Relay","AVT-325") + -- Регулятор давления (АК) + self.Train:LoadSystem("AK","Relay","AK-11B") + -- Блокировка тормозов + self.Train:LoadSystem("BPT","Relay","") + -- Блокировка дверей + self.Train:LoadSystem("BD","Relay","") + -- Вентили дверного воздухораспределителя (ВДОЛ, ВДОП, ВДЗ) + self.Train:LoadSystem("VDOL","Relay","", {bass = true}) + self.Train:LoadSystem("VDOP","Relay","", {bass = true}) + self.Train:LoadSystem("VDZ","Relay","", {bass = true}) + + -- Краны двойной тяги + self.Train:LoadSystem("DriverValveTLDisconnect","Relay","Switch", {bass = true}) + self.Train:LoadSystem("DriverValveBLDisconnect","Relay","Switch", {bass = true}) + + self.Train:LoadSystem("EmergencyBrakeValve","Relay","Switch") + -- Воздухораспределитель + self.Train:LoadSystem("AirDistributorDisconnect","Relay","Switch") + --Стояночный тормоз + self.Train:LoadSystem("ParkingBrake","Relay","Switch",{bass = true}) + -- Isolation valves + self.Train:LoadSystem("FrontBrakeLineIsolation","Relay","Switch", { normally_closed = true, bass = true}) + self.Train:LoadSystem("RearBrakeLineIsolation","Relay","Switch", { normally_closed = true, bass = true}) + self.Train:LoadSystem("FrontTrainLineIsolation","Relay","Switch", { normally_closed = true, bass = true}) + self.Train:LoadSystem("RearTrainLineIsolation","Relay","Switch", { normally_closed = true, bass = true}) + ------------------------------------------------------------------------------------------------ + --Ручное управление дверьми + --Краны выключения дверей и разобщительный кран ДВР + self.Train:LoadSystem("DoorReleaseRight","Relay","Switch") + self.Train:LoadSystem("DoorReleaseLeft","Relay","Switch") + self.Train:LoadSystem("DVRDisconnect","Relay","Switch", { normally_closed = false, bass = true}) + --Механическая блокировка дверей + self.Train:LoadSystem("IDLK1","Relay","VB-11", {bass = true}) --4 левый + self.Train:LoadSystem("IDLK2","Relay","VB-11", {bass = true}) --3 левый + self.Train:LoadSystem("IDLK3","Relay","VB-11", {bass = true}) --2 левый + self.Train:LoadSystem("IDLK4","Relay","VB-11", {bass = true}) --1 левый + self.Train:LoadSystem("IDLK5","Relay","VB-11", {bass = true}) --1 правый + self.Train:LoadSystem("IDLK6","Relay","VB-11", {bass = true}) --2 правый + self.Train:LoadSystem("IDLK7","Relay","VB-11", {bass = true}) --3 правый + self.Train:LoadSystem("IDLK8","Relay","VB-11", {bass = true}) --4 правый + --раздвинуть/сдвинуть створки руками + self.Train:LoadSystem("iod1","Relay","Switch") + self.Train:LoadSystem("iod2","Relay","Switch") + self.Train:LoadSystem("iod3","Relay","Switch") + self.Train:LoadSystem("iod4","Relay","Switch") + self.Train:LoadSystem("iod5","Relay","Switch") + self.Train:LoadSystem("iod6","Relay","Switch") + self.Train:LoadSystem("iod7","Relay","Switch") + self.Train:LoadSystem("iod8","Relay","Switch") + self.Train:LoadSystem("icd1","Relay","Switch") + self.Train:LoadSystem("icd2","Relay","Switch") + self.Train:LoadSystem("icd3","Relay","Switch") + self.Train:LoadSystem("icd4","Relay","Switch") + self.Train:LoadSystem("icd5","Relay","Switch") + self.Train:LoadSystem("icd6","Relay","Switch") + self.Train:LoadSystem("icd7","Relay","Switch") + self.Train:LoadSystem("icd8","Relay","Switch") + + -- Brake cylinder atmospheric valve open + self.BrakeCylinderValve = 0 + + -- Overpressure protection valve open + self.TrainLineOverpressureValve = 0 + + -- Compressor simulation + self.Compressor = 0 --Simulate overheat with TRK FIXME + + -- Door release valve status + self.DoorReleaseRightPrevious = 0 + self.DoorReleaseLeftPrevious = 0 + + -- Doors state + if not TURBOSTROI then + self.LeftDoorState = self.LeftDoorState or { 0,0,0,0 } + self.RightDoorState = self.RightDoorState or { 0,0,0,0 } + --self.LeftDoorDir = { 0,0,0,0 } + --self.RightDoorDir = { 0,0,0,0 } + self.LeftDoorSpeed = {1,1,1,1} + self.RightDoorSpeed = {1,1,1,1} + self.DSprev = {{0,0},{0,0},{0,0},{0,0}} + self.LeftDoorStuck = {false, false, false, false} + self.RightDoorStuck = {false, false, false, false} + + local start = math.Rand(0.6,1.0) + -- 0.6-1 + self.DoorSpeedMain = -math.Rand(start,math.Rand(start+0.1,start+0.2)) + for i=1,#self.LeftDoorSpeed do + if math.random() > 0.7 then + self.LeftDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.2) + self.RightDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.2) + else + self.LeftDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.1) + self.RightDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.1) + end + end + end + self.TrainLineOpen = false + self.BrakeLineOpen = false + + self.BLDisconnect = true + self.TLDisconnect = true + + self.OldValuePos = self.DriverValvePosition + + self.WeightLoadRatio = 0 + self.PassengerDoor = 0 +end + +function TRAIN_SYSTEM:Inputs() + return { "BrakeUp", "BrakeDown", "BrakeSet", "ValveType", "Autostop", "KM013offset" } +end + +function TRAIN_SYSTEM:Outputs() + return { "BrakeLinePressure", "BrakeCylinderPressure", "DriverValvePosition", "WorkingChamberPressure", "LeftDoorCloseCylPressure", "LeftDoorOpenCylPressure", + "ReservoirPressure", "TrainLinePressure", "DoorLinePressure", "WeightLoadRatio", "RightDoorCloseCylPressure", "RightDoorOpenCylPressure" } +end + +function TRAIN_SYSTEM:TriggerInput(name,value) + if name == "BrakeSet" then + self.DriverValvePosition = math.floor(value) + if self.ValveType == 1 then + if self.DriverValvePosition < 1 then self.DriverValvePosition = 1 end + if self.DriverValvePosition > 5 then self.DriverValvePosition = 5 end + else + if self.DriverValvePosition < 1 then self.DriverValvePosition = 1 end + if self.DriverValvePosition > 7 then self.DriverValvePosition = 7 end + end + elseif (name == "BrakeUp") and (value > 0.5) then + self:TriggerInput("BrakeSet",self.DriverValvePosition+1) + elseif (name == "BrakeDown") and (value > 0.5) then + self:TriggerInput("BrakeSet",self.DriverValvePosition-1) + elseif name == "ValveType" then + self.ValveType = math.floor(value) + elseif name == "KM013offset" then + self.KM013offset = value + elseif name == "KM013Over" then + self.km013_overcharge = value + elseif name:match("VZ%dOffset") then + local idx = name:match("VZ(%d)Offset") + self["GN"..idx.."Offset"] = math.random(2,10)*0.02 + value + self["GN"..idx.."Start"] = value + --PrintMessage(HUD_PRINTTALK, Format("Вагон %u; ВЗ-1: %.1f; ВЗ-2: %.1f",self.Train:GetWagonNumber(),self.GN1Offset or 0,self.GN2Offset or 0)) + end +end + + +-- TODO: почистить это говно, сделать раздельные звуки пневмы +-- Calculate derivatives +function TRAIN_SYSTEM:equalizeCouplePressure(dT,pressure,train,valve_status,rate,close_rate) + if not valve_status then return 0 end + local other + if IsValid(train) then other = train.Pneumatic end + + -- Get second pressure + local P2 = 0 + if other then P2 = other[pressure] end + if (not other) and (valve_status) then + self.TrainLineOpen = (pressure == "TrainLinePressure") + rate = close_rate or rate + --self.TrainLinePressure_dPdT = 0.0 + end + + -- Calculate rate + local dPdT = rate * (P2 - self[pressure]) + -- Calculate delta + local dP = dPdT*dT + if other and other.ReadOnly then + dP = dP/250 + end + -- Equalized pressure + local P0 = (P2 + self[pressure]) / 2 + -- Update pressures + if dP > 0 then + self[pressure] = math.min(P0,self[pressure] + dP) + if other and not other.ReadOnly then + other[pressure] = math.max(P0,other[pressure] - dP) + end + else + self[pressure] = math.max(P0,self[pressure] + dP) + if other and not other.ReadOnly then + other[pressure] = math.min(P0,other[pressure] - dP) + end + end + -- Update delta if losing air + if self.TrainLineOpen and (pressure == "TrainLinePressure") then + self[pressure.."_dPdT"] = (self[pressure.."_dPdT"] or 0) + dPdT + end + return dP +end +------------------------------------------------------------------------------- +function TRAIN_SYSTEM:UpdatePressures(Train,dT) + local frontBrakeOpen = Train.FrontBrakeLineIsolation.Value == 0 + local rearBrakeOpen = Train.RearBrakeLineIsolation.Value == 0 + local frontTrainOpen = Train.FrontTrainLineIsolation.Value == 0 + local rearTrainOpen = Train.RearTrainLineIsolation.Value == 0 + + local Ft = IsValid(Train.FrontTrain) and Train.FrontTrain + local Rt = IsValid(Train.RearTrain) and Train.RearTrain + local Fc, Rc = Train.FrontCouple or Train.FrontBogey, Train.RearCouple or Train.RearBogey + local Fb,Rb + if IsValid(Fc) and Fc.DepotPneumo then Fb = Fc.DepotPneumo end + if IsValid(Rc) and Rc.DepotPneumo then Rb = Rc.DepotPneumo end + + local frontBrakeLeak = false + local rearBrakeLeak = false + local frontTrainLeak = false + local rearTrainLeak = false + + -- Check if both valve on this train and connected train are open + if Ft and Ft.FrontBrakeLineIsolation then + if Ft.FrontTrain == Train then -- Nose to nose + frontBrakeLeak = frontBrakeOpen and Ft.FrontBrakeLineIsolation.Value==1 and 0.08 + frontTrainLeak = frontTrainOpen and Ft.FrontTrainLineIsolation.Value==1 and 0.08 + else -- Rear to nose + frontBrakeLeak = frontBrakeOpen and Ft.RearBrakeLineIsolation.Value==1 and 0.08 + frontTrainLeak = frontTrainOpen and Ft.RearTrainLineIsolation.Value==1 and 0.08 + end + else + frontBrakeLeak = frontBrakeOpen and 0.7 + frontTrainLeak = frontTrainOpen and not Fb and 0.3 + end + if Rt and Rt.FrontBrakeLineIsolation then + if Rt.FrontTrain == Train then -- Nose to nose + rearBrakeLeak = rearBrakeOpen and Rt.FrontBrakeLineIsolation.Value==1 and 0.08 + rearTrainLeak = rearTrainOpen and Rt.FrontTrainLineIsolation.Value==1 and 0.08 + else -- Rear to nose + rearBrakeLeak = rearBrakeOpen and Rt.RearBrakeLineIsolation.Value==1 and 0.08 + rearTrainLeak = rearTrainOpen and Rt.RearTrainLineIsolation.Value==1 and 0.08 + end + else + rearBrakeLeak = rearBrakeOpen and 0.7 + rearTrainLeak = rearTrainOpen and not Rb and 0.3 + end + + -- Equalize pressure + local Fl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",frontBrakeLeak==false and Ft,frontBrakeOpen,50,frontBrakeLeak or 0.08)*3)*(frontBrakeLeak and 1 or 0) + local Rl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",rearBrakeLeak==false and Rt,rearBrakeOpen,50,rearBrakeLeak or 0.08)*3)*(rearBrakeLeak and 1 or 0) + + Fl=Fl+math.min(0,self:equalizeCouplePressure(dT,"TrainLinePressure",frontTrainLeak==false and Ft or Fb,frontTrainOpen,100,frontTrainLeak or 0.08)*10)*(frontTrainLeak and 1 or 0) + Rl=Rl+math.min(0,self:equalizeCouplePressure(dT,"TrainLinePressure",rearTrainLeak==false and Rt or Rb,rearTrainOpen,100,rearTrainLeak or 0.08)*10)*(rearTrainLeak and 1 or 0) + + self.TrainLineOpen=frontTrainLeak or rearTrainLeak + self.BrakeLineOpen=frontBrakeLeak or rearBrakeLeak + Train:SetPackedRatio("FrontLeak",Fl) + Train:SetPackedRatio("RearLeak",Rl) +end + +function TRAIN_SYSTEM:equalizePressure(dT,pressure,target,rate,fill_rate,no_limit,smooth) + if fill_rate and (target > self[pressure]) then rate = fill_rate end + + -- Calculate derivative + local dPdT = rate + if target < self[pressure] then dPdT = -dPdT end + local dPdTramp = math.min(1.0,math.abs(target - self[pressure])*(smooth or 0.5)) + dPdT = dPdT*dPdTramp + + -- Update pressure + self[pressure] = self[pressure] + dT * dPdT + self[pressure] = math.max(0.0,math.min(16.0,self[pressure])) + self[pressure.."_dPdT"] = (self[pressure.."_dPdT"] or 0) + dPdT + if no_limit ~= true then + if self[pressure] == 0.0 then self[pressure.."_dPdT"] = 0 end + if self[pressure] == 16.0 then self[pressure.."_dPdT"] = 0 end + end + return dPdT +end +------------------------------------------------------------------------------- +function TRAIN_SYSTEM:Think(dT) + local Train = self.Train + local retainer = Train:GetNW2Int("RetainerLoad", 4) + self.WeightLoadRatio = retainer == 4 and math.max(0,math.min(1,(Train:GetNW2Float("PassengerCount")/200))) or (retainer-1)*0.5 + + --if not Train.DoorSpeedsDone then + -- local start + -- if #Train.WagonList == Train.CarCount and Train.d_speeds then + -- start = math.Rand(unpack(Train.d_speeds[math.random(1,#Train.d_speeds)])) + -- end + -- if start then + -- MsgC(Color(200,200,200),"Setting doors speed for car "..tostring(self.Train).."; start = "..tostring(start).."...") + -- self.DoorSpeedMain = start--math.Rand(start,math.Rand(start+0.1,start+0.2)) + -- for i=1,#self.LeftDoorSpeed do + -- --if math.random() > 0.7 then + -- -- self.LeftDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.2,self.DoorSpeedMain+0.2) + -- -- self.RightDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.2,self.DoorSpeedMain+0.2) + -- --else + -- self.LeftDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain) + -- self.RightDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain) + -- --end + -- end + -- Train.DoorSpeedsDone = true + -- MsgC(Color(200,200,200),"done\n") + -- else + -- MsgC(Color(200,200,200),"failed!\n") + -- end + --end + if not Train.DoorSpeedsDone and Train.CarCount then + local set + if #Train.WagonList == Train.CarCount and Train.d_speeds then + set = math.random(1,#Train.d_speeds) + local a,b = unpack(Train.d_speeds[set]) + --MsgC(Color(200,200,200),"Setting doors speed for car "..tostring(self.Train).."; set = {"..a..", "..b.."} ...") + for i=1,#self.LeftDoorSpeed do + self.LeftDoorSpeed[i] = math.Rand(a,b) + self.RightDoorSpeed[i] = math.Rand(a,b) + end + Train.DoorSpeedsDone = true + --MsgC(Color(200,200,200),"done\n") + else + --MsgC(Color(200,200,200),"failed!\n") + end + end + ---------------------------------------------------------------------------- + -- Accumulate derivatives + self.TrainLinePressure_dPdT = 0.0 + self.BrakeLinePressure_dPdT = 0.0 + self.ReservoirPressure_dPdT = 0.0 + self.BrakeCylinderPressure_dPdT = 0.0 + self.ParkingBrakePressure_dPdT = 0.0 + self.WorkingChamberPressure_dPdT = 0.0 + + -- Doors + self.LeftDoorCloseCylPressure_dPdT = 0.0 + self.RightDoorCloseCylPressure_dPdT = 0.0 + self.LeftDoorOpenCylPressure_dPdT = 0.0 + self.RightDoorOpenCylPressure_dPdT = 0.0 + self.DoorLinePressure_dPdT = 0.0 + + -- Reduce pressure for brake line + self.TrainToBrakeReducedPressure = math.min(self.KM013offset,self.TrainLinePressure) -- * 0.725) + -- Feed pressure to door line + self.DoorLinePressure = Train.DVRDisconnect.Value == 0 and math.min(3.6,self.TrainLinePressure) or self.DoorLinePressure + local trainLineConsumption_dPdT = 0.0 + local wagc = Train:GetBLConnectedWagonCount() + local HaveEPK = not Train.SubwayTrain or not Train.SubwayTrain.ARS or not Train.SubwayTrain.ARS.NoEPK + + local pr_speed = 1 + + if self.ValveType == 1 then + self.BLDisconnect = Train.DriverValveBLDisconnect.Value > 0 + self.TLDisconnect = Train.DriverValveTLDisconnect.Value > 0 and self.RealDriverValvePosition ~= 3 + pr_speed = 1*6--wagc--*((self.BrakeLinePressure-self.ReservoirPressure)/0.6) --2 + if self.TLDisconnect then self.TLDisconnectPressure = self.TrainLinePressure end + if self.BLDisconnect then self.BLDisconnectPressure = self.BrakeLinePressure end + if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end + -- 334: 1 Fill reservoir from train line, fill brake line from train line + if (self.RealDriverValvePosition == 1) then + if self.TLDisconnect or self.ReservoirPressure ~= self.TLDisconnectPressure or self.ReservoirPressure ~= self.BLDisconnectPressure then + if self.BLDisconnect then + if self.TLDisconnect then + self:equalizePressure(dT,"ReservoirPressure", self.TLDisconnectPressure, 0, 1.0,nil,2) + self:equalizePressure(dT,"BrakeLinePressure", self.TLDisconnectPressure, 0, 6.0,nil,0.2) + end + if not self.TLDisconnect then + self:equalizePressure(dT,"TLDisconnectPressure", self.BrakeLinePressure, 16, 0,nil,2) + self:equalizePressure(dT,"ReservoirPressure", self.BrakeLinePressure, 0.4, 0.06,nil,2) + self:equalizePressure(dT,"BrakeLinePressure", self.ReservoirPressure, 6.5, 0,nil,0.2) + end + else + self:equalizePressure(dT,"ReservoirPressure", self.TLDisconnectPressure, 0, self.TLDisconnect and 3.55 or 2.0,nil,2) + self:equalizePressure(dT,"TLDisconnectPressure", self.ReservoirPressure, 16, 0,nil,2) + end + end + end + + -- 334: 2 Brake line, reservoir replenished from brake line reductor + if (self.RealDriverValvePosition == 2) then + if self.TLDisconnect then + local a = 1 + if self.EmergencyValve or Train.EmergencyBrakeValve.Value > 0.5 then a = 4 end + if self.BLDisconnect then + --self.ReservoirPressure = self.BrakeLinePressure + self:equalizePressure(dT,"ReservoirPressure", self.BrakeLinePressure,6,0.8,nil,2) + self:equalizePressure(dT,"BrakeLinePressure", self.TrainToBrakeReducedPressure, pr_speed*0, pr_speed*0.3*a, nil, 1.6) + self.ReservoirPressure_dPdT = self.BrakeLinePressure_dPdT*0.8 + else + self:equalizePressure(dT,"ReservoirPressure", self.TrainToBrakeReducedPressure,0,1.55,nil,2) + end + end + end + + -- 334: 3 Close all valves + if (self.RealDriverValvePosition == 3) then + -- Typical leak + self:equalizePressure(dT,"ReservoirPressure", 0.00, 0.001) + end + + local res_dischrg_rate4 = 0.28 + local res_dischrg_rate5 = self.BLDisconnect and 1.12 or 8 + -- 334: 4 Reservoir open to atmosphere, brake line equalizes with reservoir + if (self.RealDriverValvePosition == 4) then + self:equalizePressure(dT,"ReservoirPressure", 0.0, res_dischrg_rate4, nil,nil,1)--0.35)-0.55 + end + + -- 334: 5 Reservoir and brake line open to atmosphere + if (self.RealDriverValvePosition == 5) then + self:equalizePressure(dT,"ReservoirPressure", 0.0, res_dischrg_rate5)--,nil,nil,2)--1.70 + local pr_speed = 1.25*6--wagc + if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end + if self.BLDisconnect then + if self.Leak then pr_speed = pr_speed*6.2 end + self:equalizePressure(dT,"BrakeLinePressure", 0.0, pr_speed,nil,nil,2) + end + end + -- утечка через неплотность уравнительного поршня + if self.BLDisconnect then self:equalizePressure(dT, "ReservoirPressure", self.BrakeLinePressure, 0.06, 0) end + + if (self.RealDriverValvePosition > 1) and (self.RealDriverValvePosition < 5) then + local pr_speed = 1.25*6--wagc + if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end + local _a = 0 + for k,v in ipairs(Train.WagonList) do + if v.Pneumatic.TLDisconnect and v.Pneumatic.BLDisconnect and (v.Pneumatic.RealDriverValvePosition == 2 or v.Pneumatic.RealDriverValvePosition == 1) then + _a = _a + 1 + end + if _a > 1 then break end + end + if _a > 1 then pr_speed = pr_speed*0.1 end + if self.BLDisconnect and self.BrakeLinePressure - self.ReservoirPressure > (self.RealDriverValvePosition == 3 and 0 or 0.2) then --0.2 bar is a piston sensitivity + self:equalizePressure(dT, "BrakeLinePressure", 0, pr_speed*math.abs(self.BrakeLinePressure - self.ReservoirPressure), nil, nil, 6) + end + end + + self.ReservoirPressure_dPdT = self.ReservoirPressure_dPdT + self.BrakeLinePressure_dPdT*0.2 + Train:SetPackedRatio("ReservoirPressure_dPdT",self.ReservoirPressure_dPdT/wagc*2) + --[[ + ---------------debug--------------------- + self.dlreadtimer = self.dlreadtimer or CurTime() + if CurTime() - self.dlreadtimer > 1.0 then + self.dlreadtimer = CurTime() + if Train:GetDriver() then + PrintMessage(HUD_PRINTTALK, Format("Вагон %u; P ТМ: %.3f; P УР =%.3f; Утечка ТМ %.3f; TLDis = %.3f; pr_speed = %.3f",Train:GetWagonNumber(),self.BrakeLinePressure,self.ReservoirPressure,self.BrakeLinePressure_dPdT, self.TLDisconnectPressure, pr_speed)) + end + end + ---------------debug---------------------]] + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeLinePressure_dPdT) + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.ReservoirPressure_dPdT)*0.05 + else + pr_speed = 2.8--1.25*wagc --2 + local pz_speed + -- wagc | pr_speed + ------------------ + -- 1 | 8.455 + -- 2 | 7.865 + -- 3 | 7.376 + -- 4 | 6.969 + -- 5 | 6.627 + -- 6 | 6.341 + -- 7 | 6.100 + -- 8 | 5.900 + --pr_speed = (0.4*math.exp(0.1*wagc-1)+1)*160/(2*wagc+20) --2 + --local frc = 0.6--0.35 + if self.Leak or self.BrakeLineOpen then pz_speed = pr_speed*0.25 else pz_speed = pr_speed*1.3 end--*frc end + self.BLDisconnect = Train.DriverValveBLDisconnect.Value > 0 + self.TLDisconnect = Train.DriverValveTLDisconnect.Value > 0 + if self.km013_overcharge and self.RealDriverValvePosition > 4 and not self.km13_error2 then self.km13_error2 = math.random()*0.3+0.4 end + -- 013: 1 Overcharge + if (self.RealDriverValvePosition == 1) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > self.TrainLinePressure) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(6.4,self.TrainLinePressure), pr_speed, pz_speed, nil, 1.0) + end + + -- 013: 2 Normal pressure + if (self.RealDriverValvePosition == 2) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(self.KM013offset,self.TrainToBrakeReducedPressure)) then--was pr_speed*2 + self:equalizePressure(dT,"BrakeLinePressure", math.min(self.KM013offset+(self.km13_error2 or 0),self.TrainLinePressure), pr_speed, pz_speed, nil, 2.5)-- nil, 1.0) + if self.km13_error2 and self.BrakeLinePressure >= self.KM013offset+self.km13_error2-0.1 then + self:equalizePressure(dT,"BrakeLinePressure", math.min(self.KM013offset,self.TrainToBrakeReducedPressure), 35, pz_speed, nil, 1) + self.km13_error2 = nil + end + end + + -- 013: 3 4.3 Atm + if (self.RealDriverValvePosition == 3) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(4.3,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(4.3,self.TrainToBrakeReducedPressure), pr_speed*1.5,pz_speed, nil, 2.5) + end + + -- 013: 4 4.0 Atm + if (self.RealDriverValvePosition == 4) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(4.0,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(4.0,self.TrainToBrakeReducedPressure), pr_speed*1.5,pz_speed, nil, 2.5) + end + + -- 013: 5 3.7 Atm + if (self.RealDriverValvePosition == 5) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(3.7,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(3.7,self.TrainToBrakeReducedPressure), pr_speed*1.5,pz_speed, nil, 2.5) + end + + -- 013: 6 3.0 Atm + if (self.RealDriverValvePosition == 6) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(3.0,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(3.0,self.TrainToBrakeReducedPressure), pr_speed*1.5,pz_speed, nil, 2.5) + end + + -- 013: 7 0.0 Atm + if (self.RealDriverValvePosition == 7) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 0.0) then + self:equalizePressure(dT,"BrakeLinePressure", 0.0, (0.6 + pr_speed*math.exp(math.min(0,self.BrakeLinePressure - 2.3)*1.0))*(0.15*wagc+1),pz_speed, nil, 2.5) + end + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeLinePressure_dPdT) + end + self.Leak = false + if wagc ~= Train.OldWagIsoCount or not Train.pr_spd_init then + pr_speed = (0.4*math.exp(0.1*wagc-1)+1)*160/(2*wagc+20) --2 + Train.OldWagIsoCount = wagc + Train.pr_spd_init = true + end + if self.ValveType == 1 then + Train:SetPackedRatio("Crane_dPdT", self.ReservoirPressure_dPdT ) + else + Train:SetPackedRatio("Crane_dPdT", self.BrakeLinePressure_dPdT/wagc*3 ) + end + + local leak = 0 + if Train.EmergencyBrakeValve and Train.EmergencyBrakeValve.Value > 0.5 then + local leakst = math.max(0.5,math.exp(0.5*self.BrakeLinePressure)) + leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,leakst)--,false,false,10) --was leakst*wagc/5 + self.Leak = true + end + Train:SetPackedRatio("EmergencyBrakeValve_dPdT", -leak/wagc) + ---------------------------------------------------------------------------- + -- Fill brake cylinders + if self.WCChargeValve == true then + self:equalizePressure(dT,"WorkingChamberPressure",self.BrakeLinePressure,0.094,nil,nil,1.0) --simulate 0.8mm hole btw BL and working chambers + end + local aird_ready = self.WorkingChamberPressure >= 2.2 + self.WCChargeValve = not ((self.WorkingChamberPressure - self.BrakeLinePressure) > 0.2 and (self.WorkingChamberPressure - self.BrakeLinePressure) < 2.5) + local KLSZ = self.WorkingChamberPressure > 5.2 and not self.WCChargeValve + if KLSZ then + self:equalizePressure(dT,"WorkingChamberPressure",0.0,0.12) -- КЛСЗ + end + + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.WorkingChamberPressure_dPdT*0.2) + self.GN2Offset = self.GN2Offset or math.random(20,100)*0.002 + (self.GN2Start or 2.4) + self.GN1Offset = self.GN1Offset or math.random(20,100)*0.002 + (self.GN1Start or 0.8) + self.BcBl = (self.GN2Offset + self.WeightLoadRatio*(self.GN2Offset - 1.4))/1.82--1.92 + if Train.AirDistributorDisconnect.Value == 0 and aird_ready then + -- Valve #1 + if (Train.PneumaticNo1.Value == 1.0) and (Train.PneumaticNo2.Value == 0.0) then + if self.PN1 < self.GN1Offset then + self.PN1 = math.min(self.TrainLinePressure,self.GN1Offset) + end + elseif Train.PneumaticNo1.Value == 0 and self.PN1 > 0.0 then + self.PN1 = self.BrakeCylinderPressure > 0.2 and 0.05 or self.PN1 - 0.5*dT + end + -- Valve #2 + if Train.PneumaticNo2.Value == 1.0 then + self.PN2 = math.min(self.TrainLinePressure,(self.GN2Offset + self.WeightLoadRatio*1.3)) + if self.BePN2 == false and self.BrakeCylinderPressure > 1.6 then + Train:PlayOnce("PN2end","stop") + end + self.BePN2 = true + elseif self.PN2 > 0.0 then + self.PN2 = self.BrakeCylinderPressure > 0.4 and 0.2 or self.PN2 - 0.5*dT + end + --[[ + ---------------debug--------------------- + self.brreadtimer = self.brreadtimer or CurTime() + if CurTime() - self.brreadtimer > 1.0 then + self.brreadtimer = CurTime() + if Train:GetDriver() then + --PrintMessage(HUD_PRINTTALK, Format("br_threshold = %.3f; WcBl = %s",br_threshold, tostring(WcBl))) + --PrintMessage(HUD_PRINTTALK, Format("Это %s", isLVZ and "ЛВЗ" or "не ЛВЗ")) + --PrintMessage(HUD_PRINTTALK, Format("Вагон %u; Авторежим: %.3f",Train:GetWagonNumber(),self.WeightLoadRatio)) + --PrintMessage(HUD_PRINTTALK, Format("wagc = %u; wagd = %u",wagc,wagd)) + end + end + ---------------debug---------------------]] + + self.BchExh = self.WorkingChamberPressure < 4.8 and self.BrakeLinePressure < 3.4 and 0 or 1 + self.cranPres = math.max(0,self.BcBl*(self.WorkingChamberPressure - self.BrakeLinePressure*self.BchExh)*(self.BrakeLinePressure > self.KM013offset and (0.6 + self.PN1*0.43) or 1)) + local targetPressure = math.max(0,math.min(self.GN2Offset + self.WeightLoadRatio*1.3, (self.cranPres < (self.PN1 + self.WeightLoadRatio*0.7) and (Train.PneumaticNo1.Value == 1.0) and (self.PN1 + self.WeightLoadRatio*0.7) or self.PN1) + self.PN2 + self.cranPres)) + if math.abs(self.BrakeCylinderPressure - targetPressure) > 0.150 then + self.BrakeCylinderValve = 1 + end + if math.abs(self.BrakeCylinderPressure - targetPressure) < 0.025 then + self.BrakeCylinderValve = 0 + end + if self.BrakeCylinderValve == 1 then + self:equalizePressure(dT,"BrakeCylinderPressure", math.min(self.GN2Offset + self.WeightLoadRatio*(self.GN2Offset - 1.4),targetPressure), 0.8, (Train.PneumaticNo1.Value > 0 or Train.PneumaticNo2.Value > 0) and 2.8 or 1.5, nil, 1.2) + end + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeCylinderPressure_dPdT*0.5) + elseif Train.AirDistributorDisconnect.Value ~= 0 then + self:equalizePressure(dT,"BrakeCylinderPressure", 0.0, 2.00) + end + if (self.BrakeCylinderPressure > 0.2 and self.BrakeCylinderPressure_dPdT > 0.1 or self.BrakeCylinderPressure_dPdT > 1) and not self.BrakeEngaged then + self.BrakeEngaged = true + Train:PlayOnce("brake","bass",1,math.Clamp(self.BrakeCylinderPressure_dPdT,0.7,1.2)) + end + if self.BrakeCylinderPressure < 1 and self.BrakeCylinderPressure_dPdT < -0.1 and self.BrakeEngaged then + self.BrakeEngaged = false + end + Train:SetPackedRatio("BrakeCylinderPressure_dPdT", self.BrakeCylinderPressure_dPdT) + self.TrainLinePressure = self.TrainLinePressure-math.max(0,self.BrakeCylinderPressure_dPdT*0.002) + if Train.PneumaticNo2.Value == 0 then + if self.BePN2 == true then + self.BePN2 = CurTime() + elseif self.BePN2 and self.BrakeCylinderPressure_dPdT > -0.2 then + Train:PlayOnce("PN2end","bass",math.Clamp(math.min(1,(CurTime()-self.BePN2)/1.3)*((3.2-self.BrakeCylinderPressure)/1.2),0,1)) + self.BePN2 = false + end + end + if self.BePN2 == false and (self.BrakeCylinderPressure_dPdT >= 0.2) then + self.BePN2 = nil + Train:PlayOnce("PN2end","stop") + end + + --Parking brake simulation + local PBPressure = math.Clamp(self.TrainLinePressure/5,0,1)*2.7 + if Train.ParkingBrake.Value == 0 then + self:equalizePressure(dT,"ParkingBrakePressure", PBPressure, 10,10,nil,0.5) + else + self:equalizePressure(dT,"ParkingBrakePressure", 0, 3,10,nil,0.5) + end + Train:SetPackedRatio("ParkingBrakePressure_dPdT",self.ParkingBrakePressure_dPdT) + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.ParkingBrakePressure_dPdT*0.5) + + -- Simulate cross-feed between different wagons + self:UpdatePressures(Train,dT) + + ---------------------------------------------------------------------------- + -- Simulate doors opening, closing + local LeftRelease = Train.DoorReleaseLeft.Value == 0 + local RightRelease = Train.DoorReleaseRight.Value == 0 + if self.DoorLinePressure >= 1.4 then --was > 2.6 + -- Simulate DVR engage lag + if Train.VDOL.Value == 1.0 and not Train.VDOLEnergized then + Train.VDOLEnergized = true + Train.VDOLTime = RealTime() + elseif Train.VDOL.Value == 0.0 then + Train.VDOLEnergized = false + end + if Train.VDOP.Value == 1.0 and not Train.VDOPEnergized then + Train.VDOPEnergized = true + Train.VDOPTime = RealTime() + elseif Train.VDOP.Value == 0.0 then + Train.VDOPEnergized = false + end + if (Train.VDOL.Value == 1.0) and (Train.VDOP.Value == 0.0) and not self.DoorLeft then + if Train.VDOLTime and RealTime() - Train.VDOLTime > (Train.DVRLag or 0) then self.DoorLeft = true end + if self.VDOLLoud then Train:PlayOnce("vdol_loud","cabin",0.8+math.random()*0.2,self.VDOLLoud) end + end + if (Train.VDOL.Value == 0.0) and (Train.VDOP.Value == 1.0) and not self.DoorRight then + if Train.VDOPTime and RealTime() - Train.VDOPTime > (Train.DVRLag or 0) then self.DoorRight = true end + if self.VDORLoud then Train:PlayOnce("vdop_loud","cabin",0.8+math.random()*0.2,self.VDORLoud) end + end + if Train.DVRHiss == 2 then + if Train.RD.Value == 1 and Train.VDOL.Value == 1 and not self.LeftExhausted then + Train:PlayOnce("dcyl_op_exh","bass",1,1) + self.LeftExhausted = true + end + if Train.RD.Value == 1 and Train.VDOP.Value == 1 and not self.RightExhausted then + Train:PlayOnce("dcyl_op_exh","bass",1,1) + self.RightExhausted = true + end + end + if (Train.VDZ.Value == 1.0 or Train.VDOL.Value == 1.0 and Train.VDOP.Value == 1.0 or self.RZDTimer) and (self.DoorLeft or self.DoorRight) then + --if not self.OpenWaitL or CurTime()-self.OpenWaitL < 0.2 then + self.DoorLeft = false + --end + --if not self.OpenWaitR or CurTime()-self.OpenWaitR < 0.2 then + self.DoorRight = false + --end + if Train.DVRHiss == 2 then + if Train.RD.Value == 0 and (self.LeftExhausted or self.RightExhausted) then + Train:PlayOnce("dcyl_cl_exh","bass",1,0.6) + self.LeftExhausted = false + self.RightExhausted = false + end + end + else + self.CloseValue = nil + end + if Train.VDOL.Value == 1.0 and Train.VDOP.Value == 1.0 then + self.RZDTimer = CurTime() + elseif self.RZDTimer and CurTime()-self.RZDTimer > 0.1 then + self.RZDTimer = nil + end + end + -- Тут было бы лучше сделать не 2 цилиндра на вагон, а 8, но тогда будет не 4 вызова функции, а 16... + self:equalizePressure(dT,"RightDoorOpenCylPressure", self.DoorRight and self.DoorLinePressure or 0.0, 2.2, 10) + self:equalizePressure(dT,"RightDoorCloseCylPressure", not self.DoorRight and RightRelease and self.DoorLinePressure or 0.0, 2.2, 10) + self:equalizePressure(dT,"LeftDoorOpenCylPressure", self.DoorLeft and self.DoorLinePressure or 0.0, 2.2, 10) + self:equalizePressure(dT,"LeftDoorCloseCylPressure", not self.DoorLeft and LeftRelease and self.DoorLinePressure or 0.0, 2.2, 10) + self.DoorLinePressure = self.DoorLinePressure-math.max(0,self.RightDoorOpenCylPressure_dPdT*0.01) + self.DoorLinePressure = self.DoorLinePressure-math.max(0,self.LeftDoorOpenCylPressure_dPdT*0.01) + self.DoorLinePressure = self.DoorLinePressure-math.max(0,self.RightDoorCloseCylPressure_dPdT*0.01) + self.DoorLinePressure = self.DoorLinePressure-math.max(0,self.LeftDoorCloseCylPressure_dPdT*0.01) + Train:SetPackedRatio("RightDoorCloseCylPressure_dPdT",not RightRelease and self.RightDoorCloseCylPressure_dPdT or 0) + Train:SetPackedRatio("LeftDoorCloseCylPressure_dPdT",not LeftRelease and self.LeftDoorCloseCylPressure_dPdT or 0) + if self.DoorReleaseRightPrevious ~= Train.DoorReleaseRight.Value then + self.DoorReleaseRightPrevious = Train.DoorReleaseRight.Value + ---[[ + if not self.DoorRight and self.DoorReleaseRightPrevious == 1 then + self:equalizePressure(dT,"RightDoorCloseCylPressure", 0, 6) --was DoorLinePressure + end--]] + end + if self.DoorReleaseLeftPrevious ~= Train.DoorReleaseLeft.Value then + self.DoorReleaseLeftPrevious = Train.DoorReleaseLeft.Value + ---[[ + if not self.DoorLeft and self.DoorReleaseLeftPrevious == 1 then + self:equalizePressure(dT,"LeftDoorCloseCylPressure", 0, 6) --was DoorLinePressure + end--]] + end + if self.VDOL ~= Train.VDOL.Value then + self.VDOL = Train.VDOL.Value + self:equalizePressure(dT,Train.DVRDisconnect.Value == 0 and "TrainLinePressure" or "DoorLinePressure", 0.0, 0.05) --was 0.3 + end + if self.VDOP ~= Train.VDOP.Value then + self.VDOP = Train.VDOP.Value + self:equalizePressure(dT,Train.DVRDisconnect.Value == 0 and "TrainLinePressure" or "DoorLinePressure", 0.0, 0.05) --was 0.3 + end + if self.VDZ ~= Train.VDZ.Value then + self.VDZ = Train.VDZ.Value + self:equalizePressure(dT,Train.DVRDisconnect.Value == 0 and "TrainLinePressure" or "DoorLinePressure", 0.0, 0.05) --was 0.3 + end + trainLineConsumption_dPdT = trainLineConsumption_dPdT + (Train.DVRDisconnect.Value == 0 and math.max(0,self.DoorLinePressure_dPdT*0.2) or 0) + if Train.CanStuckPassengerLeft then + for i in ipairs(self.LeftDoorStuck) do + self.LeftDoorStuck[i] = math.random() < (0.6+math.min(2,2-self.LeftDoorSpeed[i])*0.2)*Train.CanStuckPassengerLeft*0.6 and (math.random() > 0.7 and CurTime()+math.random()*15) + end + Train.CanStuckPassengerLeft = false + end + if Train.CanStuckPassengerRight then + for i in ipairs(self.RightDoorStuck) do + self.RightDoorStuck[i] = math.random() < (0.6+math.min(2,2-self.RightDoorSpeed[i])*0.2)*Train.CanStuckPassengerRight*0.6 and (math.random() > 0.7 and CurTime()+math.random()*15) + end + Train.CanStuckPassengerRight = false + end + + + Train.LeftDoorsOpen = false + Train.RightDoorsOpen = false + local openL = true + local openR = true + local llocked = false + local rlocked = false + local rmOpen = false --|Right and left doors + local rmClose = false --| + local lmOpen = false --| + local lmClose = false --|manual opening-closing + local v = "IDLK" + local m = "iod" + local n = "icd" + for i=1,4 do + rlocked = Train[v..i].Value > 0 + llocked = Train[v..tostring(9-i)].Value > 0 + rmOpen = Train[m..i].Value > 0 + lmOpen = Train[m..tostring(9-i)].Value > 0 + rmClose = Train[n..i].Value > 0 + lmClose = Train[n..tostring(9-i)].Value > 0 + --self.LeftDoorState[i] = math.Clamp(self.LeftDoorState[i] + (not llocked and ((lmOpen and 1.5 or lmClose and -1.5 or 0) + (self.DoorLinePressure > 1.0 and (math.Round(self.LeftDoorOpenCylPressure - self.LeftDoorCloseCylPressure,1))*0.36*(not (lmOpen or lmClose) and self.LeftDoorSpeed[i] or 1) or 0))*dT or 0),self.LeftDoorStuck[i] and 0.3 or 0,1) + --self.RightDoorState[i] = math.Clamp(self.RightDoorState[i] + (not rlocked and ((rmOpen and 1.5 or rmClose and -1.5 or 0) + (self.DoorLinePressure > 1.0 and (math.Round(self.RightDoorOpenCylPressure - self.RightDoorCloseCylPressure,1))*0.36*(not (rmOpen or rmClose) and self.RightDoorSpeed[i] or 1) or 0))*dT or 0),self.RightDoorStuck[i] and 0.3 or 0,1) + self.LeftDoorState[i] = math.Clamp(self.LeftDoorState[i] + (not llocked and ((lmOpen and 1.5 or lmClose and -1.5 or 0) + (self.DoorLinePressure > 1.4 and (self.LeftDoorOpenCylPressure - self.LeftDoorCloseCylPressure)*0.36*(not (lmOpen or lmClose) and self.LeftDoorSpeed[i] or 1) or 0))*dT or 0),self.LeftDoorStuck[i] and 0.3 or 0,1) + self.RightDoorState[i] = math.Clamp(self.RightDoorState[i] + (not rlocked and ((rmOpen and 1.5 or rmClose and -1.5 or 0) + (self.DoorLinePressure > 1.4 and (self.RightDoorOpenCylPressure - self.RightDoorCloseCylPressure)*0.36*(not (rmOpen or rmClose) and self.RightDoorSpeed[i] or 1) or 0))*dT or 0),self.RightDoorStuck[i] and 0.3 or 0,1) + if not Train.LeftDoorsOpen and self.LeftDoorState[i] > 0.02 then --was 0.06 + Train.LeftDoorsOpen = true + end + if not Train.RightDoorsOpen and self.RightDoorState[i] > 0.02 then --was 0.06 + Train.RightDoorsOpen = true + end + Train:SetPackedRatio("DoorL"..i,self.LeftDoorState[i]) + Train:SetPackedRatio("DoorR"..i,self.RightDoorState[i]) + if self.LeftDoorStuck[i] and (self.DoorLeft or type(self.LeftDoorStuck[i]) == "number" and CurTime()-self.LeftDoorStuck[i] > 0) then + self.LeftDoorStuck[i] = false + end + if self.RightDoorStuck[i] and (self.DoorRight or type(self.RightDoorStuck[i]) == "number" and CurTime()-self.RightDoorStuck[i] > 0) then + self.RightDoorStuck[i] = false + end + Train:SetPackedBool("DoorLS"..i,self.LeftDoorStuck[i]) + Train:SetPackedBool("DoorRS"..i,self.RightDoorStuck[i]) + end + Train:SetPackedBool("DoorL",self.DoorLeft) + Train:SetPackedBool("DoorR",self.DoorRight) + Train.BD:TriggerInput("Set",not Train.RightDoorsOpen and not Train.LeftDoorsOpen) + Train.LeftDoorsOpening = self.DoorLeft + Train.RightDoorsOpening = self.DoorRight + + ---------------------------------------------------------------------------- + -- Simulate compressor operation and train line depletion + self.Compressor = Train.KK.Value * (Train.Electric.Aux750V > 550 and 1 or 0) + self.TrainLinePressure = self.TrainLinePressure - (Train.AirConsumeRatio or 1)*trainLineConsumption_dPdT*dT -- 0.190 --0.170 --0.07 + if self.Compressor == 1 then self:equalizePressure(dT,"TrainLinePressure", 10.0, Train.CompressorEfficiency or 0.04) end -- 0.04 + self:equalizePressure(dT,"TrainLinePressure", 0,Train.AirLeakRatio or 0.003) + -- Overpressure + if self.TrainLinePressure > math.max(7.2, (9.2 - self.TrainLineOverpressureValve*0.2)) and self.TrainLineOverpressureValve%2 == 0 then self.TrainLineOverpressureValve = self.TrainLineOverpressureValve + 1 end + if self.TrainLineOverpressureValve%2 == 1 then + self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.2) + self.TrainLineOpen = true + if self.TrainLinePressure < 5.2 and self.TrainLineOverpressureValve < 20 then self.TrainLineOverpressureValve = self.TrainLineOverpressureValve + 1 end + end + + ---------------------------------------------------------------------------- + -- Pressure triggered relays + Train.AVT:TriggerInput("Open", self.BrakeCylinderPressure > 1.9) -- 1.8 - 2.0 + Train.AVT:TriggerInput("Close",self.BrakeCylinderPressure < 0.9) -- 0.9 - 1.5 + Train.AK:TriggerInput( "Open", self.TrainLinePressure > 8.2) + Train.AK:TriggerInput( "Close",self.TrainLinePressure < 6.3) + Train.BPT:TriggerInput("Set", (IsValid(Train.FrontBogey) and Train.FrontBogey.BrakeCylinderPressure+(not Train.FrontBogey.DisableParking and Train.FrontBogey.ParkingBrakePressure or 0) or self.BrakeCylinderPressure)>0.3) + Train.DKPT:TriggerInput("Set", self.BrakeCylinderPressure > 0.3) -- 1.8 - 2.0 + + ---------------------------------------------------------------------------- + -- FIXME + Train:SetNW2Bool("FbI",Train.FrontBrakeLineIsolation.Value ~= 0) + Train:SetNW2Bool("RbI",Train.RearBrakeLineIsolation.Value ~= 0) + Train:SetNW2Bool("FtI",Train.FrontTrainLineIsolation.Value ~= 0) + Train:SetNW2Bool("RtI",Train.RearTrainLineIsolation.Value ~= 0) + Train:SetNW2Bool("AD",Train.AirDistributorDisconnect.Value == 0) + Train:SetNW2Bool("DoorReleaseRight",Train.DoorReleaseRight.Value ~= 0) + Train:SetNW2Bool("DoorReleaseLeft",Train.DoorReleaseLeft.Value ~= 0) + + local ValveType = self.ValveType > 1 + self.Timer = self.Timer or CurTime() + if ((CurTime() - self.Timer > 0.10) and (self.DriverValvePosition > self.RealDriverValvePosition)) then + self.Timer = CurTime() + if not ValveType then + if self.RealDriverValvePosition ~= 3 then + Train:PlayOnce("br_334",self.RealDriverValvePosition.."-"..(self.RealDriverValvePosition+1)) + end + else + Train:PlayOnce("br_013","cabin") + end + self.RealDriverValvePosition = self.RealDriverValvePosition + 1 + end + if ((CurTime() - self.Timer > 0.10) and (self.DriverValvePosition < self.RealDriverValvePosition)) then + self.Timer = CurTime() + if not ValveType then + if self.RealDriverValvePosition ~= 5 then + Train:PlayOnce("br_334",self.RealDriverValvePosition.."-"..(self.RealDriverValvePosition-1)) + end + else + Train:PlayOnce("br_013","cabin") + end + self.RealDriverValvePosition = self.RealDriverValvePosition - 1 + end +end diff --git a/lua/metrostroi/systems/sys_81_714_pneumatic.lua b/lua/metrostroi/systems/sys_81_714_pneumatic.lua new file mode 100644 index 00000000..7377fa9e --- /dev/null +++ b/lua/metrostroi/systems/sys_81_714_pneumatic.lua @@ -0,0 +1,706 @@ +-------------------------------------------------------------------------------- +-- 81-714 pneumatic system +-------------------------------------------------------------------------------- +-- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o. +-- Contains proprietary code. See license.txt for additional information. +-------------------------------------------------------------------------------- +Metrostroi.DefineSystem("81_714_Pneumatic") +TRAIN_SYSTEM.DontAccelerateSimulation = true + +function TRAIN_SYSTEM:Initialize(parameters) + self.ValveType = 1 + -- Position of the train drivers valve + -- Type 1 (334) + -- 1 Accelerated charge + -- 2 Normal charge (brake release) + -- 3 Closed + -- 4 Service application + -- 5 Emergency application + -- + -- Type 2 (013) + -- 1 Accelerated charge + -- 2 Normal charge (brake release) + -- 3 Closed + -- 4 Service application + -- 5 Emergency application + self.DriverValvePosition = 2 + self.RealDriverValvePosition = self.DriverValvePosition + + + -- Pressure in reservoir + self.ParkingBrakePressure = 0 + self.ReservoirPressure = 0.0 -- atm + -- Pressure in trains feed line + self.TrainLinePressure = 8.0 -- atm + -- Pressure in trains brake line + self.BrakeLinePressure = 3.0 -- atm + -- Pressure in brake cylinder + self.BrakeCylinderPressure = 0.0 -- atm + self.OldBrakeLinePressure = 3.0 + -- Pressure in the door line + self.DoorLinePressure = 0.0 -- atm + self.BCPressure = 0 + -- Air distrubutor part + self.WorkingChamberPressure = 5.2 + -- Disconnected KM 334 vessels (trainline and brakeline parts between disconnect valve and KM itself) emulation + self.TLDisconnectPressure = 0.0 + self.BLDisconnectPressure = 0.0 + self.WCChargeValve = false + self.PN1 = 0 + self.PN2 = 0 + self.cranPres = 0 + self.KM013offset = 5.2 + + --DKPT + self.Train:LoadSystem("DKPT","Relay","R-52B") -- + -- Valve #1 + self.Train:LoadSystem("PneumaticNo1","Relay") + -- Valve #2 + self.Train:LoadSystem("PneumaticNo2","Relay") + -- Автоматический выключатель торможения (АВТ) + self.Train:LoadSystem("AVT","Relay","AVT-325") + -- Регулятор давления (АК) + self.Train:LoadSystem("AK","Relay","AK-11B") + -- Блокировка тормозов + self.Train:LoadSystem("BPT","Relay","") + -- Блокировка дверей + self.Train:LoadSystem("BD","Relay","") + -- Вентили дверного воздухораспределителя (ВДОЛ, ВДОП, ВДЗ) + self.Train:LoadSystem("VDOL","Relay","", {bass = true}) + self.Train:LoadSystem("VDOP","Relay","", {bass = true}) + self.Train:LoadSystem("VDZ","Relay","", {bass = true}) + + -- Краны двойной тяги + self.Train:LoadSystem("DriverValveTLDisconnect","Relay","Switch", {bass = true}) + self.Train:LoadSystem("DriverValveBLDisconnect","Relay","Switch", {bass = true}) + + self.Train:LoadSystem("EmergencyBrakeValve","Relay","Switch") + -- Воздухораспределитель + self.Train:LoadSystem("AirDistributorDisconnect","Relay","Switch") + --Стояночный тормоз + self.Train:LoadSystem("ParkingBrake","Relay","Switch",{bass = true}) + -- Isolation valves + self.Train:LoadSystem("FrontBrakeLineIsolation","Relay","Switch", { normally_closed = true, bass = true}) + self.Train:LoadSystem("RearBrakeLineIsolation","Relay","Switch", { normally_closed = true, bass = true}) + self.Train:LoadSystem("FrontTrainLineIsolation","Relay","Switch", { normally_closed = true, bass = true}) + self.Train:LoadSystem("RearTrainLineIsolation","Relay","Switch", { normally_closed = true, bass = true}) + + -- Brake cylinder atmospheric valve open + self.BrakeCylinderValve = 0 + + -- Overpressure protection valve open + self.TrainLineOverpressureValve = 0 + + -- Compressor simulation + self.Compressor = 0 --Simulate overheat with TRK FIXME + + -- Doors state + if not TURBOSTROI then + self.LeftDoorState = { 0,0,0,0 } + self.RightDoorState = { 0,0,0,0 } + self.LeftDoorDir = { 0,0,0,0 } + self.RightDoorDir = { 0,0,0,0 } + self.LeftDoorSpeed = {0,0,0,0} + self.RightDoorSpeed = {0,0,0,0} + local start = math.Rand(0.6,0.8) + -- 0.6-1 + self.DoorSpeedMain = -math.Rand(start,math.Rand(start+0.1,start+0.2)) + for i=1,#self.LeftDoorSpeed do + if math.random() > 0.7 then + self.LeftDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.2) + self.RightDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.2) + else + self.LeftDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.1) + self.RightDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.1) + end + end + end + self.TrainLineOpen = false + self.BrakeLineOpen = false + + self.BLDisconnect = true + self.TLDisconnect = true + + self.OldValuePos = self.DriverValvePosition + + self.WeightLoadRatio = 0 + self.PassengerDoor = 0 +end + +function TRAIN_SYSTEM:Inputs() + return { "BrakeUp", "BrakeDown", "BrakeSet", "ValveType", "Autostop", "KM013offset" } +end + +function TRAIN_SYSTEM:Outputs() + return { "BrakeLinePressure", "BrakeCylinderPressure", "DriverValvePosition", "WorkingChamberPressure", + "ReservoirPressure", "TrainLinePressure", "DoorLinePressure", "WeightLoadRatio" } +end + +function TRAIN_SYSTEM:TriggerInput(name,value) + if name == "BrakeSet" then + self.DriverValvePosition = math.floor(value) + if self.ValveType == 1 then + if self.DriverValvePosition < 1 then self.DriverValvePosition = 1 end + if self.DriverValvePosition > 5 then self.DriverValvePosition = 5 end + else + if self.DriverValvePosition < 1 then self.DriverValvePosition = 1 end + if self.DriverValvePosition > 7 then self.DriverValvePosition = 7 end + end + elseif (name == "BrakeUp") and (value > 0.5) then + self:TriggerInput("BrakeSet",self.DriverValvePosition+1) + elseif (name == "BrakeDown") and (value > 0.5) then + self:TriggerInput("BrakeSet",self.DriverValvePosition-1) + elseif name == "ValveType" then + self.ValveType = math.floor(value) + elseif name == "KM013offset" then + self.KM013offset = value + elseif name:match("VZ%dOffset") then + local idx = name:match("VZ(%d)Offset") + self["GN"..idx.."Offset"] = math.random(2,10)*0.02 + value + self["GN"..idx.."Start"] = value + --PrintMessage(HUD_PRINTTALK, Format("Вагон %u; ВЗ-1: %.1f; ВЗ-2: %.1f",self.Train:GetWagonNumber(),self.GN1Offset or 0,self.GN2Offset or 0)) + end +end + + +-- TODO: почистить это говно, сделать раздельные звуки пневмы +-- Calculate derivatives +function TRAIN_SYSTEM:equalizeCouplePressure(dT,pressure,train,valve_status,rate,close_rate) + if not valve_status then return 0 end + local other + if IsValid(train) then other = train.Pneumatic end + + -- Get second pressure + local P2 = 0 + if other then P2 = other[pressure] end + if (not other) and (valve_status) then + self.TrainLineOpen = (pressure == "TrainLinePressure") + rate = close_rate or rate + --self.TrainLinePressure_dPdT = 0.0 + end + + -- Calculate rate + local dPdT = rate * (P2 - self[pressure]) + -- Calculate delta + local dP = dPdT*dT + if other and other.ReadOnly then + dP = dP/250 + end + -- Equalized pressure + local P0 = (P2 + self[pressure]) / 2 + -- Update pressures + if dP > 0 then + self[pressure] = math.min(P0,self[pressure] + dP) + if other and not other.ReadOnly then + other[pressure] = math.max(P0,other[pressure] - dP) + end + else + self[pressure] = math.max(P0,self[pressure] + dP) + if other and not other.ReadOnly then + other[pressure] = math.min(P0,other[pressure] - dP) + end + end + -- Update delta if losing air + if self.TrainLineOpen and (pressure == "TrainLinePressure") then + self[pressure.."_dPdT"] = (self[pressure.."_dPdT"] or 0) + dPdT + end + return dP +end +------------------------------------------------------------------------------- +function TRAIN_SYSTEM:UpdatePressures(Train,dT) + local frontBrakeOpen = Train.FrontBrakeLineIsolation.Value == 0 + local rearBrakeOpen = Train.RearBrakeLineIsolation.Value == 0 + local frontTrainOpen = Train.FrontTrainLineIsolation.Value == 0 + local rearTrainOpen = Train.RearTrainLineIsolation.Value == 0 + + local Ft = IsValid(Train.FrontTrain) and Train.FrontTrain + local Rt = IsValid(Train.RearTrain) and Train.RearTrain + local Fc, Rc = Train.FrontCouple or Train.FrontBogey, Train.RearCouple or Train.RearBogey + local Fb,Rb + if IsValid(Fc) and Fc.DepotPneumo then Fb = Fc.DepotPneumo end + if IsValid(Rc) and Rc.DepotPneumo then Rb = Rc.DepotPneumo end + + local frontBrakeLeak = false + local rearBrakeLeak = false + local frontTrainLeak = false + local rearTrainLeak = false + + -- Check if both valve on this train and connected train are open + if Ft and Ft.FrontBrakeLineIsolation then + if Ft.FrontTrain == Train then -- Nose to nose + frontBrakeLeak = frontBrakeOpen and Ft.FrontBrakeLineIsolation.Value==1 and 0.08 + frontTrainLeak = frontTrainOpen and Ft.FrontTrainLineIsolation.Value==1 and 0.08 + else -- Rear to nose + frontBrakeLeak = frontBrakeOpen and Ft.RearBrakeLineIsolation.Value==1 and 0.08 + frontTrainLeak = frontTrainOpen and Ft.RearTrainLineIsolation.Value==1 and 0.08 + end + else + frontBrakeLeak = frontBrakeOpen and 0.7 + frontTrainLeak = frontTrainOpen and not Fb and 0.3 + end + if Rt and Rt.FrontBrakeLineIsolation then + if Rt.FrontTrain == Train then -- Nose to nose + rearBrakeLeak = rearBrakeOpen and Rt.FrontBrakeLineIsolation.Value==1 and 0.08 + rearTrainLeak = rearTrainOpen and Rt.FrontTrainLineIsolation.Value==1 and 0.08 + else -- Rear to nose + rearBrakeLeak = rearBrakeOpen and Rt.RearBrakeLineIsolation.Value==1 and 0.08 + rearTrainLeak = rearTrainOpen and Rt.RearTrainLineIsolation.Value==1 and 0.08 + end + else + rearBrakeLeak = rearBrakeOpen and 0.7 + rearTrainLeak = rearTrainOpen and not Rb and 0.3 + end + + -- Equalize pressure + local Fl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",frontBrakeLeak==false and Ft,frontBrakeOpen,50,frontBrakeLeak or 0.08)*3)*(frontBrakeLeak and 1 or 0) + local Rl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",rearBrakeLeak==false and Rt,rearBrakeOpen,50,rearBrakeLeak or 0.08)*3)*(rearBrakeLeak and 1 or 0) + + Fl=Fl+math.min(0,self:equalizeCouplePressure(dT,"TrainLinePressure",frontTrainLeak==false and Ft or Fb,frontTrainOpen,100,frontTrainLeak or 0.08)*10)*(frontTrainLeak and 1 or 0) + Rl=Rl+math.min(0,self:equalizeCouplePressure(dT,"TrainLinePressure",rearTrainLeak==false and Rt or Rb,rearTrainOpen,100,rearTrainLeak or 0.08)*10)*(rearTrainLeak and 1 or 0) + + self.TrainLineOpen=frontTrainLeak or rearTrainLeak + self.BrakeLineOpen=frontBrakeLeak or rearBrakeLeak + Train:SetPackedRatio("FrontLeak",Fl) + Train:SetPackedRatio("RearLeak",Rl) +end + +function TRAIN_SYSTEM:equalizePressure(dT,pressure,target,rate,fill_rate,no_limit,smooth) + if fill_rate and (target > self[pressure]) then rate = fill_rate end + + -- Calculate derivative + local dPdT = rate + if target < self[pressure] then dPdT = -dPdT end + local dPdTramp = math.min(1.0,math.abs(target - self[pressure])*(smooth or 0.5)) + dPdT = dPdT*dPdTramp + + -- Update pressure + self[pressure] = self[pressure] + dT * dPdT + self[pressure] = math.max(0.0,math.min(16.0,self[pressure])) + self[pressure.."_dPdT"] = (self[pressure.."_dPdT"] or 0) + dPdT + if no_limit ~= true then + if self[pressure] == 0.0 then self[pressure.."_dPdT"] = 0 end + if self[pressure] == 16.0 then self[pressure.."_dPdT"] = 0 end + end + return dPdT +end +------------------------------------------------------------------------------- +function TRAIN_SYSTEM:Think(dT) + local Train = self.Train + local retainer = Train:GetNW2Int("RetainerLoad", 4) + self.WeightLoadRatio = retainer == 4 and math.max(0,math.min(1,(Train:GetNW2Float("PassengerCount")/200))) or (retainer-1)*0.5 + + ---------------------------------------------------------------------------- + -- Accumulate derivatives + self.TrainLinePressure_dPdT = 0.0 + self.BrakeLinePressure_dPdT = 0.0 + self.ReservoirPressure_dPdT = 0.0 + self.BrakeCylinderPressure_dPdT = 0.0 + self.ParkingBrakePressure_dPdT = 0.0 + self.WorkingChamberPressure_dPdT = 0.0 + + -- Reduce pressure for brake line + self.TrainToBrakeReducedPressure = math.min(self.KM013offset,self.TrainLinePressure) -- * 0.725) + -- Feed pressure to door line + self.DoorLinePressure = self.TrainToBrakeReducedPressure * 0.90 + local trainLineConsumption_dPdT = 0.0 + local wagc = Train.CarCount and Train:GetBLConnectedWagonCount() or #Train.WagonList + local HaveEPK = not Train.SubwayTrain or not Train.SubwayTrain.ARS or not Train.SubwayTrain.ARS.NoEPK + + local pr_speed = 1 + + if self.ValveType == 1 then + self.BLDisconnect = Train.DriverValveBLDisconnect.Value > 0 + self.TLDisconnect = Train.DriverValveTLDisconnect.Value > 0 and self.RealDriverValvePosition ~= 3 + pr_speed = 1*wagc--*((self.BrakeLinePressure-self.ReservoirPressure)/0.6) --2 + if self.TLDisconnect then self.TLDisconnectPressure = self.TrainLinePressure end + if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end + -- 334: 1 Fill reservoir from train line, fill brake line from train line + if (self.RealDriverValvePosition == 1) then + if self.TLDisconnect or self.ReservoirPressure ~= self.TLDisconnectPressure then + if self.BLDisconnect then + self.ReservoirPressure = self.BrakeLinePressure + self:equalizePressure(dT,"BrakeLinePressure", self.TLDisconnectPressure, pr_speed*(pr_speed < wagc and 1 or 1.35),nil,nil,2)--0.7 + else + self:equalizePressure(dT,"ReservoirPressure", self.TLDisconnectPressure, 3.55,nil,nil,2) + end + end + end + + -- 334: 2 Brake line, reservoir replenished from brake line reductor + if (self.RealDriverValvePosition == 2) then + if self.TLDisconnect then + local a = 1 + if --[[self.EmergencyValve or ]]Train.EmergencyBrakeValve.Value > 0.5 then a = 1.85 end + if self.BLDisconnect then + self.ReservoirPressure = self.BrakeLinePressure + self:equalizePressure(dT,"BrakeLinePressure", self.TrainToBrakeReducedPressure, pr_speed*0, pr_speed*0.6*a, nil, 1.6) + self.ReservoirPressure_dPdT = self.BrakeLinePressure_dPdT*0.8 + else + self:equalizePressure(dT,"ReservoirPressure", self.TrainToBrakeReducedPressure,0,1.55,nil,2) + end + end + end + + -- 334: 3 Close all valves + if (self.RealDriverValvePosition == 3) then + -- Typical leak + self:equalizePressure(dT,"ReservoirPressure", 0.00, 0.001) + end + + local res_dischrg_rate4 = self.BLDisconnect and 0.55 or 8 + local res_dischrg_rate5 = self.BLDisconnect and 1.12 or 8 + -- 334: 4 Reservoir open to atmosphere, brake line equalizes with reservoir + if (self.RealDriverValvePosition == 4) then + self:equalizePressure(dT,"ReservoirPressure", 0.0, res_dischrg_rate4, nil,nil,6)--0.35)-0.55 + end + + -- 334: 5 Reservoir and brake line open to atmosphere + if (self.RealDriverValvePosition == 5) then + self:equalizePressure(dT,"ReservoirPressure", 0.0, res_dischrg_rate5)--,nil,nil,2)--1.70 + local pr_speed = 1.25*wagc + if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end + if self.BLDisconnect then + if self.Leak then pr_speed = pr_speed*6.2 end + self:equalizePressure(dT,"BrakeLinePressure", 0.0, pr_speed,nil,nil,2) + end + end + -- утечка через неплотность уравнительного поршня + if self.BLDisconnect then self:equalizePressure(dT, "ReservoirPressure", self.BrakeLinePressure, 0.06, 0) end + if (self.RealDriverValvePosition > 2) and (self.RealDriverValvePosition < 5) then + local pr_speed = 1.25*wagc + if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end + local _a = 0 + for _i = 1, #Train.WagonList do + if Train.WagonList[_i].Pneumatic.TLDisconnect and Train.WagonList[_i].Pneumatic.BLDisconnect and (Train.WagonList[_i].Pneumatic.RealDriverValvePosition == 2 or Train.WagonList[_i].Pneumatic.RealDriverValvePosition == 1) then + _a = _a + 1 + end + if _a > 0 then break end + end + if _a > 0 then pr_speed = pr_speed*0.1 end + if self.BLDisconnect and self.BrakeLinePressure - self.ReservoirPressure > (self.RealDriverValvePosition == 3 and 0 or self.RealDriverValvePosition == 4 and 0.2 or 100) then --0.2 bar is a piston sensitivity + self:equalizePressure(dT, "BrakeLinePressure", 0, pr_speed*math.abs(self.BrakeLinePressure - self.ReservoirPressure), nil, nil, 6) + end + end + + if not self.TLDisconnect then + self.TLDisconnectPressure = math.max(0,self.TLDisconnectPressure - math.abs(self.ReservoirPressure_dPdT)*dT) + end + self.ReservoirPressure_dPdT = self.ReservoirPressure_dPdT + self.BrakeLinePressure_dPdT*0.2 + Train:SetPackedRatio("ReservoirPressure_dPdT",self.ReservoirPressure_dPdT/wagc*2) + --[[ + ---------------debug--------------------- + self.dlreadtimer = self.dlreadtimer or CurTime() + if CurTime() - self.dlreadtimer > 1.0 then + self.dlreadtimer = CurTime() + if Train:GetDriver() then + PrintMessage(HUD_PRINTTALK, Format("Вагон %u; P ТМ: %.3f; P УР =%.3f; Утечка ТМ %.3f; TLDis = %.3f; pr_speed = %.3f",Train:GetWagonNumber(),self.BrakeLinePressure,self.ReservoirPressure,self.BrakeLinePressure_dPdT, self.TLDisconnectPressure, pr_speed)) + end + end + ---------------debug---------------------]] + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeLinePressure_dPdT) + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.ReservoirPressure_dPdT)*0.05 + else + pr_speed = 2.8--1.25*wagc --2 + local pz_speed + -- wagc | pr_speed + ------------------ + -- 1 | 8.455 + -- 2 | 7.865 + -- 3 | 7.376 + -- 4 | 6.969 + -- 5 | 6.627 + -- 6 | 6.341 + -- 7 | 6.100 + -- 8 | 5.900 + --pr_speed = (0.4*math.exp(0.1*wagc-1)+1)*160/(2*wagc+20) --2 + --local frc = 0.6--0.35 + if self.Leak or self.BrakeLineOpen then pz_speed = pr_speed*0.25 else pz_speed = pr_speed*1.3 end--*frc end + self.BLDisconnect = Train.DriverValveBLDisconnect.Value > 0 + self.TLDisconnect = Train.DriverValveTLDisconnect.Value > 0 + if self.RealDriverValvePosition > 4 and not self.km13_error2 then self.km13_error2 = 0.7 end + -- 013: 1 Overcharge + if (self.RealDriverValvePosition == 1) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > self.TrainLinePressure) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(6.4,self.TrainLinePressure), pr_speed, pz_speed, nil, 1.0) + end + + -- 013: 2 Normal pressure + if (self.RealDriverValvePosition == 2) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(self.KM013offset,self.TrainToBrakeReducedPressure)) then--was pr_speed*2 + self:equalizePressure(dT,"BrakeLinePressure", math.min(self.KM013offset+(self.km13_error2 or 0),self.TrainLinePressure), pr_speed, pz_speed, nil, 2.5)-- nil, 1.0) + if self.km13_error2 and self.BrakeLinePressure >= self.KM013offset+self.km13_error2-0.1 then + self:equalizePressure(dT,"BrakeLinePressure", math.min(self.KM013offset,self.TrainToBrakeReducedPressure), 35, pz_speed, nil, 1) + self.km13_error2 = nil + end + end + + -- 013: 3 4.3 Atm + if (self.RealDriverValvePosition == 3) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(4.3,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(4.3,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5) + end + + -- 013: 4 4.0 Atm + if (self.RealDriverValvePosition == 4) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(4.0,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(4.0,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5) + end + + -- 013: 5 3.7 Atm + if (self.RealDriverValvePosition == 5) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(3.7,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(3.7,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5) + end + + -- 013: 6 3.0 Atm + if (self.RealDriverValvePosition == 6) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(3.0,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(3.0,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5) + end + + -- 013: 7 0.0 Atm + if (self.RealDriverValvePosition == 7) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 0.0) then + self:equalizePressure(dT,"BrakeLinePressure", 0.0, (0.6 + pr_speed*math.exp(math.min(0,self.BrakeLinePressure - 2.3)*1.0))*(0.15*wagc+1),pz_speed, nil, 2.5) + end + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeLinePressure_dPdT) + end + self.Leak = false + if wagc ~= Train.OldWagIsoCount or not Train.pr_spd_init then + pr_speed = (0.4*math.exp(0.1*wagc-1)+1)*160/(2*wagc+20) --2 + Train.OldWagIsoCount = wagc + Train.pr_spd_init = true + end + if self.ValveType == 1 then + Train:SetPackedRatio("Crane_dPdT", self.ReservoirPressure_dPdT ) + else + Train:SetPackedRatio("Crane_dPdT", self.BrakeLinePressure_dPdT/wagc*3 ) + end + + local leak = 0 + if Train.EmergencyBrakeValve and Train.EmergencyBrakeValve.Value > 0.5 then + local leakst = math.max(0.5,math.exp(0.5*self.BrakeLinePressure)) + leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,leakst)--,false,false,10) --was leakst*wagc/5 + self.Leak = true + end + Train:SetPackedRatio("EmergencyBrakeValve_dPdT", -leak/wagc) + ---------------------------------------------------------------------------- + -- Fill brake cylinders + if self.WCChargeValve == true then + self:equalizePressure(dT,"WorkingChamberPressure",self.BrakeLinePressure,0.094,nil,nil,1.0) --simulate 0.8mm hole btw BL and working chambers + end + local aird_ready = self.WorkingChamberPressure >= 2.2 + self.WCChargeValve = not ((self.WorkingChamberPressure - self.BrakeLinePressure) > 0.2 and (self.WorkingChamberPressure - self.BrakeLinePressure) < 2.5) + local KLSZ = self.WorkingChamberPressure > 5.2 and not self.WCChargeValve + if KLSZ then + self:equalizePressure(dT,"WorkingChamberPressure",0.0,0.12) -- КЛСЗ + end + + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.WorkingChamberPressure_dPdT*0.2) + self.GN2Offset = self.GN2Offset or math.random(20,100)*0.002 + (self.GN2Start or 2.4) + self.GN1Offset = self.GN1Offset or math.random(20,100)*0.002 + (self.GN1Start or 0.8) + self.BcBl = (self.GN2Offset + self.WeightLoadRatio*(self.GN2Offset - 1.4))/1.82--1.92 + if Train.AirDistributorDisconnect.Value == 0 and aird_ready then + -- Valve #1 + if (Train.PneumaticNo1.Value == 1.0) and (Train.PneumaticNo2.Value == 0.0) then + if self.PN1 < self.GN1Offset then + self.PN1 = math.min(self.TrainLinePressure,self.GN1Offset) + end + elseif Train.PneumaticNo1.Value == 0 and self.PN1 > 0.0 then + self.PN1 = self.BrakeCylinderPressure > 0.2 and 0.05 or self.PN1 - 0.5*dT + end + -- Valve #2 + if Train.PneumaticNo2.Value == 1.0 then + self.PN2 = math.min(self.TrainLinePressure,(self.GN2Offset + self.WeightLoadRatio*1.3)) + if self.BePN2 == false and self.BrakeCylinderPressure > 1.6 then + Train:PlayOnce("PN2end","stop") + end + self.BePN2 = true + elseif self.PN2 > 0.0 then + self.PN2 = self.BrakeCylinderPressure > 0.4 and 0.2 or self.PN2 - 0.5*dT + end + --[[ + ---------------debug--------------------- + self.brreadtimer = self.brreadtimer or CurTime() + if CurTime() - self.brreadtimer > 1.0 then + self.brreadtimer = CurTime() + if Train:GetDriver() then + --PrintMessage(HUD_PRINTTALK, Format("br_threshold = %.3f; WcBl = %s",br_threshold, tostring(WcBl))) + --PrintMessage(HUD_PRINTTALK, Format("Это %s", isLVZ and "ЛВЗ" or "не ЛВЗ")) + --PrintMessage(HUD_PRINTTALK, Format("Вагон %u; Авторежим: %.3f",Train:GetWagonNumber(),self.WeightLoadRatio)) + --PrintMessage(HUD_PRINTTALK, Format("wagc = %u; wagd = %u",wagc,wagd)) + end + end + ---------------debug---------------------]] + + self.BchExh = self.WorkingChamberPressure < 4.8 and self.BrakeLinePressure < 3.4 and 0 or 1 + self.cranPres = math.max(0,self.BcBl*(self.WorkingChamberPressure - self.BrakeLinePressure*self.BchExh)*(self.BrakeLinePressure > self.KM013offset and (0.6 + self.PN1*0.43) or 1)) + local targetPressure = math.max(0,math.min(self.GN2Offset + self.WeightLoadRatio*1.3, (self.cranPres < (self.PN1 + self.WeightLoadRatio*0.7) and (Train.PneumaticNo1.Value == 1.0) and (self.PN1 + self.WeightLoadRatio*0.7) or self.PN1) + self.PN2 + self.cranPres)) + if math.abs(self.BrakeCylinderPressure - targetPressure) > 0.150 then + self.BrakeCylinderValve = 1 + end + if math.abs(self.BrakeCylinderPressure - targetPressure) < 0.025 then + self.BrakeCylinderValve = 0 + end + if self.BrakeCylinderValve == 1 then + self:equalizePressure(dT,"BrakeCylinderPressure", math.min(self.GN2Offset + self.WeightLoadRatio*(self.GN2Offset - 1.4),targetPressure), 0.8, (Train.PneumaticNo1.Value > 0 or Train.PneumaticNo2.Value > 0) and 2.8 or 1.5, nil, 1.2) + end + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeCylinderPressure_dPdT*0.5) + elseif Train.AirDistributorDisconnect.Value ~= 0 then + self:equalizePressure(dT,"BrakeCylinderPressure", 0.0, 2.00) + end + if (self.BrakeCylinderPressure > 0.2 and self.BrakeCylinderPressure_dPdT > 0.1 or self.BrakeCylinderPressure_dPdT > 1) and not self.BrakeEngaged then + self.BrakeEngaged = true + Train:PlayOnce("brake","bass",1,math.Clamp(self.BrakeCylinderPressure_dPdT,0.7,1.2)) + end + if self.BrakeCylinderPressure < 1 and self.BrakeCylinderPressure_dPdT < -0.1 and self.BrakeEngaged then + self.BrakeEngaged = false + end + Train:SetPackedRatio("BrakeCylinderPressure_dPdT", self.BrakeCylinderPressure_dPdT) + self.TrainLinePressure = self.TrainLinePressure-math.max(0,self.BrakeCylinderPressure_dPdT*0.002) + if Train.PneumaticNo2.Value == 0 then + if self.BePN2 == true then + self.BePN2 = CurTime() + elseif self.BePN2 and self.BrakeCylinderPressure_dPdT > -0.2 then + Train:PlayOnce("PN2end","bass",math.Clamp(math.min(1,(CurTime()-self.BePN2)/1.3)*((3.2-self.BrakeCylinderPressure)/1.2),0,1)) + self.BePN2 = false + end + end + if self.BePN2 == false and (self.BrakeCylinderPressure_dPdT >= 0.2) then + self.BePN2 = nil + Train:PlayOnce("PN2end","stop") + end + + --Parking brake simulation + local PBPressure = math.Clamp(self.TrainLinePressure/5,0,1)*2.7 + if Train.ParkingBrake.Value == 0 then + self:equalizePressure(dT,"ParkingBrakePressure", PBPressure, 10,10,nil,0.5) + else + self:equalizePressure(dT,"ParkingBrakePressure", 0, 3,10,nil,0.5) + end + Train:SetPackedRatio("ParkingBrakePressure_dPdT",self.ParkingBrakePressure_dPdT) + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.ParkingBrakePressure_dPdT*0.5) + + -- Simulate cross-feed between different wagons + self:UpdatePressures(Train,dT) + + ---------------------------------------------------------------------------- + -- Simulate compressor operation and train line depletion + self.Compressor = Train.KK.Value * (Train.Electric.Aux750V > 550 and 1 or 0) + self.TrainLinePressure = self.TrainLinePressure - (Train.AirConsumeRatio or 0.06)*trainLineConsumption_dPdT*dT -- 0.190 --0.170 --0.07 + if self.Compressor == 1 then self:equalizePressure(dT,"TrainLinePressure", 10.0, Train.CompressorEfficiency or 0.07) end -- 0.04 + self:equalizePressure(dT,"TrainLinePressure", 0,Train.AirLeakRatio or 0.003) + -- Overpressure + if self.TrainLinePressure > math.max(7.2, (9.2 - self.TrainLineOverpressureValve*0.2)) and self.TrainLineOverpressureValve%2 == 0 then self.TrainLineOverpressureValve = self.TrainLineOverpressureValve + 1 end + if self.TrainLineOverpressureValve%2 == 1 then + self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.2) + self.TrainLineOpen = true + if self.TrainLinePressure < 5.2 and self.TrainLineOverpressureValve < 20 then self.TrainLineOverpressureValve = self.TrainLineOverpressureValve + 1 end + end + + ---------------------------------------------------------------------------- + -- Pressure triggered relays + Train.AVT:TriggerInput("Open", self.BrakeCylinderPressure > 1.9) -- 1.8 - 2.0 + Train.AVT:TriggerInput("Close",self.BrakeCylinderPressure < 0.9) -- 0.9 - 1.5 + Train.AK:TriggerInput( "Open", self.TrainLinePressure > 8.2) + Train.AK:TriggerInput( "Close",self.TrainLinePressure < 6.3) + Train.BPT:TriggerInput("Set", (IsValid(Train.FrontBogey) and Train.FrontBogey.BrakeCylinderPressure+(not Train.FrontBogey.DisableParking and Train.FrontBogey.ParkingBrakePressure or 0) or self.BrakeCylinderPressure)>0.3) + Train.DKPT:TriggerInput("Set", self.BrakeCylinderPressure > 0.3) -- 1.8 - 2.0 + + ---------------------------------------------------------------------------- + -- Simulate doors opening, closing + if self.DoorLinePressure > 3.5 then + if (Train.VDOL.Value == 1.0) and (Train.VDOP.Value == 0.0) and not self.DoorLeft then + self.DoorLeft = true + if self.VDOLLoud then Train:PlayOnce("vdol_loud","cabin",0.8+math.random()*0.2,self.VDOLLoud) end + end + if (Train.VDOL.Value == 0.0) and (Train.VDOP.Value == 1.0) and not self.DoorRight then + self.DoorRight = true + if self.VDORLoud then Train:PlayOnce("vdop_loud","cabin",0.8+math.random()*0.2,self.VDORLoud) end + end + if (Train.VDZ.Value == 1.0 or Train.VDOL.Value == 1.0 and Train.VDOP.Value == 1.0 or self.RZDTimer) and (self.DoorLeft or self.DoorRight) then + if not self.OpenWaitL or CurTime()-self.OpenWaitL < 0.2 then + self.DoorLeft = false + end + if not self.OpenWaitR or CurTime()-self.OpenWaitR < 0.2 then + self.DoorRight = false + end + else + self.CloseValue = nil + end + if Train.VDOL.Value == 1.0 and Train.VDOP.Value == 1.0 then + self.RZDTimer = CurTime() + elseif self.RZDTimer and CurTime()-self.RZDTimer > 0.1 then + self.RZDTimer = nil + end + end + if self.VDOL ~= Train.VDOL.Value then + self.VDOL = Train.VDOL.Value + self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.05) + end + if self.VDOP ~= Train.VDOP.Value then + self.VDOP = Train.VDOP.Value + self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.05) + end + if self.VDZ ~= Train.VDZ.Value then + self.VDZ = Train.VDZ.Value + self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.05) + end + + + Train.LeftDoorsOpen = false + Train.RightDoorsOpen = false + local openL = true + local openR = true + for i=1,4 do + self.LeftDoorDir[i] = math.Clamp(self.LeftDoorDir[i]+dT/(self.DoorLeft and self.LeftDoorSpeed[i] or -self.LeftDoorSpeed[i]),-1,1) + self.RightDoorDir[i] = math.Clamp(self.RightDoorDir[i]+dT/(self.DoorRight and self.RightDoorSpeed[i] or -self.RightDoorSpeed[i]),-1,1) + self.LeftDoorState[i] = math.Clamp(self.LeftDoorState[i] + ((self.LeftDoorDir[i]/self.LeftDoorSpeed[i])*dT),0,1) + if self.LeftDoorState[i] == 0 or self.LeftDoorState[i] == 1 then self.LeftDoorDir[i] = 0 end + self.RightDoorState[i] = math.Clamp(self.RightDoorState[i] + ((self.RightDoorDir[i]/self.RightDoorSpeed[i])*dT),0,1) + if self.RightDoorState[i] == 0 or self.RightDoorState[i] == 1 then self.RightDoorDir[i] = 0 end + if not Train.LeftDoorsOpen and self.LeftDoorState[i] > 0 then + Train.LeftDoorsOpen = true + end + if self.LeftDoorState[i] > self.LeftDoorSpeed[i]/20 then self.OpenWaitL = false end + if self.RightDoorState[i] > self.LeftDoorSpeed[i]/20 then self.OpenWaitR = false end + if self.LeftDoorState[i] > 0 then openL = false end + if self.RightDoorState[i] > 0 then openR = false end + if not Train.RightDoorsOpen and self.RightDoorState[i] > 0 then + Train.RightDoorsOpen = true + end + Train:SetPackedRatio("DoorL"..i,self.LeftDoorState[i]) + Train:SetPackedRatio("DoorR"..i,self.RightDoorState[i]) + end + if openL and not self.OpenWaitL then self.OpenWaitL = CurTime() end + if openR and not self.OpenWaitR then self.OpenWaitR = CurTime() end + Train:SetPackedBool("DoorL",self.DoorLeft) + Train:SetPackedBool("DoorR",self.DoorRight) + Train.BD:TriggerInput("Set",not Train.RightDoorsOpen and not Train.LeftDoorsOpen) + + ---------------------------------------------------------------------------- + -- FIXME + Train:SetNW2Bool("FbI",Train.FrontBrakeLineIsolation.Value ~= 0) + Train:SetNW2Bool("RbI",Train.RearBrakeLineIsolation.Value ~= 0) + Train:SetNW2Bool("FtI",Train.FrontTrainLineIsolation.Value ~= 0) + Train:SetNW2Bool("RtI",Train.RearTrainLineIsolation.Value ~= 0) + Train:SetNW2Bool("AD",Train.AirDistributorDisconnect.Value == 0) + + local ValveType = self.ValveType > 1 + self.Timer = self.Timer or CurTime() + if ((CurTime() - self.Timer > 0.10) and (self.DriverValvePosition > self.RealDriverValvePosition)) then + self.Timer = CurTime() + if not ValveType then + if self.RealDriverValvePosition ~= 3 then + Train:PlayOnce("br_334",self.RealDriverValvePosition.."-"..(self.RealDriverValvePosition+1)) + end + else + Train:PlayOnce("br_013","cabin") + end + self.RealDriverValvePosition = self.RealDriverValvePosition + 1 + end + if ((CurTime() - self.Timer > 0.10) and (self.DriverValvePosition < self.RealDriverValvePosition)) then + self.Timer = CurTime() + if not ValveType then + if self.RealDriverValvePosition ~= 5 then + Train:PlayOnce("br_334",self.RealDriverValvePosition.."-"..(self.RealDriverValvePosition-1)) + end + else + Train:PlayOnce("br_013","cabin") + end + self.RealDriverValvePosition = self.RealDriverValvePosition - 1 + end +end diff --git a/lua/metrostroi/systems/sys_81_717_new_pneumatic.lua b/lua/metrostroi/systems/sys_81_717_new_pneumatic.lua new file mode 100644 index 00000000..3fac0119 --- /dev/null +++ b/lua/metrostroi/systems/sys_81_717_new_pneumatic.lua @@ -0,0 +1,1050 @@ +-------------------------------------------------------------------------------- +-- 81-717 pneumatic system +-------------------------------------------------------------------------------- +-- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o. +-- Contains proprietary code. See license.txt for additional information. +-------------------------------------------------------------------------------- +Metrostroi.DefineSystem("81_717_NewPneumatic") +TRAIN_SYSTEM.DontAccelerateSimulation = true + +function TRAIN_SYSTEM:Initialize(parameters) + self.ValveType = 1 + self.DisconnectType = parameters and parameters.br013_1 + -- Position of the train drivers valve + -- Type 1 (334) + -- 1 Accelerated charge + -- 2 Normal charge (brake release) + -- 3 Closed + -- 4 Service application + -- 5 Emergency application + -- + -- Type 2 (013) + -- 1 Accelerated charge + -- 2 Normal charge (brake release) + -- 3 Closed + -- 4 Service application + -- 5 Emergency application + self.DriverValvePosition = 2 + self.RealDriverValvePosition = self.DriverValvePosition + + + -- Pressure in reservoir + self.ParkingBrakePressure = 0 + self.ReservoirPressure = 0.0 -- atm + -- Pressure in trains feed line + self.TrainLinePressure = 8.0 -- atm + -- Pressure in trains brake line + self.BrakeLinePressure = 3.0 -- atm + self.EPKPressure = 0.0 -- atm + -- Pressure in brake cylinder + self.BrakeCylinderPressure = 0.0 -- atm + -- Pressure in the door line + self.DoorLinePressure = 0.0 -- atm + self._1stRightDoorCloseCylPressure = 0.0 + self.LeftDoorCloseCylPressure = 0.0 + self.LeftDoorOpenCylPressure = 0.0 + self.RightDoorCloseCylPressure = 0.0 + self.RightDoorOpenCylPressure = 0.0 + self.LeftExhausted = false + self.RightExhausted = false + + self.OldBrakeLinePressure = 0.0 + self.BCPressure = 0 + -- Air distrubutor part + self.WorkingChamberPressure = 5.2 + -- Disconnected KM 334 vessels (trainline and brakeline parts between disconnect valve and KM itself) emulation + self.TLDisconnectPressure = 0.0 + self.BLDisconnectPressure = 0.0 + self.WCChargeValve = false + self.PN1 = 0 + self.PN2 = 0 + self.cranPres = 0 + self.KM013offset = 5.2 + self.km013_overcharge = false + + --DKPT + self.Train:LoadSystem("DKPT","Relay","R-52B") -- + -- Valve #1 + self.Train:LoadSystem("PneumaticNo1","Relay") + -- Valve #2 + self.Train:LoadSystem("PneumaticNo2","Relay") + -- Автоматический выключатель торможения (АВТ) + self.Train:LoadSystem("AVT","Relay","AVT-325") + -- Регулятор давления (АК) + self.Train:LoadSystem("AK","Relay","AK-11B") + -- Автоматический выключатель управления (АВУ) + self.Train:LoadSystem("AVU","Relay","AVU-045") + -- Блокировка тормозов + self.Train:LoadSystem("BPT","Relay","") + -- Блокировка дверей + self.Train:LoadSystem("BD","Relay","") + -- Вентили дверного воздухораспределителя (ВДОЛ, ВДОП, ВДЗ) + self.Train:LoadSystem("VDOL","Relay","", {bass = true}) + self.Train:LoadSystem("VDOP","Relay","", {bass = true}) + self.Train:LoadSystem("VDZ","Relay","", {bass = true}) + + -- Разобщение клапана машиниста + self.Train:LoadSystem("DriverValveDisconnect","Relay","Switch", {bass = true}) + -- Краны двойной тяги + self.Train:LoadSystem("DriverValveTLDisconnect","Relay","Switch", {bass = true}) + self.Train:LoadSystem("DriverValveBLDisconnect","Relay","Switch", {bass = true}) + + self.Train:LoadSystem("EmergencyBrakeValve","Relay","Switch") + -- Воздухораспределитель + self.Train:LoadSystem("AirDistributorDisconnect","Relay","Switch") + --УАВА + self.Train:LoadSystem("UAVA","Relay","Switch",{ bass = true}) + self.Train:LoadSystem("UAVAContact","Relay","Switch") + self.Train:LoadSystem("UAVAC","Relay","",{normally_closed=true,bass=true}) + --Срывной клапан + self.Train:LoadSystem("AutostopValve","Relay","Switch") + --Стояночный тормоз + self.Train:LoadSystem("ParkingBrake","Relay","Switch",{bass = true}) + --ЭПК + self.Train:LoadSystem("EPK","Relay","Switch",{ bass = true}) + self.Train:LoadSystem("SOT","Relay") + -- Isolation valves + self.Train:LoadSystem("FrontBrakeLineIsolation","Relay","Switch", { normally_closed = true, bass = true}) + self.Train:LoadSystem("RearBrakeLineIsolation","Relay","Switch", { normally_closed = true, bass = true}) + self.Train:LoadSystem("FrontTrainLineIsolation","Relay","Switch", { normally_closed = true, bass = true}) + self.Train:LoadSystem("RearTrainLineIsolation","Relay","Switch", { normally_closed = true, bass = true}) + + self.Train:LoadSystem("SQ3","Relay","") + ------------------------------------------------------------------------------------------------ + --Ручное управление дверьми + --Краны выключения дверей и разобщительный кран ДВР + self.Train:LoadSystem("DoorReleaseExtra","Relay","Switch") + self.Train:LoadSystem("DoorReleaseRight","Relay","Switch") + self.Train:LoadSystem("DoorReleaseLeft","Relay","Switch") + self.Train:LoadSystem("DVRDisconnect","Relay","Switch", { normally_closed = false, bass = true}) + --Механическая блокировка дверей + self.Train:LoadSystem("HDLK1","Relay","VB-11", {bass = true}) --1 правый + self.Train:LoadSystem("HDLK2","Relay","VB-11", {bass = true}) --2 правый + self.Train:LoadSystem("HDLK3","Relay","VB-11", {bass = true}) --3 правый + self.Train:LoadSystem("HDLK4","Relay","VB-11", {bass = true}) --4 правый + self.Train:LoadSystem("HDLK5","Relay","VB-11", {bass = true}) --4 левый + self.Train:LoadSystem("HDLK6","Relay","VB-11", {bass = true}) --3 левый + self.Train:LoadSystem("HDLK7","Relay","VB-11", {bass = true}) --2 левый + self.Train:LoadSystem("HDLK8","Relay","VB-11", {bass = true}) --1 левый + --раздвинуть/сдвинуть створки руками + self.Train:LoadSystem("outerhod1","Relay","Switch") --передние правые двери головного вагона (открытие снаружи состава) + self.Train:LoadSystem("hod1","Relay","Switch") + self.Train:LoadSystem("hod2","Relay","Switch") + self.Train:LoadSystem("hod3","Relay","Switch") + self.Train:LoadSystem("hod4","Relay","Switch") + self.Train:LoadSystem("hod5","Relay","Switch") + self.Train:LoadSystem("hod6","Relay","Switch") + self.Train:LoadSystem("hod7","Relay","Switch") + self.Train:LoadSystem("hod8","Relay","Switch") + self.Train:LoadSystem("hcd1","Relay","Switch") + self.Train:LoadSystem("hcd2","Relay","Switch") + self.Train:LoadSystem("hcd3","Relay","Switch") + self.Train:LoadSystem("hcd4","Relay","Switch") + self.Train:LoadSystem("hcd5","Relay","Switch") + self.Train:LoadSystem("hcd6","Relay","Switch") + self.Train:LoadSystem("hcd7","Relay","Switch") + self.Train:LoadSystem("hcd8","Relay","Switch") + + -- Door release valve status + self.DoorReleaseRightPrevious = 0 + self.DoorReleaseLeftPrevious = 0 + self.DoorReleaseExtraPrevious = 0 + + -- Brake cylinder atmospheric valve open + self.BrakeCylinderValve = 0 + + -- Overpressure protection valve open + self.TrainLineOverpressureValve = 0 + + -- Compressor simulation + self.Compressor = 0 --Simulate overheat with TRK FIXME + + -- Disconnect valve status + self.DriverValveDisconnectPrevious = 0 + + -- Doors state + if not TURBOSTROI then + self.LeftDoorState = self.LeftDoorState or { 0,0,0,0 } + self.RightDoorState = self.RightDoorState or { 0,0,0,0 } + --self.LeftDoorDir = { 0,0,0,0 } + --self.RightDoorDir = { 0,0,0,0 } + self.LeftDoorSpeed = {1,1,1,1} + self.RightDoorSpeed = {1,1,1,1} + self.DSprev = {{0,0},{0,0},{0,0},{0,0}} + self.LeftDoorStuck = {false, false, false, false} + self.RightDoorStuck = {false, false, false, false} + + local start = math.Rand(0.6,1.0) + -- 0.6-1 + self.DoorSpeedMain = -math.Rand(start,math.Rand(start+0.1,start+0.2)) + for i=1,#self.LeftDoorSpeed do + if math.random() > 0.7 then + self.LeftDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.2) + self.RightDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.2) + else + self.LeftDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.1) + self.RightDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.1) + end + end + end + self.TrainLineOpen = false + self.BrakeLineOpen = false + + self.BLDisconnect = true + self.TLDisconnect = true + + self.EmergencyValve = false + self.EmergencyValveEPK = false + self.OldValuePos = self.DriverValvePosition + + self.WeightLoadRatio = 0 + self.PassengerDoor = 0 +end + +function TRAIN_SYSTEM:Inputs() + return { "BrakeUp", "BrakeDown", "BrakeSet", "ValveType", "Autostop", "KM013offset" } +end + +function TRAIN_SYSTEM:Outputs() + return { "BrakeLinePressure", "BrakeCylinderPressure", "DriverValvePosition", "WorkingChamberPressure", "LeftDoorCloseCylPressure", "LeftDoorOpenCylPressure", + "ReservoirPressure", "TrainLinePressure", "DoorLinePressure", "WeightLoadRatio", "RightDoorCloseCylPressure", "_1stRightDoorCloseCylPressure", "RightDoorOpenCylPressure" } +end + +function TRAIN_SYSTEM:TriggerInput(name,value) + if name == "BrakeSet" then + self.DriverValvePosition = math.floor(value) + if self.ValveType == 1 then + if self.DriverValvePosition < 1 then self.DriverValvePosition = 1 end + if self.DriverValvePosition > 5 then self.DriverValvePosition = 5 end + else + if self.DriverValvePosition < 1 then self.DriverValvePosition = 1 end + if self.DriverValvePosition > 7 then self.DriverValvePosition = 7 end + end + elseif (name == "BrakeUp") and (value > 0.5) then + self:TriggerInput("BrakeSet",self.DriverValvePosition+1) + elseif (name == "BrakeDown") and (value > 0.5) then + self:TriggerInput("BrakeSet",self.DriverValvePosition-1) + elseif name == "ValveType" then + self.ValveType = math.floor(value) + elseif name:match("VZ%dOffset") then + local idx = name:match("VZ(%d)Offset") + self["GN"..idx.."Offset"] = math.random(2,10)*0.02 + value + self["GN"..idx.."Start"] = value + --PrintMessage(HUD_PRINTTALK, Format("Вагон %u; ВЗ-1: %.1f; ВЗ-2: %.1f",self.Train:GetWagonNumber(),self.GN1Offset or 0,self.GN2Offset or 0)) + elseif name == "KM013offset" then + self.KM013offset = value + elseif name == "KM013Over" then + self.km013_overcharge = value + elseif name == "Autostop" then + local HaveUAVA = not self.Train.SubwayTrain or not self.Train.SubwayTrain.ARS or not self.Train.SubwayTrain.ARS.NoUAVA + if HaveUAVA and self.Train.UAVA.Value == 0 then + self.EmergencyValve = true + if value ~= 2 then + self.Train.UAVAC:TriggerInput("Set",0) + if not self.Train.AutoStopNotify then + self.Train.AutoStopNotify = true + RunConsoleCommand("say","Autostop braking",self.Train:GetDriverName()) + end + end + end + end +end + + +-- TODO: почистить это говно, сделать раздельные звуки пневмы +-- Calculate derivatives +function TRAIN_SYSTEM:equalizeCouplePressure(dT,pressure,train,valve_status,rate,close_rate) + if not valve_status then return 0 end + local other + if IsValid(train) then other = train.Pneumatic end + + -- Get second pressure + local P2 = 0 + if other then P2 = other[pressure] end + if (not other) and (valve_status) then + self.TrainLineOpen = (pressure == "TrainLinePressure") + rate = close_rate or rate + --self.TrainLinePressure_dPdT = 0.0 + end + + -- Calculate rate + local dPdT = rate * (P2 - self[pressure]) + -- Calculate delta + local dP = dPdT*dT + if other and other.ReadOnly then + dP = dP/250 + end + -- Equalized pressure + local P0 = (P2 + self[pressure]) / 2 + -- Update pressures + if dP > 0 then + self[pressure] = math.min(P0,self[pressure] + dP) + if other and not other.ReadOnly then + other[pressure] = math.max(P0,other[pressure] - dP) + end + else + self[pressure] = math.max(P0,self[pressure] + dP) + if other and not other.ReadOnly then + other[pressure] = math.min(P0,other[pressure] - dP) + end + end + -- Update delta if losing air + if self.TrainLineOpen and (pressure == "TrainLinePressure") then + self[pressure.."_dPdT"] = (self[pressure.."_dPdT"] or 0) + dPdT + end + return dP +end +------------------------------------------------------------------------------- +function TRAIN_SYSTEM:UpdatePressures(Train,dT) + local frontBrakeOpen = Train.FrontBrakeLineIsolation.Value == 0 + local rearBrakeOpen = Train.RearBrakeLineIsolation.Value == 0 + local frontTrainOpen = Train.FrontTrainLineIsolation.Value == 0 + local rearTrainOpen = Train.RearTrainLineIsolation.Value == 0 + + local Ft = IsValid(Train.FrontTrain) and Train.FrontTrain + local Rt = IsValid(Train.RearTrain) and Train.RearTrain + local Fc, Rc = Train.FrontCouple or Train.FrontBogey, Train.RearCouple or Train.RearBogey + local Fb,Rb + if IsValid(Fc) and Fc.DepotPneumo then Fb = Fc.DepotPneumo end + if IsValid(Rc) and Rc.DepotPneumo then Rb = Rc.DepotPneumo end + + local frontBrakeLeak = false + local rearBrakeLeak = false + local frontTrainLeak = false + local rearTrainLeak = false + + -- Check if both valve on this train and connected train are open + if Ft and Ft.FrontBrakeLineIsolation then + if Ft.FrontTrain == Train then -- Nose to nose + frontBrakeLeak = frontBrakeOpen and Ft.FrontBrakeLineIsolation.Value==1 and 0.08 + frontTrainLeak = frontTrainOpen and Ft.FrontTrainLineIsolation.Value==1 and 0.08 + else -- Rear to nose + frontBrakeLeak = frontBrakeOpen and Ft.RearBrakeLineIsolation.Value==1 and 0.08 + frontTrainLeak = frontTrainOpen and Ft.RearTrainLineIsolation.Value==1 and 0.08 + end + else + frontBrakeLeak = frontBrakeOpen and 0.7 + frontTrainLeak = frontTrainOpen and not Fb and 0.3 + end + if Rt and Rt.FrontBrakeLineIsolation then + if Rt.FrontTrain == Train then -- Nose to nose + rearBrakeLeak = rearBrakeOpen and Rt.FrontBrakeLineIsolation.Value==1 and 0.08 + rearTrainLeak = rearTrainOpen and Rt.FrontTrainLineIsolation.Value==1 and 0.08 + else -- Rear to nose + rearBrakeLeak = rearBrakeOpen and Rt.RearBrakeLineIsolation.Value==1 and 0.08 + rearTrainLeak = rearTrainOpen and Rt.RearTrainLineIsolation.Value==1 and 0.08 + end + else + rearBrakeLeak = rearBrakeOpen and 0.7 + rearTrainLeak = rearTrainOpen and not Rb and 0.3 + end + + -- Equalize pressure + local Fl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",frontBrakeLeak==false and Ft,frontBrakeOpen,50,frontBrakeLeak or 0.08)*3)*(frontBrakeLeak and 1 or 0) + local Rl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",rearBrakeLeak==false and Rt,rearBrakeOpen,50,rearBrakeLeak or 0.08)*3)*(rearBrakeLeak and 1 or 0) + + Fl=Fl+math.min(0,self:equalizeCouplePressure(dT,"TrainLinePressure",frontTrainLeak==false and Ft or Fb,frontTrainOpen,100,frontTrainLeak or 0.08)*10)*(frontTrainLeak and 1 or 0) + Rl=Rl+math.min(0,self:equalizeCouplePressure(dT,"TrainLinePressure",rearTrainLeak==false and Rt or Rb,rearTrainOpen,100,rearTrainLeak or 0.08)*10)*(rearTrainLeak and 1 or 0) + + self.TrainLineOpen=frontTrainLeak or rearTrainLeak + self.BrakeLineOpen=frontBrakeLeak or rearBrakeLeak + Train:SetPackedRatio("FrontLeak",Fl) + Train:SetPackedRatio("RearLeak",Rl) +end + +function TRAIN_SYSTEM:equalizePressure(dT,pressure,target,rate,fill_rate,no_limit,smooth) + if fill_rate and (target > self[pressure]) then rate = fill_rate end + + -- Calculate derivative + local dPdT = rate + if target < self[pressure] then dPdT = -dPdT end + local dPdTramp = math.min(1.0,math.abs(target - self[pressure])*(smooth or 0.5)) + dPdT = dPdT*dPdTramp + + -- Update pressure + self[pressure] = self[pressure] + dT * dPdT + self[pressure] = math.max(0.0,math.min(16.0,self[pressure])) + self[pressure.."_dPdT"] = (self[pressure.."_dPdT"] or 0) + dPdT + if no_limit ~= true then + if self[pressure] == 0.0 then self[pressure.."_dPdT"] = 0 end + if self[pressure] == 16.0 then self[pressure.."_dPdT"] = 0 end + end + return dPdT +end +------------------------------------------------------------------------------- +function TRAIN_SYSTEM:Think(dT) + local Train = self.Train + local retainer = Train:GetNW2Int("RetainerLoad", 4) + self.WeightLoadRatio = retainer == 4 and math.max(0,math.min(1,(Train:GetNW2Float("PassengerCount")/200))) or (retainer-1)*0.5 + Train.Panel.UAVACOpened = (1-Train.UAVAC.Value)*((CurTime()-CurTime()%0.5)%1) + + --if not Train.DoorSpeedsDone then + -- local start + -- if #Train.WagonList == Train.CarCount and Train.d_speeds then start = math.Rand(unpack(Train.d_speeds[math.random(1,#Train.d_speeds)])) end + -- if start then + -- MsgC(Color(200,200,200),"Setting doors speed for car "..tostring(self.Train).."; start = "..tostring(start).."...") + -- self.DoorSpeedMain = start--math.Rand(start,math.Rand(start+0.1,start+0.2)) + -- for i=1,#self.LeftDoorSpeed do + -- if math.random() > 0.7 then + -- self.LeftDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.2,self.DoorSpeedMain+0.3) + -- self.RightDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.2,self.DoorSpeedMain+0.3) + -- else + -- self.LeftDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.1) + -- self.RightDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.1) + -- end + -- end + -- self.Train.DoorSpeedsDone = true + -- MsgC(Color(200,200,200),"done\n") + -- else + -- MsgC(Color(200,200,200),"failed!\n") + -- end + --end + if not Train.DoorSpeedsDone and Train.CarCount then + local set + if #Train.WagonList == Train.CarCount and Train.d_speeds then + set = math.random(1,#Train.d_speeds) + local a,b = unpack(Train.d_speeds[set]) + --MsgC(Color(200,200,200),"Setting doors speed for car "..tostring(self.Train).."; set = {"..a..", "..b.."} ...") + for i=1,#self.LeftDoorSpeed do + self.LeftDoorSpeed[i] = math.Rand(a,b) + self.RightDoorSpeed[i] = math.Rand(a,b) + end + Train.DoorSpeedsDone = true + --MsgC(Color(200,200,200),"done\n") + else + --MsgC(Color(200,200,200),"failed!\n") + end + end + + ---------------------------------------------------------------------------- + -- Accumulate derivatives + self.TrainLinePressure_dPdT = 0.0 + self.BrakeLinePressure_dPdT = 0.0 + self.EPKPressure_dPdT = 0.0 + self.ReservoirPressure_dPdT = 0.0 + self.BrakeCylinderPressure_dPdT = 0.0 + self.ParkingBrakePressure_dPdT = 0.0 + self.WorkingChamberPressure_dPdT = 0.0 + + -- Doors + self.LeftDoorCloseCylPressure_dPdT = 0.0 + self.RightDoorCloseCylPressure_dPdT = 0.0 + self._1stRightDoorCloseCylPressure_dPdT = 0.0 + self.LeftDoorOpenCylPressure_dPdT = 0.0 + self.RightDoorOpenCylPressure_dPdT = 0.0 + self.DoorLinePressure_dPdT = 0.0 + + -- Reduce pressure for brake line + self.TrainToBrakeReducedPressure = math.min(self.KM013offset,self.TrainLinePressure) -- * 0.725) + -- Feed pressure to door line + self.DoorLinePressure = Train.DVRDisconnect.Value == 0 and math.min(3.6,self.TrainLinePressure) or self.DoorLinePressure + local trainLineConsumption_dPdT = 0.0 + local wagc = Train:GetBLConnectedWagonCount() + local HaveEPK = not Train.SubwayTrain or not Train.SubwayTrain.ARS or not Train.SubwayTrain.ARS.NoEPK + + local pr_speed = 1 + -- работа срывного клапана + if Train.AutostopValve.Value > 0 then + self:TriggerInput("Autostop",self.BrakeLinePressure > 1.86 and 1 or 2) --value == 2 — просто открыть срывной клапан без размыкания контактов УАВА + end + + if self.ValveType == 1 then + self.BLDisconnect = Train.DriverValveBLDisconnect.Value > 0 + self.TLDisconnect = Train.DriverValveTLDisconnect.Value > 0 and self.RealDriverValvePosition ~= 3 + pr_speed = 1*6--wagc--*((self.BrakeLinePressure-self.ReservoirPressure)/0.6) + if self.TLDisconnect then self.TLDisconnectPressure = self.TrainLinePressure end + if self.BLDisconnect then self.BLDisconnectPressure = self.BrakeLinePressure end + if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end + -- 334: 1 Fill reservoir from train line, fill brake line from train line + if (self.RealDriverValvePosition == 1) then + if self.TLDisconnect or self.ReservoirPressure ~= self.TLDisconnectPressure or self.ReservoirPressure ~= self.BLDisconnectPressure then + if self.BLDisconnect then + if self.TLDisconnect then + self:equalizePressure(dT,"ReservoirPressure", self.TLDisconnectPressure, 0, 1.0,nil,2) + self:equalizePressure(dT,"BrakeLinePressure", self.TLDisconnectPressure, 0, 6.0,nil,0.2) + end + if not self.TLDisconnect then + self:equalizePressure(dT,"TLDisconnectPressure", self.BrakeLinePressure, 16, 0,nil,2) + self:equalizePressure(dT,"ReservoirPressure", self.BrakeLinePressure, 0.4, 0.06,nil,2) + self:equalizePressure(dT,"BrakeLinePressure", self.ReservoirPressure, 6.5, 0,nil,0.2) + end + --self:equalizePressure(dT,"BrakeLinePressure", self.TLDisconnectPressure, pr_speed*(pr_speed < wagc and 1 or 1.35),nil,nil,2) + else + self:equalizePressure(dT,"ReservoirPressure", self.TLDisconnectPressure, 0, self.TLDisconnect and 3.55 or 2.0,nil,2) + self:equalizePressure(dT,"TLDisconnectPressure", self.ReservoirPressure, 16, 0,nil,2) + end + end + end + + -- 334: 2 Brake line, reservoir replenished from brake line reductor + if (self.RealDriverValvePosition == 2) then + if self.TLDisconnect then + local a = 1 + if self.EmergencyValve or Train.EmergencyBrakeValve.Value > 0.5 then a = 4 end + if self.BLDisconnect then + --self.ReservoirPressure = self.BrakeLinePressure + self:equalizePressure(dT,"ReservoirPressure", self.BrakeLinePressure,6,0.8,nil,2) + self:equalizePressure(dT,"BrakeLinePressure", self.TrainToBrakeReducedPressure, pr_speed*0, pr_speed*0.3*a, nil, 1.6) + self.ReservoirPressure_dPdT = self.BrakeLinePressure_dPdT*0.8 + else + self:equalizePressure(dT,"ReservoirPressure", self.TrainToBrakeReducedPressure,0,1.55,nil,2) + end + end + end + + -- 334: 3 Close all valves + if (self.RealDriverValvePosition == 3) then + -- Typical leak + self:equalizePressure(dT,"ReservoirPressure", 0.00, 0.001) + end + + local res_dischrg_rate4 = 0.28--self.BLDisconnect and 0.55 or 1 + local res_dischrg_rate5 = self.BLDisconnect and 1.12 or 8 + -- 334: 4 Reservoir open to atmosphere, brake line equalizes with reservoir + if (self.RealDriverValvePosition == 4) then + self:equalizePressure(dT,"ReservoirPressure", 0.0, res_dischrg_rate4, nil,nil,1)--0.35)-0.55 + end + + -- 334: 5 Reservoir and brake line open to atmosphere + if (self.RealDriverValvePosition == 5) then + self:equalizePressure(dT,"ReservoirPressure", 0.0, res_dischrg_rate5)--,nil,nil,2)--1.70 + local pr_speed = 1.25*6--wagc + if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end + if self.BLDisconnect then + if self.Leak then pr_speed = pr_speed*6.2 end + self:equalizePressure(dT,"BrakeLinePressure", 0.0, pr_speed,nil,nil,2) + end + end + -- утечка через неплотность уравнительного поршня + if self.BLDisconnect then self:equalizePressure(dT, "ReservoirPressure", self.BrakeLinePressure, 0.06, 0) end + + if (self.RealDriverValvePosition > 1) and (self.RealDriverValvePosition < 5) then + local pr_speed = 1.25*6--wagc + if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end + local _a = 0 + for k,v in ipairs(Train.WagonList) do + if v.Pneumatic.TLDisconnect and v.Pneumatic.BLDisconnect and (v.Pneumatic.RealDriverValvePosition == 2 or v.Pneumatic.RealDriverValvePosition == 1) then + _a = _a + 1 + end + if _a > 1 then break end + end + if _a > 1 then pr_speed = pr_speed*0.1 end + if self.BLDisconnect and self.BrakeLinePressure - self.ReservoirPressure > (self.RealDriverValvePosition == 3 and 0 or 0.2) then --0.2 bar is a piston sensitivity + self:equalizePressure(dT, "BrakeLinePressure", 0, pr_speed*math.abs(self.BrakeLinePressure - self.ReservoirPressure), nil, nil, 6) + end + end + + --[[if not self.TLDisconnect then + self.TLDisconnectPressure = math.max(0,self.TLDisconnectPressure - math.abs(self.ReservoirPressure_dPdT)*0.8) + end]] + self.ReservoirPressure_dPdT = self.ReservoirPressure_dPdT + self.BrakeLinePressure_dPdT*0.2 + Train:SetPackedRatio("ReservoirPressure_dPdT",self.ReservoirPressure_dPdT/wagc*2) + --[[ + ---------------debug--------------------- + self.dlreadtimer = self.dlreadtimer or CurTime() + if CurTime() - self.dlreadtimer > 1.0 then + self.dlreadtimer = CurTime() + if Train:GetDriver() then + PrintMessage(HUD_PRINTTALK, Format("Вагон %u; P ТМ: %.3f; P УР =%.3f; Утечка ТМ %.3f; TLDis = %.3f; pr_speed = %.3f",Train:GetWagonNumber(),self.BrakeLinePressure,self.ReservoirPressure,self.BrakeLinePressure_dPdT, self.TLDisconnectPressure, pr_speed)) + end + end + ---------------debug---------------------]] + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeLinePressure_dPdT) + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.ReservoirPressure_dPdT)*0.05 + else + pr_speed = 2.8 + local pz_speed + -- wagc | pr_speed + ------------------ + -- 1 | 8.455 + -- 2 | 7.865 + -- 3 | 7.376 + -- 4 | 6.969 + -- 5 | 6.627 + -- 6 | 6.341 + -- 7 | 6.100 + -- 8 | 5.900 + --pr_speed = (0.4*math.exp(0.1*wagc-1)+1)*160/(2*wagc+20) --2 + --[[ + ---------------debug--------------------- + self.brreadtimer = self.brreadtimer or CurTime() + if CurTime() - self.brreadtimer > 1.0 then + self.brreadtimer = CurTime() + if Train:GetDriver() and Train.R_Radio.Value > 0 then + --PrintMessage(HUD_PRINTTALK, Format("br_threshold = %.3f; WcBl = %s",br_threshold, tostring(WcBl))) + --PrintMessage(HUD_PRINTTALK, Format("Это %s", isLVZ and "ЛВЗ" or "не ЛВЗ")) + --PrintMessage(HUD_PRINTTALK, Format("Вагон %u; Авторежим: %.3f",Train:GetWagonNumber(),self.WeightLoadRatio)) + --PrintMessage(HUD_PRINTTALK, Format("wagc = %u",wagc)) + end + end + ---------------debug---------------------]] + --local frc = 0.4--0.35 = 2.1 = 3.64 + if self.Leak or self.BrakeLineOpen then pz_speed = pr_speed*0.75 else pz_speed = pr_speed*1.3 end + self.BLDisconnect = self.DisconnectType and Train.DriverValveBLDisconnect.Value > 0 or Train.DriverValveDisconnect.Value > 0 + self.TLDisconnect = self.DisconnectType and Train.DriverValveTLDisconnect.Value > 0 or Train.DriverValveDisconnect.Value > 0 + if self.km013_overcharge and self.RealDriverValvePosition > 4 and not self.km13_error2 then self.km13_error2 = math.random()*0.3+0.4 end + -- 013: 1 Overcharge + if (self.RealDriverValvePosition == 1) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > self.TrainLinePressure) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(6.4,self.TrainLinePressure), pr_speed, pz_speed, nil, 1.0) + end + + -- 013: 2 Normal pressure + if (self.RealDriverValvePosition == 2) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(self.KM013offset,self.TrainToBrakeReducedPressure)) then--was pr_speed*2 + self:equalizePressure(dT,"BrakeLinePressure", math.min(self.KM013offset+(self.km13_error2 or 0),self.TrainLinePressure), pr_speed, pz_speed, nil, 2.5)-- nil, 1.0) + if self.km13_error2 and self.BrakeLinePressure >= self.KM013offset+self.km13_error2-0.1 then + self:equalizePressure(dT,"BrakeLinePressure", math.min(self.KM013offset,self.TrainToBrakeReducedPressure), 35, pz_speed, nil, 1) + self.km13_error2 = nil + end + end + + -- 013: 3 4.3 Atm + if (self.RealDriverValvePosition == 3) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(4.3,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(4.3,self.TrainToBrakeReducedPressure), pr_speed*1.5,pz_speed, nil, 2.5) + end + + -- 013: 4 4.0 Atm + if (self.RealDriverValvePosition == 4) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(4.0,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(4.0,self.TrainToBrakeReducedPressure), pr_speed*1.5,pz_speed, nil, 2.5) + end + + -- 013: 5 3.7 Atm + if (self.RealDriverValvePosition == 5) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(3.7,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(3.7,self.TrainToBrakeReducedPressure), pr_speed*1.5,pz_speed, nil, 2.5) + end + + -- 013: 6 3.0 Atm + if (self.RealDriverValvePosition == 6) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(3.0,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(3.0,self.TrainToBrakeReducedPressure), pr_speed*1.5,pz_speed, nil, 2.5) + end + + -- 013: 7 0.0 Atm + if (self.RealDriverValvePosition == 7) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 0.0) then + self:equalizePressure(dT,"BrakeLinePressure", 0.0, (0.6 + pr_speed*math.exp(math.min(0,self.BrakeLinePressure - 2.3)*1.0))*(0.15*wagc+1),pz_speed, nil, 2.5) + end + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeLinePressure_dPdT) + end + local leak + self.Leak = false + if wagc ~= Train.OldWagIsoCount or not Train.pr_spd_init then + pr_speed = (0.4*math.exp(0.1*wagc-1)+1)*160/(2*wagc+20) --2 + Train.OldWagIsoCount = wagc + Train.pr_spd_init = true + end + if HaveEPK and Train.EPKC then + local leak = 0 + local epkDiff = math.abs(self.EPKPressure-self.BrakeLinePressure) + if self.BLDisconnect and Train.EPK.Value>0 then + if Train.EPKC.Value>0 then + self:equalizePressure(dT,"EPKPressure", self.BrakeLinePressure,math.min(1,epkDiff)*6, math.min(1,epkDiff)*16,false,4*epkDiff*2) + end + if self.EPKPressure0.3 then + leak = self:equalizePressure(dT,"BrakeLinePressure", self.EPKPressure,pr_speed*epkDiff/1.2,pr_speed*epkDiff/3.28) + end + self.Leak = self.Leak or leak<-0.1 + end + if Train.EPK.Value == 0 or Train.EPKC.Value == 0 then + leak = leak+self:equalizePressure(dT,"EPKPressure", 0,16,false,false,5) + end + if self.ValveType==2 and not self.BLDisconnect then + self:equalizePressure(dT,"EPKPressure", 0,16,false,false,5) + end + Train:SetPackedRatio("EmergencyValveEPK_dPdT", -leak/wagc*8) + end + if self.ValveType == 1 then + Train:SetPackedRatio("Crane_dPdT", self.ReservoirPressure_dPdT ) + else + Train:SetPackedRatio("Crane_dPdT", self.BrakeLinePressure_dPdT/wagc*3 ) + end + if self.EmergencyValveDisable then + self.EmergencyValveDisable=false + self.EmergencyValve=false + Train.AutoStopNotify=false + end + local leak = 0 + if self.EmergencyValve then + local leakst = self.BLDisconnect and math.max(0.3,math.log(self.BrakeLinePressure,1.2) - 2.0) or math.max(1.6,math.log(0.63*self.BrakeLinePressure,1.15)) + leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,leakst*(0.68+0.07*wagc)) + if Train.UAVA.Value > 0 or (self.BrakeLinePressure < 1.8 and Train.AutostopValve.Value == 0) then --пока держим ЛКМ нажатой, срывной клапан открыт + self.EmergencyValveDisable = true + end + self.Leak = true + end + + local UAVABlocked = (self.BrakeLinePressure>1.8 and Train.UAVA.Value==0) + if (Train.UAVA.Blocked>0) ~= UAVABlocked then + Train.UAVA:TriggerInput("Block",UAVABlocked and 1 or 0) + end + + local UAVACBlocked = self.EmergencyValve and not self.EmergencyValveDisable + if (Train.UAVAC.Blocked>0) ~= UAVACBlocked then + Train.UAVAC:TriggerInput("Block",UAVACBlocked and 1 or 0) + end + + Train:SetPackedRatio("EmergencyValve_dPdT", -0.6*leak/wagc) --Регулировка свиста срывного клапана was -1.8 + + local leak = 0 + if Train.EmergencyBrakeValve and Train.EmergencyBrakeValve.Value > 0.5 then + local leakst = math.max(0.5,math.exp(0.5*self.BrakeLinePressure)) + leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,leakst)--,false,false,10) --was leakst*wagc/5 + self.Leak = true + end + Train:SetPackedRatio("EmergencyBrakeValve_dPdT", -leak/wagc) + ---------------------------------------------------------------------------- + -- Fill brake cylinders + if self.WCChargeValve == true then + self:equalizePressure(dT,"WorkingChamberPressure",self.BrakeLinePressure,0.094,nil,nil,1.0) --simulate 0.8mm hole btw BL and working chambers + end + local aird_ready = self.WorkingChamberPressure >= 2.2 + self.WCChargeValve = not ((self.WorkingChamberPressure - self.BrakeLinePressure) > 0.2 and (self.WorkingChamberPressure - self.BrakeLinePressure) < 2.5) + local KLSZ = self.WorkingChamberPressure > 5.2 and not self.WCChargeValve + if KLSZ then + self:equalizePressure(dT,"WorkingChamberPressure",0.0,0.12) -- КЛСЗ + end + + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.WorkingChamberPressure_dPdT*0.2) + self.GN2Offset = self.GN2Offset or math.random(20,100)*0.002 + (self.GN2Start or 2.5) + self.GN1Offset = self.GN1Offset or math.random(20,100)*0.002 + (self.GN1Start or 0.9) + self.BcBl = (self.GN2Offset + self.WeightLoadRatio*(self.GN2Offset - 1.4))/1.82--1.92 + if Train.AirDistributorDisconnect.Value == 0 and aird_ready then + -- Valve #1 + if (Train.PneumaticNo1.Value == 1.0) and (Train.PneumaticNo2.Value == 0.0) then + if self.PN1 < self.GN1Offset then + self.PN1 = math.min(self.TrainLinePressure,self.GN1Offset) + end + elseif Train.PneumaticNo1.Value == 0 and self.PN1 > 0.0 then + self.PN1 = self.BrakeCylinderPressure > 0.2 and 0.05 or self.PN1 - 0.5*dT + end + -- Valve #2 + if Train.PneumaticNo2.Value == 1.0 then + self.PN2 = math.min(self.TrainLinePressure,(self.GN2Offset + self.WeightLoadRatio*1.3)) + if self.BePN2 == false and self.BrakeCylinderPressure > 1.6 then + Train:PlayOnce("PN2end","stop") + end + self.BePN2 = true + elseif self.PN2 > 0.0 then + self.PN2 = self.BrakeCylinderPressure > 0.4 and 0.2 or self.PN2 - 0.5*dT + end + + self.BchExh = self.WorkingChamberPressure < 4.8 and self.BrakeLinePressure < 3.4 and 0 or 1 + self.cranPres = math.max(0,self.BcBl*(self.WorkingChamberPressure - self.BrakeLinePressure*self.BchExh)*(self.BrakeLinePressure > self.KM013offset and (0.6 + self.PN1*0.43) or 1)) + local targetPressure = math.max(0,math.min(self.GN2Offset + self.WeightLoadRatio*1.3, (self.cranPres < (self.PN1 + self.WeightLoadRatio*0.7) and (Train.PneumaticNo1.Value == 1.0) and (self.PN1 + self.WeightLoadRatio*0.7) or self.PN1) + self.PN2 + self.cranPres)) + if math.abs(self.BrakeCylinderPressure - targetPressure) > 0.150 then + self.BrakeCylinderValve = 1 + end + if math.abs(self.BrakeCylinderPressure - targetPressure) < 0.025 then + self.BrakeCylinderValve = 0 + end + if self.BrakeCylinderValve == 1 then + self:equalizePressure(dT,"BrakeCylinderPressure", math.min(self.GN2Offset + self.WeightLoadRatio*(self.GN2Offset - 1.4),targetPressure), 0.8, (Train.PneumaticNo1.Value > 0 or Train.PneumaticNo2.Value > 0) and 2.8 or 1.5, nil, 1.2) + end + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeCylinderPressure_dPdT*0.5) + elseif Train.AirDistributorDisconnect.Value ~= 0 then + self:equalizePressure(dT,"BrakeCylinderPressure", 0.0, 2.00) + end + if (self.BrakeCylinderPressure > 0.2 and self.BrakeCylinderPressure_dPdT > 0.1 or self.BrakeCylinderPressure_dPdT > 1) and not self.BrakeEngaged then + self.BrakeEngaged = true + Train:PlayOnce("brake","bass",1,math.Clamp(self.BrakeCylinderPressure_dPdT,0.7,1.2)) + end + if self.BrakeCylinderPressure < 1 and self.BrakeCylinderPressure_dPdT < -0.1 and self.BrakeEngaged then + self.BrakeEngaged = false + end + Train:SetPackedRatio("BrakeCylinderPressure_dPdT", self.BrakeCylinderPressure_dPdT) + self.TrainLinePressure = self.TrainLinePressure-math.max(0,self.BrakeCylinderPressure_dPdT*0.002) + if Train.PneumaticNo2.Value == 0 then + if self.BePN2 == true then + self.BePN2 = CurTime() + elseif self.BePN2 and self.BrakeCylinderPressure_dPdT > -0.2 then + Train:PlayOnce("PN2end","bass",math.Clamp(math.min(1,(CurTime()-self.BePN2)/1.3)*((3.2-self.BrakeCylinderPressure)/1.2),0,1)) + self.BePN2 = false + end + end + if self.BePN2 == false and (self.BrakeCylinderPressure_dPdT >= 0.2) then + self.BePN2 = nil + Train:PlayOnce("PN2end","stop") + end + + if Train.UAVAContact.Value > 0.5 and Train.UAVAC.Value < 0.5 then + Train.UAVAC:TriggerInput("Set",1) + Train:PlayOnce("uava_reset","bass",1) + end + + --Parking brake simulation + local PBPressure = math.Clamp(self.TrainLinePressure/5,0,1)*2.7 + if Train.ParkingBrake.Value == 0 then + self:equalizePressure(dT,"ParkingBrakePressure", PBPressure, 10,10,nil,0.5) + else + self:equalizePressure(dT,"ParkingBrakePressure", 0, 3,10,nil,0.5) + end + Train:SetPackedRatio("ParkingBrakePressure_dPdT",self.ParkingBrakePressure_dPdT) + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.ParkingBrakePressure_dPdT*0.5) + + -- Simulate cross-feed between different wagons + self:UpdatePressures(Train,dT) + + ---------------------------------------------------------------------------- + -- Simulate doors opening, closing + local LeftRelease = Train.DoorReleaseLeft.Value == 0 + local RightRelease = Train.DoorReleaseRight.Value == 0 + local _1stRightRelease = Train.DoorReleaseExtra.Value == 0 + if self.DoorLinePressure >= 1.4 then --was > 2.6 + -- Simulate DVR engage lag + if Train.VDOL.Value == 1.0 and not Train.VDOLEnergized then + Train.VDOLEnergized = true + Train.VDOLTime = RealTime() + elseif Train.VDOL.Value == 0.0 then + Train.VDOLEnergized = false + end + if Train.VDOP.Value == 1.0 and not Train.VDOPEnergized then + Train.VDOPEnergized = true + Train.VDOPTime = RealTime() + elseif Train.VDOP.Value == 0.0 then + Train.VDOPEnergized = false + end + if (Train.VDOL.Value == 1.0) and (Train.VDOP.Value == 0.0) and not self.DoorLeft then + if Train.VDOLTime and RealTime() - Train.VDOLTime > (Train.DVRLag or 0) then self.DoorLeft = true end + if self.VDOLLoud then Train:PlayOnce("vdol_loud","cabin",0.8+math.random()*0.2,self.VDOLLoud) end + end + if (Train.VDOL.Value == 0.0) and (Train.VDOP.Value == 1.0) and not self.DoorRight then + if Train.VDOPTime and RealTime() - Train.VDOPTime > (Train.DVRLag or 0) then self.DoorRight = true end + if self.VDORLoud then Train:PlayOnce("vdop_loud","cabin",0.8+math.random()*0.2,self.VDORLoud) end + end + if Train.DVRHiss == 2 then + if Train.RD.Value == 1 and Train.VDOL.Value == 1 and not self.LeftExhausted then + Train:PlayOnce("dcyl_op_exh","bass",1,1) + self.LeftExhausted = true + end + if Train.RD.Value == 1 and Train.VDOP.Value == 1 and not self.RightExhausted then + Train:PlayOnce("dcyl_op_exh","bass",1,1) + self.RightExhausted = true + end + end + if (Train.VDZ.Value == 1.0 or Train.VDOL.Value == 1.0 and Train.VDOP.Value == 1.0 or self.RZDTimer) and (self.DoorLeft or self.DoorRight) then + self.DoorRight = false + self.DoorLeft = false + if Train.DVRHiss == 2 then + if Train.RD.Value == 0 and (self.LeftExhausted or self.RightExhausted) then + Train:PlayOnce("dcyl_cl_exh","bass",1,0.6) + self.LeftExhausted = false + self.RightExhausted = false + end + end + else + self.CloseValue = nil + end + if Train.VDOL.Value == 1.0 and Train.VDOP.Value == 1.0 then + self.RZDTimer = CurTime() + elseif self.RZDTimer and CurTime()-self.RZDTimer > 0.1 then + self.RZDTimer = nil + end + end + -- Тут было бы лучше сделать не 2 цилиндра на вагон, а 8, но тогда будет не 5 вызовов функции, а 17... + self:equalizePressure(dT,"RightDoorOpenCylPressure", self.DoorRight and self.DoorLinePressure or 0.0, 2.2, 10) + self:equalizePressure(dT,"RightDoorCloseCylPressure", not self.DoorRight and RightRelease and self.DoorLinePressure or 0.0, 2.2, 10) + self:equalizePressure(dT,"_1stRightDoorCloseCylPressure", not self.DoorRight and _1stRightRelease and RightRelease and self.DoorLinePressure or 0.0, 2.2, 10) + self:equalizePressure(dT,"LeftDoorOpenCylPressure", self.DoorLeft and self.DoorLinePressure or 0.0, 2.2, 10) + self:equalizePressure(dT,"LeftDoorCloseCylPressure", not self.DoorLeft and LeftRelease and self.DoorLinePressure or 0.0, 2.2, 10) + self.DoorLinePressure = self.DoorLinePressure-math.max(0,self.RightDoorOpenCylPressure_dPdT*0.01) + self.DoorLinePressure = self.DoorLinePressure-math.max(0,self.LeftDoorOpenCylPressure_dPdT*0.01) + self.DoorLinePressure = self.DoorLinePressure-math.max(0,self.RightDoorCloseCylPressure_dPdT*0.01) + self.DoorLinePressure = self.DoorLinePressure-math.max(0,self._1stRightDoorCloseCylPressure_dPdT*0.002) + self.DoorLinePressure = self.DoorLinePressure-math.max(0,self.LeftDoorCloseCylPressure_dPdT*0.01) + Train:SetPackedRatio("RightDoorCloseCylPressure_dPdT",not RightRelease and self.RightDoorCloseCylPressure_dPdT or 0) + Train:SetPackedRatio("LeftDoorCloseCylPressure_dPdT",not LeftRelease and self.LeftDoorCloseCylPressure_dPdT or 0) + Train:SetPackedRatio("_1stRightDoorCloseCylPressure_dPdT",not _1stRightRelease and self._1stRightDoorCloseCylPressure_dPdT or 0) + if self.DoorReleaseRightPrevious ~= Train.DoorReleaseRight.Value then + self.DoorReleaseRightPrevious = Train.DoorReleaseRight.Value + if not self.DoorRight and self.DoorReleaseRightPrevious == 1 then + self:equalizePressure(dT,"RightDoorCloseCylPressure", 0, 6) --was DoorLinePressure + end + end + if self.DoorReleaseExtraPrevious ~= Train.DoorReleaseExtra.Value then + self.DoorReleaseExtraPrevious = Train.DoorReleaseExtra.Value + if not self.DoorRight and self.DoorReleaseExtraPrevious == 1 then + self:equalizePressure(dT,"_1stRightDoorCloseCylPressure", 0, 6) + end + end + if self.DoorReleaseLeftPrevious ~= Train.DoorReleaseLeft.Value then + self.DoorReleaseLeftPrevious = Train.DoorReleaseLeft.Value + if not self.DoorLeft and self.DoorReleaseLeftPrevious == 1 then + self:equalizePressure(dT,"LeftDoorCloseCylPressure", 0, 6) --was DoorLinePressure + end + end + --[[ + ---------------debug--------------------- + self.dlreadtimer = self.dlreadtimer or CurTime() + if CurTime() - self.dlreadtimer > 1.0 then + self.dlreadtimer = CurTime() + if Train:GetDriver() then + PrintMessage(HUD_PRINTTALK, Format("Вагон %u; P д.м..: %.3f; КВД правый %u",Train:GetWagonNumber(),self.DoorLinePressure,Train.DoorReleaseRight.Value)) + end + end + ---------------debug---------------------]] + if self.VDOL ~= Train.VDOL.Value then + self.VDOL = Train.VDOL.Value + self:equalizePressure(dT,Train.DVRDisconnect.Value == 0 and "TrainLinePressure" or "DoorLinePressure", 0.0, 0.05) --was 0.3 + end + if self.VDOP ~= Train.VDOP.Value then + self.VDOP = Train.VDOP.Value + self:equalizePressure(dT,Train.DVRDisconnect.Value == 0 and "TrainLinePressure" or "DoorLinePressure", 0.0, 0.05) --was 0.3 + end + if self.VDZ ~= Train.VDZ.Value then + self.VDZ = Train.VDZ.Value + self:equalizePressure(dT,Train.DVRDisconnect.Value == 0 and "TrainLinePressure" or "DoorLinePressure", 0.0, 0.05) --was 0.3 + end + trainLineConsumption_dPdT = trainLineConsumption_dPdT + (Train.DVRDisconnect.Value == 0 and math.max(0,self.DoorLinePressure_dPdT*0.2) or 0) + if Train.CanStuckPassengerLeft then + for i in ipairs(self.LeftDoorStuck) do + self.LeftDoorStuck[i] = math.random() < (0.6+math.min(2,2-self.LeftDoorSpeed[i])*0.2)*Train.CanStuckPassengerLeft*0.6 and (math.random() > 0.7 and CurTime()+math.random()*15) + end + Train.CanStuckPassengerLeft = false + end + if Train.CanStuckPassengerRight then + for i in ipairs(self.RightDoorStuck) do + self.RightDoorStuck[i] = math.random() < (0.6+math.min(2,2-self.RightDoorSpeed[i])*0.2)*Train.CanStuckPassengerRight*0.6 and (math.random() > 0.7 and CurTime()+math.random()*15) + end + Train.CanStuckPassengerRight = false + end + + + Train.LeftDoorsOpen = false + Train.RightDoorsOpen = false + local openL = true + local openR = true + local llocked = false + local rlocked = false + local rmOpen = false --|Right and left doors + local rmClose = false --| + local lmOpen = false --| + local lmClose = false --|manual opening-closing + local v = "HDLK" + local m = "hod" + local n = "hcd" + for i=1,4 do + rlocked = Train[v..i].Value > 0 + llocked = Train[v..tostring(9-i)].Value > 0 + rmOpen = Train[m..i].Value > 0 or Train["outerhod"..i] and Train["outerhod"..i].Value > 0 + lmOpen = Train[m..tostring(9-i)].Value > 0 + rmClose = Train[n..i].Value > 0 + lmClose = Train[n..tostring(9-i)].Value > 0 + --self.LeftDoorState[i] = math.Clamp(self.LeftDoorState[i] + (not llocked and ((lmOpen and 1.5 or lmClose and -1.5 or 0) + + -- (self.DoorLinePressure > 1.0 and (math.Round(self.LeftDoorOpenCylPressure - self.LeftDoorCloseCylPressure,1))*0.36*(not (lmOpen or lmClose) and self.LeftDoorSpeed[i] or 1) or 0))*dT or 0),self.LeftDoorStuck[i] and 0.3 or 0,1) + --self.RightDoorState[i] = math.Clamp(self.RightDoorState[i] + (not rlocked and ((rmOpen and 1.5 or rmClose and -1.5 or 0) + + -- (self.DoorLinePressure > 1.0 and (math.Round(self.RightDoorOpenCylPressure - (i == 1 and self._1stRightDoorCloseCylPressure or self.RightDoorCloseCylPressure),1))*0.36*(not (rmOpen or rmClose) and self.RightDoorSpeed[i] or 1) or 0))*dT or 0),self.RightDoorStuck[i] and 0.3 or 0,1) + + self.LeftDoorState[i] = math.Clamp(self.LeftDoorState[i] + (not llocked and ((lmOpen and 1.5 or lmClose and -1.5 or 0) + + (self.DoorLinePressure > 1.4 and (self.LeftDoorOpenCylPressure - self.LeftDoorCloseCylPressure)*0.36*(not (lmOpen or lmClose) and self.LeftDoorSpeed[i] or 1) or 0))*dT or 0),self.LeftDoorStuck[i] and 0.3 or 0,1) + self.RightDoorState[i] = math.Clamp(self.RightDoorState[i] + (not rlocked and ((rmOpen and 1.5 or rmClose and -1.5 or 0) + + (self.DoorLinePressure > 1.4 and (self.RightDoorOpenCylPressure - (i == 1 and self._1stRightDoorCloseCylPressure or self.RightDoorCloseCylPressure))*0.36*(not (rmOpen or rmClose) and self.RightDoorSpeed[i] or 1) or 0))*dT or 0),self.RightDoorStuck[i] and 0.3 or 0,1) + if not Train.LeftDoorsOpen and self.LeftDoorState[i] > 0.02 then --was 0.06 + Train.LeftDoorsOpen = true + end + if not Train.RightDoorsOpen and self.RightDoorState[i] > 0.02 then --was 0.06 + Train.RightDoorsOpen = true + end + Train:SetPackedRatio("DoorL"..i,self.LeftDoorState[i]) + Train:SetPackedRatio("DoorR"..i,self.RightDoorState[i]) + if self.LeftDoorStuck[i] and (self.DoorLeft or type(self.LeftDoorStuck[i]) == "number" and CurTime()-self.LeftDoorStuck[i] > 0) then + self.LeftDoorStuck[i] = false + end + if self.RightDoorStuck[i] and (self.DoorRight or type(self.RightDoorStuck[i]) == "number" and CurTime()-self.RightDoorStuck[i] > 0) then + self.RightDoorStuck[i] = false + end + Train:SetPackedBool("DoorLS"..i,self.LeftDoorStuck[i]) + Train:SetPackedBool("DoorRS"..i,self.RightDoorStuck[i]) + end + Train:SetPackedBool("DoorL",self.DoorLeft) + Train:SetPackedBool("DoorR",self.DoorRight) + Train.BD:TriggerInput("Set",not Train.RightDoorsOpen and not Train.LeftDoorsOpen) + Train.LeftDoorsOpening = self.DoorLeft + Train.RightDoorsOpening = self.DoorRight + + ---------------------------------------------------------------------------- + -- Simulate compressor operation and train line depletion + self.Compressor = Train.KK.Value * (Train.Electric.Aux750V > 550 and 1 or 0) + self.TrainLinePressure = self.TrainLinePressure - (Train.AirConsumeRatio or 1)*trainLineConsumption_dPdT*dT -- 0.190 --0.170 --0.07 + if self.Compressor == 1 then self:equalizePressure(dT,"TrainLinePressure", 10.0, Train.CompressorEfficiency or 0.04) end -- 0.04 + self:equalizePressure(dT,"TrainLinePressure", 0,Train.AirLeakRatio or 0.003) + -- Overpressure + if self.TrainLinePressure > math.max(7.2, (9.2 - self.TrainLineOverpressureValve*0.2)) and self.TrainLineOverpressureValve%2 == 0 then self.TrainLineOverpressureValve = self.TrainLineOverpressureValve + 1 end + if self.TrainLineOverpressureValve%2 == 1 then + self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.2) + self.TrainLineOpen = true + if self.TrainLinePressure < 5.2 and self.TrainLineOverpressureValve < 20 then self.TrainLineOverpressureValve = self.TrainLineOverpressureValve + 1 end + end + + ---------------------------------------------------------------------------- + -- Pressure triggered relays + Train.AVT:TriggerInput("Open", self.BrakeCylinderPressure > 1.9) -- 1.8 - 2.0 + Train.AVT:TriggerInput("Close",self.BrakeCylinderPressure < 0.9) -- 0.9 - 1.5 + Train.AK:TriggerInput( "Open", self.TrainLinePressure > 8.2) + Train.AK:TriggerInput( "Close",self.TrainLinePressure < 6.3) + Train.AVU:TriggerInput("Open", self.BrakeLinePressure < 2.7) -- 2.7 - 2.9 + Train.AVU:TriggerInput("Close",self.BrakeLinePressure > 3.5) -- 3.5 - 3.7 + Train.SOT:TriggerInput("Open", self.EPKPressure < 1.3) -- 2.7 - 2.9 + Train.SOT:TriggerInput("Close", self.EPKPressure > 1.5) -- 2.7 - 2.9 + Train.BPT:TriggerInput("Set", (IsValid(Train.FrontBogey) and Train.FrontBogey.BrakeCylinderPressure+(not Train.FrontBogey.DisableParking and Train.FrontBogey.ParkingBrakePressure or 0) or self.BrakeCylinderPressure)>0.3) + Train.DKPT:TriggerInput("Set", self.BrakeCylinderPressure > 0.3) -- 1.8 - 2.0 + Train.SQ3:TriggerInput("Set", Train.PassengerDoor and 0 or 1) + + ---------------------------------------------------------------------------- + if self.DriverValveDisconnectPrevious ~= Train.DriverValveDisconnect.Value then + self.DriverValveDisconnectPrevious = Train.DriverValveDisconnect.Value + if self.DriverValveDisconnectPrevious == 0 then + self.DVDOffTimer = CurTime() + Train:PlayOnce("pneumo_disconnect2","cabin",0.9) + else + self.DVDOffTimer = nil + Train:PlayOnce("pneumo_disconnect1","cabin",0.9) + end + end + --Написано в описании КМ013, что при закрытии разобщительного он снижает давление в ТМ на 0.7, значит так и сделаем! + --(и обработку случая, когда в обеих кабинах разобщительный открыт не забудем) + local km013_setpoint = {6.4, self.KM013offset, 4.3, 4.0, 3.7, 3.0, 0} + if self.DVDOffTimer then + if self.BrakeLinePressure - (km013_setpoint[self.RealDriverValvePosition]-0.7) > 0.02 and CurTime()-self.DVDOffTimer < wagc*5/8 then + --print "Снижение давления в ТМ..." + local pr_speed = 22--1.4*wagc --2 + self:equalizePressure(dT,"BrakeLinePressure", math.max(0,km013_setpoint[self.RealDriverValvePosition]-0.7), pr_speed) + else + --print("Снижение давления в ТМ завершено за "..(CurTime()-self.DVDOffTimer).." секунд") + self.DVDOffTimer = nil + end + end + + ---------------------------------------------------------------------------- + -- FIXME + Train:SetNW2Bool("FbI",Train.FrontBrakeLineIsolation.Value ~= 0) + Train:SetNW2Bool("RbI",Train.RearBrakeLineIsolation.Value ~= 0) + Train:SetNW2Bool("FtI",Train.FrontTrainLineIsolation.Value ~= 0) + Train:SetNW2Bool("RtI",Train.RearTrainLineIsolation.Value ~= 0) + Train:SetNW2Bool("AD",Train.AirDistributorDisconnect.Value == 0) + Train:SetNW2Bool("DoorReleaseExtra",Train.DoorReleaseExtra.Value ~= 0) + Train:SetNW2Bool("DoorReleaseRight",Train.DoorReleaseRight.Value ~= 0) + Train:SetNW2Bool("DoorReleaseLeft",Train.DoorReleaseLeft.Value ~= 0) + Train:SetNW2Bool("UAVAContacts",Train.UAVAC.Value ~= 0) + + local ValveType = self.ValveType > 1 + self.Timer = self.Timer or CurTime() + if ((CurTime() - self.Timer > 0.10) and (self.DriverValvePosition > self.RealDriverValvePosition)) then + self.Timer = CurTime() + if not ValveType then + if self.RealDriverValvePosition ~= 3 then + Train:PlayOnce("br_334",self.RealDriverValvePosition.."-"..(self.RealDriverValvePosition+1)) + end + else + Train:PlayOnce("br_013","cabin") + end + self.RealDriverValvePosition = self.RealDriverValvePosition + 1 + end + if ((CurTime() - self.Timer > 0.10) and (self.DriverValvePosition < self.RealDriverValvePosition)) then + self.Timer = CurTime() + if not ValveType then + if self.RealDriverValvePosition ~= 5 then + Train:PlayOnce("br_334",self.RealDriverValvePosition.."-"..(self.RealDriverValvePosition-1)) + end + else + Train:PlayOnce("br_013","cabin") + end + self.RealDriverValvePosition = self.RealDriverValvePosition - 1 + end +end diff --git a/lua/metrostroi/systems/sys_81_717_pneumatic.lua b/lua/metrostroi/systems/sys_81_717_pneumatic.lua index b60877a5..6951c998 100644 --- a/lua/metrostroi/systems/sys_81_717_pneumatic.lua +++ b/lua/metrostroi/systems/sys_81_717_pneumatic.lua @@ -34,23 +34,24 @@ function TRAIN_SYSTEM:Initialize(parameters) -- Pressure in trains feed line self.TrainLinePressure = 8.0 -- atm -- Pressure in trains brake line - self.BrakeLinePressure = 0.0 -- atm + self.BrakeLinePressure = 3.0 -- atm self.EPKPressure = 0.0 -- atm -- Pressure in brake cylinder self.BrakeCylinderPressure = 0.0 -- atm + self.OldBrakeLinePressure = 3.0 -- Pressure in the door line self.DoorLinePressure = 0.0 -- atm - self.OldBrakeLinePressure = 0.0 self.BCPressure = 0 - -- Air distrubutor part - self.WorkingChamberPressure = 0.0 - --self.AirDistributorReady = false --заменено на локальные - --self.OverchargeReleaseValve = false --переменные - self.WCChargeValve = true + self.WorkingChamberPressure = 5.2 + -- Disconnected KM 334 vessels (trainline and brakeline parts between disconnect valve and KM itself) emulation + self.TLDisconnectPressure = 0.0 + self.BLDisconnectPressure = 0.0 + self.WCChargeValve = false self.PN1 = 0 self.PN2 = 0 self.cranPres = 0 + self.KM013offset = 5.2 --DKPT self.Train:LoadSystem("DKPT","Relay","R-52B") -- @@ -82,12 +83,12 @@ function TRAIN_SYSTEM:Initialize(parameters) self.Train:LoadSystem("EmergencyBrakeValve","Relay","Switch") -- Воздухораспределитель self.Train:LoadSystem("AirDistributorDisconnect","Relay","Switch") - --Срывной клапан - self.Train:LoadSystem("AutostopValve","Relay","Switch") --УАВА self.Train:LoadSystem("UAVA","Relay","Switch",{ bass = true}) - --self.Train:LoadSystem("UAVAContact","Relay","Switch") + self.Train:LoadSystem("UAVAContact","Relay","Switch") self.Train:LoadSystem("UAVAC","Relay","",{normally_closed=true,bass=true}) + --Срывной клапан + self.Train:LoadSystem("AutostopValve","Relay","Switch") --Стояночный тормоз self.Train:LoadSystem("ParkingBrake","Relay","Switch",{bass = true}) --ЭПК @@ -114,8 +115,6 @@ function TRAIN_SYSTEM:Initialize(parameters) self.DriverValveDisconnectPrevious = 0 -- Doors state - self.DoorLeft = false - self.DoorRight = false if not TURBOSTROI then self.LeftDoorState = { 0,0,0,0 } self.RightDoorState = { 0,0,0,0 } @@ -123,8 +122,6 @@ function TRAIN_SYSTEM:Initialize(parameters) self.RightDoorDir = { 0,0,0,0 } self.LeftDoorSpeed = {0,0,0,0} self.RightDoorSpeed = {0,0,0,0} - self.LeftDoorStuck = {false, false, false, false} - self.RightDoorStuck = {false, false, false, false} local start = math.Rand(0.6,0.8) -- 0.6-1 self.DoorSpeedMain = -math.Rand(start,math.Rand(start+0.1,start+0.2)) @@ -141,6 +138,9 @@ function TRAIN_SYSTEM:Initialize(parameters) self.TrainLineOpen = false self.BrakeLineOpen = false + self.BLDisconnect = true + self.TLDisconnect = true + self.EmergencyValve = false self.EmergencyValveEPK = false self.OldValuePos = self.DriverValvePosition @@ -150,12 +150,12 @@ function TRAIN_SYSTEM:Initialize(parameters) end function TRAIN_SYSTEM:Inputs() - return { "BrakeUp", "BrakeDown", "BrakeSet", "ValveType", "Autostop" } + return { "BrakeUp", "BrakeDown", "BrakeSet", "ValveType", "Autostop", "KM013offset" } end function TRAIN_SYSTEM:Outputs() - return { "BrakeLinePressure", "BrakeCylinderPressure", "DriverValvePosition", - "ReservoirPressure", "TrainLinePressure", "DoorLinePressure", "WeightLoadRatio", "WorkingChamberPressure" } + return { "BrakeLinePressure", "BrakeCylinderPressure", "DriverValvePosition", "WorkingChamberPressure", + "ReservoirPressure", "TrainLinePressure", "DoorLinePressure", "WeightLoadRatio" } end function TRAIN_SYSTEM:TriggerInput(name,value) @@ -174,17 +174,24 @@ function TRAIN_SYSTEM:TriggerInput(name,value) self:TriggerInput("BrakeSet",self.DriverValvePosition-1) elseif name == "ValveType" then self.ValveType = math.floor(value) + elseif name:match("VZ%dOffset") then + local idx = name:match("VZ(%d)Offset") + self["GN"..idx.."Offset"] = math.random(2,10)*0.02 + value + self["GN"..idx.."Start"] = value + --PrintMessage(HUD_PRINTTALK, Format("Вагон %u; ВЗ-1: %.1f; ВЗ-2: %.1f",self.Train:GetWagonNumber(),self.GN1Offset or 0,self.GN2Offset or 0)) + elseif name == "KM013offset" then + self.KM013offset = value elseif name == "Autostop" then local HaveUAVA = not self.Train.SubwayTrain or not self.Train.SubwayTrain.ARS or not self.Train.SubwayTrain.ARS.NoUAVA if HaveUAVA and self.Train.UAVA.Value == 0 then self.EmergencyValve = true if value ~= 2 then - self.Train.UAVAC:TriggerInput("Set",0) - if not self.Train.AutoStopNotify then - self.Train.AutoStopNotify = true - RunConsoleCommand("say","Autostop braking",self.Train:GetDriverName()) - end - end + self.Train.UAVAC:TriggerInput("Set",0) + if not self.Train.AutoStopNotify then + self.Train.AutoStopNotify = true + RunConsoleCommand("say","Autostop braking",self.Train:GetDriverName()) + end + end end end end @@ -279,14 +286,14 @@ function TRAIN_SYSTEM:UpdatePressures(Train,dT) end -- Equalize pressure - local Fl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",frontBrakeLeak==false and Ft,frontBrakeOpen,100,frontBrakeLeak or 0.08)*3)*(frontBrakeLeak and 1 or 0) - local Rl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",rearBrakeLeak==false and Rt,rearBrakeOpen,100,rearBrakeLeak or 0.08)*3)*(rearBrakeLeak and 1 or 0) + local Fl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",frontBrakeLeak==false and Ft,frontBrakeOpen,50,frontBrakeLeak or 0.08)*3)*(frontBrakeLeak and 1 or 0) + local Rl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",rearBrakeLeak==false and Rt,rearBrakeOpen,50,rearBrakeLeak or 0.08)*3)*(rearBrakeLeak and 1 or 0) Fl=Fl+math.min(0,self:equalizeCouplePressure(dT,"TrainLinePressure",frontTrainLeak==false and Ft or Fb,frontTrainOpen,100,frontTrainLeak or 0.08)*10)*(frontTrainLeak and 1 or 0) Rl=Rl+math.min(0,self:equalizeCouplePressure(dT,"TrainLinePressure",rearTrainLeak==false and Rt or Rb,rearTrainOpen,100,rearTrainLeak or 0.08)*10)*(rearTrainLeak and 1 or 0) self.TrainLineOpen=frontTrainLeak or rearTrainLeak - self.BraieLineOpen=frontBrakeLeak or rearBrakeLeak + self.BrakeLineOpen=frontBrakeLeak or rearBrakeLeak Train:SetPackedRatio("FrontLeak",Fl) Train:SetPackedRatio("RearLeak",Rl) end @@ -313,8 +320,10 @@ end ------------------------------------------------------------------------------- function TRAIN_SYSTEM:Think(dT) local Train = self.Train - self.WeightLoadRatio = math.max(0,math.min(1,(Train:GetNW2Float("PassengerCount")/200))) - --self.WeightLoadRatio = (Train.R_ZS and Train.R_ZS.Value > 0 and 0.5 or 0) + (Train.R_G and Train.R_G.Value > 0 and 0.5 or 0) + local retainer = Train:GetNW2Int("RetainerLoad", 4) + self.WeightLoadRatio = retainer == 4 and math.max(0,math.min(1,(Train:GetNW2Float("PassengerCount")/200))) or (retainer-1)*0.5 + Train.Panel.UAVACOpened = (1-Train.UAVAC.Value)*((CurTime()-CurTime()%0.5)%1) + ---------------------------------------------------------------------------- -- Accumulate derivatives self.TrainLinePressure_dPdT = 0.0 @@ -325,43 +334,50 @@ function TRAIN_SYSTEM:Think(dT) self.ParkingBrakePressure_dPdT = 0.0 self.WorkingChamberPressure_dPdT = 0.0 - local rnd = math.random(1,10) - local offs = 0.1 - self.KM013offset = self.KM013offset or math.Clamp(5.1 + (rnd >= 3 and rnd <= 7 and offs or -offs),5.0,5.2) - -- Reduce pressure for brake line self.TrainToBrakeReducedPressure = math.min(self.KM013offset,self.TrainLinePressure) -- * 0.725) -- Feed pressure to door line self.DoorLinePressure = self.TrainToBrakeReducedPressure * 0.90 local trainLineConsumption_dPdT = 0.0 - local wagc = Train:GetWagonCount() + local wagc = Train.CarCount and Train:GetBLConnectedWagonCount() or #Train.WagonList local HaveEPK = not Train.SubwayTrain or not Train.SubwayTrain.ARS or not Train.SubwayTrain.ARS.NoEPK - local BLDisconnect,pr_speed = true,1 + local pr_speed = 1 -- работа срывного клапана if Train.AutostopValve.Value > 0 then - self:TriggerInput("Autostop",self.BrakeLinePressure > 1.86 and 1 or 2) --value == 2 — просто открыть срывной клапан без размыкания контактов УАВА + self:TriggerInput("Autostop",self.BrakeLinePressure > 1.86 and 1 or 2) --value == 2 — просто открыть срывной клапан без размыкания контактов УАВА end if self.ValveType == 1 then - BLDisconnect = Train.DriverValveBLDisconnect.Value > 0 - local TLDisconnect = Train.DriverValveTLDisconnect.Value > 0 - pr_speed = 1*wagc--*((self.BrakeLinePressure-self.ReservoirPressure)/0.6) --2 - if self.Leak or self.BraieLineOpen then pr_speed = pr_speed*0.3 end + self.BLDisconnect = Train.DriverValveBLDisconnect.Value > 0 + self.TLDisconnect = Train.DriverValveTLDisconnect.Value > 0 and self.RealDriverValvePosition ~= 3 + pr_speed = 1*wagc--*((self.BrakeLinePressure-self.ReservoirPressure)/0.6) + if self.TLDisconnect then self.TLDisconnectPressure = self.TrainLinePressure end + if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end -- 334: 1 Fill reservoir from train line, fill brake line from train line if (self.RealDriverValvePosition == 1) then - if TLDisconnect or self.ReservoirPressure > self.TrainLinePressure then - self:equalizePressure(dT,"ReservoirPressure", self.TrainLinePressure, 1,nil,nil,2) - if BLDisconnect then - self:equalizePressure(dT,"BrakeLinePressure", self.TrainLinePressure, pr_speed,nil,nil,2) + if self.TLDisconnect or self.ReservoirPressure ~= self.TLDisconnectPressure then + if self.BLDisconnect then + self.ReservoirPressure = self.BrakeLinePressure + self:equalizePressure(dT,"BrakeLinePressure", self.TLDisconnectPressure, pr_speed*(pr_speed < wagc and 1 or 1.35),nil,nil,2)--0.7 + else + self:equalizePressure(dT,"ReservoirPressure", self.TLDisconnectPressure, 3.55,nil,nil,2) end end end -- 334: 2 Brake line, reservoir replenished from brake line reductor if (self.RealDriverValvePosition == 2) then - if TLDisconnect or self.ReservoirPressure > self.TrainToBrakeReducedPressure*1.05 then - self:equalizePressure(dT,"ReservoirPressure", self.TrainToBrakeReducedPressure*1.05, 0.55,nil,nil,2) + if self.TLDisconnect then + local a = 1 + if self.EmergencyValve or Train.EmergencyBrakeValve.Value > 0.5 then a = 1.85 end + if self.BLDisconnect then + self.ReservoirPressure = self.BrakeLinePressure + self:equalizePressure(dT,"BrakeLinePressure", self.TrainToBrakeReducedPressure, pr_speed*0, pr_speed*0.6*a, nil, 1.6) + self.ReservoirPressure_dPdT = self.BrakeLinePressure_dPdT*0.8 + else + self:equalizePressure(dT,"ReservoirPressure", self.TrainToBrakeReducedPressure,0,1.55,nil,2) + end end end @@ -371,155 +387,213 @@ function TRAIN_SYSTEM:Think(dT) self:equalizePressure(dT,"ReservoirPressure", 0.00, 0.001) end + local res_dischrg_rate4 = self.BLDisconnect and 0.55 or 8 + local res_dischrg_rate5 = self.BLDisconnect and 1.12 or 8 -- 334: 4 Reservoir open to atmosphere, brake line equalizes with reservoir if (self.RealDriverValvePosition == 4) then - self:equalizePressure(dT,"ReservoirPressure", 0.0,0.55,nil,nil,2)--0.35)-0.55 + self:equalizePressure(dT,"ReservoirPressure", 0.0, res_dischrg_rate4, nil,nil,6)--0.35)-0.55 end -- 334: 5 Reservoir and brake line open to atmosphere if (self.RealDriverValvePosition == 5) then - self:equalizePressure(dT,"ReservoirPressure", 0.0, 1.00)--,nil,nil,2)--1.70 - if BLDisconnect then + self:equalizePressure(dT,"ReservoirPressure", 0.0, res_dischrg_rate5)--,nil,nil,2)--1.70 + local pr_speed = 1.25*wagc + if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end + if self.BLDisconnect then + if self.Leak then pr_speed = pr_speed*6.2 end self:equalizePressure(dT,"BrakeLinePressure", 0.0, pr_speed,nil,nil,2) end end - if BLDisconnect and (TLDisconnect or self.ReservoirPressure < self.BrakeLinePressure) then - --local pr_speed = wagc*(1.375) --2 + -- утечка через неплотность уравнительного поршня + if self.BLDisconnect then self:equalizePressure(dT, "ReservoirPressure", self.BrakeLinePressure, 0.06, 0) end + if (self.RealDriverValvePosition > 2) and (self.RealDriverValvePosition < 5) then local pr_speed = 1.25*wagc - if self.Leak or self.BraieLineOpen then pr_speed = pr_speed*0.3 end - Train:SetPackedRatio("ReservoirPressure_dPdT",self:equalizePressure(dT,"BrakeLinePressure", self.ReservoirPressure,pr_speed,pr_speed*3,nil)/wagc*2) - else - Train:SetPackedRatio("ReservoirPressure_dPdT",0) + if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end + local _a = 0 + for _i = 1, #Train.WagonList do + if Train.WagonList[_i].Pneumatic.TLDisconnect and Train.WagonList[_i].Pneumatic.BLDisconnect and (Train.WagonList[_i].Pneumatic.RealDriverValvePosition == 2 or Train.WagonList[_i].Pneumatic.RealDriverValvePosition == 1) then + _a = _a + 1 + end + if _a > 0 then break end + end + if _a > 0 then pr_speed = pr_speed*0.1 end + if self.BLDisconnect and self.BrakeLinePressure - self.ReservoirPressure > (self.RealDriverValvePosition == 3 and 0 or self.RealDriverValvePosition == 4 and 0.2 or 100) then --0.2 bar is a piston sensitivity + self:equalizePressure(dT, "BrakeLinePressure", 0, pr_speed*math.abs(self.BrakeLinePressure - self.ReservoirPressure), nil, nil, 6) + end + end + + if not self.TLDisconnect then + self.TLDisconnectPressure = math.max(0,self.TLDisconnectPressure - math.abs(self.ReservoirPressure_dPdT)*dT) end + self.ReservoirPressure_dPdT = self.ReservoirPressure_dPdT + self.BrakeLinePressure_dPdT*0.2 + Train:SetPackedRatio("ReservoirPressure_dPdT",self.ReservoirPressure_dPdT/wagc*2) + --[[ + ---------------debug--------------------- + self.dlreadtimer = self.dlreadtimer or CurTime() + if CurTime() - self.dlreadtimer > 1.0 then + self.dlreadtimer = CurTime() + if Train:GetDriver() then + PrintMessage(HUD_PRINTTALK, Format("Вагон %u; P ТМ: %.3f; P УР =%.3f; Утечка ТМ %.3f; TLDis = %.3f; pr_speed = %.3f",Train:GetWagonNumber(),self.BrakeLinePressure,self.ReservoirPressure,self.BrakeLinePressure_dPdT, self.TLDisconnectPressure, pr_speed)) + end + end + ---------------debug---------------------]] trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeLinePressure_dPdT) trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.ReservoirPressure_dPdT)*0.05 else - pr_speed = 1.25*wagc --2 - if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.7 end - BLDisconnect = self.DisconnectType and Train.DriverValveBLDisconnect.Value > 0 or Train.DriverValveDisconnect.Value > 0 - local TLDisconnect = self.DisconnectType and Train.DriverValveTLDisconnect.Value > 0 or Train.DriverValveDisconnect.Value > 0 + pr_speed = 2.8--1.25*wagc --2 + local pz_speed + -- wagc | pr_speed + ------------------ + -- 1 | 8.455 + -- 2 | 7.865 + -- 3 | 7.376 + -- 4 | 6.969 + -- 5 | 6.627 + -- 6 | 6.341 + -- 7 | 6.100 + -- 8 | 5.900 + --pr_speed = (0.4*math.exp(0.1*wagc-1)+1)*160/(2*wagc+20) --2 + --[[ + ---------------debug--------------------- + self.brreadtimer = self.brreadtimer or CurTime() + if CurTime() - self.brreadtimer > 1.0 then + self.brreadtimer = CurTime() + if Train:GetDriver() and Train.R_Radio.Value > 0 then + --PrintMessage(HUD_PRINTTALK, Format("br_threshold = %.3f; WcBl = %s",br_threshold, tostring(WcBl))) + --PrintMessage(HUD_PRINTTALK, Format("Это %s", isLVZ and "ЛВЗ" or "не ЛВЗ")) + --PrintMessage(HUD_PRINTTALK, Format("Вагон %u; Авторежим: %.3f",Train:GetWagonNumber(),self.WeightLoadRatio)) + --PrintMessage(HUD_PRINTTALK, Format("wagc = %u",wagc)) + end + end + ---------------debug---------------------]] + --local frc = 0.4--0.35 + --if Train.EPK.Value > 0 or self.EmergencyValve or self.BrakeLineOpen then pz_speed = pr_speed*0.75 else pz_speed = pr_speed*1.3 end + if self.Leak or self.BrakeLineOpen then pz_speed = pr_speed*0.75 else pz_speed = pr_speed*1.3 end + self.BLDisconnect = self.DisconnectType and Train.DriverValveBLDisconnect.Value > 0 or Train.DriverValveDisconnect.Value > 0 + self.TLDisconnect = self.DisconnectType and Train.DriverValveTLDisconnect.Value > 0 or Train.DriverValveDisconnect.Value > 0 + if self.RealDriverValvePosition > 4 and not self.km13_error2 then self.km13_error2 = 0.7 end -- 013: 1 Overcharge - if (self.RealDriverValvePosition == 1) and BLDisconnect and (TLDisconnect or self.BrakeLinePressure > self.TrainLinePressure) then - self:equalizePressure(dT,"BrakeLinePressure", math.min(6.4,self.TrainLinePressure), pr_speed,Train.EPKC and Train.EPKC.Value==0 and Train.EPK.Value > 0 and pr_speed*2.2 or pr_speed*0.35, nil, 1.0) + if (self.RealDriverValvePosition == 1) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > self.TrainLinePressure) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(6.4,self.TrainLinePressure), pr_speed, pz_speed, nil, 1.0) end -- 013: 2 Normal pressure - if (self.RealDriverValvePosition == 2) and BLDisconnect and (TLDisconnect or self.BrakeLinePressure > 1.01*math.min(self.KM013offset,self.TrainToBrakeReducedPressure)) then - self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(self.KM013offset,self.TrainToBrakeReducedPressure), pr_speed,Train.EPKC and Train.EPKC.Value==0 and Train.EPK.Value > 0 and pr_speed*2 or pr_speed*0.35, nil, 1.0)-- nil, 1.0) + if (self.RealDriverValvePosition == 2) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(self.KM013offset,self.TrainToBrakeReducedPressure)) then--was pr_speed*2 + self:equalizePressure(dT,"BrakeLinePressure", math.min(self.KM013offset+(self.km13_error2 or 0),self.TrainLinePressure), pr_speed, pz_speed, nil, 2.5)-- nil, 1.0) + if self.km13_error2 and self.BrakeLinePressure >= self.KM013offset+self.km13_error2-0.1 then + self:equalizePressure(dT,"BrakeLinePressure", math.min(self.KM013offset,self.TrainToBrakeReducedPressure), 35, pz_speed, nil, 1) + self.km13_error2 = nil + end end -- 013: 3 4.3 Atm - if (self.RealDriverValvePosition == 3) and BLDisconnect and (TLDisconnect or self.BrakeLinePressure > 1.01*math.min(4.3,self.TrainToBrakeReducedPressure)) then - self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(4.3,self.TrainToBrakeReducedPressure), pr_speed,pr_speed*0.35, nil, 1.0) + if (self.RealDriverValvePosition == 3) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(4.3,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(4.3,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5) end -- 013: 4 4.0 Atm - if (self.RealDriverValvePosition == 4) and BLDisconnect and (TLDisconnect or self.BrakeLinePressure > 1.01*math.min(4.0,self.TrainToBrakeReducedPressure)) then - self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(4.0,self.TrainToBrakeReducedPressure), pr_speed,pr_speed*0.35, nil, 1.0) + if (self.RealDriverValvePosition == 4) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(4.0,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(4.0,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5) end -- 013: 5 3.7 Atm - if (self.RealDriverValvePosition == 5) and BLDisconnect and (TLDisconnect or self.BrakeLinePressure > 1.01*math.min(3.7,self.TrainToBrakeReducedPressure)) then - self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(3.7,self.TrainToBrakeReducedPressure), pr_speed,pr_speed*0.35, nil, 1.0) + if (self.RealDriverValvePosition == 5) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(3.7,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(3.7,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5) end -- 013: 6 3.0 Atm - if (self.RealDriverValvePosition == 6) and BLDisconnect and (TLDisconnect or self.BrakeLinePressure > 1.01*math.min(3.0,self.TrainToBrakeReducedPressure)) then - self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(3.0,self.TrainToBrakeReducedPressure), pr_speed,pr_speed*0.35, nil, 1.0) + if (self.RealDriverValvePosition == 6) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > math.min(3.0,self.TrainToBrakeReducedPressure)) then + self:equalizePressure(dT,"BrakeLinePressure", math.min(3.0,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5) end -- 013: 7 0.0 Atm - if (self.RealDriverValvePosition == 7) and BLDisconnect and (TLDisconnect or self.BrakeLinePressure > 0.0) then - self:equalizePressure(dT,"BrakeLinePressure", 0.0, 0.6 + pr_speed*math.exp(math.min(0,self.BrakeLinePressure - 2.8)*1.0),pr_speed*0.35, nil, 1.0) + if (self.RealDriverValvePosition == 7) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 0.0) then + self:equalizePressure(dT,"BrakeLinePressure", 0.0, (0.6 + pr_speed*math.exp(math.min(0,self.BrakeLinePressure - 2.3)*1.0))*(0.15*wagc+1),pz_speed, nil, 2.5) end trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeLinePressure_dPdT) end local leak self.Leak = false - local pr_speed = 1.25*wagc + if wagc ~= Train.OldWagIsoCount or not Train.pr_spd_init then + pr_speed = (0.4*math.exp(0.1*wagc-1)+1)*160/(2*wagc+20) --2 + Train.OldWagIsoCount = wagc + Train.pr_spd_init = true + end if HaveEPK and Train.EPKC then local leak = 0 local epkDiff = math.abs(self.EPKPressure-self.BrakeLinePressure) - if BLDisconnect and Train.EPK.Value>0 then + if self.BLDisconnect and Train.EPK.Value>0 then if Train.EPKC.Value>0 then - self:equalizePressure(dT,"EPKPressure", self.BrakeLinePressure,math.min(1,epkDiff)*6--[[ pr_speed*math.min(1,epkDiff)*2--]] ,math.min(1,epkDiff)*26,false,4*epkDiff*2) + self:equalizePressure(dT,"EPKPressure", self.BrakeLinePressure,math.min(1,epkDiff)*6, math.min(1,epkDiff)*16,false,4*epkDiff*2) end if self.EPKPressure0.3 then - leak = self:equalizePressure(dT,"BrakeLinePressure", self.EPKPressure,pr_speed*epkDiff/1.28,pr_speed*epkDiff/1.28) - --[[ if self.ValveType==1 then - leak = self:equalizePressure(dT,"ReservoirPressure", self.EPKPressure,epkDiff/2,epkDiff/2) - end--]] + leak = self:equalizePressure(dT,"BrakeLinePressure", self.EPKPressure,pr_speed*epkDiff/3.8,pr_speed*epkDiff/3.28) end self.Leak = self.Leak or leak<-0.1 end if Train.EPK.Value == 0 or Train.EPKC.Value == 0 then leak = leak+self:equalizePressure(dT,"EPKPressure", 0,16,false,false,5) end - if self.ValveType==2 and not BLDisconnect then + if self.ValveType==2 and not self.BLDisconnect then self:equalizePressure(dT,"EPKPressure", 0,16,false,false,5) end - Train:SetPackedRatio("EmergencyValveEPK_dPdT", -leak/wagc) + Train:SetPackedRatio("EmergencyValveEPK_dPdT", -leak/wagc*8) end if self.ValveType == 1 then Train:SetPackedRatio("Crane_dPdT", self.ReservoirPressure_dPdT ) else Train:SetPackedRatio("Crane_dPdT", self.BrakeLinePressure_dPdT/wagc*3 ) end - if self.EmergencyValveDisable then--and (self.BrakeLinePressure-self.OldBrakeLinePressure)>0.01 then + if self.EmergencyValveDisable then self.EmergencyValveDisable=false self.EmergencyValve=false - Train.AutoStopNotify=false + Train.AutoStopNotify=false end - self.OldBrakeLinePressure = self.BrakeLinePressure local leak = 0 if self.EmergencyValve then - local leakst = BLDisconnect and math.max(0.3,math.log(self.BrakeLinePressure,1.2) - 2.5) or math.max(1.6,math.log(0.63*self.BrakeLinePressure,1.15)) + local leakst = self.BLDisconnect and math.max(0.3,math.log(self.BrakeLinePressure,1.2) - 2.0) or math.max(1.6,math.log(0.63*self.BrakeLinePressure,1.15)) leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,leakst*wagc/6)--,false,false,10) if Train.UAVA.Value > 0 or (self.BrakeLinePressure < 1.8 and Train.AutostopValve.Value == 0) then --пока держим ЛКМ нажатой, срывной клапан открыт self.EmergencyValveDisable = true end self.Leak = true end - + local UAVABlocked = (self.BrakeLinePressure>1.8 and Train.UAVA.Value==0) if (Train.UAVA.Blocked>0) ~= UAVABlocked then Train.UAVA:TriggerInput("Block",UAVABlocked and 1 or 0) end - + local UAVACBlocked = self.EmergencyValve and not self.EmergencyValveDisable if (Train.UAVAC.Blocked>0) ~= UAVACBlocked then Train.UAVAC:TriggerInput("Block",UAVACBlocked and 1 or 0) end - Train:SetPackedRatio("EmergencyValve_dPdT", -1.8*leak/wagc) --Регулировка свиста срывного клапана + Train:SetPackedRatio("EmergencyValve_dPdT", -0.6*leak/wagc) --Регулировка свиста срывного клапана was -1.8 local leak = 0 if Train.EmergencyBrakeValve and Train.EmergencyBrakeValve.Value > 0.5 then - --local leakst = (1.6*(Train:GetWagonCount())*(self.BrakeLinePressure-math.min(2.5,self.TrainToBrakeReducedPressure))*0.9) - leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,(1.1*wagc)*2,false,false,1) + local leakst = math.max(0.5,math.exp(0.5*self.BrakeLinePressure)) + leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,leakst)--,false,false,10) --was leakst*wagc/5 self.Leak = true end Train:SetPackedRatio("EmergencyBrakeValve_dPdT", -leak/wagc) ---------------------------------------------------------------------------- -- Fill brake cylinders if self.WCChargeValve == true then - self:equalizePressure(dT,"WorkingChamberPressure",self.BrakeLinePressure,0.107,nil,nil,1.0) --simulate 0.8mm hole btw BL and working chambers + self:equalizePressure(dT,"WorkingChamberPressure",self.BrakeLinePressure,0.094,nil,nil,1.0) --simulate 0.8mm hole btw BL and working chambers end - --self.AirDistributorReady = self.WorkingChamberPressure >= 2.2 local aird_ready = self.WorkingChamberPressure >= 2.2 self.WCChargeValve = not ((self.WorkingChamberPressure - self.BrakeLinePressure) > 0.2 and (self.WorkingChamberPressure - self.BrakeLinePressure) < 2.5) - --self.OverchargeReleaseValve = self.WorkingChamberPressure > 5.2 and not self.WCChargeValve local KLSZ = self.WorkingChamberPressure > 5.2 and not self.WCChargeValve - if KLSZ then - self:equalizePressure(dT,"WorkingChamberPressure",0.0,0.22) -- КЛСЗ + if KLSZ then + self:equalizePressure(dT,"WorkingChamberPressure",0.0,0.12) -- КЛСЗ end - --trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.WorkingChamberPressure_dPdT*0.2) - local _offset2 = self.Train.AR63 and 2.5 or 2.4 - self.GN2Offset = self.GN2Offset or math.random(20,100)*0.002 + _offset2 - local _offset1 = self.Train.AR63 and 0.9 or 0.8 - self.GN1Offset = self.GN1Offset or math.random(20,100)*0.002 + _offset1 - self.BcBl = (self.GN2Offset + self.WeightLoadRatio*1.3)/1.93 + trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.WorkingChamberPressure_dPdT*0.2) + self.GN2Offset = self.GN2Offset or math.random(20,100)*0.002 + (self.GN2Start or 2.5) + self.GN1Offset = self.GN1Offset or math.random(20,100)*0.002 + (self.GN1Start or 0.9) + self.BcBl = (self.GN2Offset + self.WeightLoadRatio*(self.GN2Offset - 1.4))/1.82--1.92 if Train.AirDistributorDisconnect.Value == 0 and aird_ready then -- Valve #1 if (Train.PneumaticNo1.Value == 1.0) and (Train.PneumaticNo2.Value == 0.0) then @@ -527,22 +601,22 @@ function TRAIN_SYSTEM:Think(dT) self.PN1 = math.min(self.TrainLinePressure,self.GN1Offset) end elseif Train.PneumaticNo1.Value == 0 and self.PN1 > 0.0 then - self.PN1 = math.max(0,self.PN1-math.exp(3.6*(self.BrakeCylinderPressure - self.GN1Offset))*1.7*dT) + self.PN1 = self.BrakeCylinderPressure > 0.2 and 0.05 or self.PN1 - 0.5*dT end -- Valve #2 if Train.PneumaticNo2.Value == 1.0 then - self.PN2 = math.min(self.TrainLinePressure,(self.GN2Offset + self.WeightLoadRatio*1.3)) - if self.BePN2 == false and self.BrakeCylinderPressure > 1.6 then - Train:PlayOnce("PN2end","stop") - end - self.BePN2 = true - elseif self.PN2 > 0.0 then + self.PN2 = math.min(self.TrainLinePressure,(self.GN2Offset + self.WeightLoadRatio*1.3)) + if self.BePN2 == false and self.BrakeCylinderPressure > 1.6 then + Train:PlayOnce("PN2end","stop") + end + self.BePN2 = true + elseif self.PN2 > 0.0 then self.PN2 = self.BrakeCylinderPressure > 0.4 and 0.2 or self.PN2 - 0.5*dT end - local WcBl = (self.BrakeLinePressure < 3.55 and 0.45*(self.WorkingChamberPressure - 2.2) or self.BrakeLinePressure > 3.65 and self.BrakeLinePressure*(self.BrakeLinePressure > 4.5 and self.BrakeLinePressure_dPdT > 0.02 and 1.06 or 1)) - --self.cranPres = WcBl and math.max(0,math.min(self.GN2Offset + self.WeightLoadRatio*1.3,self.BcBl*(self.WorkingChamberPressure - WcBl)*(self.BrakeLinePressure > self.KM013offset and 0.6 or 1))) or self.cranPres - self.cranPres = WcBl and math.max(0,self.BcBl*(self.WorkingChamberPressure - WcBl)*(self.BrakeLinePressure > self.KM013offset and (0.56 + self.PN1*0.43) or 1)) or self.cranPres - local targetPressure = math.max(0,math.min(self.GN2Offset + self.WeightLoadRatio*1.3, (self.cranPres < (self.PN1 + self.WeightLoadRatio*0.7) and (Train.PneumaticNo1.Value == 1.0) and (self.PN1 + self.WeightLoadRatio*0.7) or self.PN1) + self.PN2 + self.cranPres)) + + self.BchExh = self.WorkingChamberPressure < 4.8 and self.BrakeLinePressure < 3.4 and 0 or 1 + self.cranPres = math.max(0,self.BcBl*(self.WorkingChamberPressure - self.BrakeLinePressure*self.BchExh)*(self.BrakeLinePressure > self.KM013offset and (0.6 + self.PN1*0.43) or 1)) + local targetPressure = math.max(0,math.min(self.GN2Offset + self.WeightLoadRatio*1.3, (self.cranPres < (self.PN1 + self.WeightLoadRatio*0.7) and (Train.PneumaticNo1.Value == 1.0) and (self.PN1 + self.WeightLoadRatio*0.7) or self.PN1) + self.PN2 + self.cranPres)) if math.abs(self.BrakeCylinderPressure - targetPressure) > 0.150 then self.BrakeCylinderValve = 1 end @@ -550,13 +624,11 @@ function TRAIN_SYSTEM:Think(dT) self.BrakeCylinderValve = 0 end if self.BrakeCylinderValve == 1 then - --self:equalizePressure(dT,"BrakeCylinderPressure", math.min(self.GN2Offset + self.WeightLoadRatio*1.3,targetPressure), 1, 3.5, nil, (self.BrakeLinePressure_dPdT > 0.02) and (0.9+math.Clamp((1 - self.BrakeCylinderPressure)*0.9,0,1.8)) or 1) - self:equalizePressure(dT,"BrakeCylinderPressure", math.min(self.GN2Offset + self.WeightLoadRatio*1.3,targetPressure), 1, 3.5, nil, 1) + self:equalizePressure(dT,"BrakeCylinderPressure", math.min(self.GN2Offset + self.WeightLoadRatio*(self.GN2Offset - 1.4),targetPressure), 0.8, (Train.PneumaticNo1.Value > 0 or Train.PneumaticNo2.Value > 0) and 2.8 or 1.5, nil, 1.2) end trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeCylinderPressure_dPdT*0.5) elseif Train.AirDistributorDisconnect.Value ~= 0 then self:equalizePressure(dT,"BrakeCylinderPressure", 0.0, 2.00) - self:equalizePressure(dT,"WorkingChamberPressure", 0.0, 2.00) --имитируем потягивание за тросик отпускного клапана end if (self.BrakeCylinderPressure > 0.2 and self.BrakeCylinderPressure_dPdT > 0.1 or self.BrakeCylinderPressure_dPdT > 1) and not self.BrakeEngaged then self.BrakeEngaged = true @@ -580,6 +652,11 @@ function TRAIN_SYSTEM:Think(dT) Train:PlayOnce("PN2end","stop") end + if Train.UAVAContact.Value > 0.5 and Train.UAVAC.Value < 0.5 then + Train.UAVAC:TriggerInput("Set",1) + Train:PlayOnce("uava_reset","bass",1) + end + --Parking brake simulation local PBPressure = math.Clamp(self.TrainLinePressure/5,0,1)*2.7 if Train.ParkingBrake.Value == 0 then @@ -596,15 +673,15 @@ function TRAIN_SYSTEM:Think(dT) ---------------------------------------------------------------------------- -- Simulate compressor operation and train line depletion self.Compressor = Train.KK.Value * (Train.Electric.Aux750V > 550 and 1 or 0) - self.TrainLinePressure = self.TrainLinePressure - 0.07*trainLineConsumption_dPdT*dT -- 0.190 --0.170 - if self.Compressor == 1 then self:equalizePressure(dT,"TrainLinePressure", 10.0, 0.04) end - self:equalizePressure(dT,"TrainLinePressure", 0,0.001) + self.TrainLinePressure = self.TrainLinePressure - (Train.AirConsumeRatio or 0.06)*trainLineConsumption_dPdT*dT -- 0.190 --0.170 --0.07 + if self.Compressor == 1 then self:equalizePressure(dT,"TrainLinePressure", 10.0, Train.CompressorEfficiency or 0.07) end -- 0.04 + self:equalizePressure(dT,"TrainLinePressure", 0,Train.AirLeakRatio or 0.003) -- Overpressure - if self.TrainLinePressure > 9.2 then self.TrainLineOverpressureValve = 1 end - if self.TrainLineOverpressureValve == 1 then - self:equalizePressure(dT,"TrainLinePressure", 0.0, (self.TrainLinePressure-(self.Compressor == 1 and 6.5 or 4))*0.6) --was 0.2 + if self.TrainLinePressure > math.max(7.2, (9.2 - self.TrainLineOverpressureValve*0.2)) and self.TrainLineOverpressureValve%2 == 0 then self.TrainLineOverpressureValve = self.TrainLineOverpressureValve + 1 end + if self.TrainLineOverpressureValve%2 == 1 then + self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.2) self.TrainLineOpen = true - if self.TrainLinePressure < 5.2 then self.TrainLineOverpressureValve = 0 end + if self.TrainLinePressure < 5.2 and self.TrainLineOverpressureValve < 20 then self.TrainLineOverpressureValve = self.TrainLineOverpressureValve + 1 end end ---------------------------------------------------------------------------- @@ -626,9 +703,11 @@ function TRAIN_SYSTEM:Think(dT) if self.DoorLinePressure > 3.5 then if (Train.VDOL.Value == 1.0) and (Train.VDOP.Value == 0.0) and not self.DoorLeft then self.DoorLeft = true + if self.VDOLLoud then Train:PlayOnce("vdol_loud","cabin",0.8+math.random()*0.2,self.VDOLLoud) end end if (Train.VDOL.Value == 0.0) and (Train.VDOP.Value == 1.0) and not self.DoorRight then self.DoorRight = true + if self.VDORLoud then Train:PlayOnce("vdop_loud","cabin",0.8+math.random()*0.2,self.VDORLoud) end end if (Train.VDZ.Value == 1.0 or Train.VDOL.Value == 1.0 and Train.VDOP.Value == 1.0 or self.RZDTimer) and (self.DoorLeft or self.DoorRight) then if not self.OpenWaitL or CurTime()-self.OpenWaitL < 0.2 then @@ -648,32 +727,18 @@ function TRAIN_SYSTEM:Think(dT) end if self.VDOL ~= Train.VDOL.Value then self.VDOL = Train.VDOL.Value - self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.3) - if self.VDLoud and self.VDOL > 0 and not Train.LeftDoorsOpen then Train:PlayOnce("vdol_loud"..self.VDLoudID,"bass",self.VDLoud) end + self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.05) end if self.VDOP ~= Train.VDOP.Value then self.VDOP = Train.VDOP.Value - self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.3) - if self.VDLoud and self.VDOP > 0 and not Train.RightDoorsOpen then Train:PlayOnce("vdop_loud"..self.VDLoudID,"bass",self.VDLoud) end + self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.05) end if self.VDZ ~= Train.VDZ.Value then self.VDZ = Train.VDZ.Value - self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.3) - if self.VDLoud and self.VDZ > 0 and (Train.RightDoorsOpen or Train.LeftDoorsOpen) then Train:PlayOnce("vzd_loud"..self.VDLoudID,"bass",self.VDLoud) end - end - if Train.CanStuckPassengerLeft then - for i in ipairs(self.LeftDoorStuck) do - self.LeftDoorStuck[i] = math.random() < (0.6+math.min(2,2-self.LeftDoorSpeed[i])*0.2)*Train.CanStuckPassengerLeft*0.6 and (math.random() > 0.7 and CurTime()+math.random()*15) - end - Train.CanStuckPassengerLeft = false - end - if Train.CanStuckPassengerRight then - for i in ipairs(self.RightDoorStuck) do - self.RightDoorStuck[i] = math.random() < (0.6+math.min(2,2-self.LeftDoorSpeed[i])*0.2)*Train.CanStuckPassengerRight*0.6 and (math.random() > 0.7 and CurTime()+math.random()*15) - end - Train.CanStuckPassengerRight = false + self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.05) end + Train.LeftDoorsOpen = false Train.RightDoorsOpen = false local openL = true @@ -681,9 +746,9 @@ function TRAIN_SYSTEM:Think(dT) for i=1,4 do self.LeftDoorDir[i] = math.Clamp(self.LeftDoorDir[i]+dT/(self.DoorLeft and self.LeftDoorSpeed[i] or -self.LeftDoorSpeed[i]),-1,1) self.RightDoorDir[i] = math.Clamp(self.RightDoorDir[i]+dT/(self.DoorRight and self.RightDoorSpeed[i] or -self.RightDoorSpeed[i]),-1,1) - self.LeftDoorState[i] = math.Clamp(self.LeftDoorState[i] + ((self.LeftDoorDir[i]/self.LeftDoorSpeed[i])*dT),self.LeftDoorStuck[i] and 0.3 or 0,1) + self.LeftDoorState[i] = math.Clamp(self.LeftDoorState[i] + ((self.LeftDoorDir[i]/self.LeftDoorSpeed[i])*dT),0,1) if self.LeftDoorState[i] == 0 or self.LeftDoorState[i] == 1 then self.LeftDoorDir[i] = 0 end - self.RightDoorState[i] = math.Clamp(self.RightDoorState[i] + ((self.RightDoorDir[i]/self.RightDoorSpeed[i])*dT),self.RightDoorStuck[i] and 0.3 or 0,1) + self.RightDoorState[i] = math.Clamp(self.RightDoorState[i] + ((self.RightDoorDir[i]/self.RightDoorSpeed[i])*dT),0,1) if self.RightDoorState[i] == 0 or self.RightDoorState[i] == 1 then self.RightDoorDir[i] = 0 end if not Train.LeftDoorsOpen and self.LeftDoorState[i] > 0 then Train.LeftDoorsOpen = true @@ -697,39 +762,34 @@ function TRAIN_SYSTEM:Think(dT) end Train:SetPackedRatio("DoorL"..i,self.LeftDoorState[i]) Train:SetPackedRatio("DoorR"..i,self.RightDoorState[i]) - if self.LeftDoorStuck[i] and (self.DoorLeft or type(self.LeftDoorStuck[i]) == "number" and CurTime()-self.LeftDoorStuck[i] > 0) then - self.LeftDoorStuck[i] = false - end - if self.RightDoorStuck[i] and (self.DoorRight or type(self.RightDoorStuck[i]) == "number" and CurTime()-self.RightDoorStuck[i] > 0) then - self.RightDoorStuck[i] = false - end - Train:SetPackedBool("DoorLS"..i,self.LeftDoorStuck[i]) - Train:SetPackedBool("DoorRS"..i,self.RightDoorStuck[i]) end if openL and not self.OpenWaitL then self.OpenWaitL = CurTime() end if openR and not self.OpenWaitR then self.OpenWaitR = CurTime() end Train:SetPackedBool("DoorL",self.DoorLeft) Train:SetPackedBool("DoorR",self.DoorRight) Train.BD:TriggerInput("Set",not Train.RightDoorsOpen and not Train.LeftDoorsOpen) - Train.LeftDoorsOpening = self.DoorLeft - Train.RightDoorsOpening = self.DoorRight ---------------------------------------------------------------------------- if self.DriverValveDisconnectPrevious ~= Train.DriverValveDisconnect.Value then self.DriverValveDisconnectPrevious = Train.DriverValveDisconnect.Value - if self.DriverValveDisconnectPrevious == 0 and self.TrainLinePressure>1 then + if self.DriverValveDisconnectPrevious == 0 then self.DVDOffTimer = CurTime() Train:PlayOnce("pneumo_disconnect2","cabin",0.9) - elseif self.TrainLinePressure>1 then + else self.DVDOffTimer = nil Train:PlayOnce("pneumo_disconnect1","cabin",0.9) end end + --Написано в описании КМ013, что при закрытии разобщительного он снижает давление в ТМ на 0.7, значит так и сделаем! + --(и обработку случая, когда в обеих кабинах разобщительный открыт не забудем) + local km013_setpoint = {6.4, self.KM013offset, 4.3, 4.0, 3.7, 3.0, 0} if self.DVDOffTimer then - if CurTime()-self.DVDOffTimer < 0.45 then - local pr_speed = 1.3*(Train:GetWagonCount()) --2 - self:equalizePressure(dT,"BrakeLinePressure", 0,pr_speed) + if self.BrakeLinePressure - (km013_setpoint[self.RealDriverValvePosition]-0.7) > 0.02 and CurTime()-self.DVDOffTimer < wagc*5/8 then + --print "Снижение давления в ТМ..." + local pr_speed = 22--1.4*wagc --2 + self:equalizePressure(dT,"BrakeLinePressure", math.max(0,km013_setpoint[self.RealDriverValvePosition]-0.7), pr_speed) else + --print("Снижение давления в ТМ завершено за "..(CurTime()-self.DVDOffTimer).." секунд") self.DVDOffTimer = nil end end @@ -741,8 +801,7 @@ function TRAIN_SYSTEM:Think(dT) Train:SetNW2Bool("FtI",Train.FrontTrainLineIsolation.Value ~= 0) Train:SetNW2Bool("RtI",Train.RearTrainLineIsolation.Value ~= 0) Train:SetNW2Bool("AD",Train.AirDistributorDisconnect.Value == 0) - - + Train:SetNW2Bool("UAVAContacts",Train.UAVAC.Value ~= 0) local ValveType = self.ValveType > 1 self.Timer = self.Timer or CurTime() diff --git a/lua/metrostroi/systems/sys_pr_14x_panels.lua b/lua/metrostroi/systems/sys_pr_14x_panels.lua index 9ed0e8e0..5b87d858 100644 --- a/lua/metrostroi/systems/sys_pr_14x_panels.lua +++ b/lua/metrostroi/systems/sys_pr_14x_panels.lua @@ -31,7 +31,7 @@ function TRAIN_SYSTEM:Initialize() -- Реле-повторитель провода 8 (РП8) self.Train:LoadSystem("Rp8","Relay","REV-811T",{open_time = 0.2,bass = true }) -- Контактор дверей (КД) - self.Train:LoadSystem("KD","Relay","REV-811T",{ bass = true }) + self.Train:LoadSystem("KD","Relay","REV-811T",{ bass = true, close_time = 0.5 }) -- Реле остановки (РО) self.Train:LoadSystem("RO","Relay","KPD-110E",{ bass = true, close_time = 0--[[ , close_time = 0.1--]] }) end diff --git a/lua/metrostroi_data/languages/en_717.lua b/lua/metrostroi_data/languages/en_717.lua index 84abcc7f..bc80bcc1 100644 --- a/lua/metrostroi_data/languages/en_717.lua +++ b/lua/metrostroi_data/languages/en_717.lua @@ -19,19 +19,20 @@ Spawner.717.Line2 = Train from MPL Spawner.717.Line4 = Train from PBL Spawner.717.Line5 = Train from FPL -Spawner.717.Type = Train type -Spawner.717.BodyType = Body type -Spawner.717.MVM = MVM -Spawner.717.LVZ = LVZ -Spawner.717.MaskType = Mask type -Spawner.717.CranType = Driver's valve type -Spawner.717.LampType = Lamps type -Spawner.717.Lamp1 = LPV-02 -Spawner.717.Lamp2 = LLV-01 -Spawner.717.SeatType = Seats type -Spawner.717.ARS = ARS panel type -Spawner.717.RingType = ARS beeper type -Spawner.717.BPSNType = BPSN type +Spawner.717.Type = Train type +Spawner.717.BodyType = Body type +Spawner.717.MVM = MVM +Spawner.717.LVZ = LVZ +Spawner.717.MaskType = Mask type +Spawner.717.CranType = Driver's valve type +Spawner.717.LampType = Lamps type +Spawner.717.Lamp1 = LPV-02 +Spawner.717.Lamp2 = LLV-01 +Spawner.717.SeatType = Seats type +Spawner.717.ARS = ARS panel type +Spawner.717.RingType = ARS beeper type +Spawner.717.BPSNType = BPSN type +Spawner.717.RetainerLoad = Retainer load #######Buttons########### Train.Buttons.RZP = BPSN converter protection engaged #NEW @@ -198,6 +199,21 @@ Common.PA.Enter = Enter Common.714.Start = Start traction-motors #FIXME Common.714.RV = Direction switch #FIXME +Common.717.RetEmpty = Empty car +Common.717.RetMedium = Medium load +Common.717.RetFull = Full load +Common.717.RetPassengers = Passengers load + +Common.717.AUTOSTOP = Engage emergency stop valve + +Common.717.HOD = Manually open +Common.717.HCD = Manually close +Common.717.HDLK = Doors lock +Common.717.DoorReleaseExt = First right door emergency open valve +Common.717.DoorReleaseLeft = Left doors emergency open valve +Common.717.DoorReleaseRight = Right doors emergency open valve +Common.717.DVR87 = Doors air distrubutor disconnect valve + #gmod_subway_81-717 Entities.gmod_subway_81-717_mvm.Buttons.Battery_C.1:UOSToggle = @[Common.ALL.UOS] Entities.gmod_subway_81-717_mvm.Buttons.Battery_R.2:UOSToggle = @[Common.ALL.UOS] @@ -560,6 +576,39 @@ Entities.gmod_subway_81-717_mvm.Buttons.EPKDisconnect.EPKToggle Entities.gmod_subway_81-717_mvm.Buttons.EPVDisconnect.EPKToggle = @[Common.ALL.EPV] Entities.gmod_subway_81-717_mvm.Buttons.ParkingBrake.ParkingBrakeToggle = @[Common.ALL.ParkingBrake] +Entities.gmod_subway_81-717_mvm.Buttons.AutostopValve.AutostopValveSet = @[Common.717.AUTOSTOP] + +#Doors manual controls +Entities.gmod_subway_81-717_mvm.Buttons.Doors7_8_right.hod4Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors5_6_right.hod3Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors3_4_right.hod2Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors1_2_right.hod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors7_8_right.hcd4Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors5_6_right.hcd3Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors3_4_right.hcd2Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors1_2_right.hcd1Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors7_8_left.hod5Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors5_6_left.hod6Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors3_4_left.hod7Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors1_2_left.hod8Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors7_8_left.hcd5Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors5_6_left.hcd6Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors3_4_left.hcd7Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors1_2_left.hcd8Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors1_2_right_outer.outerhod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.bldr7_8_rgh.HDLK4Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.bldr5_6_rgh.HDLK3Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.bldr3_4_rgh.HDLK2Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.bldr1_2_rgh.HDLK1Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.bldr7_8_lft.HDLK5Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.bldr5_6_lft.HDLK6Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.bldr3_4_lft.HDLK7Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.bldr1_2_lft.HDLK8Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.DoorReleaseExtra.DoorReleaseExtraToggle = @[Common.717.DoorReleaseExt] +Entities.gmod_subway_81-717_mvm.Buttons.DoorReleaseLeft.DoorReleaseLeftToggle = @[Common.717.DoorReleaseLeft] +Entities.gmod_subway_81-717_mvm.Buttons.DoorReleaseRight.DoorReleaseRightToggle = @[Common.717.DoorReleaseRight] +Entities.gmod_subway_81-717_mvm.Buttons.DVR_87.DVRDisconnectToggle = @[Common.717.DVR87] + #gmod_subway_81-717_lvz #Buttons: @@ -979,6 +1028,39 @@ Entities.gmod_subway_81-717_lvz.Buttons.EPKDisconnect.EPKToggle Entities.gmod_subway_81-717_lvz.Buttons.EPVDisconnect.EPKToggle = @[Common.ALL.EPV] Entities.gmod_subway_81-717_lvz.Buttons.ParkingBrake.ParkingBrakeToggle = @[Common.ALL.ParkingBrake] +Entities.gmod_subway_81-717_lvz.Buttons.AutostopValve.AutostopValveSet = @[Common.717.AUTOSTOP] + +#Doors manual controls +Entities.gmod_subway_81-717_lvz.Buttons.Doors7_8_right.hod4Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors5_6_right.hod3Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors3_4_right.hod2Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors1_2_right.hod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors7_8_right.hcd4Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors5_6_right.hcd3Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors3_4_right.hcd2Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors1_2_right.hcd1Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors7_8_left.hod5Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors5_6_left.hod6Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors3_4_left.hod7Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors1_2_left.hod8Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors7_8_left.hcd5Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors5_6_left.hcd6Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors3_4_left.hcd7Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors1_2_left.hcd8Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors1_2_right_outer.outerhod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.bldr7_8_rgh.HDLK4Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.bldr5_6_rgh.HDLK3Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.bldr3_4_rgh.HDLK2Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.bldr1_2_rgh.HDLK1Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.bldr7_8_lft.HDLK5Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.bldr5_6_lft.HDLK6Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.bldr3_4_lft.HDLK7Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.bldr1_2_lft.HDLK8Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.DoorReleaseExtra.DoorReleaseExtraToggle = @[Common.717.DoorReleaseExt] +Entities.gmod_subway_81-717_lvz.Buttons.DoorReleaseLeft.DoorReleaseLeftToggle = @[Common.717.DoorReleaseLeft] +Entities.gmod_subway_81-717_lvz.Buttons.DoorReleaseRight.DoorReleaseRightToggle = @[Common.717.DoorReleaseRight] +Entities.gmod_subway_81-717_lvz.Buttons.DVR_87.DVRDisconnectToggle = @[Common.717.DVR87] + #gmod_subway_81-714_mvm Entities.gmod_subway_81-714_mvm.Buttons.FrontPneumatic.FrontBrakeLineIsolationToggle = @[Common.ALL.FrontBrakeLineIsolationToggle] Entities.gmod_subway_81-714_mvm.Buttons.FrontPneumatic.FrontTrainLineIsolationToggle = @[Common.ALL.FrontTrainLineIsolationToggle] @@ -1063,6 +1145,37 @@ Entities.gmod_subway_81-714_mvm.Buttons.Voltages.!BatteryCurrent = @[Comm Entities.gmod_subway_81-714_mvm.Buttons.Pressures.!BCPressure = @[Common.ALL.BCPressure] Entities.gmod_subway_81-714_mvm.Buttons.Pressures.!BLTLPressure = @[Common.ALL.BLTLPressure] +#Doors manual controls +Entities.gmod_subway_81-714_mvm.Buttons.Doors7_8_right.iod8Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors5_6_right.iod7Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors3_4_right.iod6Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors1_2_right.iod5Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors7_8_right.icd8Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors5_6_right.icd7Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors3_4_right.icd6Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors1_2_right.icd5Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors7_8_left.iod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors5_6_left.iod2Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors3_4_left.iod3Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors1_2_left.iod4Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors7_8_left.icd1Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors5_6_left.icd2Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors3_4_left.icd3Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors1_2_left.icd4Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors1_2_right_outer.outerhod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.bldr7_8_rgh.IDLK8Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.bldr5_6_rgh.IDLK7Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.bldr3_4_rgh.IDLK6Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.bldr1_2_rgh.IDLK5Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.bldr7_8_lft.IDLK1Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.bldr5_6_lft.IDLK2Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.bldr3_4_lft.IDLK3Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.bldr1_2_lft.IDLK4Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.DoorReleaseLeft.DoorReleaseLeftToggle = @[Common.717.DoorReleaseLeft] +Entities.gmod_subway_81-714_mvm.Buttons.DoorReleaseRight.DoorReleaseRightToggle = @[Common.717.DoorReleaseRight] +Entities.gmod_subway_81-714_mvm.Buttons.DVR_87.DVRDisconnectToggle = @[Common.717.DVR87] + + #gmod_subway_81-714_lvz Entities.gmod_subway_81-714_lvz.Buttons.FrontPneumatic.FrontBrakeLineIsolationToggle = @[Common.ALL.FrontBrakeLineIsolationToggle] Entities.gmod_subway_81-714_lvz.Buttons.FrontPneumatic.FrontTrainLineIsolationToggle = @[Common.ALL.FrontTrainLineIsolationToggle] @@ -1141,6 +1254,36 @@ Entities.gmod_subway_81-714_lvz.Buttons.Voltages.!BatteryCurrent = @[Comm Entities.gmod_subway_81-714_lvz.Buttons.Pressures.!BCPressure = @[Common.ALL.BCPressure] Entities.gmod_subway_81-714_lvz.Buttons.Pressures.!BLTLPressure = @[Common.ALL.BLTLPressure] +#Doors manual controls +Entities.gmod_subway_81-714_lvz.Buttons.Doors7_8_right.iod8Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors5_6_right.iod7Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors3_4_right.iod6Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors1_2_right.iod5Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors7_8_right.icd8Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors5_6_right.icd7Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors3_4_right.icd6Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors1_2_right.icd5Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors7_8_left.iod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors5_6_left.iod2Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors3_4_left.iod3Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors1_2_left.iod4Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors7_8_left.icd1Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors5_6_left.icd2Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors3_4_left.icd3Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors1_2_left.icd4Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors1_2_right_outer.outerhod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.bldr7_8_rgh.IDLK8Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.bldr5_6_rgh.IDLK7Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.bldr3_4_rgh.IDLK6Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.bldr1_2_rgh.IDLK5Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.bldr7_8_lft.IDLK1Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.bldr5_6_lft.IDLK2Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.bldr3_4_lft.IDLK3Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.bldr1_2_lft.IDLK4Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.DoorReleaseLeft.DoorReleaseLeftToggle = @[Common.717.DoorReleaseLeft] +Entities.gmod_subway_81-714_lvz.Buttons.DoorReleaseRight.DoorReleaseRightToggle = @[Common.717.DoorReleaseRight] +Entities.gmod_subway_81-714_lvz.Buttons.DVR_87.DVRDisconnectToggle = @[Common.717.DVR87] + #Spawner: Entities.gmod_subway_81-717_mvm.Spawner.Announcer.Name = @[Common.Spawner.Announcer] Entities.gmod_subway_81-717_mvm.Spawner.Scheme.Name = @[Common.Spawner.Scheme] @@ -1202,6 +1345,14 @@ Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.11 = @[Common.Spawn Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.12 = @[Common.Spawner.Type] 11 Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.13 = @[Common.Spawner.Type] 12 Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.14 = @[Common.Spawner.Type] 13 + +Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.Name = @[Spawner.717.RetainerLoad] +Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.1 = @[Common.717.RetEmpty] +Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.2 = @[Common.717.RetMedium] +Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.3 = @[Common.717.RetFull] +Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.4 = @[Common.717.RetPassengers] +Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.5 = @[Common.Spawner.Random] + Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.Name = @[Common.Spawner.SpawnMode] Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.1 = @[Common.Spawner.SpawnMode.Full] Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.2 = @[Common.Spawner.SpawnMode.Deadlock] @@ -1209,6 +1360,13 @@ Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.3 = @[Common.Spawn Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.4 = @[Common.Spawner.SpawnMode.Depot] #Spawner: +Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.Name = @[Spawner.717.RetainerLoad] +Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.1 = @[Common.717.RetEmpty] +Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.2 = @[Common.717.RetMedium] +Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.3 = @[Common.717.RetFull] +Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.4 = @[Common.717.RetPassengers] +Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.5 = @[Common.Spawner.Random] + Entities.gmod_subway_81-717_lvz.Spawner.Texture.Name = @[Common.Spawner.Texture] Entities.gmod_subway_81-717_lvz.Spawner.PassTexture.Name = @[Common.Spawner.PassTexture] Entities.gmod_subway_81-717_lvz.Spawner.CabTexture.Name = @[Common.Spawner.CabTexture] diff --git a/lua/metrostroi_data/languages/ru_717.lua b/lua/metrostroi_data/languages/ru_717.lua index bca8c52d..1cc39ca9 100644 --- a/lua/metrostroi_data/languages/ru_717.lua +++ b/lua/metrostroi_data/languages/ru_717.lua @@ -19,19 +19,20 @@ Spawner.717.Line2 = Состав с МПЛ Spawner.717.Line4 = Состав с ПБЛ Spawner.717.Line5 = Состав с ФПЛ -Spawner.717.Type = Тип состава -Spawner.717.BodyType = Тип кузова -Spawner.717.MVM = МВМ -Spawner.717.LVZ = ЛВЗ -Spawner.717.MaskType = Тип маски -Spawner.717.CranType = Тип крана машиниста -Spawner.717.LampType = Тип ламп -Spawner.717.Lamp1 = ЛПВ-02 -Spawner.717.Lamp2 = ЛЛВ-01 -Spawner.717.SeatType = Тип сидений -Spawner.717.ARS = Тип панели АРС -Spawner.717.RingType = Тип звонка -Spawner.717.BPSNType = Тип БПСН +Spawner.717.Type = Тип состава +Spawner.717.BodyType = Тип кузова +Spawner.717.MVM = МВМ +Spawner.717.LVZ = ЛВЗ +Spawner.717.MaskType = Тип маски +Spawner.717.CranType = Тип крана машиниста +Spawner.717.LampType = Тип ламп +Spawner.717.Lamp1 = ЛПВ-02 +Spawner.717.Lamp2 = ЛЛВ-01 +Spawner.717.SeatType = Тип сидений +Spawner.717.ARS = Тип панели АРС +Spawner.717.RingType = Тип звонка +Spawner.717.BPSNType = Тип БПСН +Spawner.717.RetainerLoad = Авторежим #######Buttons########### Train.Buttons.RZP = Сработала защита БПСН @@ -198,6 +199,22 @@ Common.PA.Enter = Ввод Common.714.Start = Пуск тяговых двигателей Common.714.RV = Переключатель направления +Common.717.RetEmpty = Порожний +Common.717.RetMedium = Средняя загрузка +Common.717.RetFull = Груженый +Common.717.RetPassengers = Пассажиры + +Common.717.AUTOSTOP = Сорвать срывной клапан + +Common.717.HOD = Раздвинуть двери +Common.717.HCD = Закрыть двери +Common.717.HDLK = Блокировка дверей +Common.717.DoorReleaseExt = Выключение первой правой двери +Common.717.DoorReleaseLeft = Выключение дверей левых +Common.717.DoorReleaseRight = Выключение дверей правых +Common.717.DVR87 = Разобщительный кран ДВР + + #gmod_subway_81-717 Entities.gmod_subway_81-717_mvm.Buttons.Battery_C.1:UOSToggle = @[Common.ALL.UOS] Entities.gmod_subway_81-717_mvm.Buttons.Battery_R.2:UOSToggle = @[Common.ALL.UOS] @@ -560,6 +577,38 @@ Entities.gmod_subway_81-717_mvm.Buttons.EPKDisconnect.EPKToggle Entities.gmod_subway_81-717_mvm.Buttons.EPVDisconnect.EPKToggle = @[Common.ALL.EPV] Entities.gmod_subway_81-717_mvm.Buttons.ParkingBrake.ParkingBrakeToggle = @[Common.ALL.ParkingBrake] +Entities.gmod_subway_81-717_mvm.Buttons.AutostopValve.AutostopValveSet = @[Common.717.AUTOSTOP] + +#Doors manual controls +Entities.gmod_subway_81-717_mvm.Buttons.Doors7_8_right.hod4Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors5_6_right.hod3Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors3_4_right.hod2Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors1_2_right.hod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors7_8_right.hcd4Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors5_6_right.hcd3Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors3_4_right.hcd2Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors1_2_right.hcd1Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors7_8_left.hod5Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors5_6_left.hod6Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors3_4_left.hod7Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors1_2_left.hod8Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors7_8_left.hcd5Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors5_6_left.hcd6Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors3_4_left.hcd7Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors1_2_left.hcd8Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_mvm.Buttons.Doors1_2_right_outer.outerhod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_mvm.Buttons.bldr7_8_rgh.HDLK4Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.bldr5_6_rgh.HDLK3Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.bldr3_4_rgh.HDLK2Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.bldr1_2_rgh.HDLK1Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.bldr7_8_lft.HDLK5Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.bldr5_6_lft.HDLK6Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.bldr3_4_lft.HDLK7Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.bldr1_2_lft.HDLK8Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_mvm.Buttons.DoorReleaseExtra.DoorReleaseExtraToggle = @[Common.717.DoorReleaseExt] +Entities.gmod_subway_81-717_mvm.Buttons.DoorReleaseLeft.DoorReleaseLeftToggle = @[Common.717.DoorReleaseLeft] +Entities.gmod_subway_81-717_mvm.Buttons.DoorReleaseRight.DoorReleaseRightToggle = @[Common.717.DoorReleaseRight] +Entities.gmod_subway_81-717_mvm.Buttons.DVR_87.DVRDisconnectToggle = @[Common.717.DVR87] #gmod_subway_81-717_lvz #Buttons: @@ -979,6 +1028,39 @@ Entities.gmod_subway_81-717_lvz.Buttons.EPKDisconnect.EPKToggle Entities.gmod_subway_81-717_lvz.Buttons.EPVDisconnect.EPKToggle = @[Common.ALL.EPV] Entities.gmod_subway_81-717_lvz.Buttons.ParkingBrake.ParkingBrakeToggle = @[Common.ALL.ParkingBrake] +Entities.gmod_subway_81-717_lvz.Buttons.AutostopValve.AutostopValveSet = @[Common.717.AUTOSTOP] + +#Doors manual controls +Entities.gmod_subway_81-717_lvz.Buttons.Doors7_8_right.hod4Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors5_6_right.hod3Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors3_4_right.hod2Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors1_2_right.hod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors7_8_right.hcd4Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors5_6_right.hcd3Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors3_4_right.hcd2Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors1_2_right.hcd1Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors7_8_left.hod5Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors5_6_left.hod6Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors3_4_left.hod7Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors1_2_left.hod8Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors7_8_left.hcd5Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors5_6_left.hcd6Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors3_4_left.hcd7Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors1_2_left.hcd8Set = @[Common.717.HCD] +Entities.gmod_subway_81-717_lvz.Buttons.Doors1_2_right_outer.outerhod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-717_lvz.Buttons.bldr7_8_rgh.HDLK4Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.bldr5_6_rgh.HDLK3Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.bldr3_4_rgh.HDLK2Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.bldr1_2_rgh.HDLK1Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.bldr7_8_lft.HDLK5Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.bldr5_6_lft.HDLK6Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.bldr3_4_lft.HDLK7Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.bldr1_2_lft.HDLK8Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-717_lvz.Buttons.DoorReleaseExtra.DoorReleaseExtraToggle = @[Common.717.DoorReleaseExt] +Entities.gmod_subway_81-717_lvz.Buttons.DoorReleaseLeft.DoorReleaseLeftToggle = @[Common.717.DoorReleaseLeft] +Entities.gmod_subway_81-717_lvz.Buttons.DoorReleaseRight.DoorReleaseRightToggle = @[Common.717.DoorReleaseRight] +Entities.gmod_subway_81-717_lvz.Buttons.DVR_87.DVRDisconnectToggle = @[Common.717.DVR87] + #gmod_subway_81-714_mvm Entities.gmod_subway_81-714_mvm.Buttons.FrontPneumatic.FrontBrakeLineIsolationToggle = @[Common.ALL.FrontBrakeLineIsolationToggle] Entities.gmod_subway_81-714_mvm.Buttons.FrontPneumatic.FrontTrainLineIsolationToggle = @[Common.ALL.FrontTrainLineIsolationToggle] @@ -1063,6 +1145,36 @@ Entities.gmod_subway_81-714_mvm.Buttons.Voltages.!BatteryCurrent = @[Common.ALL. Entities.gmod_subway_81-714_mvm.Buttons.Pressures.!BCPressure = @[Common.ALL.BCPressure] Entities.gmod_subway_81-714_mvm.Buttons.Pressures.!BLTLPressure = @[Common.ALL.BLTLPressure] +#Doors manual controls +Entities.gmod_subway_81-714_mvm.Buttons.Doors7_8_right.iod8Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors5_6_right.iod7Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors3_4_right.iod6Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors1_2_right.iod5Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors7_8_right.icd8Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors5_6_right.icd7Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors3_4_right.icd6Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors1_2_right.icd5Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors7_8_left.iod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors5_6_left.iod2Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors3_4_left.iod3Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors1_2_left.iod4Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors7_8_left.icd1Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors5_6_left.icd2Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors3_4_left.icd3Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors1_2_left.icd4Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_mvm.Buttons.Doors1_2_right_outer.outerhod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_mvm.Buttons.bldr7_8_rgh.IDLK8Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.bldr5_6_rgh.IDLK7Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.bldr3_4_rgh.IDLK6Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.bldr1_2_rgh.IDLK5Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.bldr7_8_lft.IDLK1Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.bldr5_6_lft.IDLK2Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.bldr3_4_lft.IDLK3Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.bldr1_2_lft.IDLK4Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_mvm.Buttons.DoorReleaseLeft.DoorReleaseLeftToggle = @[Common.717.DoorReleaseLeft] +Entities.gmod_subway_81-714_mvm.Buttons.DoorReleaseRight.DoorReleaseRightToggle = @[Common.717.DoorReleaseRight] +Entities.gmod_subway_81-714_mvm.Buttons.DVR_87.DVRDisconnectToggle = @[Common.717.DVR87] + #gmod_subway_81-714_lvz Entities.gmod_subway_81-714_lvz.Buttons.FrontPneumatic.FrontBrakeLineIsolationToggle = @[Common.ALL.FrontBrakeLineIsolationToggle] Entities.gmod_subway_81-714_lvz.Buttons.FrontPneumatic.FrontTrainLineIsolationToggle = @[Common.ALL.FrontTrainLineIsolationToggle] @@ -1141,6 +1253,36 @@ Entities.gmod_subway_81-714_lvz.Buttons.Voltages.!BatteryCurrent = @[Common.ALL. Entities.gmod_subway_81-714_lvz.Buttons.Pressures.!BCPressure = @[Common.ALL.BCPressure] #NEW Entities.gmod_subway_81-714_lvz.Buttons.Pressures.!BLTLPressure = @[Common.ALL.BLTLPressure] #NEW +#Doors manual controls +Entities.gmod_subway_81-714_lvz.Buttons.Doors7_8_right.iod8Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors5_6_right.iod7Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors3_4_right.iod6Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors1_2_right.iod5Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors7_8_right.icd8Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors5_6_right.icd7Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors3_4_right.icd6Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors1_2_right.icd5Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors7_8_left.iod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors5_6_left.iod2Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors3_4_left.iod3Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors1_2_left.iod4Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors7_8_left.icd1Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors5_6_left.icd2Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors3_4_left.icd3Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors1_2_left.icd4Set = @[Common.717.HCD] +Entities.gmod_subway_81-714_lvz.Buttons.Doors1_2_right_outer.outerhod1Set = @[Common.717.HOD] +Entities.gmod_subway_81-714_lvz.Buttons.bldr7_8_rgh.IDLK8Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.bldr5_6_rgh.IDLK7Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.bldr3_4_rgh.IDLK6Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.bldr1_2_rgh.IDLK5Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.bldr7_8_lft.IDLK1Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.bldr5_6_lft.IDLK2Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.bldr3_4_lft.IDLK3Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.bldr1_2_lft.IDLK4Toggle = @[Common.717.HDLK] +Entities.gmod_subway_81-714_lvz.Buttons.DoorReleaseLeft.DoorReleaseLeftToggle = @[Common.717.DoorReleaseLeft] +Entities.gmod_subway_81-714_lvz.Buttons.DoorReleaseRight.DoorReleaseRightToggle = @[Common.717.DoorReleaseRight] +Entities.gmod_subway_81-714_lvz.Buttons.DVR_87.DVRDisconnectToggle = @[Common.717.DVR87] + #Spawner: Entities.gmod_subway_81-717_mvm.Spawner.Announcer.Name = @[Common.Spawner.Announcer] Entities.gmod_subway_81-717_mvm.Spawner.Scheme.Name = @[Common.Spawner.Scheme] @@ -1202,6 +1344,14 @@ Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.11 = @[Common.Spawn Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.12 = @[Common.Spawner.Type] 11 Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.13 = @[Common.Spawner.Type] 12 Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.14 = @[Common.Spawner.Type] 13 + +Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.Name = @[Spawner.717.RetainerLoad] +Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.1 = @[Common.717.RetEmpty] +Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.2 = @[Common.717.RetMedium] +Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.3 = @[Common.717.RetFull] +Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.4 = @[Common.717.RetPassengers] +Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.5 = @[Common.Spawner.Random] + Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.Name = @[Common.Spawner.SpawnMode] Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.1 = @[Common.Spawner.SpawnMode.Full] Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.2 = @[Common.Spawner.SpawnMode.Deadlock] @@ -1209,6 +1359,13 @@ Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.3 = @[Common.Spawn Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.4 = @[Common.Spawner.SpawnMode.Depot] #Spawner: +Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.Name = @[Spawner.717.RetainerLoad] +Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.1 = @[Common.717.RetEmpty] +Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.2 = @[Common.717.RetMedium] +Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.3 = @[Common.717.RetFull] +Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.4 = @[Common.717.RetPassengers] +Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.5 = @[Common.Spawner.Random] + Entities.gmod_subway_81-717_lvz.Spawner.Texture.Name = @[Common.Spawner.Texture] Entities.gmod_subway_81-717_lvz.Spawner.PassTexture.Name = @[Common.Spawner.PassTexture] Entities.gmod_subway_81-717_lvz.Spawner.CabTexture.Name = @[Common.Spawner.CabTexture] diff --git a/models/metrostroi_train/door_crans/cran_dooropen_head.dx80.vtx b/models/metrostroi_train/door_crans/cran_dooropen_head.dx80.vtx new file mode 100644 index 00000000..bb5c5ce2 --- /dev/null +++ b/models/metrostroi_train/door_crans/cran_dooropen_head.dx80.vtx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:adebfc3ca6ee07aeb3057a79dd7ca70184a6f4e03fe3263a23fcb2fa2295b5f6 +size 9069 diff --git a/models/metrostroi_train/door_crans/cran_dooropen_head.dx90.vtx b/models/metrostroi_train/door_crans/cran_dooropen_head.dx90.vtx new file mode 100644 index 00000000..729e566c --- /dev/null +++ b/models/metrostroi_train/door_crans/cran_dooropen_head.dx90.vtx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47b3ce5108fc3abe0dcd27390eb5e89b943285c6c8d447cf6a8bb1d52fa9a7b6 +size 9069 diff --git a/models/metrostroi_train/door_crans/cran_dooropen_head.mdl b/models/metrostroi_train/door_crans/cran_dooropen_head.mdl new file mode 100644 index 00000000..cdc5f429 --- /dev/null +++ b/models/metrostroi_train/door_crans/cran_dooropen_head.mdl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb5054a0b3bbb39a3dc13fc84763b5e6bca836781599239206d2487dd266ab08 +size 1712 diff --git a/models/metrostroi_train/door_crans/cran_dooropen_head.sw.vtx b/models/metrostroi_train/door_crans/cran_dooropen_head.sw.vtx new file mode 100644 index 00000000..bfae3ffe --- /dev/null +++ b/models/metrostroi_train/door_crans/cran_dooropen_head.sw.vtx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b047453d8b1d5390736eca0c978c62afd1c936718b34a2f131594edead81d35c +size 9069 diff --git a/models/metrostroi_train/door_crans/cran_dooropen_head.vvd b/models/metrostroi_train/door_crans/cran_dooropen_head.vvd new file mode 100644 index 00000000..4eb9f885 --- /dev/null +++ b/models/metrostroi_train/door_crans/cran_dooropen_head.vvd @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d23b45c83fe0fbddb7a005c1df40f92c0a2313f71a1cba0aaa26c16d6b8eb62b +size 36160 diff --git a/models/metrostroi_train/door_crans/cran_dooropen_int.dx80.vtx b/models/metrostroi_train/door_crans/cran_dooropen_int.dx80.vtx new file mode 100644 index 00000000..7912f241 --- /dev/null +++ b/models/metrostroi_train/door_crans/cran_dooropen_int.dx80.vtx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f7d4cdabd60d7876cdbb40e7a03fdb5b1031ed5165620680fd4b9099d07b9b3 +size 6093 diff --git a/models/metrostroi_train/door_crans/cran_dooropen_int.dx90.vtx b/models/metrostroi_train/door_crans/cran_dooropen_int.dx90.vtx new file mode 100644 index 00000000..e0288f28 --- /dev/null +++ b/models/metrostroi_train/door_crans/cran_dooropen_int.dx90.vtx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9baf8a0054cf74991b2e4eee83bdbc3133c41b816b85482e5c985c7491805859 +size 6093 diff --git a/models/metrostroi_train/door_crans/cran_dooropen_int.mdl b/models/metrostroi_train/door_crans/cran_dooropen_int.mdl new file mode 100644 index 00000000..f1acf15b --- /dev/null +++ b/models/metrostroi_train/door_crans/cran_dooropen_int.mdl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c35783e5d87dc894c22f3ccc242137ca42a77f94316c5e71dfdb5ee8eb182e6f +size 1708 diff --git a/models/metrostroi_train/door_crans/cran_dooropen_int.sw.vtx b/models/metrostroi_train/door_crans/cran_dooropen_int.sw.vtx new file mode 100644 index 00000000..77f88653 --- /dev/null +++ b/models/metrostroi_train/door_crans/cran_dooropen_int.sw.vtx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6e12bfc13bdefd58948b7b784d419e14d0c982b28a6b38f3eebd9f0898cffa3 +size 6093 diff --git a/models/metrostroi_train/door_crans/cran_dooropen_int.vvd b/models/metrostroi_train/door_crans/cran_dooropen_int.vvd new file mode 100644 index 00000000..49edbf2c --- /dev/null +++ b/models/metrostroi_train/door_crans/cran_dooropen_int.vvd @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9547efeb0cbd2b1b8044c9814fe9fea864138ec8ef397b4fbee0298dce8cdafa +size 24128 diff --git a/sound/subway_trains/717/door_cyl/vdo2_on.mp3 b/sound/subway_trains/717/door_cyl/vdo2_on.mp3 new file mode 100644 index 00000000..dc54761c --- /dev/null +++ b/sound/subway_trains/717/door_cyl/vdo2_on.mp3 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b81f4a9472d5d5bc60ddbd1eec4fd401b540bfef4b03d7df408437cb5df7db26 +size 28488 diff --git a/sound/subway_trains/717/door_cyl/vdo3_on.mp3 b/sound/subway_trains/717/door_cyl/vdo3_on.mp3 new file mode 100644 index 00000000..dc54761c --- /dev/null +++ b/sound/subway_trains/717/door_cyl/vdo3_on.mp3 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b81f4a9472d5d5bc60ddbd1eec4fd401b540bfef4b03d7df408437cb5df7db26 +size 28488 diff --git a/sound/subway_trains/717/door_cyl/vdo_on.mp3 b/sound/subway_trains/717/door_cyl/vdo_on.mp3 new file mode 100644 index 00000000..8fe54441 --- /dev/null +++ b/sound/subway_trains/717/door_cyl/vdo_on.mp3 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f2343ced6d07cc8506956b16b87051c8d15995c22eb1866c6a6be55fc08e8d2 +size 28201 diff --git a/sound/subway_trains/717/door_cyl/vdz2_on.mp3 b/sound/subway_trains/717/door_cyl/vdz2_on.mp3 new file mode 100644 index 00000000..5a24fed3 --- /dev/null +++ b/sound/subway_trains/717/door_cyl/vdz2_on.mp3 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85393c9975b7bb88121518ec44c2ba289d2f8d61da14025d1787e3735e88e3b6 +size 28412 diff --git a/sound/subway_trains/717/door_cyl/vdz3_on.mp3 b/sound/subway_trains/717/door_cyl/vdz3_on.mp3 new file mode 100644 index 00000000..5a24fed3 --- /dev/null +++ b/sound/subway_trains/717/door_cyl/vdz3_on.mp3 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85393c9975b7bb88121518ec44c2ba289d2f8d61da14025d1787e3735e88e3b6 +size 28412 diff --git a/sound/subway_trains/717/door_cyl/vdz_on.mp3 b/sound/subway_trains/717/door_cyl/vdz_on.mp3 new file mode 100644 index 00000000..5a24fed3 --- /dev/null +++ b/sound/subway_trains/717/door_cyl/vdz_on.mp3 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85393c9975b7bb88121518ec44c2ba289d2f8d61da14025d1787e3735e88e3b6 +size 28412