Пример #1
0
        public bool CustomCheckTrafficLights(ushort node, ushort segment)
        {
            var nodeSimulation = Options.timedLightsEnabled ? TrafficLightSimulationManager.Instance().GetNodeSimulation(node) : null;

            var instance          = Singleton <NetManager> .instance;
            var currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex;

            var num  = (uint)((node << 8) / 32768);
            var num2 = currentFrameIndex - num & 255u;

            // NON-STOCK CODE START //
            RoadBaseAI.TrafficLightState pedestrianLightState;
            CustomSegmentLights          lights = CustomTrafficLightsManager.Instance().GetSegmentLights(node, segment);

            if (lights == null || nodeSimulation == null || !nodeSimulation.IsSimulationActive())
            {
                RoadBaseAI.TrafficLightState vehicleLightState;
                bool vehicles;
                bool pedestrians;

                RoadBaseAI.GetTrafficLightState(node, ref instance.m_segments.m_buffer[segment], currentFrameIndex - num, out vehicleLightState, out pedestrianLightState, out vehicles, out pedestrians);
                if ((pedestrianLightState == RoadBaseAI.TrafficLightState.GreenToRed || pedestrianLightState == RoadBaseAI.TrafficLightState.Red) && !pedestrians && num2 >= 196u)
                {
                    RoadBaseAI.SetTrafficLightState(node, ref instance.m_segments.m_buffer[segment], currentFrameIndex - num, vehicleLightState, pedestrianLightState, vehicles, true);
                    return(true);
                }
            }
            else
            {
                if (lights.InvalidPedestrianLight)
                {
                    pedestrianLightState = RoadBaseAI.TrafficLightState.Green;
                }
                else
                {
                    pedestrianLightState = (RoadBaseAI.TrafficLightState)lights.PedestrianLightState;
                }
            }
            // NON-STOCK CODE END //

            switch (pedestrianLightState)
            {
            case RoadBaseAI.TrafficLightState.RedToGreen:
                if (num2 < 60u)
                {
                    return(false);
                }
                break;

            case RoadBaseAI.TrafficLightState.Red:
            case RoadBaseAI.TrafficLightState.GreenToRed:
                return(false);
            }
            return(true);
        }
Пример #2
0
        public void OnUpdate(NodeGeometry nodeGeometry)
        {
#if DEBUG
            Log._Debug($"TrafficLightSimulation: OnUpdate @ node {NodeId} ({nodeGeometry.NodeId})");
#endif

            if (!Flags.mayHaveTrafficLight(NodeId))
            {
                Log.Warning($"Housekeeping: Node {NodeId} has traffic light simulation but must not have a traffic light!");
                TrafficLightSimulationManager.Instance().RemoveNodeFromSimulation(NodeId, false, true);
            }

            if (!IsManualLight() && !IsTimedLight())
            {
                return;
            }

            if (!nodeGeometry.IsValid())
            {
                // node has become invalid. Remove manual/timed traffic light and destroy custom lights
                TrafficLightSimulationManager.Instance().RemoveNodeFromSimulation(NodeId, false, false);
                return;
            }

            CustomTrafficLightsManager customTrafficLightsManager = CustomTrafficLightsManager.Instance();

            for (var s = 0; s < 8; s++)
            {
                var segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[NodeId].GetSegment(s);

                if (segmentId == 0)
                {
                    continue;
                }

#if DEBUG
                Log._Debug($"TrafficLightSimulation: OnUpdate @ node {NodeId}: Adding live traffic lights to segment {segmentId}");
#endif

                // add custom lights
                if (!customTrafficLightsManager.IsSegmentLight(NodeId, segmentId))
                {
                    customTrafficLightsManager.AddSegmentLights(NodeId, segmentId);
                }

                // housekeep timed light
                customTrafficLightsManager.GetSegmentLights(NodeId, segmentId).housekeeping(true);
            }

            // ensure there is a physical traffic light
            Flags.setNodeTrafficLight(NodeId, true);

            TimedLight?.handleNewSegments();
            TimedLight?.housekeeping();
        }
Пример #3
0
 /// <summary>
 /// Adds a new segment to this step. After adding all steps the method `rebuildSegmentIds` must be called.
 /// </summary>
 /// <param name="segmentId"></param>
 internal void addSegment(ushort segmentId, bool makeRed)
 {
     segmentLights.Add(segmentId, (CustomSegmentLights)CustomTrafficLightsManager.Instance().GetOrLiveSegmentLights(timedNode.NodeId, segmentId).Clone());
     if (makeRed)
     {
         segmentLights[segmentId].MakeRed();
     }
     else
     {
         segmentLights[segmentId].MakeRedOrGreen();
     }
 }
Пример #4
0
        private void destroyLiveSegments()
        {
            CustomTrafficLightsManager customTrafficLightsManager = CustomTrafficLightsManager.Instance();

            for (var s = 0; s < 8; s++)
            {
                var segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[NodeId].GetSegment(s);

                if (segmentId == 0)
                {
                    continue;
                }
                if (customTrafficLightsManager.IsSegmentLight(NodeId, segmentId))
                {
                    customTrafficLightsManager.RemoveSegmentLight(NodeId, segmentId);
                }
            }
        }
Пример #5
0
        private void setupLiveSegments()
        {
            CustomTrafficLightsManager customTrafficLightsManager = CustomTrafficLightsManager.Instance();

            for (var s = 0; s < 8; s++)
            {
                var segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[NodeId].GetSegment(s);

                if (segmentId == 0)
                {
                    continue;
                }
                //SegmentGeometry.Get(segmentId)?.Recalculate(true, true);
                if (!customTrafficLightsManager.IsSegmentLight(NodeId, segmentId))
                {
                    customTrafficLightsManager.AddSegmentLights(NodeId, segmentId);
                }
            }
        }
Пример #6
0
        private void RenderManualNodeOverlays(RenderManager.CameraInfo cameraInfo)
        {
            var nodeSimulation = TrafficLightSimulationManager.Instance().GetNodeSimulation(SelectedNodeId);
            CustomTrafficLightsManager customTrafficLightsManager = CustomTrafficLightsManager.Instance();

            for (var i = 0; i < 8; i++)
            {
                var    colorGray = new Color(0.25f, 0.25f, 0.25f, 0.25f);
                ushort segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[SelectedNodeId].GetSegment(i);

                if (segmentId == 0 ||
                    (nodeSimulation != null && customTrafficLightsManager.IsSegmentLight(SelectedNodeId, segmentId)))
                {
                    continue;
                }

                var position = CalculateNodePositionForSegment(Singleton <NetManager> .instance.m_nodes.m_buffer[SelectedNodeId], segmentId);

                var width = _hoveredButton[0] == segmentId ? 11.25f : 10f;
                MainTool.DrawOverlayCircle(cameraInfo, colorGray, position, width, segmentId != _hoveredButton[0]);
            }
        }
Пример #7
0
        /// <summary>
        /// Updates timed segment lights according to "real-world" traffic light states
        /// </summary>
        public void UpdateLights()
        {
#if TRACE
            Singleton <CodeProfiler> .instance.Start("TimedTrafficLightsStep.UpdateLights");
#endif
            foreach (KeyValuePair <ushort, CustomSegmentLights> e in segmentLights)
            {
                var segmentId = e.Key;
                var segLights = e.Value;

                //if (segment == 0) continue;
                var liveSegLights = CustomTrafficLightsManager.Instance().GetSegmentLights(timedNode.NodeId, segmentId);
                if (liveSegLights == null)
                {
                    continue;
                }

                segLights.SetLights(liveSegLights);
            }
#if TRACE
            Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.UpdateLights");
#endif
        }
        public void Start()
        {
            /*if (!housekeeping())
             *      return;*/

            CustomTrafficLightsManager customTrafficLightsManager = CustomTrafficLightsManager.Instance();

            for (int s = 0; s < 8; ++s)
            {
                ushort segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[NodeId].GetSegment(s);
                if (segmentId == 0)
                {
                    continue;
                }
                bool needsAlwaysGreenPedestrian = true;
                foreach (TimedTrafficLightsStep step in Steps)
                {
                    if (!step.segmentLights.ContainsKey(segmentId))
                    {
                        continue;
                    }
                    if (step.segmentLights[segmentId].PedestrianLightState == RoadBaseAI.TrafficLightState.Green)
                    {
                        needsAlwaysGreenPedestrian = false;
                        break;
                    }
                }

                customTrafficLightsManager.GetOrLiveSegmentLights(NodeId, segmentId).InvalidPedestrianLight = needsAlwaysGreenPedestrian;
            }

            CurrentStep = 0;
            Steps[0].Start();
            Steps[0].SetLights();

            started = true;
        }
Пример #9
0
        public override void OnToolGUI(Event e)
        {
            var hoveredSegment = false;

            if (SelectedNodeId != 0)
            {
                CustomTrafficLightsManager    customTrafficLightsManager = CustomTrafficLightsManager.Instance();
                TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance();

                var nodeSimulation = tlsMan.GetNodeSimulation(SelectedNodeId);
                nodeSimulation.housekeeping();

                /*if (Singleton<NetManager>.instance.m_nodes.m_buffer[SelectedNode].CountSegments() == 2) {
                 *      _guiManualTrafficLightsCrosswalk(ref Singleton<NetManager>.instance.m_nodes.m_buffer[SelectedNode]);
                 *      return;
                 * }*/// TODO check

                for (var i = 0; i < 8; i++)
                {
                    var segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[SelectedNodeId].GetSegment(i);

                    if (segmentId == 0 || nodeSimulation == null ||
                        !customTrafficLightsManager.IsSegmentLight(SelectedNodeId, segmentId))
                    {
                        continue;
                    }

                    var position      = CalculateNodePositionForSegment(Singleton <NetManager> .instance.m_nodes.m_buffer[SelectedNodeId], ref Singleton <NetManager> .instance.m_segments.m_buffer[segmentId]);
                    var segmentLights = customTrafficLightsManager.GetSegmentLights(SelectedNodeId, segmentId);

                    var screenPos = Camera.main.WorldToScreenPoint(position);
                    screenPos.y = Screen.height - screenPos.y;

                    if (screenPos.z < 0)
                    {
                        continue;
                    }

                    var diff = position - Camera.main.transform.position;
                    var zoom = 1.0f / diff.magnitude * 100f;

                    // original / 2.5
                    var lightWidth  = 41f * zoom;
                    var lightHeight = 97f * zoom;

                    var pedestrianWidth  = 36f * zoom;
                    var pedestrianHeight = 61f * zoom;

                    // SWITCH MODE BUTTON
                    var modeWidth  = 41f * zoom;
                    var modeHeight = 38f * zoom;

                    var guiColor = GUI.color;

                    if (segmentLights.PedestrianLightState != null)
                    {
                        // pedestrian light

                        // SWITCH MANUAL PEDESTRIAN LIGHT BUTTON
                        hoveredSegment = RenderManualPedestrianLightSwitch(zoom, segmentId, screenPos, lightWidth, segmentLights, hoveredSegment);

                        // SWITCH PEDESTRIAN LIGHT
                        guiColor.a = _hoveredButton[0] == segmentId && _hoveredButton[1] == 2 && segmentLights.ManualPedestrianMode ? 0.92f : 0.6f;
                        GUI.color  = guiColor;

                        var myRect3 = new Rect(screenPos.x - pedestrianWidth / 2 - lightWidth + 5f * zoom, screenPos.y - pedestrianHeight / 2 + 22f * zoom, pedestrianWidth, pedestrianHeight);

                        switch (segmentLights.PedestrianLightState)
                        {
                        case RoadBaseAI.TrafficLightState.Green:
                            GUI.DrawTexture(myRect3, TrafficLightToolTextureResources.PedestrianGreenLightTexture2D);
                            break;

                        case RoadBaseAI.TrafficLightState.Red:
                        default:
                            GUI.DrawTexture(myRect3, TrafficLightToolTextureResources.PedestrianRedLightTexture2D);
                            break;
                        }

                        hoveredSegment = IsPedestrianLightHovered(myRect3, segmentId, hoveredSegment, segmentLights);
                    }

                    int lightOffset = -1;
                    foreach (ExtVehicleType vehicleType in segmentLights.VehicleTypes)
                    {
                        ++lightOffset;
                        CustomSegmentLight segmentLight = segmentLights.GetCustomLight(vehicleType);

                        Vector3 offsetScreenPos = screenPos;
                        offsetScreenPos.y -= (lightHeight + 10f * zoom) * lightOffset;

                        SetAlpha(segmentId, -1);

                        var myRect1 = new Rect(offsetScreenPos.x - modeWidth / 2, offsetScreenPos.y - modeHeight / 2 + modeHeight - 7f * zoom, modeWidth, modeHeight);

                        GUI.DrawTexture(myRect1, TrafficLightToolTextureResources.LightModeTexture2D);

                        hoveredSegment = GetHoveredSegment(myRect1, segmentId, hoveredSegment, segmentLight);

                        // COUNTER
                        hoveredSegment = RenderCounter(segmentId, offsetScreenPos, modeWidth, modeHeight, zoom, segmentLights, hoveredSegment);

                        if (lightOffset > 0)
                        {
                            // Info sign
                            var infoWidth  = 56.125f * zoom;
                            var infoHeight = 51.375f * zoom;

                            int numInfos = 0;
                            for (int k = 0; k < TrafficManagerTool.InfoSignsToDisplay.Length; ++k)
                            {
                                if ((TrafficManagerTool.InfoSignsToDisplay[k] & vehicleType) == ExtVehicleType.None)
                                {
                                    continue;
                                }
                                var infoRect = new Rect(offsetScreenPos.x + modeWidth / 2f + 7f * zoom * (float)(numInfos + 1) + infoWidth * (float)numInfos, offsetScreenPos.y - infoHeight / 2f, infoWidth, infoHeight);
                                guiColor.a = 0.6f;
                                GUI.DrawTexture(infoRect, TrafficLightToolTextureResources.VehicleInfoSignTextures[TrafficManagerTool.InfoSignsToDisplay[k]]);
                                ++numInfos;
                            }
                        }

                        SegmentGeometry geometry  = SegmentGeometry.Get(segmentId);
                        bool            startNode = geometry.StartNodeId() == SelectedNodeId;

                        if (geometry.IsOutgoingOneWay(startNode))
                        {
                            continue;
                        }

                        var hasLeftSegment    = geometry.HasLeftSegment(startNode);
                        var hasForwardSegment = geometry.HasStraightSegment(startNode);
                        var hasRightSegment   = geometry.HasRightSegment(startNode);

                        switch (segmentLight.CurrentMode)
                        {
                        case CustomSegmentLight.Mode.Simple:
                            hoveredSegment = SimpleManualSegmentLightMode(segmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment);
                            break;

                        case CustomSegmentLight.Mode.SingleLeft:
                            hoveredSegment = LeftForwardRManualSegmentLightMode(hasLeftSegment, segmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment, hasForwardSegment, hasRightSegment);
                            break;

                        case CustomSegmentLight.Mode.SingleRight:
                            hoveredSegment = RightForwardLSegmentLightMode(segmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, hasForwardSegment, hasLeftSegment, segmentLight, hasRightSegment, hoveredSegment);
                            break;

                        default:
                            // left arrow light
                            if (hasLeftSegment)
                            {
                                hoveredSegment = LeftArrowLightMode(segmentId, lightWidth, hasRightSegment, hasForwardSegment, offsetScreenPos, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment);
                            }

                            // forward arrow light
                            if (hasForwardSegment)
                            {
                                hoveredSegment = ForwardArrowLightMode(segmentId, lightWidth, hasRightSegment, offsetScreenPos, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment);
                            }

                            // right arrow light
                            if (hasRightSegment)
                            {
                                hoveredSegment = RightArrowLightMode(segmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment);
                            }
                            break;
                        }
                    }
                }
            }

            if (hoveredSegment)
            {
                return;
            }
            _hoveredButton[0] = 0;
            _hoveredButton[1] = 0;
        }
        internal void handleNewSegments()
        {
            if (NumSteps() <= 0)
            {
                // no steps defined, just create live traffic lights

                /*for (int s = 0; s < 8; ++s) {
                 *      ushort segmentId = Singleton<NetManager>.instance.m_nodes.m_buffer[NodeId].GetSegment(s);
                 *      if (segmentId <= 0)
                 *              continue;
                 *      if (! CustomTrafficLights.IsSegmentLight(NodeId, segmentId))
                 *              CustomTrafficLights.AddSegmentLights(NodeId, segmentId);
                 * }*/


                return;
            }

            CustomTrafficLightsManager customTrafficLightsManager = CustomTrafficLightsManager.Instance();
            TrafficPriorityManager     prioMan = TrafficPriorityManager.Instance();

            for (int s = 0; s < 8; ++s)
            {
                ushort segmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[NodeId].GetSegment(s);
                if (segmentId <= 0)
                {
                    continue;
                }

                List <ushort> invalidSegmentIds = new List <ushort>();
                bool          isNewSegment      = !Steps[0].segmentLights.ContainsKey(segmentId);

                if (isNewSegment)
                {
                    // segment was created
                    Log._Debug($"New segment detected: {segmentId} @ {NodeId}");

                    foreach (KeyValuePair <ushort, CustomSegmentLights> e in Steps[0].segmentLights)
                    {
                        var fromSegmentId = e.Key;

                        if (!prioMan.IsPrioritySegment(NodeId, fromSegmentId))
                        {
                            Log._Debug($"Identified old segment {fromSegmentId} @ {NodeId}");
                            invalidSegmentIds.Add(fromSegmentId);
                        }
                    }

                    Log._Debug($"Setting up segment end for new segment {segmentId} @ {NodeId}");
                    SetupSegmentEnd(segmentId);

                    if (invalidSegmentIds.Count > 0)
                    {
                        var oldSegmentId = invalidSegmentIds[0];
                        prioMan.RemovePrioritySegment(NodeId, oldSegmentId);
                        Log._Debug($"Replacing old segment {oldSegmentId} @ {NodeId} with new segment {segmentId}");

                        // replace the old segment with the newly created one
                        for (int i = 0; i < NumSteps(); ++i)
                        {
                            if (!Steps[i].segmentLights.ContainsKey(oldSegmentId))
                            {
                                Log.Error($"Step {i} at node {NodeId} does not contain step lights for old segment {oldSegmentId}");
                                Steps[i].addSegment(segmentId, true);
                                Steps[i].calcMaxSegmentLength();
                                continue;
                            }

                            CustomSegmentLights customLights = Steps[i].segmentLights[oldSegmentId];
                            Log._Debug($"Removing old segment {oldSegmentId} @ {NodeId} from step {i}");
                            Steps[i].segmentLights.Remove(oldSegmentId);
                            Log._Debug($"Setting new segment id {segmentId} at custom light from step {i}");
                            customLights.SegmentId = segmentId;
                            Steps[i].segmentLights.Add(segmentId, customLights);
                            Steps[i].calcMaxSegmentLength();
                            Log._Debug($"Getting live segment lights of new segment {segmentId} @ {NodeId} and applying mode @ step {i}");
                            CustomSegmentLights liveSegLights = customTrafficLightsManager.GetSegmentLights(NodeId, segmentId);
                            if (liveSegLights == null)
                            {
                                Log.Error($"No live segment lights for seg. {segmentId} @ node {NodeId} found!");
                                customTrafficLightsManager.AddSegmentLights(NodeId, segmentId);
                                liveSegLights = customTrafficLightsManager.GetSegmentLights(NodeId, segmentId);
                            }

                            foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in customLights.CustomLights)
                            {
                                CustomSegmentLight liveSegLight = liveSegLights.GetCustomLight(e.Key);
                                if (liveSegLight == null)
                                {
                                    continue;
                                }
                                Log._Debug($"Updating live segment light mode of new segment {segmentId} @ {NodeId} for vehicle type {e.Key} @ step {i}");
                                liveSegLight.CurrentMode = e.Value.CurrentMode;
                            }
                            Log._Debug($"Finished applying new segment {segmentId} @ {NodeId} @ step {i}");
                        }
                    }
                    else
                    {
                        Log._Debug($"Adding new segment {segmentId} to node {NodeId}");

                        // create a new manual light
                        for (int i = 0; i < NumSteps(); ++i)
                        {
                            Steps[i].addSegment(segmentId, true);
                            Steps[i].calcMaxSegmentLength();
                        }
                    }
                }
            }
        }
        public long CheckNextChange(ushort segmentId, ExtVehicleType vehicleType, int lightType)
        {
            var curStep   = CurrentStep;
            var nextStep  = (CurrentStep + 1) % NumSteps();
            var numFrames = Steps[CurrentStep].MaxTimeRemaining();

            RoadBaseAI.TrafficLightState currentState;
            CustomSegmentLights          segmentLights = CustomTrafficLightsManager.Instance().GetSegmentLights(NodeId, segmentId);

            if (segmentLights == null)
            {
                Log._Debug($"CheckNextChange: No segment lights at node {NodeId}, segment {segmentId}");
                return(99);
            }
            CustomSegmentLight segmentLight = segmentLights.GetCustomLight(vehicleType);

            if (segmentLight == null)
            {
                Log._Debug($"CheckNextChange: No segment light at node {NodeId}, segment {segmentId}");
                return(99);
            }

            if (lightType == 0)
            {
                currentState = segmentLight.GetLightMain();
            }
            else if (lightType == 1)
            {
                currentState = segmentLight.GetLightLeft();
            }
            else if (lightType == 2)
            {
                currentState = segmentLight.GetLightRight();
            }
            else
            {
                currentState = segmentLights.PedestrianLightState == null ? RoadBaseAI.TrafficLightState.Red : (RoadBaseAI.TrafficLightState)segmentLights.PedestrianLightState;
            }


            while (true)
            {
                if (nextStep == curStep)
                {
                    numFrames = 99;
                    break;
                }

                var light = Steps[nextStep].GetLight(segmentId, vehicleType, lightType);

                if (light != currentState)
                {
                    break;
                }
                else
                {
                    numFrames += Steps[nextStep].maxTime;
                }

                nextStep = (nextStep + 1) % NumSteps();
            }

            return(numFrames);
        }
Пример #12
0
        public void SetLights(bool noTransition)
        {
#if TRACE
            Singleton <CodeProfiler> .instance.Start("TimedTrafficLightsStep.SetLights");
#endif
            try {
                CustomTrafficLightsManager customTrafficLightsManager = CustomTrafficLightsManager.Instance();

                bool atEndTransition   = !noTransition && (isInEndTransition() || isEndTransitionDone());            // = yellow
                bool atStartTransition = !noTransition && !atEndTransition && isInStartTransition();                 // = red + yellow

#if DEBUG
                if (timedNode == null)
                {
                    Log.Error($"TimedTrafficLightsStep: timedNode is null!");
#if TRACE
                    Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                    return;
                }
#endif

                TimedTrafficLightsStep previousStep = timedNode.Steps[(timedNode.CurrentStep + timedNode.Steps.Count - 1) % timedNode.Steps.Count];
                TimedTrafficLightsStep nextStep     = timedNode.Steps[(timedNode.CurrentStep + 1) % timedNode.Steps.Count];

#if DEBUG
                if (previousStep == null)
                {
                    Log.Error($"TimedTrafficLightsStep: previousStep is null!");
#if TRACE
                    Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                    return;
                }

                if (nextStep == null)
                {
                    Log.Error($"TimedTrafficLightsStep: nextStep is null!");
#if TRACE
                    Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                    return;
                }

                if (previousStep.segmentLights == null)
                {
                    Log.Error($"TimedTrafficLightsStep: previousStep.segmentLights is null!");
                    return;
                }

                if (nextStep.segmentLights == null)
                {
                    Log.Error($"TimedTrafficLightsStep: nextStep.segmentLights is null!");
#if TRACE
                    Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                    return;
                }

                if (segmentLights == null)
                {
                    Log.Error($"TimedTrafficLightsStep: segmentLights is null!");
#if TRACE
                    Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                    return;
                }
#endif

#if DEBUG
                //Log._Debug($"TimedTrafficLightsStep.SetLights({noTransition}) called for NodeId={timedNode.NodeId}. atStartTransition={atStartTransition} atEndTransition={atEndTransition}");
#endif

                foreach (KeyValuePair <ushort, CustomSegmentLights> e in segmentLights)
                {
                    var segmentId            = e.Key;
                    var curStepSegmentLights = e.Value;

#if DEBUG
                    //Log._Debug($"TimedTrafficLightsStep.SetLights({noTransition})   -> segmentId={segmentId} @ NodeId={timedNode.NodeId}");
#endif

                    if (!previousStep.segmentLights.ContainsKey(segmentId))
                    {
#if DEBUG
                        Log._Debug($"TimedTrafficLightsStep: previousStep does not contain lights for segment {segmentId}!");
#endif
                        continue;
                    }

                    if (!nextStep.segmentLights.ContainsKey(segmentId))
                    {
#if DEBUG
                        Log._Debug($"TimedTrafficLightsStep: nextStep does not contain lights for segment {segmentId}!");
#endif
                        continue;
                    }

                    var prevStepSegmentLights = previousStep.segmentLights[segmentId];
                    var nextStepSegmentLights = nextStep.segmentLights[segmentId];

                    //segLightState.makeRedOrGreen(); // TODO temporary fix

                    var liveSegmentLights = customTrafficLightsManager.GetOrLiveSegmentLights(timedNode.NodeId, segmentId);
                    if (liveSegmentLights == null)
                    {
                        continue;
                    }

                    if (curStepSegmentLights.PedestrianLightState != null && prevStepSegmentLights.PedestrianLightState != null && nextStepSegmentLights.PedestrianLightState != null)
                    {
                        RoadBaseAI.TrafficLightState pedLightState = calcLightState((RoadBaseAI.TrafficLightState)prevStepSegmentLights.PedestrianLightState, (RoadBaseAI.TrafficLightState)curStepSegmentLights.PedestrianLightState, (RoadBaseAI.TrafficLightState)nextStepSegmentLights.PedestrianLightState, atStartTransition, atEndTransition);
                        //Log._Debug($"TimedStep.SetLights: Setting pedestrian light state @ seg. {segmentId} to {pedLightState} {curStepSegmentLights.ManualPedestrianMode}");
                        liveSegmentLights.ManualPedestrianMode = curStepSegmentLights.ManualPedestrianMode;
                        liveSegmentLights.PedestrianLightState = pedLightState;
                        //Log._Debug($"Step @ {timedNode.NodeId}: Segment {segmentId}: Ped.: {liveSegmentLights.PedestrianLightState.ToString()}");
                    }

#if DEBUG
                    if (curStepSegmentLights.VehicleTypes == null)
                    {
                        Log.Error($"TimedTrafficLightsStep: curStepSegmentLights.VehicleTypes is null!");
#if TRACE
                        Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                        return;
                    }
#endif

                    foreach (ExtVehicleType vehicleType in curStepSegmentLights.VehicleTypes)
                    {
#if DEBUG
                        //Log._Debug($"TimedTrafficLightsStep.SetLights({noTransition})     -> segmentId={segmentId} @ NodeId={timedNode.NodeId} for vehicle {vehicleType}");
#endif

                        CustomSegmentLight liveSegmentLight = liveSegmentLights.GetCustomLight(vehicleType);
                        if (liveSegmentLight == null)
                        {
#if DEBUG
                            Log._Debug($"Timed step @ seg. {segmentId}, node {timedNode.NodeId} has a traffic light for {vehicleType} but the live segment does not have one.");
#endif
                            continue;
                        }
                        CustomSegmentLight curStepSegmentLight  = curStepSegmentLights.GetCustomLight(vehicleType);
                        CustomSegmentLight prevStepSegmentLight = prevStepSegmentLights.GetCustomLight(vehicleType);
                        CustomSegmentLight nextStepSegmentLight = nextStepSegmentLights.GetCustomLight(vehicleType);
#if DEBUG
                        if (curStepSegmentLight == null)
                        {
                            Log.Error($"TimedTrafficLightsStep: curStepSegmentLight is null!");
#if TRACE
                            Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                            return;
                        }

                        if (prevStepSegmentLight == null)
                        {
                            Log.Error($"TimedTrafficLightsStep: prevStepSegmentLight is null!");
#if TRACE
                            Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                            return;
                        }

                        if (nextStepSegmentLight == null)
                        {
                            Log.Error($"TimedTrafficLightsStep: nextStepSegmentLight is null!");
#if TRACE
                            Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
                            return;
                        }
#endif

                        liveSegmentLight.CurrentMode = curStepSegmentLight.CurrentMode;
                        liveSegmentLight.LightMain   = calcLightState(prevStepSegmentLight.LightMain, curStepSegmentLight.LightMain, nextStepSegmentLight.LightMain, atStartTransition, atEndTransition);
                        liveSegmentLight.LightLeft   = calcLightState(prevStepSegmentLight.LightLeft, curStepSegmentLight.LightLeft, nextStepSegmentLight.LightLeft, atStartTransition, atEndTransition);
                        liveSegmentLight.LightRight  = calcLightState(prevStepSegmentLight.LightRight, curStepSegmentLight.LightRight, nextStepSegmentLight.LightRight, atStartTransition, atEndTransition);

#if DEBUG
                        //Log._Debug($"TimedTrafficLightsStep.SetLights({noTransition})     -> *SETTING* LightLeft={liveSegmentLight.LightLeft} LightMain={liveSegmentLight.LightMain} LightRight={liveSegmentLight.LightRight} for segmentId={segmentId} @ NodeId={timedNode.NodeId} for vehicle {vehicleType}");
#endif

                        //Log._Debug($"Step @ {timedNode.NodeId}: Segment {segmentId} for vehicle type {vehicleType}: L: {liveSegmentLight.LightLeft.ToString()} F: {liveSegmentLight.LightMain.ToString()} R: {liveSegmentLight.LightRight.ToString()}");
                    }

                    /*if (timedNode.NodeId == 20164) {
                     *      Log._Debug($"Step @ {timedNode.NodeId}: Segment {segmentId}: {segmentLight.LightLeft.ToString()} {segmentLight.LightMain.ToString()} {segmentLight.LightRight.ToString()} {segmentLight.LightPedestrian.ToString()}");
                     * }*/

                    liveSegmentLights.UpdateVisuals();
                }
            } catch (Exception e) {
                Log.Error($"Exception in TimedTrafficStep.SetLights: {e.ToString()}");
                //invalid = true;
            }
#if TRACE
            Singleton <CodeProfiler> .instance.Stop("TimedTrafficLightsStep.SetLights");
#endif
        }