public override void OnToolGUI(Event e) { //base.OnToolGUI(e); _cursorInSecondaryPanel = false; if (SelectedNodeId == 0 || SelectedSegmentId == 0) { return; } int numDirections; int numLanes = TrafficManagerTool.GetSegmentNumVehicleLanes(SelectedSegmentId, SelectedNodeId, out numDirections); if (numLanes <= 0) { SelectedNodeId = 0; SelectedSegmentId = 0; return; } var style = new GUIStyle { normal = { background = SecondPanelTexture }, alignment = TextAnchor.MiddleCenter, border = { bottom = 2, top = 2, right = 2, left = 2 } }; Vector3 nodePos = Singleton <NetManager> .instance.m_nodes.m_buffer[SelectedNodeId].m_position; var screenPos = Camera.main.WorldToScreenPoint(nodePos); screenPos.y = Screen.height - screenPos.y; //Log._Debug($"node pos of {SelectedNodeId}: {nodePos.ToString()} {screenPos.ToString()}"); if (screenPos.z < 0) { return; } var camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position; var diff = nodePos - camPos; if (diff.magnitude > TrafficManagerTool.PriorityCloseLod) { return; // do not draw if too distant } int width = numLanes * 128; var windowRect3 = new Rect(screenPos.x - width / 2, screenPos.y - 70, width, 50); GUILayout.Window(250, windowRect3, _guiLaneChangeWindow, "", style); _cursorInSecondaryPanel = windowRect3.Contains(Event.current.mousePosition); }
public override void OnToolGUI(Event e) { //base.OnToolGUI(e); _cursorInSecondaryPanel = false; if (SelectedNodeId == 0 || SelectedSegmentId == 0) { return; } int numDirections; int numLanes = TrafficManagerTool.GetSegmentNumVehicleLanes(SelectedSegmentId, SelectedNodeId, out numDirections, LaneArrowManager.VEHICLE_TYPES); if (numLanes <= 0) { SelectedNodeId = 0; SelectedSegmentId = 0; return; } var style = new GUIStyle { normal = { background = SecondPanelTexture }, alignment = TextAnchor.MiddleCenter, border = { bottom = 2, top = 2, right = 2, left = 2 } }; Vector3 nodePos = Singleton <NetManager> .instance.m_nodes.m_buffer[SelectedNodeId].m_position; Vector3 screenPos; bool visible = MainTool.WorldToScreenPoint(nodePos, out screenPos); if (!visible) { return; } var camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position; var diff = nodePos - camPos; if (diff.magnitude > TrafficManagerTool.MaxOverlayDistance) { return; // do not draw if too distant } int width = numLanes * 128; var windowRect3 = new Rect(screenPos.x - width / 2, screenPos.y - 70, width, 50); GUILayout.Window(250, windowRect3, _guiLaneChangeWindow, "", style); _cursorInSecondaryPanel = windowRect3.Contains(Event.current.mousePosition); }
public override void OnToolGUI(Event e) { // base.OnToolGUI(e); cursorInSecondaryPanel_ = false; if ((SelectedNodeId == 0) || (SelectedSegmentId == 0)) { return; } int numLanes = TrafficManagerTool.GetSegmentNumVehicleLanes( SelectedSegmentId, SelectedNodeId, out int numDirections, LaneArrowManager.VEHICLE_TYPES); if (numLanes <= 0) { SelectedNodeId = 0; SelectedSegmentId = 0; return; } Vector3 nodePos = Singleton <NetManager> .instance.m_nodes.m_buffer[SelectedNodeId].m_position; bool visible = MainTool.WorldToScreenPoint(nodePos, out Vector3 screenPos); if (!visible) { return; } Vector3 camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position; Vector3 diff = nodePos - camPos; if (diff.sqrMagnitude > TrafficManagerTool.MAX_OVERLAY_DISTANCE_SQR) { return; // do not draw if too distant } int width = numLanes * 128; int height = 50; bool startNode = (bool)netService.IsStartNode(SelectedSegmentId, SelectedNodeId); if (CanReset(SelectedSegmentId, startNode)) { height += 40; } var windowRect3 = new Rect(screenPos.x - (width / 2), screenPos.y - 70, width, height); GUILayout.Window(250, windowRect3, GuiLaneChangeWindow, string.Empty, BorderlessStyle); cursorInSecondaryPanel_ = windowRect3.Contains(Event.current.mousePosition); }
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 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); }
private bool DrawVehicleRestrictionHandles(ushort segmentId, ref NetSegment segment, bool viewOnly, out bool stateUpdated) { stateUpdated = false; if (viewOnly && !Options.vehicleRestrictionsOverlay && MainTool.GetToolMode() != ToolMode.VehicleRestrictions) { return(false); } Vector3 center = segment.m_bounds.center; bool visible = MainTool.WorldToScreenPoint(center, out Vector3 _); if (!visible) { return(false); } Vector3 camPos = Singleton <SimulationManager> .instance.m_simulationView.m_position; Vector3 diff = center - camPos; if (diff.sqrMagnitude > TrafficManagerTool.MAX_OVERLAY_DISTANCE_SQR) { return(false); // do not draw if too distant } int numLanes = TrafficManagerTool.GetSegmentNumVehicleLanes( segmentId, null, out int numDirections, VehicleRestrictionsManager.VEHICLE_TYPES); // draw vehicle restrictions over each lane NetInfo segmentInfo = segment.Info; Vector3 yu = (segment.m_endDirection - segment.m_startDirection).normalized; // if ((segment.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 int maxNumSigns = 0; if (VehicleRestrictionsManager.Instance.IsRoadSegment(segmentInfo)) { maxNumSigns = RoadVehicleTypes.Length; } else if (VehicleRestrictionsManager.Instance.IsRailSegment(segmentInfo)) { maxNumSigns = RailVehicleTypes.Length; } // Vector3 zero = center - 0.5f * (float)(numLanes + numDirections - 1) * f * (xu + yu); // "bottom left" Vector3 zero = center - (0.5f * (numLanes - 1 + numDirections - 1) * f * xu) - (0.5f * 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; Color guiColor = GUI.color; IList <LanePos> sortedLanes = Constants.ServiceFactory.NetService.GetSortedLanes( segmentId, ref segment, null, VehicleRestrictionsManager.LANE_TYPES, VehicleRestrictionsManager.VEHICLE_TYPES); bool hovered = false; 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); } ExtVehicleType[] possibleVehicleTypes; 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, VehicleRestrictionsMode.Configured); uint y = 0; #if DEBUG_disabled_xxx Vector3 labelCenter = zero + f * (float)x * xu + f * (float)y * yu; // in game coordinates Vector3 labelScreenPos; bool visible = MainTool.WorldToScreenPoint(labelCenter, out labelScreenPos); 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 = MainTool.DrawGenericSquareOverlayGridTexture( RoadUITextures.VehicleRestrictionTextures[vehicleType][allowed], camPos, zero, f, xu, yu, x, y, vehicleRestrictionsSignSize, !viewOnly); 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; if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) { ApplyRestrictionsToAllSegments(sortedLaneIndex); } } ++y; } ++x; } 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); }