Exemplo n.º 1
0
        public object Clone()
        {
#if TRACE
            Singleton <CodeProfiler> .instance.Start("CustomSegmentLights.Clone");
#endif
            CustomSegmentLights clone = new CustomSegmentLights(nodeId, segmentId);
            foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in CustomLights)
            {
                clone.CustomLights.Add(e.Key, (CustomSegmentLight)e.Value.Clone());
            }
            clone.pedestrianLightState      = pedestrianLightState;
            clone.ManualPedestrianMode      = ManualPedestrianMode;
            clone.VehicleTypes              = new LinkedList <ExtVehicleType>(VehicleTypes);
            clone.LastChangeFrame           = LastChangeFrame;
            clone.autoPedestrianVehicleType = autoPedestrianVehicleType;
            //if (autoPedestrianVehicleType != ExtVehicleType.None) {
            clone.CustomLights.TryGetValue(clone.autoPedestrianVehicleType, out clone.mainSegmentLight);
            //clone.mainSegmentLight = clone.CustomLights[autoPedestrianVehicleType];
            //}
            clone.housekeeping(false);
#if TRACE
            Singleton <CodeProfiler> .instance.Stop("CustomSegmentLights.Clone");
#endif
            return(clone);
        }
Exemplo n.º 2
0
        public CustomSegmentLight(CustomSegmentLights lights, RoadBaseAI.TrafficLightState mainLight)
        {
            this.lights = lights;

            SetStates(mainLight, leftLight, rightLight);
            UpdateVisuals();
        }
        public CustomSegmentLight(CustomSegmentLights lights, ushort nodeId, ushort segmentId, RoadBaseAI.TrafficLightState mainLight)
        {
            this.NodeId    = nodeId;
            this.SegmentId = segmentId;
            this.lights    = lights;

            LightMain  = mainLight;
            LightLeft  = mainLight;
            LightRight = mainLight;

            UpdateVisuals();
        }
		public CustomSegmentLight(CustomSegmentLights lights, ushort nodeId, ushort segmentId, RoadBaseAI.TrafficLightState mainLight, RoadBaseAI.TrafficLightState leftLight, RoadBaseAI.TrafficLightState rightLight/*, RoadBaseAI.TrafficLightState pedestrianLight*/) {
			this.NodeId = nodeId;
			this.SegmentId = segmentId;
			this.lights = lights;

			LightMain = mainLight;
			LightLeft = leftLight;
			LightRight = rightLight;
			//LightPedestrian = pedestrianLight;

			UpdateVisuals();
		}
        public CustomSegmentLight(CustomSegmentLights lights, ushort nodeId, ushort segmentId, RoadBaseAI.TrafficLightState mainLight, RoadBaseAI.TrafficLightState leftLight, RoadBaseAI.TrafficLightState rightLight /*, RoadBaseAI.TrafficLightState pedestrianLight*/)
        {
            this.NodeId    = nodeId;
            this.SegmentId = segmentId;
            this.lights    = lights;

            LightMain  = mainLight;
            LightLeft  = leftLight;
            LightRight = rightLight;

            UpdateVisuals();
        }
		//public bool PedestrianEnabled;

		public CustomSegmentLight(CustomSegmentLights lights, ushort nodeId, ushort segmentId, RoadBaseAI.TrafficLightState mainLight) {
			this.NodeId = nodeId;
			this.SegmentId = segmentId;
			this.lights = lights;

			LightMain = mainLight;
			LightLeft = mainLight;
			LightRight = mainLight;
			/*LightPedestrian = mainLight == RoadBaseAI.TrafficLightState.Green
				? RoadBaseAI.TrafficLightState.Red
				: RoadBaseAI.TrafficLightState.Green;*/

			UpdateVisuals();
		}
Exemplo n.º 7
0
        /// <summary>
        /// Adds a new segment to this step. It is cloned from the live custom traffic light. After adding all steps the method `rebuildSegmentIds` must be called.
        /// </summary>
        /// <param name="segmentId"></param>
        internal void addSegment(ushort segmentId, bool startNode, bool makeRed)
        {
            CustomSegmentLights clonedLights = (CustomSegmentLights)CustomSegmentLightsManager.Instance.GetOrLiveSegmentLights(segmentId, startNode).Clone();

            segmentLights.Add(segmentId, clonedLights);
            if (makeRed)
            {
                segmentLights[segmentId].MakeRed();
            }
            else
            {
                segmentLights[segmentId].MakeRedOrGreen();
            }
            clonedLights.LightsManager = this;
        }
        //public bool PedestrianEnabled;

        public CustomSegmentLight(CustomSegmentLights lights, ushort nodeId, ushort segmentId, RoadBaseAI.TrafficLightState mainLight)
        {
            this.NodeId    = nodeId;
            this.SegmentId = segmentId;
            this.lights    = lights;

            LightMain  = mainLight;
            LightLeft  = mainLight;
            LightRight = mainLight;

            /*LightPedestrian = mainLight == RoadBaseAI.TrafficLightState.Green
             *      ? RoadBaseAI.TrafficLightState.Red
             *      : RoadBaseAI.TrafficLightState.Green;*/

            UpdateVisuals();
        }
Exemplo n.º 9
0
        public static CustomSegmentLights GetOrLiveSegmentLights(ushort nodeId, ushort segmentId)
        {
#if TRACE
            Singleton <CodeProfiler> .instance.Start("CustomTrafficLights.GetOrLiveSegmentLights");
#endif
            if (!IsSegmentLight(nodeId, segmentId))
            {
                AddLiveSegmentLights(nodeId, segmentId);
            }

            CustomSegmentLights ret = GetSegmentLights(nodeId, segmentId);
#if TRACE
            Singleton <CodeProfiler> .instance.Stop("CustomTrafficLights.GetOrLiveSegmentLights");
#endif
            return(ret);
        }
Exemplo n.º 10
0
        internal void SetLights(CustomSegmentLights otherLights)
        {
            foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in otherLights.CustomLights)
            {
                CustomSegmentLight ourLight = null;
                if (!CustomLights.TryGetValue(e.Key, out ourLight))
                {
                    continue;
                }

                ourLight.SetStates(e.Value.LightMain, e.Value.LightLeft, e.Value.LightRight, false);
                //ourLight.LightPedestrian = e.Value.LightPedestrian;
            }
            pedestrianLightState     = otherLights.pedestrianLightState;
            manualPedestrianMode     = otherLights.manualPedestrianMode;
            AutoPedestrianLightState = otherLights.AutoPedestrianLightState;
        }
Exemplo n.º 11
0
        public object Clone()
        {
            CustomSegmentLights clone = new CustomSegmentLights(LightsManager, segmentId, startNode, false);

            foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in CustomLights)
            {
                clone.CustomLights.Add(e.Key, (CustomSegmentLight)e.Value.Clone());
            }
            clone.pedestrianLightState     = pedestrianLightState;
            clone.manualPedestrianMode     = manualPedestrianMode;
            clone.VehicleTypes             = new LinkedList <ExtVehicleType>(VehicleTypes);
            clone.LastChangeFrame          = LastChangeFrame;
            clone.mainSegmentLight         = mainSegmentLight;
            clone.AutoPedestrianLightState = AutoPedestrianLightState;
            clone.housekeeping(false, false);
            return(clone);
        }
Exemplo n.º 12
0
        internal void SetLights(CustomSegmentLights otherLights)
        {
#if TRACE
            Singleton <CodeProfiler> .instance.Start("CustomSegmentLights.SetLights");
#endif
            foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in otherLights.CustomLights)
            {
                CustomSegmentLight ourLight = null;
                if (!CustomLights.TryGetValue(e.Key, out ourLight))
                {
                    continue;
                }

                ourLight.LightMain  = e.Value.LightMain;
                ourLight.LightLeft  = e.Value.LightLeft;
                ourLight.LightRight = e.Value.LightRight;
                //ourLight.LightPedestrian = e.Value.LightPedestrian;
            }
            pedestrianLightState = otherLights.pedestrianLightState;
            ManualPedestrianMode = otherLights.ManualPedestrianMode;
#if TRACE
            Singleton <CodeProfiler> .instance.Stop("CustomSegmentLights.SetLights");
#endif
        }
Exemplo n.º 13
0
        /*public static TimedTrafficLights AddTimedLight(ushort nodeid, List<ushort> nodeGroup, bool vehiclesMayEnterBlockedJunctions) {
         *      TimedScripts.Add(nodeid, new TimedTrafficLights(nodeid, nodeGroup, vehiclesMayEnterBlockedJunctions));
         *      return TimedScripts[nodeid];
         * }
         *
         * public static void RemoveTimedLight(ushort nodeid) {
         *      TimedScripts.Remove(nodeid);
         * }
         *
         * public static bool IsTimedLight(ushort nodeid) {
         *      return TimedScripts.ContainsKey(nodeid);
         * }
         *
         * public static TimedTrafficLights GetTimedLight(ushort nodeid) {
         *      if (!IsTimedLight(nodeid))
         *              return null;
         *      return TimedScripts[nodeid];
         * }
         *
         * internal static void OnLevelUnloading() {
         *      TimedScripts.Clear();
         * }*/

        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;
                    }
                    CustomTrafficLights.AddLiveSegmentLights(NodeId, segmentId);
                }

                return;
            }

            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      = true;

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

                    if (fromSegmentId == segmentId)
                    {
                        isNewSegment = false;
                    }

                    if (!TrafficPriority.IsPrioritySegment(NodeId, fromSegmentId))
                    {
                        invalidSegmentIds.Add(fromSegmentId);
                    }
                }

                if (isNewSegment)
                {
                    Log._Debug($"New segment detected: {segmentId} @ {NodeId}");
                    // segment was created
                    CustomTrafficLights.AddLiveSegmentLights(NodeId, segmentId);
                    TrafficPriority.AddPrioritySegment(NodeId, segmentId, SegmentEnd.PriorityType.None);

                    if (invalidSegmentIds.Count > 0)
                    {
                        var oldSegmentId = invalidSegmentIds[0];
                        TrafficPriority.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)
                        {
                            CustomSegmentLights segmentLights = Steps[i].segmentLights[oldSegmentId];
                            Steps[i].segmentLights.Remove(oldSegmentId);
                            segmentLights.SegmentId = segmentId;
                            Steps[i].segmentLights.Add(segmentId, segmentLights);
                            Steps[i].calcMaxSegmentLength();
                            CustomSegmentLights liveSegLights = CustomTrafficLights.GetSegmentLights(NodeId, segmentId);
                            foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e in segmentLights.CustomLights)
                            {
                                CustomSegmentLight liveSegLight = liveSegLights.GetCustomLight(e.Key);
                                if (liveSegLight == null)
                                {
                                    continue;
                                }
                                liveSegLight.CurrentMode = e.Value.CurrentMode;
                            }
                        }
                    }
                    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();
                        }
                    }
                }
            }
        }
Exemplo n.º 14
0
        internal void CalculateAutoPedestrianLightState(bool propagate = true)
        {
            //Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Calculating pedestrian light state of node {NodeId}");
            SegmentGeometry    segGeo             = SegmentGeometry.Get(SegmentId);
            SegmentEndGeometry segmentEndGeometry = StartNode ? segGeo.StartNodeGeometry : segGeo.EndNodeGeometry;

            if (segmentEndGeometry == null)
            {
                Log._Debug($"Could not get SegmentEndGeometry for segment {SegmentId} @ {NodeId}.");
                AutoPedestrianLightState = RoadBaseAI.TrafficLightState.Green;
                return;
            }
            ushort nodeId = segmentEndGeometry.NodeId();

            if (propagate)
            {
                foreach (ushort otherSegmentId in segmentEndGeometry.ConnectedSegments)
                {
                    if (otherSegmentId == 0)
                    {
                        continue;
                    }

                    CustomSegmentLights otherLights = LightsManager.GetSegmentLights(nodeId, otherSegmentId);
                    if (otherLights == null)
                    {
                        //Log._Debug($"Expected other (propagate) CustomSegmentLights at segment {otherSegmentId} @ {NodeId} but there was none. Original segment id: {SegmentId}");
                        continue;
                    }

                    otherLights.CalculateAutoPedestrianLightState(false);
                }
            }

            if (IsAnyGreen())
            {
                //Log._Debug($"Any green at seg. {SegmentId} @ {NodeId}");
                AutoPedestrianLightState = RoadBaseAI.TrafficLightState.Red;
                return;
            }

            //Log._Debug($"Querying incoming segments at seg. {SegmentId} @ {NodeId}");
            RoadBaseAI.TrafficLightState autoPedestrianLightState = RoadBaseAI.TrafficLightState.Green;

            if (!segmentEndGeometry.IncomingOneWay)
            {
                // query straight segments
                foreach (ushort otherSegmentId in segmentEndGeometry.IncomingStraightSegments)
                {
                    if (otherSegmentId == 0)
                    {
                        continue;
                    }
                    //Log._Debug($"Checking incoming straight segment {otherSegmentId} at seg. {SegmentId} @ {NodeId}");

                    CustomSegmentLights otherLights = LightsManager.GetSegmentLights(nodeId, otherSegmentId);
                    if (otherLights == null)
                    {
                        //Log._Debug($"Expected other (straight) CustomSegmentLights at segment {otherSegmentId} @ {NodeId} but there was none. Original segment id: {SegmentId}");
                        continue;
                    }

                    if (!otherLights.IsAllMainRed())
                    {
                        //Log._Debug($"Not all main red at {otherSegmentId} at seg. {SegmentId} @ {NodeId}");
                        autoPedestrianLightState = RoadBaseAI.TrafficLightState.Red;
                        break;
                    }
                }

                // query left/right segments
                if (autoPedestrianLightState == RoadBaseAI.TrafficLightState.Green)
                {
                    bool lhd = TrafficPriorityManager.IsLeftHandDrive();
                    foreach (ushort otherSegmentId in lhd ? segmentEndGeometry.IncomingLeftSegments : segmentEndGeometry.IncomingRightSegments)
                    {
                        if (otherSegmentId == 0)
                        {
                            continue;
                        }

                        //Log._Debug($"Checking left/right segment {otherSegmentId} at seg. {SegmentId} @ {NodeId}");

                        CustomSegmentLights otherLights = LightsManager.GetSegmentLights(nodeId, otherSegmentId);
                        if (otherLights == null)
                        {
                            //Log._Debug($"Expected other (left/right) CustomSegmentLights at segment {otherSegmentId} @ {NodeId} but there was none. Original segment id: {SegmentId}");
                            continue;
                        }

                        if ((lhd && !otherLights.IsAllRightRed()) || (!lhd && !otherLights.IsAllLeftRed()))
                        {
                            //Log._Debug($"Not all left red at {otherSegmentId} at seg. {SegmentId} @ {NodeId}");
                            autoPedestrianLightState = RoadBaseAI.TrafficLightState.Red;
                            break;
                        }
                    }
                }
            }

            AutoPedestrianLightState = autoPedestrianLightState;
            //Log.Warning($"Calculated AutoPedestrianLightState for segment {SegmentId} @ {NodeId}: {AutoPedestrianLightState}");
        }
		internal void SetLights(CustomSegmentLights otherLights) {
			foreach (KeyValuePair<ExtVehicleType, CustomSegmentLight> e in otherLights.CustomLights) {
				CustomSegmentLight ourLight = null;
				if (!CustomLights.TryGetValue(e.Key, out ourLight))
					continue;

				ourLight.LightMain = e.Value.LightMain;
				ourLight.LightLeft = e.Value.LightLeft;
				ourLight.LightRight = e.Value.LightRight;
				//ourLight.LightPedestrian = e.Value.LightPedestrian;
			}
			pedestrianLightState = otherLights.pedestrianLightState;
			ManualPedestrianMode = otherLights.ManualPedestrianMode;
		}
        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);
        }
		private bool RenderCounter(int segmentId, Vector3 screenPos, float modeWidth, float modeHeight, float zoom,
			CustomSegmentLights segmentLights, bool hoveredSegment) {
			SetAlpha(segmentId, 0);

			var myRectCounter = new Rect(screenPos.x - modeWidth / 2, screenPos.y - modeHeight / 2 - 6f * zoom, modeWidth, modeHeight);

			GUI.DrawTexture(myRectCounter, TrafficLightToolTextureResources.LightCounterTexture2D);

			var counterSize = 20f * zoom;

			var counter = segmentLights.LastChange();

			var myRectCounterNum = new Rect(screenPos.x - counterSize + 15f * zoom + (counter >= 10 ? -5 * zoom : 0f),
				screenPos.y - counterSize + 11f * zoom, counterSize, counterSize);

			_counterStyle.fontSize = (int)(18f * zoom);
			_counterStyle.normal.textColor = new Color(1f, 1f, 1f);

			GUI.Label(myRectCounterNum, counter.ToString(), _counterStyle);

			if (!myRectCounter.Contains(Event.current.mousePosition))
				return hoveredSegment;
			_hoveredButton[0] = segmentId;
			_hoveredButton[1] = 0;
			return true;
		}
		private bool RenderManualPedestrianLightSwitch(float zoom, int segmentId, Vector3 screenPos, float lightWidth,
			CustomSegmentLights segmentLights, bool hoveredSegment) {
			if (segmentLights.PedestrianLightState == null)
				return false;

			var guiColor = GUI.color;
			var manualPedestrianWidth = 36f * zoom;
			var manualPedestrianHeight = 35f * zoom;

			guiColor.a = _hoveredButton[0] == segmentId && (_hoveredButton[1] == 1 || _hoveredButton[1] == 2) ? 0.92f : 0.6f;

			GUI.color = guiColor;

			var myRect2 = new Rect(screenPos.x - manualPedestrianWidth / 2 - lightWidth + 5f * zoom,
				screenPos.y - manualPedestrianHeight / 2 - 9f * zoom, manualPedestrianWidth, manualPedestrianHeight);

			GUI.DrawTexture(myRect2, segmentLights.ManualPedestrianMode ? TrafficLightToolTextureResources.PedestrianModeManualTexture2D : TrafficLightToolTextureResources.PedestrianModeAutomaticTexture2D);

			if (!myRect2.Contains(Event.current.mousePosition))
				return hoveredSegment;

			_hoveredButton[0] = segmentId;
			_hoveredButton[1] = 1;

			if (!Input.GetMouseButtonDown(0) || mouseClickProcessed)
				return true;

			mouseClickProcessed = true;
			segmentLights.ManualPedestrianMode = true;
			return true;
		}
		private bool IsPedestrianLightHovered(Rect myRect3, int segmentId, bool hoveredSegment, CustomSegmentLights segmentLights) {
			if (!myRect3.Contains(Event.current.mousePosition))
				return hoveredSegment;
			if (segmentLights.PedestrianLightState == null)
				return false;

			_hoveredButton[0] = segmentId;
			_hoveredButton[1] = 2;

			if (!Input.GetMouseButtonDown(0) || mouseClickProcessed)
				return true;
			mouseClickProcessed = true;

			if (!segmentLights.ManualPedestrianMode) {
				segmentLights.ManualPedestrianMode = true;
			} else {
				segmentLights.ChangeLightPedestrian();
			}
			return true;
		}
        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 object Clone() {
			CustomSegmentLights clone = new CustomSegmentLights(nodeId, segmentId);
			foreach (KeyValuePair<ExtVehicleType, CustomSegmentLight> e in CustomLights) {
				clone.CustomLights.Add(e.Key, (CustomSegmentLight)e.Value.Clone());
			}
			clone.pedestrianLightState = pedestrianLightState;
			clone.ManualPedestrianMode = ManualPedestrianMode;
			clone.VehicleTypes = new LinkedList<ExtVehicleType>(VehicleTypes);
			clone.LastChangeFrame = LastChangeFrame;
			clone.autoPedestrianVehicleType = autoPedestrianVehicleType;
			//if (autoPedestrianVehicleType != ExtVehicleType.None) {
			clone.CustomLights.TryGetValue(clone.autoPedestrianVehicleType, out clone.mainSegmentLight);
			//clone.mainSegmentLight = clone.CustomLights[autoPedestrianVehicleType];
			//}
			clone.housekeeping(false);
			return clone;
		}