public override void OnLoadData()
        {
            Log.Info("Loading Traffic Manager: PE Data");
            StateLoading = true;
            bool loadingSucceeded = true;

            try {
                Log.Info("Initializing flags");
                Flags.OnBeforeLoadData();
            } catch (Exception e) {
                Log.Error($"OnLoadData: Error while initializing Flags: {e.ToString()}");
                loadingSucceeded = false;
            }

            try {
                Log.Info("Initializing node geometries");
                NodeGeometry.OnBeforeLoadData();
            } catch (Exception e) {
                Log.Error($"OnLoadData: Error while initializing NodeGeometry: {e.ToString()}");
                loadingSucceeded = false;
            }

            try {
                Log.Info("Initializing segment geometries");
                SegmentGeometry.OnBeforeLoadData();
            } catch (Exception e) {
                Log.Error($"OnLoadData: Error while initializing SegmentGeometry: {e.ToString()}");
                loadingSucceeded = false;
            }

            foreach (ICustomManager manager in LoadingExtension.RegisteredManagers)
            {
                try {
                    Log.Info($"OnBeforeLoadData: {manager.GetType().Name}");
                    manager.OnBeforeLoadData();
                } catch (Exception e) {
                    Log.Error($"OnLoadData: Error while initializing {manager.GetType().Name}: {e.ToString()}");
                    loadingSucceeded = false;
                }
            }

            Log.Info("Initialization done. Loading mod data now.");

            try {
                byte[] data = _serializableData.LoadData(DataId);
                DeserializeData(data);
            } catch (Exception e) {
                Log.Error($"OnLoadData: Error while deserializing data: {e.ToString()}");
                loadingSucceeded = false;
            }

            // load options
            try {
                byte[] options = _serializableData.LoadData("TMPE_Options");
                if (options != null)
                {
                    if (!OptionsManager.Instance.LoadData(options))
                    {
                        loadingSucceeded = false;
                    }
                }
            } catch (Exception e) {
                Log.Error($"OnLoadData: Error while loading options: {e.ToString()}");
                loadingSucceeded = false;
            }

            if (loadingSucceeded)
            {
                Log.Info("OnLoadData completed successfully.");
            }
            else
            {
                Log.Info("An error occurred while loading.");
                //UIView.library.ShowModal<ExceptionPanel>("ExceptionPanel").SetMessage("An error occurred while loading", "Traffic Manager: President Edition detected an error while loading. Please do NOT save this game under the old filename, otherwise your timed traffic lights, custom lane arrows, etc. are in danger. Instead, please navigate to http://steamcommunity.com/sharedfiles/filedetails/?id=583429740 and follow the steps under 'In case problems arise'.", true);
            }

            StateLoading = false;

            foreach (ICustomManager manager in LoadingExtension.RegisteredManagers)
            {
                try {
                    Log.Info($"OnAfterLoadData: {manager.GetType().Name}");
                    manager.OnAfterLoadData();
                } catch (Exception e) {
                    Log.Error($"OnLoadData: Error while initializing {manager.GetType().Name}: {e.ToString()}");
                    loadingSucceeded = false;
                }
            }
        }
        public override void OnToolGUI(Event e)
        {
            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();

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

                    bool showPedLight = segmentLights.PedestrianLightState != null && junctionRestrictionsManager.IsPedestrianCrossingAllowed(segmentLights.SegmentId, segmentLights.StartNode);

                    Vector3 screenPos;
                    bool    visible = MainTool.WorldToScreenPoint(position, out screenPos);

                    if (!visible)
                    {
                        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 (showPedLight)
                    {
                        // pedestrian light

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

                        // SWITCH PEDESTRIAN LIGHT
                        guiColor.a = MainTool.GetHandleAlpha(_hoveredButton[0] == end.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, TextureResources.PedestrianGreenLightTexture2D);
                            break;

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

                        hoveredSegment = IsPedestrianLightHovered(myRect3, end.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(end.SegmentId, -1);

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

                        GUI.DrawTexture(myRect1, TextureResources.LightModeTexture2D);

                        hoveredSegment = GetHoveredSegment(myRect1, end.SegmentId, hoveredSegment, segmentLight);

                        // COUNTER
                        hoveredSegment = RenderCounter(end.SegmentId, offsetScreenPos, modeWidth, modeHeight, zoom, segmentLights, hoveredSegment);

                        if (vehicleType != ExtVehicleType.None)
                        {
                            // 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 = MainTool.GetHandleAlpha(false);
                                GUI.DrawTexture(infoRect, TextureResources.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 LightMode.Simple:
                            hoveredSegment = SimpleManualSegmentLightMode(end.SegmentId, offsetScreenPos, lightWidth, pedestrianWidth, zoom, lightHeight, segmentLight, hoveredSegment);
                            break;

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

                        case LightMode.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;
        }
예제 #3
0
 protected override void HandleValidNode(NodeGeometry geometry)
 {
     Flags.applyNodeTrafficLightFlag(geometry.NodeId);
 }
예제 #4
0
        public void ShowGUI(bool viewOnly)
        {
            try {
                TrafficLightSimulationManager tlsMan  = TrafficLightSimulationManager.Instance;
                TrafficPriorityManager        prioMan = TrafficPriorityManager.Instance;
                TrafficLightManager           tlm     = TrafficLightManager.Instance;

                Vector3 camPos = Constants.ServiceFactory.SimulationService.CameraPosition;

                bool clicked = !viewOnly?MainTool.CheckClicked() : false;

                ushort removedNodeId    = 0;
                bool   showRemoveButton = false;
                foreach (ushort nodeId in currentPriorityNodeIds)
                {
                    if (!Constants.ServiceFactory.NetService.IsNodeValid(nodeId))
                    {
                        continue;
                    }

                    if (!MainTool.IsNodeWithinViewDistance(nodeId))
                    {
                        continue;
                    }

                    NodeGeometry nodeGeo = NodeGeometry.Get(nodeId);

                    Vector3 nodePos = default(Vector3);
                    Constants.ServiceFactory.NetService.ProcessNode(nodeId, delegate(ushort nId, ref NetNode node) {
                        nodePos = node.m_position;
                        return(true);
                    });

                    foreach (SegmentEndGeometry endGeo in nodeGeo.SegmentEndGeometries)
                    {
                        if (endGeo == null)
                        {
                            continue;
                        }
                        if (endGeo.OutgoingOneWay)
                        {
                            continue;
                        }
                        ushort segmentId = endGeo.SegmentId;
                        bool   startNode = endGeo.StartNode;

                        // calculate sign position
                        Vector3 signPos = nodePos;

                        Constants.ServiceFactory.NetService.ProcessSegment(segmentId, delegate(ushort sId, ref NetSegment segment) {
                            signPos += 10f * (startNode ? segment.m_startDirection : segment.m_endDirection);
                            return(true);
                        });

                        Vector3 signScreenPos;
                        if (!MainTool.WorldToScreenPoint(ref signPos, out signScreenPos))
                        {
                            continue;
                        }

                        // draw sign and handle input
                        PriorityType sign = prioMan.GetPrioritySign(segmentId, startNode);
                        if (viewOnly && sign == PriorityType.None)
                        {
                            continue;
                        }
                        if (!viewOnly && sign != PriorityType.None)
                        {
                            showRemoveButton = true;
                        }

                        if (MainTool.DrawGenericSquareOverlayTexture(TextureResources.PrioritySignTextures[sign], ref camPos, ref signPos, 90f, !viewOnly, 0.5f, 0.8f) && clicked)
                        {
                            PriorityType?newSign = null;
                            switch (sign)
                            {
                            case PriorityType.Main:
                                newSign = PriorityType.Yield;
                                break;

                            case PriorityType.Yield:
                                newSign = PriorityType.Stop;
                                break;

                            case PriorityType.Stop:
                                newSign = PriorityType.Main;
                                break;

                            case PriorityType.None:
                            default:
                                newSign = prioMan.CountPrioritySignsAtNode(nodeId, PriorityType.Main) >= 2 ? PriorityType.Yield : PriorityType.Main;
                                break;
                            }

                            if (newSign != null)
                            {
                                SetPrioritySign(segmentId, startNode, (PriorityType)newSign);
                            }
                        }                 // draw sign
                    }                     // foreach segment end

                    if (viewOnly)
                    {
                        continue;
                    }

                    // draw remove button and handle click
                    if (showRemoveButton && MainTool.DrawHoverableSquareOverlayTexture(TextureResources.SignRemoveTexture2D, ref camPos, ref nodePos, 90f, 0.5f, 0.8f) && clicked)
                    {
                        prioMan.RemovePrioritySignsFromNode(nodeId);
                        Log._Debug($"PrioritySignsTool.ShowGUI: Removed priority signs from node {nodeId}");
                        removedNodeId = nodeId;
                    }
                }                 // foreach node

                if (removedNodeId != 0)
                {
                    currentPriorityNodeIds.Remove(removedNodeId);
                    SelectedNodeId = 0;
                }
            } catch (Exception e) {
                Log.Error(e.ToString());
            }
        }
 protected override void HandleInvalidNode(NodeGeometry geometry)
 {
     RemoveNodeFromSimulation(geometry.NodeId, false, true);
 }
예제 #6
0
 protected override void HandleInvalidNode(NodeGeometry geometry)
 {
     Flags.resetTrafficLight(geometry.NodeId);
 }
        /// <summary>
        /// Recalculates lane arrows based on present lane connections.
        /// </summary>
        /// <param name="laneId"></param>
        /// <param name="nodeId"></param>
        private void RecalculateLaneArrows(uint laneId, ushort nodeId, bool startNode)
        {
#if DEBUGCONN
            bool debug = GlobalConfig.Instance.Debug.Switches[23];
            if (debug)
            {
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}) called");
            }
#endif
            if (!Options.laneConnectorEnabled)
            {
                return;
            }

            if (!Flags.mayHaveLaneArrows(laneId, startNode))
            {
#if DEBUGCONN
                if (debug)
                {
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): lane {laneId}, startNode? {startNode} must not have lane arrows");
                }
#endif
                return;
            }

            if (!HasConnections(laneId, startNode))
            {
#if DEBUGCONN
                if (debug)
                {
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): lane {laneId} does not have outgoing connections");
                }
#endif
                return;
            }

            if (nodeId == 0)
            {
#if DEBUGCONN
                if (debug)
                {
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): invalid node");
                }
#endif
                return;
            }

            Flags.LaneArrows arrows = Flags.LaneArrows.None;

            NetManager netManager = Singleton <NetManager> .instance;
            ushort     segmentId  = netManager.m_lanes.m_buffer[laneId].m_segment;

            if (segmentId == 0)
            {
#if DEBUGCONN
                if (debug)
                {
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): invalid segment");
                }
#endif
                return;
            }

#if DEBUGCONN
            if (debug)
            {
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): startNode? {startNode}");
            }
#endif

            NodeGeometry nodeGeo = NodeGeometry.Get(nodeId);
            if (!nodeGeo.IsValid())
            {
#if DEBUGCONN
                if (debug)
                {
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): invalid node geometry");
                }
#endif
                return;
            }

            SegmentGeometry segmentGeo = SegmentGeometry.Get(segmentId);
            if (segmentGeo == null)
            {
#if DEBUGCONN
                if (debug)
                {
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): invalid segment geometry");
                }
#endif
                return;
            }

            ushort[] connectedSegmentIds = segmentGeo.GetConnectedSegments(startNode);
            if (connectedSegmentIds == null)
            {
#if DEBUGCONN
                if (debug)
                {
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): connectedSegmentIds is null");
                }
#endif
                return;
            }
            ushort[] allSegmentIds = new ushort[connectedSegmentIds.Length + 1];
            allSegmentIds[0] = segmentId;
            Array.Copy(connectedSegmentIds, 0, allSegmentIds, 1, connectedSegmentIds.Length);

            foreach (ushort otherSegmentId in allSegmentIds)
            {
                if (otherSegmentId == 0)
                {
                    continue;
                }
                ArrowDirection dir = segmentGeo.GetDirection(otherSegmentId, startNode);

#if DEBUGCONN
                if (debug)
                {
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {otherSegmentId}. dir={dir}");
                }
#endif

                // check if arrow has already been set for this direction
                switch (dir)
                {
                case ArrowDirection.Turn:
                    if (Constants.ServiceFactory.SimulationService.LeftHandDrive)
                    {
                        if ((arrows & Flags.LaneArrows.Right) != Flags.LaneArrows.None)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if ((arrows & Flags.LaneArrows.Left) != Flags.LaneArrows.None)
                        {
                            continue;
                        }
                    }
                    break;

                case ArrowDirection.Forward:
                    if ((arrows & Flags.LaneArrows.Forward) != Flags.LaneArrows.None)
                    {
                        continue;
                    }
                    break;

                case ArrowDirection.Left:
                    if ((arrows & Flags.LaneArrows.Left) != Flags.LaneArrows.None)
                    {
                        continue;
                    }
                    break;

                case ArrowDirection.Right:
                    if ((arrows & Flags.LaneArrows.Right) != Flags.LaneArrows.None)
                    {
                        continue;
                    }
                    break;

                default:
                    continue;
                }

#if DEBUGCONN
                if (debug)
                {
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {otherSegmentId}: need to determine arrows");
                }
#endif

                bool addArrow = false;

                uint curLaneId = netManager.m_segments.m_buffer[otherSegmentId].m_lanes;
                while (curLaneId != 0)
                {
#if DEBUGCONN
                    if (debug)
                    {
                        Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {otherSegmentId}: checking lane {curLaneId}");
                    }
#endif
                    if (AreLanesConnected(laneId, curLaneId, startNode))
                    {
#if DEBUGCONN
                        if (debug)
                        {
                            Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {otherSegmentId}: checking lane {curLaneId}: lanes are connected");
                        }
#endif
                        addArrow = true;
                        break;
                    }

                    curLaneId = netManager.m_lanes.m_buffer[curLaneId].m_nextLane;
                }

#if DEBUGCONN
                if (debug)
                {
                    Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {otherSegmentId}: finished processing lanes. addArrow={addArrow} arrows (before)={arrows}");
                }
#endif
                if (addArrow)
                {
                    switch (dir)
                    {
                    case ArrowDirection.Turn:
                        if (Constants.ServiceFactory.SimulationService.LeftHandDrive)
                        {
                            arrows |= Flags.LaneArrows.Right;
                        }
                        else
                        {
                            arrows |= Flags.LaneArrows.Left;
                        }
                        break;

                    case ArrowDirection.Forward:
                        arrows |= Flags.LaneArrows.Forward;
                        break;

                    case ArrowDirection.Left:
                        arrows |= Flags.LaneArrows.Left;
                        break;

                    case ArrowDirection.Right:
                        arrows |= Flags.LaneArrows.Right;
                        break;

                    default:
                        continue;
                    }

#if DEBUGCONN
                    if (debug)
                    {
                        Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {otherSegmentId}: arrows={arrows}");
                    }
#endif
                }
            }

#if DEBUGCONN
            if (debug)
            {
                Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): setting lane arrows to {arrows}");
            }
#endif

            LaneArrowManager.Instance.SetLaneArrows(laneId, arrows, true);
        }
 protected override void HandleInvalidNode(NodeGeometry geometry)
 {
 }
        public void OnUpdate(GeometryUpdate update)
        {
            if (update.segmentGeometry != null)
            {
                // Handle a segment update
                SegmentGeometry geometry = update.segmentGeometry;
                if (!geometry.IsValid())
                {
#if DEBUGGEO
                    if (GlobalConfig.Instance.Debug.Switches[5])
                    {
                        Log._Debug($"{this.GetType().Name}.HandleInvalidSegment({geometry.SegmentId})");
                    }
#endif
                    HandleInvalidSegment(geometry);
                }
                else
                {
#if DEBUGGEO
                    if (GlobalConfig.Instance.Debug.Switches[5])
                    {
                        Log._Debug($"{this.GetType().Name}.HandleValidSegment({geometry.SegmentId})");
                    }
#endif
                    HandleValidSegment(geometry);
                }
            }
            else if (update.nodeGeometry != null)
            {
                // Handle a node update
                NodeGeometry geometry = update.nodeGeometry;
                if (!geometry.IsValid())
                {
#if DEBUGGEO
                    if (GlobalConfig.Instance.Debug.Switches[5])
                    {
                        Log._Debug($"{this.GetType().Name}.HandleInvalidNode({geometry.NodeId})");
                    }
#endif
                    HandleInvalidNode(geometry);
                }
                else
                {
#if DEBUGGEO
                    if (GlobalConfig.Instance.Debug.Switches[5])
                    {
                        Log._Debug($"{this.GetType().Name}.HandleValidNode({geometry.NodeId})");
                    }
#endif
                    HandleValidNode(geometry);
                }
            }
            else
            {
                // Handle a segment end replacement
                SegmentEndGeometry endGeo = SegmentGeometry.Get(update.replacement.newSegmentEndId.SegmentId)?.GetEnd(update.replacement.newSegmentEndId.StartNode);
                if (endGeo != null)
                {
#if DEBUGGEO
                    if (GlobalConfig.Instance.Debug.Switches[5])
                    {
                        Log._Debug($"{this.GetType().Name}.HandleSegmentReplacement({update.replacement.oldSegmentEndId} -> {update.replacement.newSegmentEndId})");
                    }
#endif
                    HandleSegmentEndReplacement(update.replacement, endGeo);
                }
            }
        }
 /// <summary>
 /// Handles a valid node
 /// </summary>
 /// <param name="geometry">node geometry</param>
 protected virtual void HandleValidNode(NodeGeometry geometry)
 {
 }
 protected override void HandleValidNode(NodeGeometry geometry)
 {
     TrafficPriorityManager.Instance.AddPriorityNode(geometry.NodeId, true);
 }