Пример #1
0
        public void CustomNodeSimulationStep(ushort nodeId, ref NetNode data)
        {
            if (simStartFrame == 0)
            {
                simStartFrame = Singleton <SimulationManager> .instance.m_currentFrameIndex;
            }

            try {
                if (TrafficLightTool.getToolMode() != ToolMode.AddPrioritySigns)
                {
                    try {
                        TrafficPriority.nodeHousekeeping(nodeId);
                    } catch (Exception e) {
                        Log.Error($"Error occured while housekeeping node {nodeId}: " + e.ToString());
                    }
                }

                TrafficPriority.TrafficLightSimulationStep();

                var nodeSim = TrafficLightSimulation.GetNodeSimulation(nodeId);
                if (nodeSim == null || !nodeSim.IsSimulationActive())
                {
                    OriginalSimulationStep(nodeId, ref data);
                }
            } catch (Exception e) {
                Log.Warning($"CustomNodeSimulationStep: An error occurred: {e.ToString()}");
            }
        }
 internal void Housekeeping()
 {
     if (TrafficManagerTool.GetToolMode() != ToolMode.AddPrioritySigns && TrafficLightSimulation.GetNodeSimulation(NodeId) == null && Type == PriorityType.None)
     {
         TrafficPriority.RemovePrioritySegments(NodeId);
     }
 }
        public override void OnPrimaryClickOverlay()
        {
            if (SelectedNodeId != 0)
            {
                return;
            }

            TrafficLightSimulation sim = TrafficLightSimulation.GetNodeSimulation(HoveredNodeId);

            if (sim == null || !sim.IsTimedLight())
            {
                if ((Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_flags & NetNode.Flags.TrafficLights) == NetNode.Flags.None)
                {
                    TrafficPriority.RemovePrioritySegments(HoveredNodeId);
                    Flags.setNodeTrafficLight(HoveredNodeId, true);
                }

                SelectedNodeId = HoveredNodeId;

                sim = TrafficLightSimulation.AddNodeToSimulation(SelectedNodeId);
                sim.SetupManualTrafficLight();

                /*for (var s = 0; s < 8; s++) {
                 *      var segment = Singleton<NetManager>.instance.m_nodes.m_buffer[SelectedNodeId].GetSegment(s);
                 *      if (segment != 0 && !TrafficPriority.IsPrioritySegment(SelectedNodeId, segment)) {
                 *              TrafficPriority.AddPrioritySegment(SelectedNodeId, segment, SegmentEnd.PriorityType.None);
                 *      }
                 * }*/
            }
            else
            {
                MainTool.ShowTooltip(Translation.GetString("NODE_IS_TIMED_LIGHT"), Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_position);
            }
        }
Пример #4
0
        public bool CustomCheckTrafficLights(ushort node, ushort segment)
        {
            var nodeSimulation = TrafficLightSimulation.GetNodeSimulation(node);

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

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

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

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

                RoadBaseAI.GetTrafficLightState(node, ref instance.m_segments.m_buffer[segment], currentFrameIndex - num, out vehicleLightState, out pedestrianLightState, out vehicles, out pedestrians);
                if ((pedestrianLightState == RoadBaseAI.TrafficLightState.GreenToRed || pedestrianLightState == RoadBaseAI.TrafficLightState.Red) && !pedestrians && num2 >= 196u)
                {
                    RoadBaseAI.SetTrafficLightState(node, ref instance.m_segments.m_buffer[segment], currentFrameIndex - num, vehicleLightState, pedestrianLightState, vehicles, true);
                    return(true);
                }
            }
            else
            {
                if (lights.PedestrianLightState == null)
                {
                    Log._Debug($"A pedestrian wants to cross node {node} at segment {segment} but there is no pedestrian traffic light!");
                    pedestrianLightState = lights.GetAutoPedestrianLightState();
                }
                else
                {
                    pedestrianLightState = (RoadBaseAI.TrafficLightState)lights.PedestrianLightState;
                }
            }
            // NON-STOCK CODE END //

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

            case RoadBaseAI.TrafficLightState.Red:
            case RoadBaseAI.TrafficLightState.GreenToRed:
                return(false);
            }
            return(true);
        }
Пример #5
0
        public static void GetTrafficLightState(ushort vehicleId, ref Vehicle vehicleData, ushort nodeId, ushort fromSegmentId, ushort toSegmentId, ref NetSegment segmentData, uint frame, out RoadBaseAI.TrafficLightState vehicleLightState, out RoadBaseAI.TrafficLightState pedestrianLightState)
        {
            TrafficLightSimulation nodeSim = TrafficLightSimulation.GetNodeSimulation(nodeId);

            if (nodeSim == null || !nodeSim.IsSimulationActive())
            {
                RoadBaseAI.GetTrafficLightState(nodeId, ref segmentData, frame, out vehicleLightState, out pedestrianLightState);
            }
            else
            {
                GetCustomTrafficLightState(vehicleId, ref vehicleData, nodeId, fromSegmentId, toSegmentId, out vehicleLightState, out pedestrianLightState, nodeSim);
            }
        }
        public override void Cleanup()
        {
            if (SelectedNodeId == 0)
            {
                return;
            }
            var nodeSimulation = TrafficLightSimulation.GetNodeSimulation(SelectedNodeId);

            if (nodeSimulation == null || !nodeSimulation.IsManualLight())
            {
                return;
            }

            nodeSimulation.DestroyManualTrafficLight();
            TrafficLightSimulation.RemoveNodeFromSimulation(SelectedNodeId, true);
        }
        private void RenderManualNodeOverlays(RenderManager.CameraInfo cameraInfo)
        {
            var nodeSimulation = TrafficLightSimulation.GetNodeSimulation(SelectedNodeId);

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

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

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

                var width = _hoveredButton[0] == segmentId ? 11.25f : 10f;
                MainTool.DrawOverlayCircle(cameraInfo, colorGray, position, width, segmentId != _hoveredButton[0]);
            }
        }
        public override void Cleanup()
        {
            return;

            if (SelectedNodeId == 0)
            {
                return;
            }
            if (NetworkInterface.Network.selectedNodeIds.Contains(SelectedNodeId))
            {
                return;
            }
            var nodeSimulation = TrafficLightSimulation.GetNodeSimulation(SelectedNodeId);

            if (nodeSimulation == null || !nodeSimulation.IsManualLight())
            {
                return;
            }

            nodeSimulation.DestroyManualTrafficLight();
            TrafficLightSimulation.RemoveNodeFromSimulation(SelectedNodeId, true, false);
        }
Пример #9
0
        public override void OnPrimaryClickOverlay()
        {
            if (HoveredNodeId == 0)
            {
                return;
            }

            if ((Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_flags & NetNode.Flags.Junction) == NetNode.Flags.None)
            {
                return;
            }

            TrafficLightSimulation sim = TrafficLightSimulation.GetNodeSimulation(HoveredNodeId);

            if (sim != null && sim.IsTimedLight())
            {
                MainTool.ShowTooltip(Translation.GetString("NODE_IS_TIMED_LIGHT"), Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_position);
                return;
            }

            TrafficPriority.RemovePrioritySegments(HoveredNodeId);
            Flags.setNodeTrafficLight(HoveredNodeId, (Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_flags & NetNode.Flags.TrafficLights) == NetNode.Flags.None);
        }
 public override void OnClickOverlay()
 {
     if ((Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_flags & NetNode.Flags.Junction) != NetNode.Flags.None)
     {
         if ((Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_flags & NetNode.Flags.TrafficLights) != NetNode.Flags.None)
         {
             TrafficLightSimulation sim = TrafficLightSimulation.GetNodeSimulation(HoveredNodeId);
             if (sim != null && sim.IsTimedLight())
             {
                 MainTool.ShowTooltip(Translation.GetString("NODE_IS_TIMED_LIGHT"), Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_position);
             }
             else
             {
                 TrafficLightSimulation.RemoveNodeFromSimulation(HoveredNodeId, true);    // TODO refactor!
                 Flags.setNodeTrafficLight(HoveredNodeId, false);                         // TODO refactor!
             }
         }
         else
         {
             TrafficPriority.RemovePrioritySegments(HoveredNodeId);
             Flags.setNodeTrafficLight(HoveredNodeId, true);
         }
     }
 }
Пример #11
0
        /// <summary>
        /// Handles vehicle path information in order to manage special nodes (nodes with priority signs or traffic lights).
        /// Data like "vehicle X is on segment S0 and is going to segment S1" is collected.
        /// </summary>
        /// <param name="vehicleId"></param>
        /// <param name="vehicleData"></param>
        internal static void HandleVehicle(ushort vehicleId, ref Vehicle vehicleData, bool addTraffic, bool realTraffic, byte maxUpcomingPathPositions, bool debug = false)
        {
            if (maxUpcomingPathPositions <= 0)
            {
                maxUpcomingPathPositions = 1;                 // we need at least one upcoming path position
            }
            var netManager          = Singleton <NetManager> .instance;
            var lastFrameData       = vehicleData.GetLastFrameData();
            var lastFrameVehiclePos = lastFrameData.m_position;

#if DEBUGV
            var camPos = Camera.main.transform.position;
            //debug = (lastFrameVehiclePos - camPos).sqrMagnitude < CloseLod;
            debug = false;
            List <String> logBuffer = new List <String>();
            bool          logme     = false;
#endif
            if ((vehicleData.m_flags & Vehicle.Flags.Created) == 0)
            {
                TrafficPriority.RemoveVehicleFromSegments(vehicleId);
                return;
            }

            if (vehicleData.Info.m_vehicleType != VehicleInfo.VehicleType.Car &&
                vehicleData.Info.m_vehicleType != VehicleInfo.VehicleType.Train &&
                vehicleData.Info.m_vehicleType != VehicleInfo.VehicleType.Tram)
            {
                //Log._Debug($"HandleVehicle does not handle vehicles of type {vehicleData.Info.m_vehicleType}");
                return;
            }
#if DEBUGV
            logBuffer.Add("Calculating prio info for vehicleId " + vehicleId);
#endif

            ExtVehicleType?vehicleType = CustomVehicleAI.DetermineVehicleTypeFromVehicle(vehicleId, ref vehicleData);
            if (vehicleType == null)
            {
                Log.Warning($"Could not determine vehicle type of vehicle {vehicleId}!");
            }

            if (vehicleType == null || vehicleType == ExtVehicleType.None)
            {
                return;
            }

            // add vehicle to our vehicle list
            VehiclePosition vehiclePos = TrafficPriority.GetVehiclePosition(vehicleId);

            // we extract the segment information directly from the vehicle
            var                      currentPathUnitId        = vehicleData.m_path;
            List <ushort>            realTimeDestinationNodes = new List <ushort>();            // current and upcoming node ids
            List <PathUnit.Position> realTimePositions        = new List <PathUnit.Position>(); // current and upcoming vehicle positions

#if DEBUGV
            logBuffer.Add("* vehicleId " + vehicleId + ". currentPathId: " + currentPathUnitId + " pathPositionIndex: " + vehicleData.m_pathPositionIndex);
#endif

            if (currentPathUnitId > 0)
            {
                // vehicle has a path...
                if ((Singleton <PathManager> .instance.m_pathUnits.m_buffer[currentPathUnitId].m_pathFindFlags & PathUnit.FLAG_READY) != 0)
                {
                    // The path(unit) is established and is ready for use: get the vehicle's current position in terms of segment and lane
                    realTimePositions.Add(Singleton <PathManager> .instance.m_pathUnits.m_buffer[currentPathUnitId].GetPosition(vehicleData.m_pathPositionIndex >> 1));
                    if (realTimePositions[0].m_offset == 0)
                    {
                        realTimeDestinationNodes.Add(netManager.m_segments.m_buffer[realTimePositions[0].m_segment].m_startNode);
                    }
                    else
                    {
                        realTimeDestinationNodes.Add(netManager.m_segments.m_buffer[realTimePositions[0].m_segment].m_endNode);
                    }

                    if (maxUpcomingPathPositions > 0)
                    {
                        // evaluate upcoming path units
                        byte i          = 0;
                        uint pathUnitId = currentPathUnitId;
                        int  pathPos    = (byte)((vehicleData.m_pathPositionIndex >> 1) + 1);
                        while (true)
                        {
                            if (pathPos > 11)
                            {
                                // go to next path unit
                                pathPos    = 0;
                                pathUnitId = Singleton <PathManager> .instance.m_pathUnits.m_buffer[pathUnitId].m_nextPathUnit;
#if DEBUGV
                                logBuffer.Add("* vehicleId " + vehicleId + ". Going to next path unit (1). pathUnitId=" + pathUnitId);
#endif
                                if (pathUnitId <= 0)
                                {
                                    break;
                                }
                            }

                            PathUnit.Position nextRealTimePosition = default(PathUnit.Position);
                            if (!Singleton <PathManager> .instance.m_pathUnits.m_buffer[pathUnitId].GetPosition(pathPos, out nextRealTimePosition))                             // if this returns false, there is no next path unit
                            {
#if DEBUGV
                                logBuffer.Add("* vehicleId " + vehicleId + ". No next path unit! pathPos=" + pathPos + ", pathUnitId=" + pathUnitId);
#endif
                                break;
                            }

                            ushort destNodeId = 0;
                            if (nextRealTimePosition.m_segment > 0)
                            {
                                if (nextRealTimePosition.m_offset == 0)
                                {
                                    destNodeId = netManager.m_segments.m_buffer[nextRealTimePosition.m_segment].m_startNode;
                                }
                                else
                                {
                                    destNodeId = netManager.m_segments.m_buffer[nextRealTimePosition.m_segment].m_endNode;
                                }
                            }

#if DEBUGV
                            logBuffer.Add("* vehicleId " + vehicleId + ". Next path unit! node " + destNodeId + ", seg. " + nextRealTimePosition.m_segment + ", pathUnitId=" + pathUnitId + ", pathPos: " + pathPos);
#endif

                            realTimePositions.Add(nextRealTimePosition);
                            realTimeDestinationNodes.Add(destNodeId);

                            if (i >= maxUpcomingPathPositions - 1)
                            {
                                break;                                 // we calculate up to 2 upcoming path units at the moment
                            }
                            ++pathPos;
                            ++i;
                        }
                    }

                    // please don't ask why we use "m_pathPositionIndex >> 1" (which equals to "m_pathPositionIndex / 2") here (Though it would
                    // be interesting to know why they used such an ugly indexing scheme!!). I assume the oddness of m_pathPositionIndex relates
                    // to the car's position on the segment. If it is even the car might be in the segment's first half and if it is odd, it might
                    // be in the segment's second half.
#if DEBUGV
                    logBuffer.Add("* vehicleId " + vehicleId + ". *INFO* rtPos.seg=" + realTimePositions[0].m_segment + " nrtPos.seg=" + (realTimePositions.Count > 1 ? "" + realTimePositions[1].m_segment : "n/a"));
#endif
                }
            }

            // we have seen the car!
            vehiclePos.LastFrame = Singleton <SimulationManager> .instance.m_currentFrameIndex;

#if DEBUGV
            logBuffer.Add("* vehicleId " + vehicleId + ". ToNode: " + vehiclePos.ToNode + ". FromSegment: " + vehiclePos.FromSegment /* + ". FromLaneId: " + TrafficPriority.Vehicles[vehicleId].FromLaneId*/);
#endif
            if (addTraffic && vehicleData.m_leadingVehicle == 0 && realTimePositions.Count > 0)
            {
                // add traffic to lane
                uint laneId = PathManager.GetLaneID(realTimePositions[0]);
                CustomRoadAI.AddTraffic(laneId, (ushort)Mathf.RoundToInt(vehicleData.CalculateTotalLength(vehicleId)), (ushort)Mathf.RoundToInt(lastFrameData.m_velocity.magnitude), realTraffic);
            }

#if DEBUGV
            logBuffer.Add("* vehicleId " + vehicleId + ". Real time positions: " + realTimePositions.Count + ", Destination nodes: " + realTimeDestinationNodes.Count);
#endif
            if (realTimePositions.Count >= 1)
            {
                // we found a valid path unit
                var sourceLaneIndex = realTimePositions[0].m_lane;

                if (
                    !vehiclePos.Valid ||
                    vehiclePos.ToNode != realTimeDestinationNodes[0] ||
                    vehiclePos.FromSegment != realTimePositions[0].m_segment ||
                    vehiclePos.FromLaneIndex != sourceLaneIndex)
                {
                    // vehicle information is not up-to-date. remove the car from old priority segments (if existing)...
                    TrafficPriority.RemoveVehicleFromSegments(vehicleId);

                    if (realTimePositions.Count >= 2)
                    {
                        // save vehicle information for priority rule handling
                        vehiclePos.Valid                     = true;
                        vehiclePos.CarState                  = VehicleJunctionTransitState.None;
                        vehiclePos.WaitTime                  = 0;
                        vehiclePos.Stopped                   = false;
                        vehiclePos.ToNode                    = realTimeDestinationNodes[0];
                        vehiclePos.FromSegment               = realTimePositions[0].m_segment;
                        vehiclePos.FromLaneIndex             = realTimePositions[0].m_lane;
                        vehiclePos.ToSegment                 = realTimePositions[1].m_segment;
                        vehiclePos.ToLaneIndex               = realTimePositions[1].m_lane;
                        vehiclePos.ReduceSpeedByValueToYield = UnityEngine.Random.Range(16f, 28f);
                        vehiclePos.OnEmergency               = (vehicleData.m_flags & Vehicle.Flags.Emergency2) != 0;
                        vehiclePos.VehicleType               = (ExtVehicleType)vehicleType;

#if DEBUGV
                        logBuffer.Add($"* vehicleId {vehicleId}. Setting current position to: from {vehiclePos.FromSegment} (lane {vehiclePos.FromLaneIndex}), going over {vehiclePos.ToNode}, to {vehiclePos.ToSegment} (lane {vehiclePos.ToLaneIndex})");
#endif

                        //if (!Options.disableSomething) {
                        // add the vehicle to upcoming priority segments that have timed traffic lights
                        for (int i = 0; i < realTimePositions.Count - 1; ++i)
                        {
                            var prioritySegment = TrafficPriority.GetPrioritySegment(realTimeDestinationNodes[i], realTimePositions[i].m_segment);
                            if (prioritySegment == null)
                            {
                                continue;
                            }

                            // add upcoming segments only if there is a timed traffic light
                            TrafficLightSimulation nodeSim = TrafficLightSimulation.GetNodeSimulation(realTimeDestinationNodes[i]);
                            if (i > 0 && (nodeSim == null || !nodeSim.IsTimedLight() || !nodeSim.IsTimedLightActive()))
                            {
                                continue;
                            }

                            VehiclePosition upcomingVehiclePos = new VehiclePosition();
                            upcomingVehiclePos.Valid                     = true;
                            upcomingVehiclePos.CarState                  = VehicleJunctionTransitState.None;
                            upcomingVehiclePos.LastFrame                 = vehiclePos.LastFrame;
                            upcomingVehiclePos.ToNode                    = realTimeDestinationNodes[i];
                            upcomingVehiclePos.FromSegment               = realTimePositions[i].m_segment;
                            upcomingVehiclePos.FromLaneIndex             = realTimePositions[i].m_lane;
                            upcomingVehiclePos.ToSegment                 = realTimePositions[i + 1].m_segment;
                            upcomingVehiclePos.ToLaneIndex               = realTimePositions[i + 1].m_lane;
                            upcomingVehiclePos.ReduceSpeedByValueToYield = UnityEngine.Random.Range(16f, 28f);
                            upcomingVehiclePos.OnEmergency               = (vehicleData.m_flags & Vehicle.Flags.Emergency2) != 0;
                            upcomingVehiclePos.VehicleType               = (ExtVehicleType)vehicleType;
#if DEBUGV
                            logBuffer.Add($"* vehicleId {vehicleId}. Adding future position: from {upcomingVehiclePos.FromSegment}  (lane {upcomingVehiclePos.FromLaneIndex}), going over {upcomingVehiclePos.ToNode}, to {upcomingVehiclePos.ToSegment} (lane {upcomingVehiclePos.ToLaneIndex})");
#endif

                            prioritySegment.AddVehicle(vehicleId, upcomingVehiclePos);
                        }
                    }
                    //}
                }
                else
                {
#if DEBUGV
                    logBuffer.Add($"* vehicleId {vehicleId}. Nothing has changed. from {vehiclePos.FromSegment} (lane {vehiclePos.FromLaneIndex}), going over {vehiclePos.ToNode}, to {vehiclePos.ToSegment} (lane {vehiclePos.ToLaneIndex})");
                    logme = false;
#endif
                }
            }
            else
            {
#if DEBUGV
                logBuffer.Add($"* vehicleId {vehicleId}. Insufficient path unit positions.");
#endif
                TrafficPriority.RemoveVehicleFromSegments(vehicleId);
            }

#if DEBUGV
            if (logme)
            {
                Log._Debug("vehicleId: " + vehicleId + " ============================================");
                foreach (String logBuf in logBuffer)
                {
                    Log._Debug(logBuf);
                }
                Log._Debug("vehicleId: " + vehicleId + " ============================================");
            }
#endif
        }
        public void ShowGUI(bool viewOnly)
        {
            try {
                if (viewOnly && !Options.prioritySignsOverlay)
                {
                    return;
                }

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

                var hoveredSegment = false;
                //Log.Message("_guiPrioritySigns called. num of prio segments: " + TrafficPriority.PrioritySegments.Count);

                HashSet <ushort> nodeIdsWithSigns = new HashSet <ushort>();
                for (ushort segmentId = 0; segmentId < NetManager.MAX_SEGMENT_COUNT; ++segmentId)
                {
                    var trafficSegment = TrafficPriority.TrafficSegments[segmentId];
                    if (trafficSegment == null)
                    {
                        continue;
                    }
                    SegmentGeometry geometry = SegmentGeometry.Get(segmentId);

                    List <SegmentEnd> prioritySegments = new List <SegmentEnd>();
                    if (TrafficLightSimulation.GetNodeSimulation(trafficSegment.Node1) == null)
                    {
                        SegmentEnd tmpSeg1   = TrafficPriority.GetPrioritySegment(trafficSegment.Node1, segmentId);
                        bool       startNode = geometry.StartNodeId() == trafficSegment.Node1;
                        if (tmpSeg1 != null && !geometry.IsOutgoingOneWay(startNode))
                        {
                            prioritySegments.Add(tmpSeg1);
                            nodeIdsWithSigns.Add(trafficSegment.Node1);
                        }
                    }
                    if (TrafficLightSimulation.GetNodeSimulation(trafficSegment.Node2) == null)
                    {
                        SegmentEnd tmpSeg2   = TrafficPriority.GetPrioritySegment(trafficSegment.Node2, segmentId);
                        bool       startNode = geometry.StartNodeId() == trafficSegment.Node2;
                        if (tmpSeg2 != null && !geometry.IsOutgoingOneWay(startNode))
                        {
                            prioritySegments.Add(tmpSeg2);
                            nodeIdsWithSigns.Add(trafficSegment.Node2);
                        }
                    }

                    //Log.Message("init ok");

                    foreach (var prioritySegment in prioritySegments)
                    {
                        var nodeId = prioritySegment.NodeId;
                        //Log.Message("_guiPrioritySigns: nodeId=" + nodeId);

                        var nodePositionVector3 = Singleton <NetManager> .instance.m_nodes.m_buffer[nodeId].m_position;
                        var camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position;
                        var diff   = nodePositionVector3 - camPos;
                        if (diff.magnitude > TrafficManagerTool.PriorityCloseLod)
                        {
                            continue;                             // do not draw if too distant
                        }
                        if (Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_startNode == (ushort)nodeId)
                        {
                            nodePositionVector3.x += Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_startDirection.x * 10f;
                            nodePositionVector3.y += Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_startDirection.y * 10f;
                            nodePositionVector3.z += Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_startDirection.z * 10f;
                        }
                        else
                        {
                            nodePositionVector3.x += Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_endDirection.x * 10f;
                            nodePositionVector3.y += Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_endDirection.y * 10f;
                            nodePositionVector3.z += Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_endDirection.z * 10f;
                        }

                        var nodeScreenPosition = Camera.main.WorldToScreenPoint(nodePositionVector3);
                        nodeScreenPosition.y = Screen.height - nodeScreenPosition.y;
                        if (nodeScreenPosition.z < 0)
                        {
                            continue;
                        }
                        var zoom            = 1.0f / diff.magnitude * 100f * MainTool.GetBaseZoom();
                        var size            = 110f * zoom;
                        var guiColor        = GUI.color;
                        var nodeBoundingBox = new Rect(nodeScreenPosition.x - size / 2, nodeScreenPosition.y - size / 2, size, size);
                        hoveredSegment = !viewOnly && TrafficManagerTool.IsMouseOver(nodeBoundingBox);

                        if (hoveredSegment)
                        {
                            // mouse hovering over sign
                            guiColor.a = 0.8f;
                        }
                        else
                        {
                            guiColor.a = 0.5f;
                            size       = 90f * zoom;
                        }
                        var nodeDrawingBox = new Rect(nodeScreenPosition.x - size / 2, nodeScreenPosition.y - size / 2, size, size);

                        GUI.color = guiColor;

                        bool setUndefinedSignsToMainRoad = false;
                        switch (prioritySegment.Type)
                        {
                        case SegmentEnd.PriorityType.Main:
                            GUI.DrawTexture(nodeDrawingBox, TrafficLightToolTextureResources.SignPriorityTexture2D);
                            if (clicked && hoveredSegment)
                            {
                                //Log._Debug("Click on node " + nodeId + ", segment " + segmentId + " to change prio type (1)");
                                //Log.Message("PrioritySegment.Type = Yield");
                                prioritySegment.Type        = SegmentEnd.PriorityType.Yield;
                                setUndefinedSignsToMainRoad = true;
                                clicked = false;
                            }
                            break;

                        case SegmentEnd.PriorityType.Yield:
                            GUI.DrawTexture(nodeDrawingBox, TrafficLightToolTextureResources.SignYieldTexture2D);
                            if (clicked && hoveredSegment)
                            {
                                //Log._Debug("Click on node " + nodeId + ", segment " + segmentId + " to change prio type (2)");
                                prioritySegment.Type        = SegmentEnd.PriorityType.Stop;
                                setUndefinedSignsToMainRoad = true;
                                clicked = false;
                            }

                            break;

                        case SegmentEnd.PriorityType.Stop:
                            GUI.DrawTexture(nodeDrawingBox, TrafficLightToolTextureResources.SignStopTexture2D);
                            if (clicked && hoveredSegment)
                            {
                                //Log._Debug("Click on node " + nodeId + ", segment " + segmentId + " to change prio type (3)");
                                prioritySegment.Type = SegmentEnd.PriorityType.Main;
                                clicked = false;
                            }
                            break;

                        case SegmentEnd.PriorityType.None:
                            if (viewOnly)
                            {
                                break;
                            }
                            GUI.DrawTexture(nodeDrawingBox, TrafficLightToolTextureResources.SignNoneTexture2D);

                            if (clicked && hoveredSegment)
                            {
                                //Log._Debug("Click on node " + nodeId + ", segment " + segmentId + " to change prio type (4)");
                                //Log.Message("PrioritySegment.Type = None");
                                prioritySegment.Type = GetNumberOfMainRoads(nodeId, ref Singleton <NetManager> .instance.m_nodes.m_buffer[nodeId]) >= 2
                                                                                ? SegmentEnd.PriorityType.Yield
                                                                                : SegmentEnd.PriorityType.Main;
                                if (prioritySegment.Type == SegmentEnd.PriorityType.Yield)
                                {
                                    setUndefinedSignsToMainRoad = true;
                                }
                                clicked = false;
                            }
                            break;
                        }

                        if (setUndefinedSignsToMainRoad)
                        {
                            foreach (var otherPrioritySegment in TrafficPriority.GetPrioritySegments(nodeId))
                            {
                                if (otherPrioritySegment.SegmentId == prioritySegment.SegmentId)
                                {
                                    continue;
                                }
                                if (otherPrioritySegment.Type == SegmentEnd.PriorityType.None)
                                {
                                    otherPrioritySegment.Type = SegmentEnd.PriorityType.Main;
                                }
                            }
                        }
                    }
                }

                if (viewOnly)
                {
                    return;
                }

                ushort hoveredExistingNodeId = 0;
                foreach (ushort nodeId in nodeIdsWithSigns)
                {
                    var nodePositionVector3 = Singleton <NetManager> .instance.m_nodes.m_buffer[nodeId].m_position;
                    var camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position;
                    var diff   = nodePositionVector3 - camPos;
                    if (diff.magnitude > TrafficManagerTool.PriorityCloseLod)
                    {
                        continue;
                    }

                    // draw deletion button
                    var nodeScreenPosition = Camera.main.WorldToScreenPoint(nodePositionVector3);
                    nodeScreenPosition.y = Screen.height - nodeScreenPosition.y;
                    if (nodeScreenPosition.z < 0)
                    {
                        continue;
                    }
                    var zoom            = 1.0f / diff.magnitude * 100f;
                    var size            = 100f * zoom;
                    var nodeBoundingBox = new Rect(nodeScreenPosition.x - size / 2, nodeScreenPosition.y - size / 2, size, size);

                    var guiColor          = GUI.color;
                    var nodeCenterHovered = TrafficManagerTool.IsMouseOver(nodeBoundingBox);
                    if (nodeCenterHovered)
                    {
                        hoveredExistingNodeId = nodeId;
                        guiColor.a            = 0.8f;
                    }
                    else
                    {
                        guiColor.a = 0.5f;
                    }
                    GUI.color = guiColor;

                    GUI.DrawTexture(nodeBoundingBox, TrafficLightToolTextureResources.SignRemoveTexture2D);
                }

                // add a new or delete a priority segment node
                if (HoveredNodeId != 0 || hoveredExistingNodeId != 0)
                {
                    bool delete = false;
                    if (hoveredExistingNodeId > 0)
                    {
                        delete = true;
                    }

                    // determine if we may add new priority signs to this node
                    bool ok = false;
                    TrafficLightSimulation nodeSim = TrafficLightSimulation.GetNodeSimulation(HoveredNodeId);
                    if ((Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_flags & NetNode.Flags.TrafficLights) == NetNode.Flags.None)
                    {
                        // no traffic light set
                        ok = true;
                    }
                    else if (nodeSim == null || !nodeSim.IsTimedLight())
                    {
                        ok = true;
                    }

                    if (!Flags.mayHaveTrafficLight(HoveredNodeId))
                    {
                        ok = false;
                    }

                    if (clicked)
                    {
                        //Log._Debug("_guiPrioritySigns: hovered+clicked @ nodeId=" + HoveredNodeId + "/" + hoveredExistingNodeId);

                        if (delete)
                        {
                            TrafficPriority.RemovePrioritySegments(hoveredExistingNodeId);
                        }
                        else if (ok)
                        {
                            if (!TrafficPriority.IsPriorityNode(HoveredNodeId))
                            {
                                //Log._Debug("_guiPrioritySigns: adding prio segments @ nodeId=" + HoveredNodeId);
                                TrafficLightSimulation.RemoveNodeFromSimulation(HoveredNodeId, false, true);
                                Flags.setNodeTrafficLight(HoveredNodeId, false);                                 // TODO refactor!
                                TrafficPriority.AddPriorityNode(HoveredNodeId);
                            }
                        }
                        else if (nodeSim != null && nodeSim.IsTimedLight())
                        {
                            MainTool.ShowTooltip(Translation.GetString("NODE_IS_TIMED_LIGHT"), Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_position);
                        }
                    }
                }
            } catch (Exception e) {
                Log.Error(e.ToString());
            }
        }
        public override void OnToolGUI(Event e)
        {
            var hoveredSegment = false;

            if (SelectedNodeId != 0)
            {
                var nodeSimulation = TrafficLightSimulation.GetNodeSimulation(SelectedNodeId);
                nodeSimulation.housekeeping();

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

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

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

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

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

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

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

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

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

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

                    var guiColor = GUI.color;

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

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

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

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

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

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

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

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

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

                        SetAlpha(segmentId, -1);

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

                        GUI.DrawTexture(myRect1, TrafficLightToolTextureResources.LightModeTexture2D);

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

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

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

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

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

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

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

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

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

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

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

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

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

            if (hoveredSegment)
            {
                return;
            }
            _hoveredButton[0] = 0;
            _hoveredButton[1] = 0;
        }
Пример #14
0
        public static void OriginalSetTrafficLightState(bool customCall, ushort nodeID, ref NetSegment segmentData, uint frame, RoadBaseAI.TrafficLightState vehicleLightState, RoadBaseAI.TrafficLightState pedestrianLightState, bool vehicles, bool pedestrians)
        {
            /// NON-STOCK CODE START ///
            TrafficLightSimulation nodeSim = TrafficLightSimulation.GetNodeSimulation(nodeID);

            if (nodeSim == null || !nodeSim.IsSimulationActive() || customCall)
            {
                /// NON-STOCK CODE END ///
                int num = (int)pedestrianLightState << 2 | (int)vehicleLightState;
                if (segmentData.m_startNode == nodeID)
                {
                    if ((frame >> 8 & 1u) == 0u)
                    {
                        segmentData.m_trafficLightState0 = (byte)((int)(segmentData.m_trafficLightState0 & 240) | num);
                    }
                    else
                    {
                        segmentData.m_trafficLightState1 = (byte)((int)(segmentData.m_trafficLightState1 & 240) | num);
                    }
                    if (vehicles)
                    {
                        segmentData.m_flags |= NetSegment.Flags.TrafficStart;
                    }
                    else
                    {
                        segmentData.m_flags &= ~NetSegment.Flags.TrafficStart;
                    }
                    if (pedestrians)
                    {
                        segmentData.m_flags |= NetSegment.Flags.CrossingStart;
                    }
                    else
                    {
                        segmentData.m_flags &= ~NetSegment.Flags.CrossingStart;
                    }
                }
                else
                {
                    if ((frame >> 8 & 1u) == 0u)
                    {
                        segmentData.m_trafficLightState0 = (byte)((int)(segmentData.m_trafficLightState0 & 15) | num << 4);
                    }
                    else
                    {
                        segmentData.m_trafficLightState1 = (byte)((int)(segmentData.m_trafficLightState1 & 15) | num << 4);
                    }
                    if (vehicles)
                    {
                        segmentData.m_flags |= NetSegment.Flags.TrafficEnd;
                    }
                    else
                    {
                        segmentData.m_flags &= ~NetSegment.Flags.TrafficEnd;
                    }
                    if (pedestrians)
                    {
                        segmentData.m_flags |= NetSegment.Flags.CrossingEnd;
                    }
                    else
                    {
                        segmentData.m_flags &= ~NetSegment.Flags.CrossingEnd;
                    }
                }
            }             // NON-STOCK CODE
        }
Пример #15
0
        private static void GetCustomTrafficLightState(ushort vehicleId, ref Vehicle vehicleData, ushort nodeId, ushort fromSegmentId, ushort toSegmentId, out RoadBaseAI.TrafficLightState vehicleLightState, out RoadBaseAI.TrafficLightState pedestrianLightState, TrafficLightSimulation nodeSim = null)
        {
            if (nodeSim == null)
            {
                nodeSim = TrafficLightSimulation.GetNodeSimulation(nodeId);
                if (nodeSim == null)
                {
                    Log.Error($"GetCustomTrafficLightState: node traffic light simulation not found at node {nodeId}! Vehicle {vehicleId} comes from segment {fromSegmentId} and goes to node {nodeId}");
                    throw new ApplicationException($"GetCustomTrafficLightState: node traffic light simulation not found at node {nodeId}! Vehicle {vehicleId} comes from segment {fromSegmentId} and goes to node {nodeId}");
                }
            }

            // get vehicle position

            /*VehiclePosition vehiclePos = TrafficPriority.GetVehiclePosition(vehicleId);
             * if (!vehiclePos.Valid || vehiclePos.FromSegment != fromSegmentId || vehiclePos.ToNode != nodeId) {
             *      Log._Debug($"GetTrafficLightState: Recalculating position for vehicle {vehicleId}! FromSegment={vehiclePos.FromSegment} Valid={vehiclePos.Valid}");
             *      try {
             *              HandleVehicle(vehicleId, ref Singleton<VehicleManager>.instance.m_vehicles.m_buffer[vehicleId], false, false);
             *      } catch (Exception e) {
             *              Log.Error("VehicleAI GetTrafficLightState Error: " + e.ToString());
             *      }
             * }
             *
             * if (!vehiclePos.Valid || vehiclePos.FromSegment != fromSegmentId || vehiclePos.ToNode != nodeId) {
             *      Log.Warning($"GetTrafficLightState: Vehicle {vehicleId} is not moving at segment {fromSegmentId} to node {nodeId}! FromSegment={vehiclePos.FromSegment} ToNode={vehiclePos.ToNode} Valid={vehiclePos.Valid}");
             *      vehicleLightState = RoadBaseAI.TrafficLightState.Red;
             *      pedestrianLightState = RoadBaseAI.TrafficLightState.Red;
             *      return;
             * }*/

            // get vehicle type
            ExtVehicleType?vehicleType = CustomVehicleAI.DetermineVehicleTypeFromVehicle(vehicleId, ref vehicleData);

            if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Tram && vehicleType != ExtVehicleType.Tram)
            {
                Log.Warning($"vehicleType={vehicleType} ({(int)vehicleType}) for Tram");
            }
            //Log._Debug($"GetCustomTrafficLightState: Vehicle {vehicleId} is a {vehicleType}");
            if (vehicleType == null)
            {
                Log.Warning($"GetTrafficLightState: Could not determine vehicle type of vehicle {vehicleId}!");
                vehicleLightState    = RoadBaseAI.TrafficLightState.Red;
                pedestrianLightState = RoadBaseAI.TrafficLightState.Red;
                return;
            }

            // get responsible traffic light
            CustomSegmentLights lights = CustomTrafficLights.GetSegmentLights(nodeId, fromSegmentId);
            CustomSegmentLight  light  = lights == null ? null : lights.GetCustomLight((ExtVehicleType)vehicleType);

            if (lights == null || light == null)
            {
                Log.Warning($"GetTrafficLightState: No custom light for vehicleType {vehicleType} @ node {nodeId}, segment {fromSegmentId} found. lights null? {lights == null} light null? {light == null}");
                vehicleLightState    = RoadBaseAI.TrafficLightState.Red;
                pedestrianLightState = RoadBaseAI.TrafficLightState.Red;
                return;
            }

            SegmentGeometry geometry = CustomRoadAI.GetSegmentGeometry(fromSegmentId);

            // get traffic light state from responsible traffic light
            if (geometry.IsLeftSegment(toSegmentId, nodeId))
            {
                vehicleLightState = light.GetLightLeft();
            }
            else if (geometry.IsRightSegment(toSegmentId, nodeId))
            {
                vehicleLightState = light.GetLightRight();
            }
            else
            {
                vehicleLightState = light.GetLightMain();
            }

            // get traffic lights state for pedestrians
            pedestrianLightState = (lights.PedestrianLightState != null) ? (RoadBaseAI.TrafficLightState)lights.PedestrianLightState : RoadBaseAI.TrafficLightState.Red;
        }
        public override void OnSaveData()
        {
            Log.Info("Recalculating segment geometries");
            SegmentGeometry.OnBeforeSaveData();
            Log.Info("Saving Mod Data.");
            var configuration = new Configuration();

            if (TrafficPriority.TrafficSegments != null)
            {
                for (ushort i = 0; i < Singleton <NetManager> .instance.m_segments.m_size; i++)
                {
                    try {
                        SavePrioritySegment(i, configuration);
                    } catch (Exception e) {
                        Log.Error($"Exception occurred while saving priority segment @ {i}: {e.ToString()}");
                    }

                    try {
                        SaveSegmentNodeFlags(i, configuration);
                    } catch (Exception e) {
                        Log.Error($"Exception occurred while saving segment node flags @ {i}: {e.ToString()}");
                    }
                }
            }

            for (ushort i = 0; i < Singleton <NetManager> .instance.m_nodes.m_size; i++)
            {
                /*if (TrafficLightSimulation.LightSimulationByNodeId != null) {
                 *      SaveTrafficLightSimulation(i, configuration);
                 * }*/

                /*if (TrafficLightsManual.ManualSegments != null) {
                 *      SaveManualTrafficLight(i, configuration);
                 * }*/

                TrafficLightSimulation sim = TrafficLightSimulation.GetNodeSimulation(i);
                if (sim != null && sim.IsTimedLight())
                {
                    try {
                        SaveTimedTrafficLight(i, configuration);
                    } catch (Exception e) {
                        Log.Error($"Exception occurred while saving timed traffic light @ {i}: {e.ToString()}");
                    }
                    // TODO save new traffic lights
                }

                try {
                    SaveNodeLights(i, configuration);
                } catch (Exception e) {
                    Log.Error($"Exception occurred while saving node traffic light @ {i}: {e.ToString()}");
                }
            }

#if !TAM
            if (LoadingExtension.IsPathManagerCompatible)
            {
#endif
            for (uint i = 0; i < Singleton <NetManager> .instance.m_lanes.m_buffer.Length; i++)
            {
                try {
                    SaveLaneData(i, configuration);
                } catch (Exception e) {
                    Log.Error($"Exception occurred while saving lane data @ {i}: {e.ToString()}");
                }
            }
#if !TAM
        }
#endif

            foreach (KeyValuePair <uint, ushort> e in Flags.getAllLaneSpeedLimits())
            {
                try {
                    SaveLaneSpeedLimit(new Configuration.LaneSpeedLimit(e.Key, e.Value), configuration);
                } catch (Exception ex) {
                    Log.Error($"Exception occurred while saving lane speed limit @ {e.Key}: {ex.ToString()}");
                }
            }

            foreach (KeyValuePair <uint, ExtVehicleType> e in Flags.getAllLaneAllowedVehicleTypes())
            {
                try {
                    SaveLaneAllowedVehicleTypes(new Configuration.LaneVehicleTypes(e.Key, e.Value), configuration);
                } catch (Exception ex) {
                    Log.Error($"Exception occurred while saving lane vehicle restrictions @ {e.Key}: {ex.ToString()}");
                }
            }

            var binaryFormatter = new BinaryFormatter();
            var memoryStream    = new MemoryStream();

            try {
                binaryFormatter.Serialize(memoryStream, configuration);
                memoryStream.Position = 0;
                Log.Info($"Save data byte length {memoryStream.Length}");
                _serializableData.SaveData(DataId, memoryStream.ToArray());

                // save options
                _serializableData.SaveData("TMPE_Options", new byte[] {
                    (byte)Options.simAccuracy,
                    (byte)0,                    //Options.laneChangingRandomization,
                    (byte)Options.recklessDrivers,
                    (byte)(Options.relaxedBusses ? 1 : 0),
                    (byte)(Options.nodesOverlay ? 1 : 0),
                    (byte)(Options.allowEnterBlockedJunctions ? 1 : 0),
                    (byte)(Options.advancedAI ? 1 : 0),
                    (byte)(Options.highwayRules ? 1 : 0),
                    (byte)(Options.prioritySignsOverlay ? 1 : 0),
                    (byte)(Options.timedLightsOverlay ? 1 : 0),
                    (byte)(Options.speedLimitsOverlay ? 1 : 0),
                    (byte)(Options.vehicleRestrictionsOverlay ? 1 : 0),
                    (byte)(Options.strongerRoadConditionEffects ? 1 : 0),
                    (byte)(Options.allowUTurns ? 1 : 0),
                    (byte)(Options.allowLaneChangesWhileGoingStraight ? 1 : 0),
                    (byte)(Options.enableDespawning ? 1 : 0),
                    (byte)(Options.IsDynamicPathRecalculationActive() ? 1 : 0),
                    (byte)(Options.connectedLanesOverlay ? 1 : 0)
                });
            } catch (Exception ex) {
                Log.Error("Unexpected error saving data: " + ex.Message);
            } finally {
                memoryStream.Close();
            }
        }
        private static void SaveTimedTrafficLight(ushort i, Configuration configuration)
        {
            try {
                TrafficLightSimulation sim = TrafficLightSimulation.GetNodeSimulation(i);
                if (sim == null || !sim.IsTimedLight())
                {
                    return;
                }

                Log._Debug($"Going to save timed light at node {i}.");

                var timedNode = sim.TimedLight;
                timedNode.handleNewSegments();

                Configuration.TimedTrafficLights cnfTimedLights = new Configuration.TimedTrafficLights();
                configuration.TimedLights.Add(cnfTimedLights);

                cnfTimedLights.nodeId     = timedNode.NodeId;
                cnfTimedLights.nodeGroup  = timedNode.NodeGroup;
                cnfTimedLights.started    = timedNode.IsStarted();
                cnfTimedLights.timedSteps = new List <Configuration.TimedTrafficLightsStep>();

                for (var j = 0; j < timedNode.NumSteps(); j++)
                {
                    Log._Debug($"Saving timed light step {j} at node {i}.");
                    TimedTrafficLightsStep timedStep = timedNode.Steps[j];
                    Configuration.TimedTrafficLightsStep cnfTimedStep = new Configuration.TimedTrafficLightsStep();
                    cnfTimedLights.timedSteps.Add(cnfTimedStep);

                    cnfTimedStep.minTime         = timedStep.minTime;
                    cnfTimedStep.maxTime         = timedStep.maxTime;
                    cnfTimedStep.waitFlowBalance = timedStep.waitFlowBalance;
                    cnfTimedStep.segmentLights   = new Dictionary <ushort, Configuration.CustomSegmentLights>();
                    foreach (KeyValuePair <ushort, CustomSegmentLights> e in timedStep.segmentLights)
                    {
                        Log._Debug($"Saving timed light step {j}, segment {e.Key} at node {i}.");

                        CustomSegmentLights segLights = e.Value;
                        Configuration.CustomSegmentLights cnfSegLights = new Configuration.CustomSegmentLights();
                        cnfTimedStep.segmentLights.Add(e.Key, cnfSegLights);

                        cnfSegLights.nodeId               = segLights.NodeId;
                        cnfSegLights.segmentId            = segLights.SegmentId;
                        cnfSegLights.customLights         = new Dictionary <ExtVehicleType, Configuration.CustomSegmentLight>();
                        cnfSegLights.pedestrianLightState = segLights.PedestrianLightState;
                        cnfSegLights.manualPedestrianMode = segLights.ManualPedestrianMode;

                        Log._Debug($"Saving pedestrian light @ seg. {e.Key}, step {j}: {cnfSegLights.pedestrianLightState} {cnfSegLights.manualPedestrianMode}");

                        foreach (KeyValuePair <Traffic.ExtVehicleType, CustomSegmentLight> e2 in segLights.CustomLights)
                        {
                            Log._Debug($"Saving timed light step {j}, segment {e.Key}, vehicleType {e2.Key} at node {i}.");

                            CustomSegmentLight segLight = e2.Value;
                            Configuration.CustomSegmentLight cnfSegLight = new Configuration.CustomSegmentLight();
                            cnfSegLights.customLights.Add(e2.Key, cnfSegLight);

                            cnfSegLight.nodeId      = segLight.NodeId;
                            cnfSegLight.segmentId   = segLight.SegmentId;
                            cnfSegLight.currentMode = (int)segLight.CurrentMode;
                            cnfSegLight.leftLight   = segLight.LightLeft;
                            cnfSegLight.mainLight   = segLight.LightMain;
                            cnfSegLight.rightLight  = segLight.LightRight;
                        }
                    }
                }
            } catch (Exception e) {
                Log.Error($"Error adding TimedTrafficLights to save {e.Message}");
            }
        }
Пример #18
0
        internal void Recalculate()
        {
#if DEBUGGEO
            Log._Debug($"NodeGeometry: Recalculate @ {NodeId}");
#endif

            Cleanup();

            Flags.applyNodeTrafficLightFlag(NodeId);

            // check if node is valid
            if (!IsValid())
            {
                for (int i = 0; i < 8; ++i)
                {
                    SegmentEndGeometries[i] = null;
                }
                TrafficLightSimulation.RemoveNodeFromSimulation(NodeId, false, true);
                Flags.setNodeTrafficLight(NodeId, false);
            }
            else
            {
                NetManager netManager      = Singleton <NetManager> .instance;
                bool       hasTrafficLight = (netManager.m_nodes.m_buffer[NodeId].m_flags & NetNode.Flags.TrafficLights) != NetNode.Flags.None;
                var        nodeSim         = TrafficLightSimulation.GetNodeSimulation(NodeId);
                if (nodeSim == null)
                {
                    byte numSegmentsWithSigns = 0;
                    for (var s = 0; s < 8; s++)
                    {
                        var segmentId = netManager.m_nodes.m_buffer[NodeId].GetSegment(s);
                        if (segmentId <= 0)
                        {
                            continue;
                        }

#if DEBUGx
                        Log._Debug($"NodeGeometry.Recalculate: Housekeeping segment {segmentId}");
#endif

                        SegmentEnd prioritySegment = TrafficPriority.GetPrioritySegment(NodeId, segmentId);
                        if (prioritySegment == null)
                        {
                            continue;
                        }

                        // if node is a traffic light, it must not have priority signs
                        if (hasTrafficLight && prioritySegment.Type != SegmentEnd.PriorityType.None)
                        {
                            Log.Warning($"Housekeeping: Node {NodeId}, Segment {segmentId} is a priority sign but node has a traffic light!");
                            prioritySegment.Type = SegmentEnd.PriorityType.None;
                        }

                        // if a priority sign is set, everything is ok
                        if (prioritySegment.Type != SegmentEnd.PriorityType.None)
                        {
                            ++numSegmentsWithSigns;
                        }
                    }

                    if (numSegmentsWithSigns > 0)
                    {
                        // add priority segments for newly created segments
                        numSegmentsWithSigns += TrafficPriority.AddPriorityNode(NodeId);
                    }
                }

                // calculate node properties
                byte incomingSegments = 0;
                byte outgoingSegments = 0;
                for (int i = 0; i < 8; ++i)
                {
                    if (SegmentEndGeometries[i] == null)
                    {
                        continue;
                    }
#if DEBUGGEO
                    Log._Debug($"NodeGeometry.Recalculate: Iterating over segment end {SegmentEndGeometries[i].SegmentId} @ node {NodeId}");
#endif

                    bool startNode = SegmentEndGeometries[i].StartNode;
                    if (SegmentEndGeometries[i].GetSegmentGeometry().IsIncoming(startNode))
                    {
                        ++incomingSegments;
                    }
                    if (SegmentEndGeometries[i].GetSegmentGeometry().IsOutgoing(startNode))
                    {
                        ++outgoingSegments;
                    }
                }

                IsSimpleJunction = incomingSegments == 1 || outgoingSegments == 1;
#if DEBUGGEO
                Log._Debug($"NodeGeometry.Recalculate: Node {NodeId} has {incomingSegments} incoming and {outgoingSegments} outgoing segments.");
#endif
            }

            NotifyObservers();
        }