AddCSLuaFile("cl_init.lua") AddCSLuaFile("shared.lua") include("shared.lua") util.AddNetworkString "metrostroi-signal" util.AddNetworkString "metrostroi-signal-state" function ENT:SetSprite(index,active,model,scale,brightness,pos,color) if active and self.Sprites[index] then return end if not active and not self.Sprites[index] then return end if not active and self.Sprites[index] then SafeRemoveEntity(self.Sprites[index]) self.Sprites[index] = nil end if active then local sprite = ents.Create("env_sprite") sprite:SetParent(self) sprite:SetLocalPos(pos) sprite:SetLocalAngles(self:GetAngles()) -- Set parameters sprite:SetKeyValue("rendercolor", Format("%i %i %i", color.r*brightness, color.g*brightness, color.b*brightness ) ) sprite:SetKeyValue("rendermode", 9) -- 9: WGlow, 3: Glow sprite:SetKeyValue("renderfx", 14) sprite:SetKeyValue("model", model) sprite:SetKeyValue("scale", scale) sprite:SetKeyValue("spawnflags", 1) -- Turn sprite on sprite:Spawn() self.Sprites[index] = sprite end end function ENT:OpenRoute(route) self.LastOpenedRoute = route if self.Routes[route].Manual then self.Routes[route].IsOpened = true end if not self.Routes[route].Switches then return end local Switches = string.Explode(",",self.Routes[route].Switches) for i1 =1, #Switches do if not Switches[i1] or Switches[i1] == "" then continue end local SwitchState = Switches[i1]:sub(-1,-1) == "-" local SwitchName = Switches[i1]:sub(1,-2) --if not self.Switches[SwitchName] then self.Switches[SwitchName] = Metrostroi.GetSwitchByName(SwitchName) end if not Metrostroi.GetSwitchByName(SwitchName) then print(self.Name,"switch not found") continue end --If route go right from this switch - add it if SwitchState ~= (Metrostroi.GetSwitchByName(SwitchName):GetSignal() ~= 0) then Metrostroi.GetSwitchByName(SwitchName):SendSignal(SwitchState and "alt" or "main",nil,true) --RunConsoleCommand("say","changing",SwitchName) end end end function ENT:CloseRoute(route) if self.Routes[route].Manual then self.Routes[route].IsOpened = false end if not self.Routes[route].Switches then return end local Switches = string.Explode(",",self.Routes[route].Switches) for i1 =1, #Switches do if not Switches[i1] or Switches[i1] == "" then continue end --local SwitchState = Switches[i1]:sub(-1,-1) == "-" local SwitchName = Switches[i1]:sub(1,-2) --if not self.Switches[SwitchName] then self.Switches[SwitchName] = Metrostroi.GetSwitchByName(SwitchName) end if not Metrostroi.GetSwitchByName(SwitchName) then print(self.Name,"switch not found") continue end --If route go right from this switch - add it if SwitchState ~= (Metrostroi.GetSwitchByName(SwitchName):GetSignal() ~= 0) then Metrostroi.GetSwitchByName(SwitchName):SendSignal("main",nil,true) --RunConsoleCommand("say","changing",SwitchName) end end end function MSignalSayHook(ply, comm, fromULX) if ulx and not fromULX then return end for i,sig in pairs(ents.FindByClass("gmod_track_signal")) do local comm = comm if comm:sub(1,8) == "!sactiv " then comm = comm:sub(9,-1):upper() comm = string.Explode(":",comm) if sig.Routes then for k,v in pairs(sig.Routes) do if (v.RouteName and v.RouteName:upper() == comm[1] or comm[1] == "*") and v.Emer then if sig.LastOpenedRoute and k ~= sig.LastOpenedRoute then sig:CloseRoute(sig.LastOpenedRoute) end v.IsOpened = true break end end end elseif comm:sub(1,10) == "!sdeactiv " then comm = comm:sub(11,-1):upper() comm = string.Explode(":",comm) if sig.Routes then for k,v in pairs(sig.Routes) do if (v.RouteName and v.RouteName:upper() == comm[1] or comm[1] == "*") and v.Emer then v.IsOpened = false break end end end elseif comm:sub(1,8) == "!sclose " then comm = comm:sub(9,-1):upper() comm = string.Explode(":",comm) if comm[1] == sig.Name then if sig.Routes[1] and sig.Routes[1].Manual then sig:CloseRoute(1) else if not sig.Close then sig.Close = true end if sig.InvationSignal then sig.InvationSignal = false end if (sig.LastOpenedRoute and sig.LastOpenedRoute == 1) or sig.Routes[1].Repeater then sig:CloseRoute(1) else sig:OpenRoute(1) end end elseif sig.Routes then for k,v in pairs(sig.Routes) do if v.RouteName and v.RouteName:upper() == comm[1] then if sig.LastOpenedRoute and k ~= sig.LastOpenedRoute then sig:CloseRoute(sig.LastOpenedRoute) end sig:CloseRoute(k) end end end elseif comm:sub(1,7) == "!sopen " then comm = comm:sub(8,-1):upper() comm = string.Explode(":",comm) if comm[1] == sig.Name then if comm[2] then if sig.NextSignals[comm[2]] then local Route for k,v in pairs(sig.Routes) do if v.NextSignal == comm[2] then Route = k break end end sig:OpenRoute(Route) end else if sig.Routes[1] and sig.Routes[1].Manual then sig:OpenRoute(1) elseif sig.Close then sig.Close = false end end elseif sig.Routes then for k,v in pairs(sig.Routes) do if v.RouteName and v.RouteName:upper() == comm[1] then if sig.LastOpenedRoute and k ~= sig.LastOpenedRoute then sig:CloseRoute(sig.LastOpenedRoute) end sig:OpenRoute(k) end end end elseif comm:sub(1,7) == "!sopps " then comm = comm:sub(8,-1):upper() comm = string.Explode(":",comm) if comm[1] == sig.Name then sig.InvationSignal = true end elseif comm:sub(1,7) == "!sclps " then comm = comm:sub(8,-1):upper() comm = string.Explode(":",comm) if comm[1] == sig.Name then sig.InvationSignal = false end elseif comm:sub(1,7) == "!senao " then comm = comm:sub(8,-1):upper() comm = string.Explode(":",comm) if comm[1] == sig.Name then if sig.AODisabled then sig.AODisabled = false end end elseif comm:sub(1,8) == "!sdisao " then comm = comm:sub(9,-1):upper() comm = string.Explode(":",comm) if comm[1] == sig.Name then if sig.ARSSpeedLimit == 2 then sig.AODisabled = true end end end end end hook.Add("PlayerSay","metrostroi-signal-say", function(ply, comm) MSignalSayHook(ply,comm) end) function ENT:Initialize() self:SetModel(self.TrafficLightModels[self.SignalType or 0].ArsBox.model) self.Sprites = {} self.Sig = "" self.FreeBS = 1 self.OldBSState = 1 self.OutputARS = 1 self.EnableDelay = {} self.PostInitalized = true self.Controllers = nil end function ENT:PreInitalize() self.AutostopOverride = nil if not self.Routes or self.Routes[1].NextSignal == "" then self.AutostopOverride = true end if self.Sprites then for k,v in pairs(self.Sprites) do SafeRemoveEntity(v) self.Sprites[k] = nil end end self.NextSignals = {} --self.Switches = {} for k,v in ipairs(self.Routes) do if v.NextSignal == "" then self.NextSignals[""] = nil--self elseif v.NextSignal == "*" then else if not v.NextSignal then ErrorNoHalt(Format("Metrostroi: No next signal name in signal %s! Check it now!\n", self.Name)) self.AutostopOverride = true else self.NextSignals[v.NextSignal] = Metrostroi.GetSignalByName(v.NextSignal) if not self.NextSignals[v.NextSignal] then print(Format("Metrostroi: Signal %s, signal not found(%s)", self.Name, v.NextSignal)) self.AutostopOverride = true end end end end self.MU = false for k,v in ipairs(self.Lenses) do if v:find("M") then self.MU = true break end end end function ENT:PostInitalize() if not self.Routes or #self.Routes == 0 then print(self, "NEED SETUP") return end for k,v in ipairs(self.Routes) do if v.NextSignal == "*" and self.TrackPosition then local sig local cursig = self while true do cursig = Metrostroi.GetARSJoint(cursig.TrackPosition.node1,cursig.TrackPosition.x,cursig.TrackDir,false) if not IsValid(cursig) then break end sig = cursig if not cursig.PassOcc then break end end if IsValid(sig) then self.NextSignals["*"] = sig else self.AutostopOverride = true print(Format("Metrostroi: Signal %s, cant automaticly find signal", self.Name)) end end end local pos = self.TrackPosition local node = pos and pos.node1 or nil self.Node = node self.SwitchesFunction = {} self.Switches = {} for i = 1,#self.Routes do if not self.Routes[i].Switches then continue end local Switches = string.Explode(",",self.Routes[i].Switches) local SwitchesTbl = {} --local GoodSwitches = true --Checking all route switches for i1 =1, #Switches do if not Switches[i1] or Switches[i1] == "" then continue end local SwitchState = Switches[i1]:sub(-1,-1) == "-" local SwitchName = Switches[i1]:sub(1,-2) if not Metrostroi.GetSwitchByName(SwitchName) then print(Format("Metrostroi: %s, switch not found(%s)", self.Name, SwitchName)) continue end --If route go right from this switch - add it table.insert(SwitchesTbl,{n = SwitchName,s = SwitchState}) end self.Switches[i] = SwitchesTbl if #SwitchesTbl == 0 then continue end self.SwitchesFunction[i] = function() local GoodSwitches = true for i1 = 1,#self.Switches[i] do if not self.Switches[i][i1] or not IsValid(Metrostroi.GetSwitchByName(self.Switches[i][i1].n)) then continue end if self.Switches[i][i1].s ~= (Metrostroi.GetSwitchByName(self.Switches[i][i1].n):GetSignal() > 0) then GoodSwitches = false break end end return GoodSwitches end end for k,v in pairs(self.Routes) do if not v.Lights then continue end v.LightsExploded = string.Explode("-",v.Lights) end if not self.RouteNumberSetup or not self.RouteNumberSetup:find("W") then self.GoodInvationSignal = 0 local index = 1 for k,v in ipairs(self.Lenses) do if v ~= "M" then for i = 1,#v do if v[i] == "W" then self.GoodInvationSignal = index end index = index + 1 end end end else self.GoodInvationSignal = -1 end if self.Left then self:SetModel(self.TrafficLightModels[self.SignalType or 0].ArsBoxMittor.model) else self:SetModel(self.TrafficLightModels[self.SignalType or 0].ArsBox.model) end self.PostInitalized = false end function ENT:OnRemove() Metrostroi.UpdateSignalEntities() Metrostroi.PostSignalInitialize() end function ENT:GetARS(ARSID,Force1_5,Force2_6) if self.OverrideTrackOccupied then return ARSID == 2 end if not self.ARSSpeedLimit then return false end local nxt = self.ARSNextSpeedLimit == 2 and 0 or self.ARSNextSpeedLimit ~= 1 and self.ARSNextSpeedLimit return self.ARSSpeedLimit == ARSID or ((self.TwoToSix and not Force1_5 or Force2_6) and nxt and nxt == ARSID and self.ARSSpeedLimit > nxt) end --[[ function ENT:GetRS() if not self.TwoToSix or not self.ARSSpeedLimit then return false end --if self.ARSSpeedLimit == 1 or self.ARSSpeedLimit == 2 then return false end if self.ARSSpeedLimit <= 2 then return false end return self.OverrideTrackOccupied or self.ARSSpeedLimit == 0 or (not self.ARSNextSpeedLimit or self.ARSNextSpeedLimit == 1) or self.ARSSpeedLimit <= self.ARSNextSpeedLimit end--]] function ENT:GetRS() if self.OverrideTrackOccupied or not self.TwoToSix or not self.ARSSpeedLimit then return false end --if self.ARSSpeedLimit == 1 or self.ARSSpeedLimit == 2 then return false end if self.ARSSpeedLimit ~= 0 and self.ARSSpeedLimit== 2 then return false end return (self.ARSSpeedLimit > 4 or self.ARSSpeedLimit == 4 and self.Approve0) and (not self.ARSNextSpeedLimit or self.ARSNextSpeedLimit >= self.ARSSpeedLimit) end function ENT:Get325HzAproove0() if self.OverrideTrackOccupied or not self.ARSSpeedLimit then return false end return self.ARSSpeedLimit == 0 and self.Approve0 end function ENT:GetMaxARS() local ARSCodes = self.Routes[1].ARSCodes if not self.Routes[1] or not ARSCodes then return 1 end return tonumber(ARSCodes[#ARSCodes]) or 1 end function ENT:GetMaxARSNext() local Routes = self.NextSignalLink and self.NextSignalLink.Routes or self.Routes local ARSCodes = Routes[1] and Routes[1].ARSCodes local code = tonumber(ARSCodes[#ARSCodes]) or 1 local This = self:GetMaxARS() if not ARSCodes then return This end if code > This then return This end --if not ARSCodes then return 1 end return tonumber(ARSCodes[#ARSCodes]) or 1 end function ENT:CheckOccupation() --print(self.FoundedAll) --if not self.FoundedAll then return end if not self.Close and not self.KGU then --not self.OverrideTrackOccupied and if self.Node and self.TrackPosition then self.Occupied,self.OccupiedBy,self.OccupiedByNow = Metrostroi.IsTrackOccupied(self.Node, self.TrackPosition.x,self.TrackPosition.forward,self.ARSOnly and "ars" or "light", self) end if self.Routes[self.Route] and self.Routes[self.Route].Manual then self.Occupied = self.Occupied or not self.Routes[self.Route].IsOpened end if self.OccupiedByNowOld ~= self.OccupiedByNow then self.InvationSignal = false self.AODisabled = false self.OccupiedByNowOld = self.OccupiedByNow end else self.NextSignalLink = nil self.Occupied = self.Close or self.KGU --self.OverrideTrackOccupied or end end function ENT:ARSLogic(tim) --print(self.FoundedAll) --if not self.FoundedAll then return end if not self.Routes or not self.NextSignals then return end -- Check track occuping if not self.Routes[self.Route or 1].Repeater then self:CheckOccupation() if self.Occupied then if self.Routes[self.Route or 1].Manual then self.Routes[self.Route or 1].IsOpened = false end end if self.Occupied or not self.NextSignalLink or not self.NextSignalLink.FreeBS then self.FreeBS = 0 else self.FreeBS = math.min(30,self.NextSignalLink.FreeBS + 1) -- old 10 freebs - костыль end if self.FreeBS - (self.OldBSState or self.FreeBS) > 1 then local Free = self.FreeBS timer.Simple(tim+0.1,function() if not IsValid(self) then return end if self.NextSignalLink and self.NextSignalLink.FreeBS + 1 - self.OldBSState > 1 then self.FreeBS = Free self.OldBSState = Free end end) self.FreeBS = self.OldBSState end self.OldBSState = self.FreeBS if self.FreeBS == 1 then self.OccupiedBy = self elseif self.FreeBS > 1 then self.AutostopEnt = nil end if self.OccupiedByNow ~= self.AutostopEnt and self.AutostopEnt ~= self.CurrentAutostopEnt then self.AutostopEnt = nil end end if self.OldRoute ~= self.Route then self.InvationSignal = false self.AODisabled = false self.OldRoute = self.Route end --Removing NSL self.NextSignalLink = nil --Set the first route, if no switches in route or no switches --or not self.Switches if #self.Routes == 1 and (self.Routes[1].Switches == "" or not self.Routes[1].Switches) then self.NextSignalLink = self.NextSignals[self.Routes[1].NextSignal] self.Route = 1 else local route --Finding right route for i = 1,#self.Routes do --If all switches right - get this route! if self.SwitchesFunction[i] and self.SwitchesFunction[i]() and (not self.Routes[i].Manual and not self.Routes[i].Emer or self.Routes[i].IsOpened) then --if self.Route ~= i then route = i --self.NextSignalLink = nil --end elseif not self.SwitchesFunction[i] and (not self.Routes[i].Manual and not self.Routes[i].Emer or self.Routes[i].IsOpened) then route = i --self.NextSignalLink = nil end end if self.Route ~= route and (not self.Routes[route] or not self.Routes[route].Emer) then self.Route = route self.NextSignalLink = false else if self.Route ~= route then self.Route = route end self.NextSignalLink = self.Routes[route] and self.NextSignals[self.Routes[route].NextSignal] end end if self.NextSignalLink == nil then if self.Occupied then self.NextSignalLink = self self.FreeBS = 0 --self.Route = 1 end end if self.Routes[self.Route] then if self.Routes[self.Route or 1].Repeater then self.RealName = IsValid(self.NextSignalLink) and self.NextSignalLink.RealName or self.Name else self.RealName = self.Name end if self.Routes[self.Route or 1].Repeater then self.RealName = IsValid(self.NextSignalLink) and self.NextSignalLink.Name or self.Name self.ARSSpeedLimit = IsValid(self.NextSignalLink) and self.NextSignalLink.ARSSpeedLimit or 1 self.ARSNextSpeedLimit = IsValid(self.NextSignalLink) and self.NextSignalLink.ARSNextSpeedLimit or 1 self.FreeBS = IsValid(self.NextSignalLink) and self.NextSignalLink.FreeBS or 0 elseif self.Routes[self.Route].ARSCodes then local ARSCodes = self.Routes[self.Route].ARSCodes self.ARSNextSpeedLimit = IsValid(self.NextSignalLink) and self.NextSignalLink.ARSSpeedLimit or tonumber(ARSCodes[1]) self.ARSSpeedLimit = tonumber(ARSCodes[math.min(#ARSCodes, self.FreeBS+1)]) or 0 if self.AODisabled and self.ARSSpeedLimit ~= 2 then self.AODisabled = false end if (self.InvationSignal or self.AODisabled) and self.ARSSpeedLimit == 2 then self.ARSSpeedLimit = 1 end end end if self.NextSignalLink ~= false and (self.Occupied or not self.NextSignalLink or not self.NextSignalLink.FreeBS) then if self.Routes[self.Route or 1].Manual then self.Routes[self.Route or 1].IsOpened = false end end end function ENT:Think() if self.PostInitalized then return end --DEBUG if Metrostroi.SignalDebugCV:GetBool() then self:SetNW2Bool("Debug",true) local next = self.NextSignalLink local pos = self.TrackPosition local prev = self.PrevSig if next then next.PrevSig = self local nextpos = self.NextSignalLink.TrackPosition self:SetNW2String("NextSignalName",next.Name) if pos and nextpos then self:SetNW2Float("DistanceToNext",nextpos.x - pos.x) else self:SetNW2Float("DistanceToNext",0) end self:SetNW2Int("NextPosID",nextpos and nextpos.path and nextpos.path.id or 0) self:SetNW2Float("NextPos",nextpos and nextpos.x or 0) else self:SetNW2String("NextSignalName","N/A") self:SetNW2Float("DistanceToNext",0) self:SetNW2Float("NextPos",0) self:SetNW2Float("NextPosID",0) end if prev then local prevpos = prev.TrackPosition if pos and prevpos then self:SetNW2Float("DistanceToPrev",-prevpos.x + pos.x) else self:SetNW2Float("DistanceToPrev",0) end self:SetNW2String("PrevSignalName",self.PrevSig.Name) self:SetNW2Int("PrevPosID",prevpos and prevpos.path and prevpos.path.id or 0) self:SetNW2Float("PrevPos",prevpos and prevpos.x or 0) else self:SetNW2String("PrevSignalName","N/A") self:SetNW2Int("PrevPosID",0) self:SetNW2Float("PrevPos",0) end self:SetNW2Float("Pos",pos and pos.x or 0) self:SetNW2Int("PosID",pos and pos.path and pos.path.id or 0) self:SetNW2Bool("CurrentRoute",self.Route or -1) self:SetNW2Bool("Occupied",self.Occupied) self:SetNW2Bool("2/6",self.TwoToSix) self:SetNW2Int("FreeBS",self.FreeBS) self:SetNW2Bool("LinkedToController",self.Controllers ~= nil) self:SetNW2Int("ControllersNumber",self.Controllers ~= nil and #self.Controllers or -1) self:SetNW2Bool("BlockedByController",self.ControllerLogic) for i=0,8 do if i==3 or i==5 then continue end self:SetNW2Bool("CurrentARS"..i,self:GetARS(i)) end self:SetNW2Bool("CurrentARS325",self:GetRS()) self:SetNW2Bool("CurrentARS325_2",self:Get325HzAproove0()) end if not self.ControllerLogic then if not self.Routes or #self.Routes == 0 then ErrorNoHalt(Format("Metrostroi:Signal %s don't have a routes!\n",self.Name)) return end if not self.Routes[self.Route or 1] then ErrorNoHalt(Format("Metrostroi:Signal %s have a null %s route!!\n",self.Name,self.Route)) return end self.PrevTime = self.PrevTime or 0 if (CurTime() - self.PrevTime) > 1.0 then self.PrevTime = CurTime()+math.random(0.5,1.5) self:ARSLogic(self.PrevTime - CurTime()) end self.RouteNumberOverrite = nil local number = "" if self.MU or self.ARSOnly or self.RouteNumberSetup and self.RouteNumberSetup ~= "" or self.RouteNumber and self.RouteNumber ~= "" then if self.NextSignalLink then if not self.NextSignalLink.Red and not self.Red then self.RouteNumberOverrite = self.NextSignalLink.RouteNumberOverrite ~= "" and self.NextSignalLink.RouteNumberOverrite or self.NextSignalLink.RouteNumber else self.RouteNumberOverrite = self.RouteNumber end if (not self.Red or self.InvationSignal) and self.Routes[self.Route or 1].EnRou then if self.NextSignalLink.RouteNumberOverrite then number = number..self.NextSignalLink.RouteNumberOverrite end if self.NextSignalLink.RouteNumber and not self.AutoEnabled then number = number..self.NextSignalLink.RouteNumber end end --print(self.Name,self.NextSignalLink.RouteNumberOverrite) self.RouteNumberOverrite = (self.RouteNumberOverrite or "")..number else self.RouteNumberOverrite = self.RouteNumber end end if self.InvationSignal and self.GoodInvationSignal == -1 then number = number.."W" end if self.KGU then number = number.."K" end if number then self:SetNW2String("Number",number) end if self.ARSOnly then if self.Sprites then for k,v in pairs(self.Sprites) do SafeRemoveEntity(v) self.Sprites[k] = nil end if self.ARSOnly and self.Sprites then self.Sprites = nil end end self:SetNW2String("Signal","") self.AutoEnabled = not self.ARSOnly return end self.AutoEnabled = false self.Red = nil if not self.Routes[self.Route or 1].Lights then return end local Route = self.Routes[self.Route or 1] local index = 1 local offset = self.RenderOffset[self.SignalType] or Vector(0,0,0) self.Sig = "" self.Colors = "" for k,v in ipairs(self.Lenses) do if self.Routes[self.Route or 1].Repeater and IsValid(self.NextSignalLink) and (not self.Routes[self.Route or 1].Lights or self.Routes[self.Route or 1].Lights == "") then break end if v ~= "M" then --get the some models data local data = #v ~= 1 and self.TrafficLightModels[self.SignalType][#v-1] or self.TrafficLightModels[self.SignalType][self.Signal_IS] if not data then continue end for i = 1,#v do --Get the LightID and check, is this light must light up local LightID = IsValid(self.NextSignalLink) and math.min(#Route.LightsExploded,self.FreeBS+1) or 1 local AverageState = Route.LightsExploded[LightID]:find(tostring(index)) or ((v[i] == "W" and self.InvationSignal and self.GoodInvationSignal == index) and 1 or 0) local MustBlink = (v[i] == "W" and self.InvationSignal and self.GoodInvationSignal == index) or (AverageState > 0 and Route.LightsExploded[LightID][AverageState+1] == "b") --Blinking, when next is "b" (or it's invasion signal') self.Sig = self.Sig..(AverageState > 0 and (MustBlink and 2 or 1) or 0) if AverageState > 0 then if self.GoodInvationSignal ~= index then self.Colors = self.Colors..(MustBlink and v[i]:lower() or v[i]:upper()) end if v[i] == "R" then self.AutoEnabled = not self.NonAutoStop self.Red = true end end index = index + 1 end end end else local number = self.RouteNumberReplace or "" --[[self.PrevTime = self.PrevTime or 0 if (CurTime() - self.PrevTime) > 1.0 then self.PrevTime = CurTime()+math.random(0.5,1.5) self:ARSLogic(self.PrevTime - CurTime()) self:CheckOccupation() end]] --[[ if self.MU or self.ARSOnly or self.RouteNumberSetup and self.RouteNumberSetup ~= "" or self.RouteNumber and self.RouteNumber ~= "" then if self.NextSignalLink then if not self.NextSignalLink.AutoEnabled and not self.AutoEnabled then self.RouteNumberOverrite = self.NextSignalLink.RouteNumberOverrite ~= "" and self.NextSignalLink.RouteNumberOverrite or self.NextSignalLink.RouteNumber else self.RouteNumberOverrite = self.RouteNumber end if self.NextSignalLink.RouteNumberOverrite and not self.AutoEnabled and (self.Routes[self.Route or 1].EnRou or self.InvationSignal) then number = number..self.NextSignalLink.RouteNumberOverrite end if self.NextSignalLink.RouteNumber and (self.Routes[self.Route or 1].EnRou and not self.AutoEnabled or self.InvationSignal) then number = number..self.NextSignalLink.RouteNumber end --print(self.Name,self.NextSignalLink.RouteNumberOverrite) self.RouteNumberOverrite = (self.RouteNumberOverrite or "")..number else self.RouteNumberOverrite = self.RouteNumber end end]] if self.InvationSignal and self.GoodInvationSignal == -1 then number = number.."W" end if self.KGU then number = number.."K" end if number then self:SetNW2String("Number",number) end local index = 1 self.Colors = "" for k,v in ipairs(self.Lenses) do if v ~= "M" then --get the some models data local data = #v ~= 1 and self.TrafficLightModels[self.SignalType][#v-1] or self.TrafficLightModels[self.SignalType][self.Signal_IS] if not data then continue end for i = 1,#v do if (self.Sig[index] == "1" or self.Sig[index] == "2") then self.Colors = self.Colors..v[i]:lower() end index = index + 1 end end end end if self.Controllers then for k,v in pairs(self.Controllers) do if self.Sig ~= v.Sig then local Route = self.Routes[self.Route or 1] local LightID = IsValid(self.NextSignalLink) and math.min(#Route.LightsExploded,self.FreeBS+1) or 1 local lights = Route.LightsExploded[LightID] v:TriggerOutput("LenseEnabled",self,Route.LightsExploded[LightID]) v.Sig = self.Sig end if v.OldIS ~= self.InvationSignal then if self.InvationSignal then v:TriggerOutput("LenseEnabled",self,"I") else v:TriggerOutput("LenseDisabled",self,"I") end v.OldIS = self.InvationSignal end end end self:SetNW2String("Signal",self.Sig) if not self.AutostopPresent then self:SetNW2Bool("Autostop",self.AutoEnabled) end self:NextThink(CurTime() + 0.25) return true end --Net functions --Send update, if parameters have been changed function ENT:SendUpdate(ply) net.Start("metrostroi-signal") net.WriteEntity(self) net.WriteInt(self.SignalType or 0,3) net.WriteString(self.Name or "NOT LOADED") net.WriteString(self.ARSOnly and "ARSOnly" or self.LensesStr) net.WriteString(self.SignalType == 0 and self.RouteNumberSetup or "") net.WriteBool(self.Left) net.WriteBool(self.Double) net.WriteBool(self.DoubleL) net.WriteBool(not self.NonAutoStop) if ply then net.Send(ply) else net.Broadcast() end end --On receive update request, we send update net.Receive("metrostroi-signal", function(_, ply) local ent = net.ReadEntity() if not IsValid(ent) or not ent.SendUpdate then return end ent:SendUpdate(ply) end) Metrostroi.OptimisationPatch()