Example #1
0
        public void OnUpdate(NodeGeometry nodeGeometry)
        {
#if DEBUG
            Log._Debug($"TrafficLightSimulation: OnUpdate @ node {NodeId} ({nodeGeometry.NodeId})");
#endif

            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;
            }

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

            CustomSegmentLightsManager customTrafficLightsManager = CustomSegmentLightsManager.Instance;

            foreach (SegmentEndGeometry end in nodeGeometry.SegmentEndGeometries)
            {
                if (end == null)
                {
                    continue;
                }

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

                // add custom lights

                /*if (!customTrafficLightsManager.IsSegmentLight(end.SegmentId, end.StartNode)) {
                 *      customTrafficLightsManager.AddSegmentLights(end.SegmentId, end.StartNode);
                 * }*/

                // housekeep timed light
                customTrafficLightsManager.GetSegmentLights(end.SegmentId, end.StartNode).housekeeping(true, true);
            }

            // ensure there is a physical traffic light
            TrafficLightManager.Instance.AddTrafficLight(NodeId);

            TimedLight?.handleNewSegments();
            TimedLight?.housekeeping();
        }
        private void ClearInvalidPedestrianLights()
        {
            CustomSegmentLightsManager customTrafficLightsManager = CustomSegmentLightsManager.Instance;

            NodeGeometry nodeGeometry = NodeGeometry.Get(NodeId);

            //Log._Debug($"Checking for invalid pedestrian lights @ {NodeId}.");
            foreach (SegmentEndGeometry end in nodeGeometry.SegmentEndGeometries)
            {
                if (end == null)
                {
                    continue;
                }

                customTrafficLightsManager.GetSegmentLights(end.SegmentId, end.StartNode).InvalidPedestrianLight = false;
            }
        }
        private void CheckInvalidPedestrianLights()
        {
            CustomSegmentLightsManager customTrafficLightsManager = CustomSegmentLightsManager.Instance;
            NodeGeometry nodeGeometry = NodeGeometry.Get(NodeId);

            //Log._Debug($"Checking for invalid pedestrian lights @ {NodeId}.");
            foreach (SegmentEndGeometry end in nodeGeometry.SegmentEndGeometries)
            {
                if (end == null)
                {
                    continue;
                }

                //Log._Debug($"Checking seg. {segmentId} @ {NodeId}.");
                bool needsAlwaysGreenPedestrian = true;
                int  i = 0;
                foreach (TimedTrafficLightsStep step in Steps)
                {
                    //Log._Debug($"Checking step {i}, seg. {segmentId} @ {NodeId}.");
                    if (!step.segmentLights.ContainsKey(end.SegmentId))
                    {
                        //Log._Debug($"Step {i} @ {NodeId} does not contain a segment light for seg. {segmentId}.");
                        ++i;
                        continue;
                    }
                    //Log._Debug($"Checking step {i}, seg. {segmentId} @ {NodeId}: {step.segmentLights[segmentId].PedestrianLightState} (pedestrianLightState={step.segmentLights[segmentId].pedestrianLightState}, ManualPedestrianMode={step.segmentLights[segmentId].ManualPedestrianMode}, AutoPedestrianLightState={step.segmentLights[segmentId].AutoPedestrianLightState}");
                    if (step.segmentLights[end.SegmentId].PedestrianLightState == RoadBaseAI.TrafficLightState.Green)
                    {
                        //Log._Debug($"Step {i} @ {NodeId} has a green ped. light @ seg. {segmentId}.");
                        needsAlwaysGreenPedestrian = false;
                        break;
                    }
                    ++i;
                }
                //Log._Debug($"Setting InvalidPedestrianLight of seg. {segmentId} @ {NodeId} to {needsAlwaysGreenPedestrian}.");
                customTrafficLightsManager.GetSegmentLights(end.SegmentId, end.StartNode).InvalidPedestrianLight = needsAlwaysGreenPedestrian;
            }
        }
        public override void OnToolGUI(Event e)
        {
            IExtSegmentManager    segMan    = Constants.ManagerFactory.ExtSegmentManager;
            IExtSegmentEndManager segEndMan = Constants.ManagerFactory.ExtSegmentEndManager;
            var hoveredSegment = false;

            if (SelectedNodeId != 0)
            {
                CustomSegmentLightsManager    customTrafficLightsManager = CustomSegmentLightsManager.Instance;
                TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance;
                JunctionRestrictionsManager   junctionRestrictionsManager = JunctionRestrictionsManager.Instance;

                if (!tlsMan.HasManualSimulation(SelectedNodeId))
                {
                    return;
                }

                tlsMan.TrafficLightSimulations[SelectedNodeId].Housekeeping();

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

                for (int i = 0; i < 8; ++i)
                {
                    ushort segmentId = nodesBuffer[SelectedNodeId].GetSegment(i);
                    if (segmentId == 0)
                    {
                        continue;
                    }

                    bool startNode =
                        (bool)Constants.ServiceFactory.NetService.IsStartNode(
                            segmentId,
                            SelectedNodeId);
                    Vector3 position = CalculateNodePositionForSegment(
                        nodesBuffer[SelectedNodeId],
                        ref segmentsBuffer[segmentId]);
                    ICustomSegmentLights segmentLights =
                        customTrafficLightsManager.GetSegmentLights(segmentId, startNode, false);

                    if (segmentLights == null)
                    {
                        continue;
                    }

                    bool showPedLight = segmentLights.PedestrianLightState != null &&
                                        junctionRestrictionsManager.IsPedestrianCrossingAllowed(
                        segmentLights.SegmentId,
                        segmentLights.StartNode);
                    bool visible = MainTool.WorldToScreenPoint(position, out Vector3 screenPos);

                    if (!visible)
                    {
                        continue;
                    }

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

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

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

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

                    Color guiColor = GUI.color;

                    if (showPedLight)
                    {
                        // pedestrian light

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

                        // SWITCH PEDESTRIAN LIGHT
                        guiColor.a = TrafficManagerTool.GetHandleAlpha(
                            hoveredButton[0] == segmentId && hoveredButton[1] == 2 &&
                            segmentLights.ManualPedestrianMode);
                        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,
                                TrafficLightTextures.PedestrianGreenLight);
                            break;
                        }

                        // also: case RoadBaseAI.TrafficLightState.Red:
                        default: {
                            GUI.DrawTexture(
                                myRect3,
                                TrafficLightTextures.PedestrianRedLight);
                            break;
                        }
                        }

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

                    int lightOffset = -1;

                    foreach (ExtVehicleType vehicleType in segmentLights.VehicleTypes)
                    {
                        ++lightOffset;
                        ICustomSegmentLight 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, TrafficLightTextures.LightMode);

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

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

                        if (vehicleType != ExtVehicleType.None)
                        {
                            // Info sign
                            float infoWidth  = 56.125f * zoom;
                            float 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 = TrafficManagerTool.GetHandleAlpha(false);

                                GUI.DrawTexture(
                                    infoRect,
                                    RoadUITextures.VehicleInfoSignTextures[TrafficManagerTool.InfoSignsToDisplay[k]]);

                                ++numInfos;
                            }
                        }

                        ExtSegment    seg    = segMan.ExtSegments[segmentId];
                        ExtSegmentEnd segEnd =
                            segEndMan.ExtSegmentEnds[segEndMan.GetIndex(segmentId, startNode)];
                        if (seg.oneWay && segEnd.outgoing)
                        {
                            continue;
                        }

                        segEndMan.CalculateOutgoingLeftStraightRightSegments(
                            ref segEnd,
                            ref nodesBuffer[segmentId],
                            out bool hasLeftSegment,
                            out bool hasForwardSegment,
                            out bool hasRightSegment);

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

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

                        case LightMode.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;
                        }
                        } // end switch
                    }     // end foreach all vehicle type
                }         // end for all 8 segments
            }             // end if a node is selected

            if (hoveredSegment)
            {
                return;
            }

            hoveredButton[0] = 0;
            hoveredButton[1] = 0;
        }
Example #5
0
        public override void OnToolGUI(Event e)
        {
            var hoveredSegment = false;

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

                var nodeSimulation = tlsMan.GetNodeSimulation(SelectedNodeId);
                if (nodeSimulation == null || !nodeSimulation.IsManualLight())
                {
                    return;
                }
                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

                NodeGeometry nodeGeometry = NodeGeometry.Get(SelectedNodeId);
                foreach (SegmentEndGeometry end in nodeGeometry.SegmentEndGeometries)
                {
                    if (end == null)
                    {
                        continue;
                    }

                    var position      = CalculateNodePositionForSegment(Singleton <NetManager> .instance.m_nodes.m_buffer[SelectedNodeId], ref Singleton <NetManager> .instance.m_segments.m_buffer[end.SegmentId]);
                    var segmentLights = customTrafficLightsManager.GetSegmentLights(end.SegmentId, end.StartNode, false);
                    if (segmentLights == null)
                    {
                        continue;
                    }

                    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, end.SegmentId, screenPos, lightWidth, segmentLights, hoveredSegment);

                        // SWITCH PEDESTRIAN LIGHT
                        guiColor.a = _hoveredButton[0] == end.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, end.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(end.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, end.SegmentId, hoveredSegment, segmentLight);

                        // COUNTER
                        hoveredSegment = RenderCounter(end.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;
                            }
                        }

                        if (end.OutgoingOneWay)
                        {
                            continue;
                        }

                        var hasLeftSegment    = end.NumLeftSegments > 0;
                        var hasForwardSegment = end.NumStraightSegments > 0;
                        var hasRightSegment   = end.NumRightSegments > 0;

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

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

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

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

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

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

            if (hoveredSegment)
            {
                return;
            }
            _hoveredButton[0] = 0;
            _hoveredButton[1] = 0;
        }
Example #6
0
        public void UpdateLiveLights(bool noTransition)
        {
            try {
                CustomSegmentLightsManager customTrafficLightsManager = CustomSegmentLightsManager.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!");
                    return;
                }
#endif

                if (PreviousStepRefIndex >= timedNode.NumSteps())
                {
                    PreviousStepRefIndex = -1;
                }
                if (NextStepRefIndex >= timedNode.NumSteps())
                {
                    NextStepRefIndex = -1;
                }
                TimedTrafficLightsStep previousStep = timedNode.Steps[PreviousStepRefIndex >= 0 ? PreviousStepRefIndex : ((timedNode.CurrentStep + timedNode.Steps.Count - 1) % timedNode.Steps.Count)];
                TimedTrafficLightsStep nextStep     = timedNode.Steps[NextStepRefIndex >= 0 ? NextStepRefIndex : ((timedNode.CurrentStep + 1) % timedNode.Steps.Count)];

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

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

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

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

                if (segmentLights == null)
                {
                    Log.Error($"TimedTrafficLightsStep: segmentLights is null!");
                    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.GetSegmentLights(segmentId, curStepSegmentLights.StartNode, false);
                    if (liveSegmentLights == null)
                    {
                        continue;
                    }

                    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 = liveSegmentLights.AutoPedestrianLightState = pedLightState;
                    //Log.Warning($"Step @ {timedNode.NodeId}: Segment {segmentId}: Ped.: {liveSegmentLights.PedestrianLightState.ToString()} / {liveSegmentLights.AutoPedestrianLightState.ToString()}");

#if DEBUG
                    if (curStepSegmentLights.VehicleTypes == null)
                    {
                        Log.Error($"TimedTrafficLightsStep: curStepSegmentLights.VehicleTypes is null!");
                        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!");
                            return;
                        }

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

                        if (nextStepSegmentLight == null)
                        {
                            Log.Error($"TimedTrafficLightsStep: nextStepSegmentLight is null!");
                            return;
                        }
#endif

                        liveSegmentLight.currentMode = curStepSegmentLight.CurrentMode;

                        /*curStepSegmentLight.EnsureModeLights();
                         * prevStepSegmentLight.EnsureModeLights();
                         * nextStepSegmentLight.EnsureModeLights();*/

                        RoadBaseAI.TrafficLightState mainLight  = calcLightState(prevStepSegmentLight.LightMain, curStepSegmentLight.LightMain, nextStepSegmentLight.LightMain, atStartTransition, atEndTransition);
                        RoadBaseAI.TrafficLightState leftLight  = calcLightState(prevStepSegmentLight.LightLeft, curStepSegmentLight.LightLeft, nextStepSegmentLight.LightLeft, atStartTransition, atEndTransition);
                        RoadBaseAI.TrafficLightState rightLight = calcLightState(prevStepSegmentLight.LightRight, curStepSegmentLight.LightRight, nextStepSegmentLight.LightRight, atStartTransition, atEndTransition);
                        liveSegmentLight.SetStates(mainLight, leftLight, rightLight, false);

#if DEBUGTTL
                        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 for node {timedNode.NodeId}: {e.ToString()}");
                //invalid = true;
            }
        }
        internal void handleNewSegments()
        {
            Log._Debug($"TimedTrafficLights.handleNewSegments: called for timed traffic light @ {NodeId}");
            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);
                 * }*/

                Log._Debug($"TimedTrafficLights.handleNewSegments: no steps @ {NodeId}");
                return;
            }

            CustomSegmentLightsManager customTrafficLightsManager = CustomSegmentLightsManager.Instance;
            TrafficPriorityManager     prioMan = TrafficPriorityManager.Instance;

            NodeGeometry nodeGeometry = NodeGeometry.Get(NodeId);

            //Log._Debug($"Checking for invalid pedestrian lights @ {NodeId}.");
            foreach (SegmentEndGeometry end in nodeGeometry.SegmentEndGeometries)
            {
                if (end == null)
                {
                    continue;
                }
                Log._Debug($"TimedTrafficLights.handleNewSegments: handling existing seg. {end.SegmentId} @ {NodeId}");

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

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

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

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

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

                    if (invalidSegmentIds.Count > 0)
                    {
                        var oldSegmentId = invalidSegmentIds[0];
                        prioMan.RemovePrioritySegment(NodeId, oldSegmentId);
                        Log._Debug($"Replacing old segment {oldSegmentId} @ {NodeId} with new segment {end.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(end.SegmentId, end.StartNode, 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 {end.SegmentId} at custom light from step {i}");
                            customLights.Relocate(end.SegmentId, end.StartNode);
                            Steps[i].segmentLights.Add(end.SegmentId, customLights);
                            Steps[i].calcMaxSegmentLength();
                            Log._Debug($"Getting live segment lights of new segment {end.SegmentId} @ {NodeId} and applying mode @ step {i}");
                            CustomSegmentLights liveSegLights = customTrafficLightsManager.GetSegmentLights(end.SegmentId, end.StartNode);

                            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 {end.SegmentId} @ {NodeId} for vehicle type {e.Key} @ step {i}");
                                liveSegLight.CurrentMode = e.Value.CurrentMode;
                            }
                            Log._Debug($"Finished applying new segment {end.SegmentId} @ {NodeId} @ step {i}");
                        }
                    }
                    else
                    {
                        Log._Debug($"Adding new segment {end.SegmentId} to node {NodeId}");

                        // create a new manual light
                        for (int i = 0; i < NumSteps(); ++i)
                        {
                            Steps[i].addSegment(end.SegmentId, end.StartNode, true);
                            Steps[i].calcMaxSegmentLength();
                        }
                    }
                }
            }
        }