private void DrawSpeedLimitHandles(ushort segmentId, ref NetSegment segment, bool viewOnly, ref Vector3 camPos) { if (viewOnly && !Options.speedLimitsOverlay) { return; } Vector3 center = segment.m_bounds.center; NetManager netManager = Singleton <NetManager> .instance; SpeedValue speedLimitToSet = viewOnly ? new SpeedValue(-1f) : currentPaletteSpeedLimit; bool showPerLane = showLimitsPerLane; if (!viewOnly) { showPerLane = showLimitsPerLane ^ (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)); } // US signs are rectangular, all other are round float speedLimitSignVerticalScale = GetVerticalTextureScale(); if (showPerLane) { // show individual speed limit handle per lane int numLanes = TrafficManagerTool.GetSegmentNumVehicleLanes( segmentId, null, out int numDirections, SpeedLimitManager.VEHICLE_TYPES); NetInfo segmentInfo = segment.Info; Vector3 yu = (segment.m_endDirection - segment.m_startDirection).normalized; Vector3 xu = Vector3.Cross(yu, new Vector3(0, 1f, 0)).normalized; // if ((segment.m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.None) { // xu = -xu; } float f = viewOnly ? 4f : 7f; // reserved sign size in game coordinates Vector3 zero = center - (0.5f * (((numLanes - 1) + numDirections) - 1) * f * xu); uint x = 0; IList <LanePos> sortedLanes = Constants.ServiceFactory.NetService.GetSortedLanes( segmentId, ref segment, null, SpeedLimitManager.LANE_TYPES, SpeedLimitManager.VEHICLE_TYPES); bool onlyMonorailLanes = sortedLanes.Count > 0; if (!viewOnly) { foreach (LanePos laneData in sortedLanes) { byte laneIndex = laneData.laneIndex; NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex]; if ((laneInfo.m_vehicleType & VehicleInfo.VehicleType.Monorail) == VehicleInfo.VehicleType.None) { onlyMonorailLanes = false; break; } } } var directions = new HashSet <NetInfo.Direction>(); int sortedLaneIndex = -1; foreach (LanePos laneData in sortedLanes) { ++sortedLaneIndex; uint laneId = laneData.laneId; byte laneIndex = laneData.laneIndex; NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex]; if (!directions.Contains(laneInfo.m_finalDirection)) { if (directions.Count > 0) { ++x; // space between different directions } directions.Add(laneInfo.m_finalDirection); } SpeedValue laneSpeedLimit = new SpeedValue( SpeedLimitManager.Instance.GetCustomSpeedLimit(laneId)); bool hoveredHandle = MainTool.DrawGenericOverlayGridTexture( SpeedLimitTextures.GetSpeedLimitTexture(laneSpeedLimit), camPos, zero, f, f, xu, yu, x, 0, speedLimitSignSize, speedLimitSignSize * speedLimitSignVerticalScale, !viewOnly); if (!viewOnly && !onlyMonorailLanes && ((laneInfo.m_vehicleType & VehicleInfo.VehicleType.Monorail) != VehicleInfo.VehicleType.None)) { Texture2D tex1 = RoadUITextures.VehicleInfoSignTextures[ LegacyExtVehicleType.ToNew(ExtVehicleType.PassengerTrain)]; MainTool.DrawStaticSquareOverlayGridTexture( tex1, camPos, zero, f, xu, yu, x, 1, speedLimitSignSize); } if (hoveredHandle) { } if (hoveredHandle && Input.GetMouseButton(0) && !IsCursorInPanel()) { SpeedLimitManager.Instance.SetSpeedLimit( segmentId, laneIndex, laneInfo, laneId, speedLimitToSet.GameUnits); if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) { int slIndexCopy = sortedLaneIndex; SegmentLaneTraverser.Traverse( segmentId, SegmentTraverser.TraverseDirection.AnyDirection, SegmentTraverser.TraverseSide.AnySide, SegmentLaneTraverser.LaneStopCriterion.LaneCount, SegmentTraverser.SegmentStopCriterion.Junction, SpeedLimitManager.LANE_TYPES, SpeedLimitManager.VEHICLE_TYPES, data => { if (data.SegVisitData.Initial) { return(true); } if (slIndexCopy != data.SortedLaneIndex) { return(true); } Constants.ServiceFactory.NetService.ProcessSegment( data.SegVisitData.CurSeg.segmentId, (ushort curSegmentId, ref NetSegment curSegment) => { NetInfo.Lane curLaneInfo = curSegment.Info.m_lanes[ data.CurLanePos.laneIndex]; SpeedLimitManager.Instance.SetSpeedLimit( curSegmentId, data.CurLanePos.laneIndex, curLaneInfo, data.CurLanePos.laneId, speedLimitToSet.GameUnits); return(true); }); return(true); }); } } ++x; } } else { // draw speedlimits over mean middle points of lane beziers if (!segmentCenterByDir.TryGetValue( segmentId, out Dictionary <NetInfo.Direction, Vector3> segCenter)) { segCenter = new Dictionary <NetInfo.Direction, Vector3>(); segmentCenterByDir.Add(segmentId, segCenter); TrafficManagerTool.CalculateSegmentCenterByDir(segmentId, segCenter); } foreach (KeyValuePair <NetInfo.Direction, Vector3> e in segCenter) { bool visible = MainTool.WorldToScreenPoint(e.Value, out Vector3 screenPos); if (!visible) { continue; } float zoom = (1.0f / (e.Value - camPos).magnitude) * 100f * MainTool.GetBaseZoom(); float size = (viewOnly ? 0.8f : 1f) * speedLimitSignSize * zoom; Color guiColor = GUI.color; var boundingBox = new Rect(screenPos.x - (size / 2), screenPos.y - (size / 2), size, size * speedLimitSignVerticalScale); bool hoveredHandle = !viewOnly && TrafficManagerTool.IsMouseOver(boundingBox); guiColor.a = TrafficManagerTool.GetHandleAlpha(hoveredHandle); if (hoveredHandle) { // mouse hovering over sign } // Draw something right here, the road sign texture GUI.color = guiColor; SpeedValue displayLimit = new SpeedValue( SpeedLimitManager.Instance.GetCustomSpeedLimit(segmentId, e.Key)); Texture2D tex = SpeedLimitTextures.GetSpeedLimitTexture(displayLimit); GUI.DrawTexture(boundingBox, tex); if (hoveredHandle && Input.GetMouseButton(0) && !IsCursorInPanel()) { // change the speed limit to the selected one // Log._Debug($"Setting speed limit of segment {segmentId}, dir {e.Key.ToString()} // to {speedLimitToSet}"); SpeedLimitManager.Instance.SetSpeedLimit(segmentId, e.Key, currentPaletteSpeedLimit.GameUnits); if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) { NetInfo.Direction normDir = e.Key; if ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None) { normDir = NetInfo.InvertDirection(normDir); } SegmentLaneTraverser.Traverse( segmentId, SegmentTraverser.TraverseDirection.AnyDirection, SegmentTraverser.TraverseSide.AnySide, SegmentLaneTraverser.LaneStopCriterion.LaneCount, SegmentTraverser.SegmentStopCriterion.Junction, SpeedLimitManager.LANE_TYPES, SpeedLimitManager.VEHICLE_TYPES, data => { if (data.SegVisitData.Initial) { return(true); } bool reverse = data.SegVisitData.ViaStartNode == data.SegVisitData.ViaInitialStartNode; ushort otherSegmentId = data.SegVisitData.CurSeg.segmentId; NetInfo otherSegmentInfo = netManager.m_segments.m_buffer[otherSegmentId].Info; byte laneIndex = data.CurLanePos.laneIndex; NetInfo.Lane laneInfo = otherSegmentInfo.m_lanes[laneIndex]; NetInfo.Direction otherNormDir = laneInfo.m_finalDirection; if (((netManager.m_segments.m_buffer[otherSegmentId].m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None) ^ reverse) { otherNormDir = NetInfo.InvertDirection(otherNormDir); } if (otherNormDir == normDir) { SpeedLimitManager.Instance.SetSpeedLimit( otherSegmentId, laneInfo.m_finalDirection, speedLimitToSet.GameUnits); } return(true); }); } } guiColor.a = 1f; GUI.color = guiColor; } } }
private bool DrawParkingRestrictionHandles(ushort segmentId, bool clicked, ref NetSegment segment, bool viewOnly, ref Vector3 camPos) { if (viewOnly && !Options.parkingRestrictionsOverlay) { return(false); } NetManager netManager = Singleton <NetManager> .instance; ParkingRestrictionsManager parkingManager = ParkingRestrictionsManager.Instance; bool hovered = false; // draw parking restriction signs over mean middle points of lane beziers if (!segmentCenterByDir.TryGetValue( segmentId, out Dictionary <NetInfo.Direction, Vector3> segCenter)) { segCenter = new Dictionary <NetInfo.Direction, Vector3>(); segmentCenterByDir.Add(segmentId, segCenter); TrafficManagerTool.CalculateSegmentCenterByDir(segmentId, segCenter); } foreach (KeyValuePair <NetInfo.Direction, Vector3> e in segCenter) { bool allowed = parkingManager.IsParkingAllowed(segmentId, e.Key); if (allowed && viewOnly) { continue; } bool visible = MainTool.WorldToScreenPoint(e.Value, out Vector3 screenPos); if (!visible) { continue; } float zoom = (1.0f / (e.Value - camPos).magnitude) * 100f * MainTool.GetBaseZoom(); float size = (viewOnly ? 0.8f : 1f) * SIGN_SIZE * zoom; Color guiColor = GUI.color; Rect boundingBox = new Rect( screenPos.x - (size / 2), screenPos.y - (size / 2), size, size); if (Options.speedLimitsOverlay) { boundingBox.y -= size + 10f; } bool hoveredHandle = !viewOnly && TrafficManagerTool.IsMouseOver(boundingBox); guiColor.a = TrafficManagerTool.GetHandleAlpha(hoveredHandle); if (hoveredHandle) { // mouse hovering over sign hovered = true; } GUI.color = guiColor; GUI.DrawTexture(boundingBox, RoadUITextures.ParkingRestrictionTextures[allowed]); if (hoveredHandle && clicked && !IsCursorInPanel() && parkingManager.ToggleParkingAllowed(segmentId, e.Key)) { allowed = !allowed; if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) { NetInfo.Direction normDir = e.Key; if ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None) { normDir = NetInfo.InvertDirection(normDir); } bool LaneVisitor(SegmentLaneVisitData data) { if (data.SegVisitData.Initial) { return(true); } bool reverse = data.SegVisitData.ViaStartNode == data.SegVisitData.ViaInitialStartNode; ushort otherSegmentId = data.SegVisitData.CurSeg.segmentId; NetInfo otherSegmentInfo = netManager.m_segments.m_buffer[otherSegmentId].Info; byte laneIndex = data.CurLanePos.laneIndex; NetInfo.Lane laneInfo = otherSegmentInfo.m_lanes[laneIndex]; NetInfo.Direction otherNormDir = laneInfo.m_finalDirection; if (((netManager.m_segments.m_buffer[otherSegmentId].m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None) ^ reverse) { otherNormDir = NetInfo.InvertDirection(otherNormDir); } if (otherNormDir == normDir) { parkingManager.SetParkingAllowed( otherSegmentId, laneInfo.m_finalDirection, allowed); } return(true); } SegmentLaneTraverser.Traverse( segmentId, SegmentTraverser.TraverseDirection.AnyDirection, SegmentTraverser.TraverseSide.AnySide, SegmentLaneTraverser.LaneStopCriterion.LaneCount, SegmentTraverser.SegmentStopCriterion.Junction, ParkingRestrictionsManager.LANE_TYPES, ParkingRestrictionsManager.VEHICLE_TYPES, LaneVisitor); } } guiColor.a = 1f; GUI.color = guiColor; } return(hovered); }
private bool drawSpeedLimitHandles(ushort segmentId, bool viewOnly, ref Vector3 camPos) { if (viewOnly && !Options.speedLimitsOverlay) { return(false); } // draw speedlimits over mean middle points of lane beziers if (!segmentCenterByDir.ContainsKey(segmentId)) { segmentCenterByDir.Add(segmentId, new Dictionary <NetInfo.Direction, Vector3>()); TrafficManagerTool.CalculateSegmentCenterByDir(segmentId, segmentCenterByDir[segmentId]); } bool hovered = false; foreach (KeyValuePair <NetInfo.Direction, Vector3> e in segmentCenterByDir[segmentId]) { var screenPos = Camera.main.WorldToScreenPoint(e.Value); screenPos.y = Screen.height - screenPos.y; float zoom = 1.0f / (e.Value - camPos).magnitude * 100f * MainTool.GetBaseZoom(); float size = speedLimitSignSize * zoom; Color guiColor = GUI.color; Rect boundingBox = new Rect(screenPos.x - size / 2, screenPos.y - size / 2, size, size); bool hoveredHandle = !viewOnly && TrafficManagerTool.IsMouseOver(boundingBox); if (hoveredHandle) { // mouse hovering over sign hovered = true; guiColor.a = 0.8f; } else { guiColor.a = 0.5f; } GUI.color = guiColor; try { GUI.DrawTexture(boundingBox, TrafficLightToolTextureResources.SpeedLimitTextures[SpeedLimitManager.Instance.GetCustomSpeedLimit(segmentId, e.Key)]); } catch (Exception ex) { Log.Error("segment " + segmentId + " limit: " + SpeedLimitManager.Instance.GetCustomSpeedLimit(segmentId, e.Key) + ", ex: " + ex.ToString()); } if (hoveredHandle && Input.GetMouseButton(0) && !IsCursorInPanel()) { // change the speed limit to the selected one ushort speedLimitToSet = SpeedLimitManager.Instance.AvailableSpeedLimits[curSpeedLimitIndex]; //Log._Debug($"Setting speed limit of segment {segmentId}, dir {e.Key.ToString()} to {speedLimitToSet}"); SpeedLimitManager.Instance.SetSpeedLimit(segmentId, e.Key, speedLimitToSet); // TODO use SegmentTraverser if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) { // apply new speed limit to connected segments NetInfo selectedSegmentInfo = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].Info; List <object[]> selectedSortedLanes = TrafficManagerTool.GetSortedVehicleLanes(segmentId, selectedSegmentInfo, null, VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Metro | VehicleInfo.VehicleType.Train); // TODO refactor vehicle mask LinkedList <ushort> nodesToProcess = new LinkedList <ushort>(); HashSet <ushort> processedNodes = new HashSet <ushort>(); HashSet <ushort> processedSegments = new HashSet <ushort>(); processedSegments.Add(SelectedSegmentId); ushort selectedStartNodeId = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_startNode; ushort selectedEndNodeId = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_endNode; if (selectedStartNodeId != 0) { nodesToProcess.AddFirst(selectedStartNodeId); } if (selectedEndNodeId != 0) { nodesToProcess.AddFirst(selectedEndNodeId); } while (nodesToProcess.First != null) { ushort nodeId = nodesToProcess.First.Value; nodesToProcess.RemoveFirst(); processedNodes.Add(nodeId); if (Singleton <NetManager> .instance.m_nodes.m_buffer[nodeId].CountSegments() > 2) { continue; // junction. stop. } // explore segments at node for (var s = 0; s < 8; s++) { var otherSegmentId = Singleton <NetManager> .instance.m_nodes.m_buffer[nodeId].GetSegment(s); if (otherSegmentId <= 0 || processedSegments.Contains(otherSegmentId)) { continue; } processedSegments.Add(otherSegmentId); NetInfo segmentInfo = Singleton <NetManager> .instance.m_segments.m_buffer[otherSegmentId].Info; List <object[]> sortedLanes = TrafficManagerTool.GetSortedVehicleLanes(otherSegmentId, segmentInfo, null, VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Metro | VehicleInfo.VehicleType.Train); // TODO refactor vehicle mask if (sortedLanes.Count == selectedSortedLanes.Count) { // number of lanes matches selected segment for (int i = 0; i < sortedLanes.Count; ++i) { object[] selectedLaneData = selectedSortedLanes[i]; object[] laneData = sortedLanes[i]; uint selectedLaneId = (uint)selectedLaneData[0]; uint selectedLaneIndex = (uint)selectedLaneData[2]; NetInfo.Lane selectedLaneInfo = segmentInfo.m_lanes[selectedLaneIndex]; uint laneId = (uint)laneData[0]; uint laneIndex = (uint)laneData[2]; NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex]; if (laneInfo.m_finalDirection == e.Key) { SpeedLimitManager.Instance.SetSpeedLimit(otherSegmentId, laneInfo.m_finalDirection, speedLimitToSet); } // apply restrictions of selected segment & lane //VehicleRestrictionsManager.SetAllowedVehicleTypes(otherSegmentId, segmentInfo, laneIndex, laneInfo, laneId, VehicleRestrictionsManager.GetAllowedVehicleTypes(SelectedSegmentId, selectedSegmentInfo, selectedLaneIndex, selectedLaneInfo)); } // add nodes to explore ushort startNodeId = Singleton <NetManager> .instance.m_segments.m_buffer[otherSegmentId].m_startNode; ushort endNodeId = Singleton <NetManager> .instance.m_segments.m_buffer[otherSegmentId].m_endNode; if (startNodeId != 0 && !processedNodes.Contains(startNodeId)) { nodesToProcess.AddFirst(startNodeId); } if (endNodeId != 0 && !processedNodes.Contains(endNodeId)) { nodesToProcess.AddFirst(endNodeId); } } } } } //mouseClickProcessed = true; } guiColor.a = 1f; GUI.color = guiColor; } return(hovered); }
private bool drawSpeedLimitHandles(ushort segmentId, ref NetSegment segment, bool viewOnly, ref Vector3 camPos) { if (viewOnly && !Options.speedLimitsOverlay) { return(false); } Vector3 center = segment.m_bounds.center; NetManager netManager = Singleton <NetManager> .instance; bool hovered = false; ushort speedLimitToSet = viewOnly ? (ushort)0 : SpeedLimitManager.Instance.AvailableSpeedLimits[curSpeedLimitIndex]; bool showPerLane = showLimitsPerLane; if (!viewOnly) { showPerLane = showLimitsPerLane ^ (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)); } if (showPerLane) { // show individual speed limit handle per lane int numDirections; int numLanes = TrafficManagerTool.GetSegmentNumVehicleLanes(segmentId, null, out numDirections, SpeedLimitManager.VEHICLE_TYPES); NetInfo segmentInfo = segment.Info; Vector3 yu = (segment.m_endDirection - segment.m_startDirection).normalized; Vector3 xu = Vector3.Cross(yu, new Vector3(0, 1f, 0)).normalized; /*if ((segment.m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.None) { * xu = -xu; * }*/ float f = viewOnly ? 4f : 7f; // reserved sign size in game coordinates Vector3 zero = center - 0.5f * (float)(numLanes - 1 + numDirections - 1) * f * xu; uint x = 0; var guiColor = GUI.color; IList <LanePos> sortedLanes = Constants.ServiceFactory.NetService.GetSortedLanes(segmentId, ref segment, null, SpeedLimitManager.LANE_TYPES, SpeedLimitManager.VEHICLE_TYPES); bool onlyMonorailLanes = sortedLanes.Count > 0; if (!viewOnly) { foreach (LanePos laneData in sortedLanes) { byte laneIndex = laneData.laneIndex; NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex]; if ((laneInfo.m_vehicleType & VehicleInfo.VehicleType.Monorail) == VehicleInfo.VehicleType.None) { onlyMonorailLanes = false; break; } } } HashSet <NetInfo.Direction> directions = new HashSet <NetInfo.Direction>(); int sortedLaneIndex = -1; foreach (LanePos laneData in sortedLanes) { ++sortedLaneIndex; uint laneId = laneData.laneId; byte laneIndex = laneData.laneIndex; NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex]; if (!directions.Contains(laneInfo.m_finalDirection)) { if (directions.Count > 0) { ++x; // space between different directions } directions.Add(laneInfo.m_finalDirection); } bool hoveredHandle = MainTool.DrawGenericSquareOverlayGridTexture(TextureResources.SpeedLimitTextures[SpeedLimitManager.Instance.GetCustomSpeedLimit(laneId)], camPos, zero, f, xu, yu, x, 0, speedLimitSignSize, !viewOnly, 0.5f, 0.8f); if (!viewOnly && !onlyMonorailLanes && (laneInfo.m_vehicleType & VehicleInfo.VehicleType.Monorail) != VehicleInfo.VehicleType.None) { MainTool.DrawStaticSquareOverlayGridTexture(TextureResources.VehicleInfoSignTextures[ExtVehicleType.PassengerTrain], camPos, zero, f, xu, yu, x, 1, speedLimitSignSize, 0.5f); } if (hoveredHandle) { hovered = true; } if (hoveredHandle && Input.GetMouseButton(0) && !IsCursorInPanel()) { SpeedLimitManager.Instance.SetSpeedLimit(segmentId, laneIndex, laneInfo, laneId, speedLimitToSet); if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) { SegmentLaneTraverser.Traverse(segmentId, SegmentTraverser.TraverseDirection.AnyDirection, SegmentTraverser.TraverseSide.AnySide, SegmentLaneTraverser.LaneStopCriterion.LaneCount, SegmentTraverser.SegmentStopCriterion.Junction, SpeedLimitManager.LANE_TYPES, SpeedLimitManager.VEHICLE_TYPES, delegate(SegmentLaneVisitData data) { if (data.segVisitData.initial) { return(true); } if (sortedLaneIndex != data.sortedLaneIndex) { return(true); } Constants.ServiceFactory.NetService.ProcessSegment(data.segVisitData.curGeo.SegmentId, delegate(ushort curSegmentId, ref NetSegment curSegment) { NetInfo.Lane curLaneInfo = curSegment.Info.m_lanes[data.curLanePos.laneIndex]; SpeedLimitManager.Instance.SetSpeedLimit(curSegmentId, data.curLanePos.laneIndex, curLaneInfo, data.curLanePos.laneId, speedLimitToSet); return(true); }); return(true); }); } } ++x; } } else { // draw speedlimits over mean middle points of lane beziers Dictionary <NetInfo.Direction, Vector3> segCenter; if (!segmentCenterByDir.TryGetValue(segmentId, out segCenter)) { segCenter = new Dictionary <NetInfo.Direction, Vector3>(); segmentCenterByDir.Add(segmentId, segCenter); TrafficManagerTool.CalculateSegmentCenterByDir(segmentId, segCenter); } foreach (KeyValuePair <NetInfo.Direction, Vector3> e in segCenter) { Vector3 screenPos; bool visible = MainTool.WorldToScreenPoint(e.Value, out screenPos); if (!visible) { continue; } float zoom = 1.0f / (e.Value - camPos).magnitude * 100f * MainTool.GetBaseZoom(); float size = (viewOnly ? 0.8f : 1f) * speedLimitSignSize * zoom; Color guiColor = GUI.color; Rect boundingBox = new Rect(screenPos.x - size / 2, screenPos.y - size / 2, size, size); bool hoveredHandle = !viewOnly && TrafficManagerTool.IsMouseOver(boundingBox); if (hoveredHandle) { // mouse hovering over sign hovered = true; guiColor.a = 0.8f; } else { guiColor.a = 0.5f; } GUI.color = guiColor; GUI.DrawTexture(boundingBox, TextureResources.SpeedLimitTextures[SpeedLimitManager.Instance.GetCustomSpeedLimit(segmentId, e.Key)]); if (hoveredHandle && Input.GetMouseButton(0) && !IsCursorInPanel()) { // change the speed limit to the selected one //Log._Debug($"Setting speed limit of segment {segmentId}, dir {e.Key.ToString()} to {speedLimitToSet}"); SpeedLimitManager.Instance.SetSpeedLimit(segmentId, e.Key, speedLimitToSet); if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) { NetInfo.Direction normDir = e.Key; if ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None) { normDir = NetInfo.InvertDirection(normDir); } SegmentLaneTraverser.Traverse(segmentId, SegmentTraverser.TraverseDirection.AnyDirection, SegmentTraverser.TraverseSide.AnySide, SegmentLaneTraverser.LaneStopCriterion.LaneCount, SegmentTraverser.SegmentStopCriterion.Junction, SpeedLimitManager.LANE_TYPES, SpeedLimitManager.VEHICLE_TYPES, delegate(SegmentLaneVisitData data) { if (data.segVisitData.initial) { return(true); } bool reverse = data.segVisitData.viaStartNode == data.segVisitData.viaInitialStartNode; ushort otherSegmentId = data.segVisitData.curGeo.SegmentId; NetInfo otherSegmentInfo = netManager.m_segments.m_buffer[otherSegmentId].Info; uint laneId = data.curLanePos.laneId; byte laneIndex = data.curLanePos.laneIndex; NetInfo.Lane laneInfo = otherSegmentInfo.m_lanes[laneIndex]; NetInfo.Direction otherNormDir = laneInfo.m_finalDirection; if ((netManager.m_segments.m_buffer[otherSegmentId].m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None ^ reverse) { otherNormDir = NetInfo.InvertDirection(otherNormDir); } if (otherNormDir == normDir) { SpeedLimitManager.Instance.SetSpeedLimit(otherSegmentId, laneInfo.m_finalDirection, speedLimitToSet); } return(true); }); } } guiColor.a = 1f; GUI.color = guiColor; } } return(hovered); }
private bool drawSpeedLimitHandles(ushort segmentId, bool viewOnly) { if (!LoadingExtension.IsPathManagerCompatible) { return(false); } if (viewOnly && !Options.speedLimitsOverlay) { return(false); } // draw speedlimits over mean middle points of lane beziers if (!segmentCenterByDir.ContainsKey(segmentId)) { segmentCenterByDir.Add(segmentId, new Dictionary <NetInfo.Direction, Vector3>()); TrafficManagerTool.CalculateSegmentCenterByDir(segmentId, segmentCenterByDir[segmentId]); } bool hovered = false; foreach (KeyValuePair <NetInfo.Direction, Vector3> e in segmentCenterByDir[segmentId]) { Vector3 signPos = e.Value; var screenPos = Camera.main.WorldToScreenPoint(signPos); screenPos.y = Screen.height - screenPos.y; if (screenPos.z < 0) { return(false); } var camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position; var diff = signPos - camPos; if (diff.magnitude > TrafficManagerTool.PriorityCloseLod) { return(false); // do not draw if too distant } ItemClass connectionClass = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].Info.GetConnectionClass(); if (!(connectionClass.m_service == ItemClass.Service.Road || (connectionClass.m_service == ItemClass.Service.PublicTransport && connectionClass.m_subService == ItemClass.SubService.PublicTransportTrain))) { return(false); } var zoom = 1.0f / diff.magnitude * 100f * MainTool.GetBaseZoom(); var size = speedLimitSignSize * zoom; var guiColor = GUI.color; var boundingBox = new Rect(screenPos.x - size / 2, screenPos.y - size / 2, size, size); bool hoveredHandle = !viewOnly && TrafficManagerTool.IsMouseOver(boundingBox); if (hoveredHandle) { // mouse hovering over sign hovered = true; guiColor.a = 0.8f; } else { guiColor.a = 0.5f; } GUI.color = guiColor; try { GUI.DrawTexture(boundingBox, TrafficLightToolTextureResources.SpeedLimitTextures[SpeedLimitManager.GetCustomSpeedLimit(segmentId, e.Key)]); } catch (Exception ex) { Log.Error("segment " + segmentId + " limit: " + SpeedLimitManager.GetCustomSpeedLimit(segmentId, e.Key) + ", ex: " + ex.ToString()); } if (hoveredHandle && Input.GetMouseButton(0)) { // change the speed limit to the selected one ushort speedLimitToSet = SpeedLimitManager.AvailableSpeedLimits[curSpeedLimitIndex]; //Log._Debug($"Setting speed limit of segment {segmentId}, dir {e.Key.ToString()} to {speedLimitToSet}"); SpeedLimitManager.SetSpeedLimit(segmentId, e.Key, speedLimitToSet); //mouseClickProcessed = true; } guiColor.a = 1f; GUI.color = guiColor; } return(hovered); }