Example #1
0
 internal void Housekeeping()
 {
     if (TrafficManagerTool.GetToolMode() != ToolMode.AddPrioritySigns && TrafficLightSimulationManager.Instance().GetNodeSimulation(NodeId) == null && Type == PriorityType.None)
     {
         TrafficPriorityManager.Instance().RemovePrioritySegments(NodeId);
     }
 }
        public void CustomNodeSimulationStep(ushort nodeId, ref NetNode data)
        {
            if (simStartFrame == 0)
            {
                simStartFrame = Singleton <SimulationManager> .instance.m_currentFrameIndex;
            }

            try {
                if (TrafficManagerTool.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()}");
            }
        }
Example #3
0
        public override void ShowGUIOverlay(bool viewOnly)
        {
            if (viewOnly && !Options.prioritySignsOverlay)
            {
                return;
            }

            if (TrafficManagerTool.GetToolMode() == ToolMode.JunctionRestrictions)
            {
                return;
            }

            ShowGUI(viewOnly);
        }
        private void ShowSigns(bool viewOnly)
        {
            if (viewOnly && !Options.speedLimitsOverlay)
            {
                return;
            }

            Array16 <NetSegment> segments = Singleton <NetManager> .instance.m_segments;
            bool handleHovered            = false;

            for (int i = 1; i < segments.m_size; ++i)
            {
                if (segments.m_buffer[i].m_flags == NetSegment.Flags.None)                 // segment is unused
                {
                    continue;
                }
#if !DEBUG
                if ((segments.m_buffer[i].m_flags & NetSegment.Flags.Untouchable) != NetSegment.Flags.None)
                {
                    continue;
                }
#endif
                var segmentInfo = segments.m_buffer[i].Info;

                Vector3 centerPos = segments.m_buffer[i].m_bounds.center;
                var     screenPos = Camera.main.WorldToScreenPoint(centerPos);
                screenPos.y = Screen.height - screenPos.y;

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

                // draw speed limits
                if (TrafficManagerTool.GetToolMode() != ToolMode.VehicleRestrictions || i != SelectedSegmentId)                   // no speed limit overlay on selected segment when in vehicle restrictions mode
                {
                    if (drawSpeedLimitHandles((ushort)i, viewOnly))
                    {
                        handleHovered = true;
                    }
                }
            }
            overlayHandleHovered = handleHovered;
        }
        private bool drawVehicleRestrictionHandles(ushort segmentId, bool viewOnly, out bool stateUpdated)
        {
            stateUpdated = false;

            if (viewOnly && !Options.vehicleRestrictionsOverlay && TrafficManagerTool.GetToolMode() != ToolMode.VehicleRestrictions)
            {
                return(false);
            }

            Vector3 center = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_bounds.center;

            var screenPos = Camera.main.WorldToScreenPoint(center);

            screenPos.y = Screen.height - screenPos.y;
            if (screenPos.z < 0)
            {
                return(false);
            }
            var camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position;
            var diff   = center - camPos;

            if (diff.magnitude > TrafficManagerTool.PriorityCloseLod)
            {
                return(false);                // do not draw if too distant
            }
            int numDirections;
            // TODO refactor vehicle mask
            int numLanes = TrafficManagerTool.GetSegmentNumVehicleLanes(segmentId, null, out numDirections, VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train);

            // draw vehicle restrictions over each lane
            NetInfo segmentInfo = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].Info;
            Vector3 yu          = (Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_endDirection - Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_startDirection).normalized;

            if ((Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.None)
            {
                yu = -yu;
            }
            Vector3   xu = Vector3.Cross(yu, new Vector3(0, 1f, 0)).normalized;
            float     f  = viewOnly ? 4f : 7f;        // reserved sign size in game coordinates
            ItemClass connectionClass = segmentInfo.GetConnectionClass();
            int       maxNumSigns     = 0;

            if (connectionClass.m_service == ItemClass.Service.Road)
            {
                maxNumSigns = roadVehicleTypes.Length;
            }
            else if (connectionClass.m_service == ItemClass.Service.PublicTransport && connectionClass.m_subService == ItemClass.SubService.PublicTransportTrain)
            {
                maxNumSigns = railVehicleTypes.Length;
            }
            //Vector3 zero = center - 0.5f * (float)(numLanes + numDirections - 1) * f * (xu + yu); // "bottom left"
            Vector3 zero = center - 0.5f * (float)(numLanes - 1 + numDirections - 1) * f * xu - 0.5f * (float)maxNumSigns * f * yu;             // "bottom left"

            /*if (!viewOnly)
             *      Log._Debug($"xu: {xu.ToString()} yu: {yu.ToString()} center: {center.ToString()} zero: {zero.ToString()} numLanes: {numLanes} numDirections: {numDirections}");*/

            uint x        = 0;
            var  guiColor = GUI.color;
            // TODO refactor vehicle mask
            List <object[]>             sortedLanes = TrafficManagerTool.GetSortedVehicleLanes(segmentId, segmentInfo, null, VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train);
            bool                        hovered     = false;
            HashSet <NetInfo.Direction> directions  = new HashSet <NetInfo.Direction>();
            int sortedLaneIndex = -1;

            foreach (object[] laneData in sortedLanes)
            {
                ++sortedLaneIndex;
                uint laneId    = (uint)laneData[0];
                uint laneIndex = (uint)laneData[2];

                NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex];
                if (!directions.Contains(laneInfo.m_direction))
                {
                    if (directions.Count > 0)
                    {
                        ++x;                         // space between different directions
                    }
                    directions.Add(laneInfo.m_direction);
                }

                ExtVehicleType[] possibleVehicleTypes = null;
                if (VehicleRestrictionsManager.Instance.IsRoadLane(laneInfo))
                {
                    possibleVehicleTypes = roadVehicleTypes;
                }
                else if (VehicleRestrictionsManager.Instance.IsRailLane(laneInfo))
                {
                    possibleVehicleTypes = railVehicleTypes;
                }
                else
                {
                    ++x;
                    continue;
                }

                ExtVehicleType allowedTypes = VehicleRestrictionsManager.Instance.GetAllowedVehicleTypes(segmentId, segmentInfo, laneIndex, laneInfo);

                uint y = 0;
#if DEBUGx
                Vector3 labelCenter = zero + f * (float)x * xu + f * (float)y * yu;                 // in game coordinates

                var labelScreenPos = Camera.main.WorldToScreenPoint(labelCenter);
                labelScreenPos.y = Screen.height - labelScreenPos.y;
                diff             = labelCenter - camPos;

                var labelZoom = 1.0f / diff.magnitude * 100f;
                _counterStyle.fontSize         = (int)(11f * labelZoom);
                _counterStyle.normal.textColor = new Color(1f, 1f, 0f);

                string  labelStr  = $"Idx {laneIndex}";
                Vector2 dim       = _counterStyle.CalcSize(new GUIContent(labelStr));
                Rect    labelRect = new Rect(labelScreenPos.x - dim.x / 2f, labelScreenPos.y, dim.x, dim.y);
                GUI.Label(labelRect, labelStr, _counterStyle);

                ++y;
#endif
                foreach (ExtVehicleType vehicleType in possibleVehicleTypes)
                {
                    bool allowed = VehicleRestrictionsManager.Instance.IsAllowed(allowedTypes, vehicleType);
                    if (allowed && viewOnly)
                    {
                        continue;                         // do not draw allowed vehicles in view-only mode
                    }
                    bool hoveredHandle;
                    DrawRestrictionsSign(viewOnly, camPos, out diff, xu, yu, f, zero, x, y, ref guiColor, TrafficLightToolTextureResources.VehicleRestrictionTextures[vehicleType][allowed], out hoveredHandle);
                    if (hoveredHandle)
                    {
                        hovered = true;
                    }

                    if (hoveredHandle && MainTool.CheckClicked())
                    {
                        // toggle vehicle restrictions
                        //Log._Debug($"Setting vehicle restrictions of segment {segmentId}, lane idx {laneIndex}, {vehicleType.ToString()} to {!allowed}");
                        VehicleRestrictionsManager.Instance.ToggleAllowedType(segmentId, segmentInfo, laneIndex, laneId, laneInfo, vehicleType, !allowed);
                        stateUpdated = true;

                        // TODO use SegmentTraverser
                        if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
                        {
                            ApplyRestrictionsToAllSegments(sortedLaneIndex);
                        }
                    }

                    ++y;
                }

                ++x;
            }

            guiColor.a = 1f;
            GUI.color  = guiColor;

            return(hovered);
        }
Example #6
0
        private bool drawSignHandles(ushort nodeId, bool viewOnly, ref Vector3 camPos, out bool stateUpdated)
        {
            bool hovered = false;

            stateUpdated = false;
            if (!LoadingExtension.IsPathManagerCompatible)
            {
                return(false);
            }

            if (viewOnly && !Options.junctionRestrictionsOverlay && TrafficManagerTool.GetToolMode() != ToolMode.JunctionRestrictions)
            {
                return(false);
            }

            NetManager netManager = Singleton <NetManager> .instance;
            var        guiColor   = GUI.color;

            Vector3 nodePos = Singleton <NetManager> .instance.m_nodes.m_buffer[nodeId].m_position;

            for (int i = 0; i < 8; ++i)
            {
                ushort segmentId = netManager.m_nodes.m_buffer[nodeId].GetSegment(i);
                if (segmentId == 0)
                {
                    continue;
                }

                SegmentGeometry geometry  = SegmentGeometry.Get(segmentId);
                bool            startNode = geometry.StartNodeId() == nodeId;
                bool            incoming  = geometry.IsIncoming(startNode);

                int numSignsPerRow = incoming ? 2 : 1;

                NetInfo segmentInfo = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].Info;

                ItemClass connectionClass = segmentInfo.GetConnectionClass();
                if (connectionClass.m_service != ItemClass.Service.Road)
                {
                    continue;                     // only for road junctions
                }
                // draw all junction restriction signs
                Vector3 segmentCenterPos = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_bounds.center;
                Vector3 yu = (segmentCenterPos - nodePos).normalized;
                Vector3 xu = Vector3.Cross(yu, new Vector3(0, 1f, 0)).normalized;
                float   f  = viewOnly ? 6f : 7f;              // reserved sign size in game coordinates

                Vector3 centerStart = nodePos + yu * (viewOnly ? 5f : 14f);
                Vector3 zero        = centerStart - 0.5f * (float)(numSignsPerRow - 1) * f * xu;        // "top left"
                if (viewOnly)
                {
                    if (TrafficPriorityManager.IsLeftHandDrive())
                    {
                        zero -= xu * 8f;
                    }
                    else
                    {
                        zero += xu * 8f;
                    }
                }

                bool signHovered;
                int  x = 0;
                int  y = 0;

                // draw "lane-changing when going straight allowed" sign at (0; 0)
                bool allowed = JunctionRestrictionsManager.Instance().IsLaneChangingAllowedWhenGoingStraight(segmentId, startNode);
                if (incoming && (!viewOnly || allowed != Options.allowLaneChangesWhileGoingStraight))
                {
                    DrawSign(viewOnly, ref camPos, ref xu, ref yu, f, ref zero, x, y, ref guiColor, allowed ? TrafficLightToolTextureResources.LaneChangeAllowedTexture2D : TrafficLightToolTextureResources.LaneChangeForbiddenTexture2D, out signHovered);
                    if (signHovered)
                    {
                        hovered = true;
                        if (MainTool.CheckClicked())
                        {
                            JunctionRestrictionsManager.Instance().ToggleLaneChangingAllowedWhenGoingStraight(segmentId, startNode);
                            stateUpdated = true;
                        }
                    }

                    if (viewOnly)
                    {
                        ++y;
                    }
                    else
                    {
                        ++x;
                    }
                }

                // draw "u-turns allowed" sign at (1; 0)
                allowed = JunctionRestrictionsManager.Instance().IsUturnAllowed(segmentId, startNode);
                if (incoming && (!viewOnly || allowed != Options.allowUTurns))
                {
                    DrawSign(viewOnly, ref camPos, ref xu, ref yu, f, ref zero, x, y, ref guiColor, allowed ? TrafficLightToolTextureResources.UturnAllowedTexture2D : TrafficLightToolTextureResources.UturnForbiddenTexture2D, out signHovered);
                    if (signHovered)
                    {
                        hovered = true;

                        if (MainTool.CheckClicked())
                        {
                            JunctionRestrictionsManager.Instance().ToggleUturnAllowed(segmentId, startNode);
                            stateUpdated = true;
                        }
                    }

                    ++y;
                    x = 0;
                }

                // draw "entering blocked junctions allowed" sign at (0; 1)
                allowed = JunctionRestrictionsManager.Instance().IsEnteringBlockedJunctionAllowed(segmentId, startNode);
                if (incoming && (!viewOnly || allowed != Options.allowEnterBlockedJunctions))
                {
                    DrawSign(viewOnly, ref camPos, ref xu, ref yu, f, ref zero, x, y, ref guiColor, allowed ? TrafficLightToolTextureResources.EnterBlockedJunctionAllowedTexture2D : TrafficLightToolTextureResources.EnterBlockedJunctionForbiddenTexture2D, out signHovered);
                    if (signHovered)
                    {
                        hovered = true;

                        if (MainTool.CheckClicked())
                        {
                            JunctionRestrictionsManager.Instance().ToggleEnteringBlockedJunctionAllowed(segmentId, startNode);
                            stateUpdated = true;
                        }
                    }

                    if (viewOnly)
                    {
                        ++y;
                    }
                    else
                    {
                        ++x;
                    }
                }

                // draw "pedestrian crossing allowed" sign at (1; 1)
                allowed = JunctionRestrictionsManager.Instance().IsPedestrianCrossingAllowed(segmentId, startNode);
                if (!viewOnly || !allowed)
                {
                    DrawSign(viewOnly, ref camPos, ref xu, ref yu, f, ref zero, x, y, ref guiColor, allowed ? TrafficLightToolTextureResources.PedestrianCrossingAllowedTexture2D : TrafficLightToolTextureResources.PedestrianCrossingForbiddenTexture2D, out signHovered);
                    if (signHovered)
                    {
                        hovered = true;

                        if (MainTool.CheckClicked())
                        {
                            JunctionRestrictionsManager.Instance().TogglePedestrianCrossingAllowed(segmentId, startNode);
                            stateUpdated = true;
                        }
                    }
                }
            }

            guiColor.a = 1f;
            GUI.color  = guiColor;

            return(hovered);
        }
        private void ShowSigns(bool viewOnly)
        {
            Quaternion camRot = Camera.main.transform.rotation;
            Vector3    camPos = Camera.main.transform.position;

            NetManager        netManager        = Singleton <NetManager> .instance;
            SpeedLimitManager speedLimitManager = SpeedLimitManager.Instance;

            if (lastCamPos == null || lastCamRot == null || !lastCamRot.Equals(camRot) || !lastCamPos.Equals(camPos))
            {
                // cache visible segments
                currentlyVisibleSegmentIds.Clear();

                for (uint segmentId = 1; segmentId < NetManager.MAX_SEGMENT_COUNT; ++segmentId)
                {
                    if ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Created) == NetSegment.Flags.None)
                    {
                        continue;
                    }

                    /*if ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Untouchable) != NetSegment.Flags.None)
                     *      continue;*/

                    if ((netManager.m_segments.m_buffer[segmentId].m_bounds.center - camPos).magnitude > TrafficManagerTool.PriorityCloseLod)
                    {
                        continue;                         // do not draw if too distant
                    }
                    Vector3 screenPos = Camera.main.WorldToScreenPoint(netManager.m_segments.m_buffer[segmentId].m_bounds.center);
                    if (screenPos.z < 0)
                    {
                        continue;
                    }

                    if (!speedLimitManager.MayHaveCustomSpeedLimits((ushort)segmentId, ref netManager.m_segments.m_buffer[segmentId]))
                    {
                        continue;
                    }

                    currentlyVisibleSegmentIds.Add((ushort)segmentId);
                }

                lastCamPos = camPos;
                lastCamRot = camRot;
            }

            bool handleHovered = false;

            foreach (ushort segmentId in currentlyVisibleSegmentIds)
            {
                Vector3 screenPos = Camera.main.WorldToScreenPoint(netManager.m_segments.m_buffer[segmentId].m_bounds.center);
                screenPos.y = Screen.height - screenPos.y;
                if (screenPos.z < 0)
                {
                    continue;
                }

                NetInfo segmentInfo = netManager.m_segments.m_buffer[segmentId].Info;

                // draw speed limits
                if (TrafficManagerTool.GetToolMode() != ToolMode.VehicleRestrictions || segmentId != SelectedSegmentId)                   // no speed limit overlay on selected segment when in vehicle restrictions mode
                {
                    if (drawSpeedLimitHandles((ushort)segmentId, viewOnly, ref camPos))
                    {
                        handleHovered = true;
                    }
                }
            }
            overlayHandleHovered = handleHovered;
        }