private void DrawSign(bool viewOnly, ref Vector3 camPos, ref Vector3 xu, ref Vector3 yu, float f, ref Vector3 zero, int x, int y, ref Color guiColor, Texture2D signTexture, out bool hoveredHandle) { Vector3 signCenter = zero + f * (float)x * xu + f * (float)y * yu; // in game coordinates Vector3 signScreenPos; bool visible = MainTool.WorldToScreenPoint(signCenter, out signScreenPos); if (!visible) { hoveredHandle = false; return; } Vector3 diff = signCenter - camPos; var zoom = 1.0f / diff.magnitude * 100f * MainTool.GetBaseZoom(); var size = (viewOnly ? 0.8f : 1f) * junctionRestrictionsSignSize * zoom; var boundingBox = new Rect(signScreenPos.x - size / 2, signScreenPos.y - size / 2, size, size); hoveredHandle = !viewOnly && TrafficManagerTool.IsMouseOver(boundingBox); if (hoveredHandle) { // mouse hovering over sign guiColor.a = 0.8f; } else { guiColor.a = 0.5f; } GUI.color = guiColor; GUI.DrawTexture(boundingBox, signTexture); }
private void DrawRestrictionsSign(bool viewOnly, Vector3 camPos, out Vector3 diff, Vector3 xu, Vector3 yu, float f, Vector3 zero, uint x, uint y, ref Color guiColor, Texture2D signTexture, out bool hoveredHandle) { Vector3 signCenter = zero + f * (float)x * xu + f * (float)y * yu; // in game coordinates var signScreenPos = Camera.main.WorldToScreenPoint(signCenter); signScreenPos.y = Screen.height - signScreenPos.y; diff = signCenter - camPos; var zoom = 1.0f / diff.magnitude * 100f * MainTool.GetBaseZoom(); var size = (viewOnly ? 0.8f : 1f) * vehicleRestrictionsSignSize * zoom; var boundingBox = new Rect(signScreenPos.x - size / 2, signScreenPos.y - size / 2, size, size); hoveredHandle = !viewOnly && TrafficManagerTool.IsMouseOver(boundingBox); if (hoveredHandle) { // mouse hovering over sign guiColor.a = 0.8f; } else { guiColor.a = 0.5f; } GUI.color = guiColor; GUI.DrawTexture(boundingBox, signTexture); }
private void DrawSign(bool viewOnly, bool small, ref Vector3 camPos, ref Vector3 xu, ref Vector3 yu, float f, ref Vector3 zero, int x, int y, Color guiColor, Texture2D signTexture, out bool hoveredHandle) { Vector3 signCenter = zero + (f * x * xu) + (f * y * yu); // in game coordinates Vector3 signScreenPos; bool visible = MainTool.WorldToScreenPoint(signCenter, out signScreenPos); if (!visible) { hoveredHandle = false; return; } Vector3 diff = signCenter - camPos; float zoom = 1.0f / diff.magnitude * 100f * MainTool.GetBaseZoom(); float size = (small ? 0.75f : 1f) * (viewOnly ? 0.8f : 1f) * junctionRestrictionsSignSize * zoom; var boundingBox = new Rect( signScreenPos.x - size / 2, signScreenPos.y - size / 2, size, size); hoveredHandle = !viewOnly && TrafficManagerTool.IsMouseOver(boundingBox); guiColor.a = TrafficManagerTool.GetHandleAlpha(hoveredHandle); GUI.color = guiColor; GUI.DrawTexture(boundingBox, signTexture); }
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); }
public void ShowGUI(bool viewOnly) { try { TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance; TrafficPriorityManager prioMan = TrafficPriorityManager.Instance; TrafficLightManager tlm = TrafficLightManager.Instance; 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>(); foreach (ushort segmentId in currentPrioritySegmentIds) { var trafficSegment = prioMan.TrafficSegments[segmentId]; if (trafficSegment == null) { continue; } SegmentGeometry geometry = SegmentGeometry.Get(segmentId); prioritySegments[0] = null; prioritySegments[1] = null; if (tlsMan.GetNodeSimulation(trafficSegment.Node1) == null) { SegmentEnd tmpSeg1 = prioMan.GetPrioritySegment(trafficSegment.Node1, segmentId); bool startNode = geometry.StartNodeId() == trafficSegment.Node1; if (tmpSeg1 != null && !geometry.IsOutgoingOneWay(startNode)) { prioritySegments[0] = tmpSeg1; nodeIdsWithSigns.Add(trafficSegment.Node1); prioMan.AddPriorityNode(trafficSegment.Node1); } } if (tlsMan.GetNodeSimulation(trafficSegment.Node2) == null) { SegmentEnd tmpSeg2 = prioMan.GetPrioritySegment(trafficSegment.Node2, segmentId); bool startNode = geometry.StartNodeId() == trafficSegment.Node2; if (tmpSeg2 != null && !geometry.IsOutgoingOneWay(startNode)) { prioritySegments[1] = tmpSeg2; nodeIdsWithSigns.Add(trafficSegment.Node2); prioMan.AddPriorityNode(trafficSegment.Node2); } } //Log.Message("init ok"); foreach (var prioritySegment in prioritySegments) { if (prioritySegment == null) { continue; } 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 prioMan.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 * MainTool.GetBaseZoom(); var size = 90f * 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 = tlsMan.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 + " ok=" + ok); if (delete) { prioMan.RemovePrioritySegments(hoveredExistingNodeId); RefreshCurrentPrioritySegmentIds(); } else if (ok) { //if (!prioMan.IsPriorityNode(HoveredNodeId)) { Log._Debug("_guiPrioritySigns: adding prio segments @ nodeId=" + HoveredNodeId); tlsMan.RemoveNodeFromSimulation(HoveredNodeId, false, true); tlm.RemoveTrafficLight(HoveredNodeId); prioMan.AddPriorityNode(HoveredNodeId); RefreshCurrentPrioritySegmentIds(); //} } 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()); } }
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, 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, 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); }