internal void Housekeeping() { if (TrafficManagerTool.GetToolMode() != ToolMode.AddPrioritySigns && TrafficLightSimulationManager.Instance().GetNodeSimulation(NodeId) == null && Type == PriorityType.None) { TrafficPriorityManager.Instance().RemovePrioritySegments(NodeId); } }
private static void SavePrioritySegment(ushort segmentId, Configuration configuration) { try { TrafficPriorityManager prioMan = TrafficPriorityManager.Instance(); if (prioMan.TrafficSegments[segmentId] == null) { return; } if (prioMan.TrafficSegments[segmentId].Node1 != 0 && prioMan.TrafficSegments[segmentId].Instance1.Type != SegmentEnd.PriorityType.None) { Log._Debug($"Saving Priority Segment of type: {prioMan.TrafficSegments[segmentId].Instance1.Type} @ node {prioMan.TrafficSegments[segmentId].Node1}, seg. {segmentId}"); configuration.PrioritySegments.Add(new[] { prioMan.TrafficSegments[segmentId].Node1, segmentId, (int)prioMan.TrafficSegments[segmentId].Instance1.Type }); } if (prioMan.TrafficSegments[segmentId].Node2 == 0 || prioMan.TrafficSegments[segmentId].Instance2.Type == SegmentEnd.PriorityType.None) { return; } Log._Debug($"Saving Priority Segment of type: {prioMan.TrafficSegments[segmentId].Instance2.Type} @ node {prioMan.TrafficSegments[segmentId].Node2}, seg. {segmentId}"); configuration.PrioritySegments.Add(new[] { prioMan.TrafficSegments[segmentId].Node2, segmentId, (int)prioMan.TrafficSegments[segmentId].Instance2.Type }); } catch (Exception e) { Log.Error($"Error adding Priority Segments to Save: {e.ToString()}"); } }
private void RefreshCurrentPriorityNodeIds() { TrafficPriorityManager tpm = TrafficPriorityManager.Instance; currentPriorityNodeIds.Clear(); for (uint nodeId = 0; nodeId < NetManager.MAX_NODE_COUNT; ++nodeId) { ref NetNode netNode = ref ((ushort)nodeId).ToNode(); if (!netNode.IsValid()) { continue; } if (!tpm.MayNodeHavePrioritySigns((ushort)nodeId)) { continue; } if (!tpm.HasNodePrioritySign((ushort)nodeId) && nodeId != SelectedNodeId) { continue; } /*if (! MainTool.IsNodeWithinViewDistance(nodeId)) { * continue; * }*/ currentPriorityNodeIds.Add((ushort)nodeId); }
public static Configuration CreateConfiguration(ref bool success) { var configuration = new Configuration(); TrafficPriorityManager prioMan = TrafficPriorityManager.Instance; configuration.ExtCitizens = ExtCitizenManager.Instance.SaveData(ref success); configuration.ExtCitizenInstances = ExtCitizenInstanceManager.Instance.SaveData(ref success); configuration.PrioritySegments = ((ICustomDataManager <List <int[]> >)TrafficPriorityManager.Instance).SaveData(ref success); configuration.CustomPrioritySegments = ((ICustomDataManager <List <Configuration.PrioritySegment> >)TrafficPriorityManager.Instance).SaveData(ref success); configuration.SegmentNodeConfs = JunctionRestrictionsManager.Instance.SaveData(ref success); configuration.TimedLights = TrafficLightSimulationManager.Instance.SaveData(ref success); //configuration.NodeTrafficLights = ((ICustomDataManager<string>)TrafficLightManager.Instance).SaveData(ref success); //configuration.ToggledTrafficLights = ((ICustomDataManager<List<Configuration.NodeTrafficLight>>)TrafficLightManager.Instance).SaveData(ref success); configuration.LaneFlags = ((ICustomDataManager <string>)LaneArrowManager.Instance).SaveData(ref success); configuration.LaneArrows = ((ICustomDataManager <List <Configuration.LaneArrowData> >)LaneArrowManager.Instance).SaveData(ref success); configuration.LaneConnections = LaneConnectionManager.Instance.SaveData(ref success); configuration.LaneSpeedLimits = ((ICustomDataManager <List <Configuration.LaneSpeedLimit> >)SpeedLimitManager.Instance).SaveData(ref success); configuration.CustomDefaultSpeedLimits = ((ICustomDataManager <Dictionary <string, float> >)SpeedLimitManager.Instance).SaveData(ref success); configuration.LaneAllowedVehicleTypes = VehicleRestrictionsManager.Instance.SaveData(ref success); configuration.ParkingRestrictions = ParkingRestrictionsManager.Instance.SaveData(ref success); return(configuration); }
public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { if (MainTool.GetToolController().IsInsideUI || !Cursor.visible) { return; } // no highlight for existing priority node in sign mode if (TrafficPriorityManager.Instance().IsPriorityNode(HoveredNodeId)) { return; } if (HoveredNodeId == 0) { return; } if (!Flags.mayHaveTrafficLight(HoveredNodeId)) { return; } MainTool.DrawNodeCircle(cameraInfo, HoveredNodeId, Input.GetMouseButton(0)); }
private static int GetNumberOfMainRoads(ushort nodeId, ref NetNode node) { TrafficPriorityManager prioMan = TrafficPriorityManager.Instance; var numMainRoads = 0; for (var s = 0; s < 8; s++) { var segmentId2 = node.GetSegment(s); if (segmentId2 == 0 || !prioMan.IsPrioritySegment(nodeId, segmentId2)) { continue; } var prioritySegment2 = prioMan.GetPrioritySegment(nodeId, segmentId2); if (prioritySegment2.Type == SegmentEnd.PriorityType.Main) { numMainRoads++; } } return(numMainRoads); }
internal void UpdatePosition(ref Vehicle vehicleData, ref PathUnit.Position curPos, ref PathUnit.Position nextPos, bool skipCheck = false) { if (!skipCheck && !CheckValidity(ref vehicleData)) { return; } LastPositionUpdate = Singleton <SimulationManager> .instance.m_currentFrameIndex; SegmentEnd end = TrafficPriorityManager.Instance().GetPrioritySegment(GetTransitNodeId(ref curPos, ref nextPos), curPos.m_segment); if (CurrentSegmentEnd != end) { if (CurrentSegmentEnd != null) { Unlink(); } WaitTime = 0; if (end != null) { Link(end); JunctionTransitState = VehicleJunctionTransitState.Enter; } else { JunctionTransitState = VehicleJunctionTransitState.None; } } }
private void RefreshCurrentPriorityNodeIds() { TrafficPriorityManager tpm = TrafficPriorityManager.Instance; currentPriorityNodeIds.Clear(); for (uint nodeId = 0; nodeId < NetManager.MAX_NODE_COUNT; ++nodeId) { if (!Constants.ServiceFactory.NetService.IsNodeValid((ushort)nodeId)) { continue; } if (!tpm.MayNodeHavePrioritySigns((ushort)nodeId)) { continue; } if (!tpm.HasNodePrioritySign((ushort)nodeId) && nodeId != SelectedNodeId) { continue; } /*if (! MainTool.IsNodeWithinViewDistance(nodeId)) { * continue; * }*/ currentPriorityNodeIds.Add((ushort)nodeId); } //Log._Debug($"PrioritySignsTool.RefreshCurrentPriorityNodeIds: currentPriorityNodeIds={string.Join(", ", currentPriorityNodeIds.Select(x => x.ToString()).ToArray())}"); }
private void DestroySegmentEnd(ushort segmentId) { if (segmentId <= 0) { return; } TrafficPriorityManager.Instance().RemovePrioritySegment(NodeId, segmentId); }
internal static bool mayHaveLaneArrows(uint laneId, bool?startNode = null) { if (laneId <= 0) { return(false); } NetManager netManager = Singleton <NetManager> .instance; if (((NetLane.Flags)Singleton <NetManager> .instance.m_lanes.m_buffer[laneId].m_flags & (NetLane.Flags.Created | NetLane.Flags.Deleted)) != NetLane.Flags.Created) { return(false); } ushort segmentId = netManager.m_lanes.m_buffer[laneId].m_segment; var dir = NetInfo.Direction.Forward; var dir2 = ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.None) ? dir : NetInfo.InvertDirection(dir); var dir3 = TrafficPriorityManager.IsLeftHandDrive() ? NetInfo.InvertDirection(dir2) : dir2; NetInfo segmentInfo = netManager.m_segments.m_buffer[segmentId].Info; uint curLaneId = netManager.m_segments.m_buffer[segmentId].m_lanes; int numLanes = segmentInfo.m_lanes.Length; int laneIndex = 0; int wIter = 0; while (laneIndex < numLanes && curLaneId != 0u) { ++wIter; if (wIter >= 20) { Log.Error("Too many iterations in Flags.mayHaveLaneArrows!"); break; } if (curLaneId == laneId) { NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex]; bool isStartNode = laneInfo.m_direction != dir3; if (startNode != null && isStartNode != startNode) { return(false); } ushort nodeId = isStartNode ? netManager.m_segments.m_buffer[segmentId].m_startNode : netManager.m_segments.m_buffer[segmentId].m_endNode; if ((netManager.m_nodes.m_buffer[nodeId].m_flags & (NetNode.Flags.Created | NetNode.Flags.Deleted)) != NetNode.Flags.Created) { return(false); } return((netManager.m_nodes.m_buffer[nodeId].m_flags & NetNode.Flags.Junction) != NetNode.Flags.None); } curLaneId = netManager.m_lanes.m_buffer[curLaneId].m_nextLane; ++laneIndex; } return(false); }
private void SetupSegmentEnd(ushort segmentId) { if (segmentId <= 0) { return; } TrafficPriorityManager prioMan = TrafficPriorityManager.Instance; //if (!prioMan.IsPrioritySegment(NodeId, segmentId)) prioMan.AddPrioritySegment(NodeId, segmentId, SegmentEnd.PriorityType.None); }
public override void Cleanup() { TrafficPriorityManager prioMan = TrafficPriorityManager.Instance(); foreach (TrafficSegment trafficSegment in prioMan.TrafficSegments) { try { trafficSegment?.Instance1?.Housekeeping(); trafficSegment?.Instance2?.Housekeeping(); } catch (Exception e) { Log.Error($"Error occured while performing PrioritySignsTool.Cleanup: {e.ToString()}"); } } }
public static void resetTrafficLights(bool all) { TrafficPriorityManager prioMan = TrafficPriorityManager.Instance(); for (ushort i = 0; i < Singleton <NetManager> .instance.m_nodes.m_size; ++i) { nodeTrafficLightFlag[i] = null; if (!all && prioMan.IsPriorityNode(i)) { continue; } Singleton <NetManager> .instance.UpdateNodeFlags(i); } }
public override void OnPrimaryClickOverlay() { if (IsCursorInPanel()) { return; } if (SelectedNodeId != 0) { return; } TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance; TrafficPriorityManager prioMan = TrafficPriorityManager.Instance; if (!tlsMan.TrafficLightSimulations[HoveredNodeId].IsTimedLight()) { if ((Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_flags & NetNode.Flags.TrafficLights) == NetNode.Flags.None) { prioMan.RemovePrioritySignsFromNode(HoveredNodeId); TrafficLightManager.Instance.AddTrafficLight( HoveredNodeId, ref Singleton <NetManager> .instance.m_nodes.m_buffer[ HoveredNodeId]); } if (tlsMan.SetUpManualTrafficLight(HoveredNodeId)) { SelectedNodeId = HoveredNodeId; } // for (var s = 0; s < 8; s++) { // var segment = Singleton<NetManager> // .instance.m_nodes.m_buffer[SelectedNodeId].GetSegment(s); // if (segment != 0 && // !TrafficPriority.IsPrioritySegment(SelectedNodeId, segment)) { // TrafficPriority.AddPrioritySegment( // SelectedNodeId, // segment, // SegmentEnd.PriorityType.None); // } // } } else { MainTool.ShowError( Translation.TrafficLights.Get("Dialog.Text:Node has timed TL script")); } }
public override void OnPrimaryClickOverlay() { if (IsCursorInPanel()) { return; } if (SelectedNodeId != 0) { return; } TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance; TrafficPriorityManager prioMan = TrafficPriorityManager.Instance; ref NetNode hoveredNetNode = ref HoveredNodeId.ToNode();
/// <summary> /// Determines the allowed vehicle types that may approach the given node from the given segment (lane-wise). /// </summary> /// <param name="segmentId"></param> /// <param name="nodeId"></param> /// <returns></returns> internal Dictionary <byte, ExtVehicleType> GetAllowedVehicleTypesAsDict(ushort segmentId, ushort nodeId) { #if TRACE Singleton <CodeProfiler> .instance.Start("VehicleRestrictionsManager.GetAllowedVehicleTypesAsDict"); #endif Dictionary <byte, ExtVehicleType> ret = new Dictionary <byte, ExtVehicleType>(); NetManager netManager = Singleton <NetManager> .instance; if (segmentId == 0 || (netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Created) == NetSegment.Flags.None || nodeId == 0 || (netManager.m_nodes.m_buffer[nodeId].m_flags & NetNode.Flags.Created) == NetNode.Flags.None) { #if TRACE Singleton <CodeProfiler> .instance.Stop("VehicleRestrictionsManager.GetAllowedVehicleTypesAsDict"); #endif return(ret); } var dir = NetInfo.Direction.Forward; var dir2 = ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.None) ? dir : NetInfo.InvertDirection(dir); var dir3 = TrafficPriorityManager.IsLeftHandDrive() ? NetInfo.InvertDirection(dir2) : dir2; NetInfo segmentInfo = netManager.m_segments.m_buffer[segmentId].Info; uint curLaneId = netManager.m_segments.m_buffer[segmentId].m_lanes; int numLanes = segmentInfo.m_lanes.Length; uint laneIndex = 0; while (laneIndex < numLanes && curLaneId != 0u) { NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIndex]; ushort toNodeId = (laneInfo.m_direction == dir3) ? netManager.m_segments.m_buffer[segmentId].m_endNode : netManager.m_segments.m_buffer[segmentId].m_startNode; if (toNodeId == nodeId) { ExtVehicleType vehicleTypes = GetAllowedVehicleTypes(segmentId, segmentInfo, laneIndex, laneInfo); if (vehicleTypes != ExtVehicleType.None) { ret[(byte)laneIndex] = vehicleTypes; } } curLaneId = netManager.m_lanes.m_buffer[curLaneId].m_nextLane; ++laneIndex; } #if TRACE Singleton <CodeProfiler> .instance.Stop("VehicleRestrictionsManager.GetAllowedVehicleTypesAsDict"); #endif return(ret); }
private void RefreshCurrentPrioritySegmentIds() { currentPrioritySegmentIds.Clear(); for (ushort segmentId = 0; segmentId < NetManager.MAX_SEGMENT_COUNT; ++segmentId) { if ((Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Created) == NetSegment.Flags.None) { continue; } var trafficSegment = TrafficPriorityManager.Instance().TrafficSegments[segmentId]; if (trafficSegment == null) { continue; } currentPrioritySegmentIds.Add(segmentId); } }
internal static int GetSegmentNumVehicleLanes(ushort segmentId, ushort?nodeId, out int numDirections) { var info = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].Info; var num2 = Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_lanes; var laneIndex = 0; NetInfo.Direction?dir = null; NetInfo.Direction?dir2 = null; NetInfo.Direction?dir3 = null; numDirections = 0; HashSet <NetInfo.Direction> directions = new HashSet <NetInfo.Direction>(); if (nodeId != null) { dir = (Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_startNode == nodeId) ? NetInfo.Direction.Backward : NetInfo.Direction.Forward; dir2 = ((Singleton <NetManager> .instance.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.None) ? dir : NetInfo.InvertDirection((NetInfo.Direction)dir); dir3 = TrafficPriorityManager.IsLeftHandDrive() ? NetInfo.InvertDirection((NetInfo.Direction)dir2) : dir2; } var numLanes = 0; while (laneIndex < info.m_lanes.Length && num2 != 0u) { if (((info.m_lanes[laneIndex].m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle)) != NetInfo.LaneType.None && (info.m_lanes[laneIndex].m_vehicleType & (VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train)) != VehicleInfo.VehicleType.None) && (dir3 == null || info.m_lanes[laneIndex].m_direction == dir3)) { if (!directions.Contains(info.m_lanes[laneIndex].m_direction)) { directions.Add(info.m_lanes[laneIndex].m_direction); ++numDirections; } numLanes++; } num2 = Singleton <NetManager> .instance.m_lanes.m_buffer[(int)((UIntPtr)num2)].m_nextLane; laneIndex++; } return(numLanes); }
public void OnUpdate(SegmentGeometry geometry) { if (!geometry.IsValid()) { TrafficPriorityManager.Instance().RemovePrioritySegment(NodeId, SegmentId); return; } StartNode = Singleton <NetManager> .instance.m_segments.m_buffer[SegmentId].m_startNode == NodeId; numLanes = Singleton <NetManager> .instance.m_segments.m_buffer[SegmentId].Info.m_lanes.Length; numVehiclesFlowingToSegmentId = new Dictionary <ushort, uint>(7); numVehiclesGoingToSegmentId = new Dictionary <ushort, uint>(7); //frontVehicleIds = new ushort[numLanes]; ushort[] outgoingSegmentIds = geometry.GetOutgoingSegments(StartNode); foreach (ushort otherSegmentId in outgoingSegmentIds) { numVehiclesFlowingToSegmentId[otherSegmentId] = 0; numVehiclesGoingToSegmentId[otherSegmentId] = 0; } }
public override void OnPrimaryClickOverlay() { if (IsCursorInPanel()) { return; } if (SelectedNodeId != 0) { return; } TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance; TrafficPriorityManager prioMan = TrafficPriorityManager.Instance; TrafficLightSimulation sim = tlsMan.GetNodeSimulation(HoveredNodeId); if (sim == null || !sim.IsTimedLight()) { if ((Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_flags & NetNode.Flags.TrafficLights) == NetNode.Flags.None) { prioMan.RemovePrioritySegments(HoveredNodeId); TrafficLightManager.Instance.AddTrafficLight(HoveredNodeId); } SelectedNodeId = HoveredNodeId; sim = tlsMan.AddNodeToSimulation(SelectedNodeId); sim.SetupManualTrafficLight(); /*for (var s = 0; s < 8; s++) { * var segment = Singleton<NetManager>.instance.m_nodes.m_buffer[SelectedNodeId].GetSegment(s); * if (segment != 0 && !TrafficPriority.IsPrioritySegment(SelectedNodeId, segment)) { * TrafficPriority.AddPrioritySegment(SelectedNodeId, segment, SegmentEnd.PriorityType.None); * } * }*/ } else { MainTool.ShowTooltip(Translation.GetString("NODE_IS_TIMED_LIGHT"), Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_position); } }
public override void OnPrimaryClickOverlay() { if (IsCursorInPanel()) { return; } if (SelectedNodeId != 0) { return; } TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance; TrafficPriorityManager prioMan = TrafficPriorityManager.Instance; if (!tlsMan.TrafficLightSimulations[HoveredNodeId].IsTimedLight()) { if ((Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_flags & NetNode.Flags.TrafficLights) == NetNode.Flags.None) { prioMan.RemovePrioritySignsFromNode(HoveredNodeId); TrafficLightManager.Instance.AddTrafficLight( HoveredNodeId, ref Singleton <NetManager> .instance.m_nodes.m_buffer[ HoveredNodeId]); } if (tlsMan.SetUpManualTrafficLight(HoveredNodeId)) { SelectedNodeId = HoveredNodeId; MainTool.RequestOnscreenDisplayUpdate(); } } else { MainTool.WarningPrompt(Translation.TrafficLights.Get("Dialog.Text:Node has timed TL script")); } }
public override void OnPrimaryClickOverlay() { if (HoveredNodeId == 0) { return; } if ((Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_flags & NetNode.Flags.Junction) == NetNode.Flags.None) { return; } TrafficLightSimulation sim = TrafficLightSimulationManager.Instance().GetNodeSimulation(HoveredNodeId); if (sim != null && sim.IsTimedLight()) { MainTool.ShowTooltip(Translation.GetString("NODE_IS_TIMED_LIGHT"), Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_position); return; } TrafficPriorityManager.Instance().RemovePrioritySegments(HoveredNodeId); Flags.setNodeTrafficLight(HoveredNodeId, (Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_flags & NetNode.Flags.TrafficLights) == NetNode.Flags.None); }
public override void OnSaveData() { bool success = true; /*try { * Log.Info("Recalculating segment geometries"); * SegmentGeometry.OnBeforeSaveData(); * } catch (Exception e) { * Log.Error($"OnSaveData: Exception occurred while calling SegmentGeometry.OnBeforeSaveData: {e.ToString()}"); * error = true; * }*/ foreach (ICustomManager manager in LoadingExtension.RegisteredManagers) { try { Log.Info($"OnBeforeSaveData: {manager.GetType().Name}"); manager.OnBeforeSaveData(); } catch (Exception e) { Log.Error($"OnSaveData: Error while notifying {manager.GetType().Name}.OnBeforeSaveData: {e.ToString()}"); success = false; } } try { Log.Info("Saving Mod Data."); var configuration = new Configuration(); TrafficPriorityManager prioMan = TrafficPriorityManager.Instance; configuration.ExtCitizens = ExtCitizenManager.Instance.SaveData(ref success); configuration.ExtCitizenInstances = ExtCitizenInstanceManager.Instance.SaveData(ref success); configuration.PrioritySegments = ((ICustomDataManager <List <int[]> >)TrafficPriorityManager.Instance).SaveData(ref success); configuration.CustomPrioritySegments = ((ICustomDataManager <List <Configuration.PrioritySegment> >)TrafficPriorityManager.Instance).SaveData(ref success); configuration.SegmentNodeConfs = JunctionRestrictionsManager.Instance.SaveData(ref success); configuration.TimedLights = TrafficLightSimulationManager.Instance.SaveData(ref success); //configuration.NodeTrafficLights = ((ICustomDataManager<string>)TrafficLightManager.Instance).SaveData(ref success); //configuration.ToggledTrafficLights = ((ICustomDataManager<List<Configuration.NodeTrafficLight>>)TrafficLightManager.Instance).SaveData(ref success); configuration.LaneFlags = ((ICustomDataManager <string>)LaneArrowManager.Instance).SaveData(ref success); configuration.LaneArrows = ((ICustomDataManager <List <Configuration.LaneArrowData> >)LaneArrowManager.Instance).SaveData(ref success); configuration.LaneConnections = LaneConnectionManager.Instance.SaveData(ref success); configuration.LaneSpeedLimits = ((ICustomDataManager <List <Configuration.LaneSpeedLimit> >)SpeedLimitManager.Instance).SaveData(ref success); configuration.CustomDefaultSpeedLimits = ((ICustomDataManager <Dictionary <string, float> >)SpeedLimitManager.Instance).SaveData(ref success); configuration.LaneAllowedVehicleTypes = VehicleRestrictionsManager.Instance.SaveData(ref success); configuration.ParkingRestrictions = ParkingRestrictionsManager.Instance.SaveData(ref success); try { // save options _serializableData.SaveData("TMPE_Options", OptionsManager.Instance.SaveData(ref success)); } catch (Exception ex) { Log.Error("Unexpected error while saving options: " + ex.Message); success = false; } var binaryFormatter = new BinaryFormatter(); var memoryStream = new MemoryStream(); try { binaryFormatter.Serialize(memoryStream, configuration); memoryStream.Position = 0; Log.Info($"Save data byte length {memoryStream.Length}"); _serializableData.SaveData(DataId, memoryStream.ToArray()); } catch (Exception ex) { Log.Error("Unexpected error while saving data: " + ex.ToString()); success = false; } finally { memoryStream.Close(); } foreach (ICustomManager manager in LoadingExtension.RegisteredManagers) { try { Log.Info($"OnAfterSaveData: {manager.GetType().Name}"); manager.OnAfterSaveData(); } catch (Exception e) { Log.Error($"OnSaveData: Error while notifying {manager.GetType().Name}.OnAfterSaveData: {e.ToString()}"); success = false; } } } catch (Exception e) { success = false; Log.Error($"Error occurred while saving data: {e.ToString()}"); //UIView.library.ShowModal<ExceptionPanel>("ExceptionPanel").SetMessage("An error occurred while saving", "Traffic Manager: President Edition detected an error while saving. To help preventing future errors, please navigate to http://steamcommunity.com/sharedfiles/filedetails/?id=583429740 and follow the steps under 'In case problems arise'.", true); } }
private static void LoadDataState(out bool error) { error = false; Log.Info("Loading State from Config"); if (_configuration == null) { Log.Warning("Configuration NULL, Couldn't load save data. Possibly a new game?"); return; } TrafficPriorityManager prioMan = TrafficPriorityManager.Instance; // load ext. citizens if (_configuration.ExtCitizens != null) { if (!ExtCitizenManager.Instance.LoadData(_configuration.ExtCitizens)) { error = true; } } else { Log.Info("Ext. citizen data structure undefined!"); } // load ext. citizen instances if (_configuration.ExtCitizenInstances != null) { if (!ExtCitizenInstanceManager.Instance.LoadData(_configuration.ExtCitizenInstances)) { error = true; } } else { Log.Info("Ext. citizen instance data structure undefined!"); } // load priority segments if (_configuration.PrioritySegments != null) { if (!TrafficPriorityManager.Instance.LoadData(_configuration.PrioritySegments)) { error = true; } } else { Log.Info("Priority segments data structure (old) undefined!"); } if (_configuration.CustomPrioritySegments != null) { if (!TrafficPriorityManager.Instance.LoadData(_configuration.CustomPrioritySegments)) { error = true; } } else { Log.Info("Priority segments data structure (new) undefined!"); } // load parking restrictions if (_configuration.ParkingRestrictions != null) { if (!ParkingRestrictionsManager.Instance.LoadData(_configuration.ParkingRestrictions)) { error = true; } } else { Log.Info("Parking restrctions structure undefined!"); } // load vehicle restrictions (warning: has to be done before loading timed lights!) if (_configuration.LaneAllowedVehicleTypes != null) { if (!VehicleRestrictionsManager.Instance.LoadData(_configuration.LaneAllowedVehicleTypes)) { error = true; } } else { Log.Info("Vehicle restrctions structure undefined!"); } NetManager netManager = Singleton <NetManager> .instance; if (_configuration.TimedLights != null) { if (!TrafficLightSimulationManager.Instance.LoadData(_configuration.TimedLights)) { error = true; } } else { Log.Info("Timed traffic lights data structure undefined!"); } // load toggled traffic lights (old method) if (_configuration.NodeTrafficLights != null) { if (!TrafficLightManager.Instance.LoadData(_configuration.NodeTrafficLights)) { error = true; } } else { Log.Info("Junction traffic lights data structure (old) undefined!"); } // load toggled traffic lights (new method) if (_configuration.ToggledTrafficLights != null) { if (!TrafficLightManager.Instance.LoadData(_configuration.ToggledTrafficLights)) { error = true; } } else { Log.Info("Junction traffic lights data structure (new) undefined!"); } // load lane arrrows (old method) if (_configuration.LaneFlags != null) { if (!LaneArrowManager.Instance.LoadData(_configuration.LaneFlags)) { error = true; } } else { Log.Info("Lane arrow data structure (old) undefined!"); } // load lane arrows (new method) if (_configuration.LaneArrows != null) { if (!LaneArrowManager.Instance.LoadData(_configuration.LaneArrows)) { error = true; } } else { Log.Info("Lane arrow data structure (new) undefined!"); } // load lane connections if (_configuration.LaneConnections != null) { if (!LaneConnectionManager.Instance.LoadData(_configuration.LaneConnections)) { error = true; } } else { Log.Info("Lane connection data structure undefined!"); } // Load custom default speed limits if (_configuration.CustomDefaultSpeedLimits != null) { if (!SpeedLimitManager.Instance.LoadData(_configuration.CustomDefaultSpeedLimits)) { error = true; } } // load speed limits if (_configuration.LaneSpeedLimits != null) { if (!SpeedLimitManager.Instance.LoadData(_configuration.LaneSpeedLimits)) { error = true; } } else { Log.Info("Lane speed limit structure undefined!"); } // Load segment-at-node flags if (_configuration.SegmentNodeConfs != null) { if (!JunctionRestrictionsManager.Instance.LoadData(_configuration.SegmentNodeConfs)) { error = true; } } else { Log.Info("Segment-at-node structure undefined!"); } }
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()); } }
internal void CalculateAutoPedestrianLightState(bool propagate = true) { //Log._Debug($"CustomSegmentLights.CalculateAutoPedestrianLightState: Calculating pedestrian light state of node {NodeId}"); SegmentGeometry segGeo = SegmentGeometry.Get(SegmentId); SegmentEndGeometry segmentEndGeometry = StartNode ? segGeo.StartNodeGeometry : segGeo.EndNodeGeometry; if (segmentEndGeometry == null) { Log._Debug($"Could not get SegmentEndGeometry for segment {SegmentId} @ {NodeId}."); AutoPedestrianLightState = RoadBaseAI.TrafficLightState.Green; return; } ushort nodeId = segmentEndGeometry.NodeId(); if (propagate) { foreach (ushort otherSegmentId in segmentEndGeometry.ConnectedSegments) { if (otherSegmentId == 0) { continue; } CustomSegmentLights otherLights = LightsManager.GetSegmentLights(nodeId, otherSegmentId); if (otherLights == null) { //Log._Debug($"Expected other (propagate) CustomSegmentLights at segment {otherSegmentId} @ {NodeId} but there was none. Original segment id: {SegmentId}"); continue; } otherLights.CalculateAutoPedestrianLightState(false); } } if (IsAnyGreen()) { //Log._Debug($"Any green at seg. {SegmentId} @ {NodeId}"); AutoPedestrianLightState = RoadBaseAI.TrafficLightState.Red; return; } //Log._Debug($"Querying incoming segments at seg. {SegmentId} @ {NodeId}"); RoadBaseAI.TrafficLightState autoPedestrianLightState = RoadBaseAI.TrafficLightState.Green; if (!segmentEndGeometry.IncomingOneWay) { // query straight segments foreach (ushort otherSegmentId in segmentEndGeometry.IncomingStraightSegments) { if (otherSegmentId == 0) { continue; } //Log._Debug($"Checking incoming straight segment {otherSegmentId} at seg. {SegmentId} @ {NodeId}"); CustomSegmentLights otherLights = LightsManager.GetSegmentLights(nodeId, otherSegmentId); if (otherLights == null) { //Log._Debug($"Expected other (straight) CustomSegmentLights at segment {otherSegmentId} @ {NodeId} but there was none. Original segment id: {SegmentId}"); continue; } if (!otherLights.IsAllMainRed()) { //Log._Debug($"Not all main red at {otherSegmentId} at seg. {SegmentId} @ {NodeId}"); autoPedestrianLightState = RoadBaseAI.TrafficLightState.Red; break; } } // query left/right segments if (autoPedestrianLightState == RoadBaseAI.TrafficLightState.Green) { bool lhd = TrafficPriorityManager.IsLeftHandDrive(); foreach (ushort otherSegmentId in lhd ? segmentEndGeometry.IncomingLeftSegments : segmentEndGeometry.IncomingRightSegments) { if (otherSegmentId == 0) { continue; } //Log._Debug($"Checking left/right segment {otherSegmentId} at seg. {SegmentId} @ {NodeId}"); CustomSegmentLights otherLights = LightsManager.GetSegmentLights(nodeId, otherSegmentId); if (otherLights == null) { //Log._Debug($"Expected other (left/right) CustomSegmentLights at segment {otherSegmentId} @ {NodeId} but there was none. Original segment id: {SegmentId}"); continue; } if ((lhd && !otherLights.IsAllRightRed()) || (!lhd && !otherLights.IsAllLeftRed())) { //Log._Debug($"Not all left red at {otherSegmentId} at seg. {SegmentId} @ {NodeId}"); autoPedestrianLightState = RoadBaseAI.TrafficLightState.Red; break; } } } } AutoPedestrianLightState = autoPedestrianLightState; //Log.Warning($"Calculated AutoPedestrianLightState for segment {SegmentId} @ {NodeId}: {AutoPedestrianLightState}"); }
public static NetInfo.Direction GetSegmentEndDirection(ushort segmentId, ref NetSegment segment, bool startNode) { NetInfo segmentInfo = segment.Info; var dir = startNode ? NetInfo.Direction.Backward : NetInfo.Direction.Forward; if ((segment.m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None ^ TrafficPriorityManager.IsLeftHandDrive()) { dir = NetInfo.InvertDirection(dir); } return(dir); }
/// <summary> /// Checks for traffic lights and priority signs when changing segments (for road & rail vehicles). /// Sets the maximum allowed speed <paramref name="maxSpeed"/> if segment change is not allowed (otherwise <paramref name="maxSpeed"/> has to be set by the calling method). /// </summary> /// <param name="vehicleId">vehicle id</param> /// <param name="vehicleData">vehicle data</param> /// <param name="lastFrameData">last frame data of vehicle</param> /// <param name="isRecklessDriver">if true, this vehicle ignores red traffic lights and priority signs</param> /// <param name="prevPos">previous path position</param> /// <param name="prevTargetNodeId">previous target node</param> /// <param name="prevLaneID">previous lane</param> /// <param name="position">current path position</param> /// <param name="targetNodeId">transit node</param> /// <param name="laneID">current lane</param> /// <param name="nextPosition">next path position</param> /// <param name="nextTargetNodeId">next target node</param> /// <param name="maxSpeed">maximum allowed speed (only valid if method returns false)</param> /// <returns>true, if the vehicle may change segments, false otherwise.</returns> internal static bool MayChangeSegment(ushort vehicleId, ref Vehicle vehicleData, ref Vehicle.Frame lastFrameData, bool isRecklessDriver, ref PathUnit.Position prevPos, ushort prevTargetNodeId, uint prevLaneID, ref PathUnit.Position position, ushort targetNodeId, uint laneID, ref PathUnit.Position nextPosition, ushort nextTargetNodeId, out float maxSpeed, bool debug = false) { debug = false; if (prevTargetNodeId != targetNodeId) { // method should only be called if targetNodeId == prevTargetNode maxSpeed = 0f; return(true); } bool forceUpdatePos = false; VehicleState vehicleState = null; VehicleStateManager vehStateManager = VehicleStateManager.Instance(); if (Options.prioritySignsEnabled || Options.timedLightsEnabled) { vehicleState = vehStateManager.GetVehicleState(vehicleId); } if ((Options.prioritySignsEnabled || Options.timedLightsEnabled) && (forceUpdatePos || Options.simAccuracy >= 2)) { try { vehStateManager.UpdateVehiclePos(vehicleId, ref vehicleData, ref prevPos, ref position); } catch (Exception e) { Log.Error("VehicleAI MayChangeSegment Error: " + e.ToString()); } } var netManager = Singleton <NetManager> .instance; uint currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex; uint prevTargetNodeLower8Bits = (uint)((prevTargetNodeId << 8) / 32768); uint random = currentFrameIndex - prevTargetNodeLower8Bits & 255u; bool isRailVehicle = (vehicleData.Info.m_vehicleType & (VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Metro)) != VehicleInfo.VehicleType.None; NetNode.Flags targetNodeFlags = netManager.m_nodes.m_buffer[targetNodeId].m_flags; bool hasTrafficLight = (targetNodeFlags & NetNode.Flags.TrafficLights) != NetNode.Flags.None; bool checkTrafficLights = false; if (!isRailVehicle) { // check if to check space #if DEBUG if (debug) { Log._Debug($"CustomVehicleAI.MayChangeSegment: Vehicle {vehicleId} is not a train."); } #endif var prevLaneFlags = (NetLane.Flags)netManager.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].m_flags; var hasCrossing = (targetNodeFlags & NetNode.Flags.LevelCrossing) != NetNode.Flags.None; var isJoinedJunction = (prevLaneFlags & NetLane.Flags.JoinedJunction) != NetLane.Flags.None; bool checkSpace = !Flags.getEnterWhenBlockedAllowed(prevPos.m_segment, netManager.m_segments.m_buffer[prevPos.m_segment].m_startNode == targetNodeId) && !isRecklessDriver; //TrafficLightSimulation nodeSim = TrafficLightSimulation.GetNodeSimulation(destinationNodeId); //if (timedNode != null && timedNode.vehiclesMayEnterBlockedJunctions) { // checkSpace = false; //} if (checkSpace) { // check if there is enough space if ((targetNodeFlags & (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) == NetNode.Flags.Junction && netManager.m_nodes.m_buffer[targetNodeId].CountSegments() != 2) { var len = vehicleData.CalculateTotalLength(vehicleId) + 2f; if (!netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CheckSpace(len)) { var sufficientSpace = false; if (nextPosition.m_segment != 0 && netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_length < 30f) { NetNode.Flags nextTargetNodeFlags = netManager.m_nodes.m_buffer[nextTargetNodeId].m_flags; if ((nextTargetNodeFlags & (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) != NetNode.Flags.Junction || netManager.m_nodes.m_buffer[nextTargetNodeId].CountSegments() == 2) { uint nextLaneId = PathManager.GetLaneID(nextPosition); if (nextLaneId != 0u) { sufficientSpace = netManager.m_lanes.m_buffer[(int)((UIntPtr)nextLaneId)].CheckSpace(len); } } } if (!sufficientSpace) { maxSpeed = 0f; try { if (vehicleState != null) { #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState to BLOCKED"); } #endif vehicleState.JunctionTransitState = VehicleJunctionTransitState.Blocked; } } catch (Exception e) { Log.Error("VehicleAI MayChangeSegment error while setting junction state to BLOCKED: " + e.ToString()); } return(false); } } } } checkTrafficLights = (!isJoinedJunction || hasCrossing); } else { #if DEBUG if (debug) { Log._Debug($"CustomVehicleAI.MayChangeSegment: Vehicle {vehicleId} is a train."); } #endif checkTrafficLights = true; } try { if (vehicleState != null && vehicleState.JunctionTransitState == VehicleJunctionTransitState.Blocked) { #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState from BLOCKED to ENTER"); } #endif vehicleState.JunctionTransitState = VehicleJunctionTransitState.Enter; } if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) == 0) { if (hasTrafficLight && checkTrafficLights) { #if DEBUG if (debug) { Log._Debug($"CustomVehicleAI.MayChangeSegment: Node {targetNodeId} has a traffic light."); } #endif var destinationInfo = netManager.m_nodes.m_buffer[targetNodeId].Info; if (vehicleState != null && vehicleState.JunctionTransitState == VehicleJunctionTransitState.None) { #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState to ENTER (1)"); } #endif vehicleState.JunctionTransitState = VehicleJunctionTransitState.Enter; } RoadBaseAI.TrafficLightState vehicleLightState; RoadBaseAI.TrafficLightState pedestrianLightState; bool vehicles; bool pedestrians; CustomRoadAI.GetTrafficLightState(vehicleId, ref vehicleData, targetNodeId, prevPos.m_segment, prevPos.m_lane, position.m_segment, ref netManager.m_segments.m_buffer[prevPos.m_segment], currentFrameIndex - prevTargetNodeLower8Bits, out vehicleLightState, out pedestrianLightState, out vehicles, out pedestrians); if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Car && isRecklessDriver) // no reckless driving at railroad crossings { vehicleLightState = RoadBaseAI.TrafficLightState.Green; } #if DEBUG if (debug) { Log._Debug($"CustomVehicleAI.MayChangeSegment: Vehicle {vehicleId} has {vehicleLightState} at node {targetNodeId}"); } #endif if (!vehicles && random >= 196u) { vehicles = true; RoadBaseAI.SetTrafficLightState(targetNodeId, ref netManager.m_segments.m_buffer[prevPos.m_segment], currentFrameIndex - prevTargetNodeLower8Bits, vehicleLightState, pedestrianLightState, vehicles, pedestrians); } var stopCar = false; switch (vehicleLightState) { case RoadBaseAI.TrafficLightState.RedToGreen: if (random < 60u) { stopCar = true; } else { #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState to LEAVE (RedToGreen)"); } #endif if (vehicleState != null) { vehicleState.JunctionTransitState = VehicleJunctionTransitState.Leave; } } break; case RoadBaseAI.TrafficLightState.Red: stopCar = true; break; case RoadBaseAI.TrafficLightState.GreenToRed: if (random >= 30u) { stopCar = true; } else if (vehicleState != null) { #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState to LEAVE (GreenToRed)"); } #endif vehicleState.JunctionTransitState = VehicleJunctionTransitState.Leave; } break; } /*if ((vehicleLightState == RoadBaseAI.TrafficLightState.Green || vehicleLightState == RoadBaseAI.TrafficLightState.RedToGreen) && !Flags.getEnterWhenBlockedAllowed(prevPos.m_segment, netManager.m_segments.m_buffer[prevPos.m_segment].m_startNode == targetNodeId)) { * var hasIncomingCars = TrafficPriority.HasIncomingVehiclesWithHigherPriority(vehicleId, targetNodeId); * * if (hasIncomingCars) { * // green light but other cars are incoming and they have priority: stop * stopCar = true; * } * }*/ if (stopCar) { if (vehicleState != null) { #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState to STOP"); } #endif vehicleState.JunctionTransitState = VehicleJunctionTransitState.Stop; } maxSpeed = 0f; return(false); } } else if (vehicleState != null && Options.prioritySignsEnabled) { TrafficPriorityManager prioMan = TrafficPriorityManager.Instance(); #if DEBUG //bool debug = destinationNodeId == 10864; //bool debug = destinationNodeId == 13531; //bool debug = false;// targetNodeId == 5027; #endif //bool debug = false; #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId} is arriving @ seg. {prevPos.m_segment} ({position.m_segment}, {nextPosition.m_segment}), node {targetNodeId} which is not a traffic light."); } #endif var prioritySegment = prioMan.GetPrioritySegment(targetNodeId, prevPos.m_segment); if (prioritySegment != null) { #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId} is arriving @ seg. {prevPos.m_segment} ({position.m_segment}, {nextPosition.m_segment}), node {targetNodeId} which is not a traffic light and is a priority segment."); } #endif //if (prioritySegment.HasVehicle(vehicleId)) { #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: segment target position found"); } #endif #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: global target position found. carState = {vehicleState.JunctionTransitState.ToString()}"); } #endif var currentFrameIndex2 = Singleton <SimulationManager> .instance.m_currentFrameIndex; var frame = currentFrameIndex2 >> 4; float speed = lastFrameData.m_velocity.magnitude; if (vehicleState.JunctionTransitState == VehicleJunctionTransitState.None) { #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState to ENTER (prio)"); } #endif vehicleState.JunctionTransitState = VehicleJunctionTransitState.Enter; } if (vehicleState.JunctionTransitState != VehicleJunctionTransitState.Leave) { bool hasIncomingCars; switch (prioritySegment.Type) { case SegmentEnd.PriorityType.Stop: #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: STOP sign. waittime={vehicleState.WaitTime}, vel={speed}"); } #endif if (Options.simAccuracy <= 2 || (Options.simAccuracy >= 3 && vehicleState.WaitTime < MaxPriorityWaitTime)) { #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState to STOP (wait)"); } #endif vehicleState.JunctionTransitState = VehicleJunctionTransitState.Stop; if (speed <= TrafficPriorityManager.maxStopVelocity) { vehicleState.WaitTime++; float minStopWaitTime = UnityEngine.Random.Range(0f, 3f); if (vehicleState.WaitTime >= minStopWaitTime) { if (Options.simAccuracy >= 4) { vehicleState.JunctionTransitState = VehicleJunctionTransitState.Leave; } else { hasIncomingCars = prioMan.HasIncomingVehiclesWithHigherPriority(vehicleId, ref vehicleData, ref prevPos, ref position); #if DEBUG if (debug) { Log._Debug($"hasIncomingCars: {hasIncomingCars}"); } #endif if (hasIncomingCars) { maxSpeed = 0f; return(false); } #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState to LEAVE (min wait timeout)"); } #endif vehicleState.JunctionTransitState = VehicleJunctionTransitState.Leave; } } else { maxSpeed = 0; return(false); } } else { vehicleState.WaitTime = 0; maxSpeed = 0f; return(false); } } else { #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState to LEAVE (max wait timeout)"); } #endif vehicleState.JunctionTransitState = VehicleJunctionTransitState.Leave; } break; case SegmentEnd.PriorityType.Yield: #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: YIELD sign. waittime={vehicleState.WaitTime}"); } #endif if (Options.simAccuracy <= 2 || (Options.simAccuracy >= 3 && vehicleState.WaitTime < MaxPriorityWaitTime)) { vehicleState.WaitTime++; #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState to STOP (wait)"); } #endif vehicleState.JunctionTransitState = VehicleJunctionTransitState.Stop; if (speed <= TrafficPriorityManager.maxYieldVelocity || Options.simAccuracy <= 2) { if (Options.simAccuracy >= 4) { vehicleState.JunctionTransitState = VehicleJunctionTransitState.Leave; } else { hasIncomingCars = prioMan.HasIncomingVehiclesWithHigherPriority(vehicleId, ref vehicleData, ref prevPos, ref position); #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: hasIncomingCars: {hasIncomingCars}"); } #endif if (hasIncomingCars) { maxSpeed = 0f; return(false); } else { #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState to LEAVE (no incoming cars)"); } #endif vehicleState.JunctionTransitState = VehicleJunctionTransitState.Leave; } } } else { #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Vehicle has not yet reached yield speed (reduce {speed} by {vehicleState.ReduceSpeedByValueToYield})"); } #endif // vehicle has not yet reached yield speed maxSpeed = TrafficPriorityManager.maxYieldVelocity; return(false); } } else { #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState to LEAVE (max wait timeout)"); } #endif vehicleState.JunctionTransitState = VehicleJunctionTransitState.Leave; } break; case SegmentEnd.PriorityType.Main: case SegmentEnd.PriorityType.None: #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: MAIN sign. waittime={vehicleState.WaitTime}"); } #endif maxSpeed = 0f; if (Options.simAccuracy == 4) { return(true); } if (Options.simAccuracy <= 2 || (Options.simAccuracy == 3 && vehicleState.WaitTime < MaxPriorityWaitTime)) { vehicleState.WaitTime++; #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState to STOP (wait)"); } #endif vehicleState.JunctionTransitState = VehicleJunctionTransitState.Stop; hasIncomingCars = prioMan.HasIncomingVehiclesWithHigherPriority(vehicleId, ref vehicleData, ref prevPos, ref position); #if DEBUG if (debug) { Log._Debug($"hasIncomingCars: {hasIncomingCars}"); } #endif if (hasIncomingCars) { return(false); } #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState to LEAVE (no conflicting car)"); } #endif vehicleState.JunctionTransitState = VehicleJunctionTransitState.Leave; } return(true); } } else if (speed <= TrafficPriorityManager.maxStopVelocity) { // vehicle is not moving. reset allowance to leave junction #if DEBUG if (debug) { Log._Debug($"Vehicle {vehicleId}: Setting JunctionTransitState from LEAVE to BLOCKED (speed to low)"); } #endif vehicleState.JunctionTransitState = VehicleJunctionTransitState.Blocked; maxSpeed = 0f; return(false); } } } } } catch (Exception e) { Log.Error($"Error occured in MayChangeSegment: {e.ToString()}"); } maxSpeed = 0f; // maxSpeed should be set by caller return(true); }
public void ShowGUI(bool viewOnly) { try { IExtSegmentManager segMan = Constants.ManagerFactory.ExtSegmentManager; IExtSegmentEndManager segEndMan = Constants.ManagerFactory.ExtSegmentEndManager; TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance; TrafficPriorityManager prioMan = TrafficPriorityManager.Instance; TrafficLightManager tlm = TrafficLightManager.Instance; Vector3 camPos = Constants.ServiceFactory.SimulationService.CameraPosition; bool clicked = !viewOnly?MainTool.CheckClicked() : false; ushort removedNodeId = 0; bool showRemoveButton = false; foreach (ushort nodeId in currentPriorityNodeIds) { if (!Constants.ServiceFactory.NetService.IsNodeValid(nodeId)) { continue; } if (!MainTool.IsNodeWithinViewDistance(nodeId)) { continue; } Vector3 nodePos = default(Vector3); Constants.ServiceFactory.NetService.ProcessNode(nodeId, delegate(ushort nId, ref NetNode node) { nodePos = node.m_position; return(true); }); for (int i = 0; i < 8; ++i) { ushort segmentId = 0; Constants.ServiceFactory.NetService.ProcessNode(nodeId, delegate(ushort nId, ref NetNode node) { segmentId = node.GetSegment(i); return(true); }); if (segmentId == 0) { continue; } bool startNode = (bool)Constants.ServiceFactory.NetService.IsStartNode(segmentId, nodeId); ExtSegment seg = segMan.ExtSegments[segmentId]; ExtSegmentEnd segEnd = segEndMan.ExtSegmentEnds[segEndMan.GetIndex(segmentId, startNode)]; if (seg.oneWay && segEnd.outgoing) { continue; } // calculate sign position Vector3 signPos = nodePos; Constants.ServiceFactory.NetService.ProcessSegment(segmentId, delegate(ushort sId, ref NetSegment segment) { signPos += 10f * (startNode ? segment.m_startDirection : segment.m_endDirection); return(true); }); Vector3 signScreenPos; if (!MainTool.WorldToScreenPoint(signPos, out signScreenPos)) { continue; } // draw sign and handle input PriorityType sign = prioMan.GetPrioritySign(segmentId, startNode); if (viewOnly && sign == PriorityType.None) { continue; } if (!viewOnly && sign != PriorityType.None) { showRemoveButton = true; } if (MainTool.DrawGenericSquareOverlayTexture(TextureResources.PrioritySignTextures[sign], camPos, signPos, 90f, !viewOnly) && clicked) { PriorityType?newSign = null; switch (sign) { case PriorityType.Main: newSign = PriorityType.Yield; break; case PriorityType.Yield: newSign = PriorityType.Stop; break; case PriorityType.Stop: newSign = PriorityType.Main; break; case PriorityType.None: default: newSign = prioMan.CountPrioritySignsAtNode(nodeId, PriorityType.Main) >= 2 ? PriorityType.Yield : PriorityType.Main; break; } if (newSign != null) { SetPrioritySign(segmentId, startNode, (PriorityType)newSign); } } // draw sign } // foreach segment end if (viewOnly) { continue; } // draw remove button and handle click if (showRemoveButton && MainTool.DrawHoverableSquareOverlayTexture(TextureResources.SignRemoveTexture2D, camPos, nodePos, 90f) && clicked) { prioMan.RemovePrioritySignsFromNode(nodeId); Log._Debug($"PrioritySignsTool.ShowGUI: Removed priority signs from node {nodeId}"); removedNodeId = nodeId; } } // foreach node if (removedNodeId != 0) { currentPriorityNodeIds.Remove(removedNodeId); SelectedNodeId = 0; } } catch (Exception e) { Log.Error(e.ToString()); } }
/// <summary> /// Recalculates lane arrows based on present lane connections. /// </summary> /// <param name="laneId"></param> /// <param name="nodeId"></param> private void RecalculateLaneArrows(uint laneId, ushort nodeId, bool startNode) { #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}) called"); #endif if (!Flags.mayHaveLaneArrows(laneId, startNode)) { #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): lane {laneId}, startNode? {startNode} must not have lane arrows"); #endif return; } if (!HasConnections(laneId, startNode)) { #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): lane {laneId} does not have outgoing connections"); #endif return; } if (nodeId == 0) { #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): invalid node"); #endif return; } Flags.LaneArrows arrows = Flags.LaneArrows.None; NetManager netManager = Singleton <NetManager> .instance; ushort segmentId = netManager.m_lanes.m_buffer[laneId].m_segment; if (segmentId == 0) { #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): invalid segment"); #endif return; } #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): startNode? {startNode}"); #endif NodeGeometry nodeGeo = NodeGeometry.Get(nodeId); if (!nodeGeo.IsValid()) { #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): invalid node geometry"); #endif return; } SegmentGeometry segmentGeo = SegmentGeometry.Get(segmentId); if (!segmentGeo.IsValid()) { #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): invalid segment geometry"); #endif return; } ushort[] connectedSegmentIds = segmentGeo.GetConnectedSegments(startNode); if (connectedSegmentIds == null) { #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): connectedSegmentIds is null"); #endif return; } foreach (ushort connectedSegmentId in connectedSegmentIds) { if (connectedSegmentId == 0) { continue; } ArrowDirection dir = segmentGeo.GetDirection(connectedSegmentId, startNode); #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {connectedSegmentId}. dir={dir}"); #endif // check if arrow has already been set for this direction switch (dir) { case ArrowDirection.Turn: if (TrafficPriorityManager.IsLeftHandDrive()) { if ((arrows & Flags.LaneArrows.Right) != Flags.LaneArrows.None) { continue; } } else { if ((arrows & Flags.LaneArrows.Left) != Flags.LaneArrows.None) { continue; } } break; case ArrowDirection.Forward: if ((arrows & Flags.LaneArrows.Forward) != Flags.LaneArrows.None) { continue; } break; case ArrowDirection.Left: if ((arrows & Flags.LaneArrows.Left) != Flags.LaneArrows.None) { continue; } break; case ArrowDirection.Right: if ((arrows & Flags.LaneArrows.Right) != Flags.LaneArrows.None) { continue; } break; default: continue; } #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {connectedSegmentId}: need to determine arrows"); #endif bool addArrow = false; uint curLaneId = netManager.m_segments.m_buffer[connectedSegmentId].m_lanes; while (curLaneId != 0) { #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {connectedSegmentId}: checking lane {curLaneId}"); #endif if (AreLanesConnected(laneId, curLaneId, startNode)) { #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {connectedSegmentId}: checking lane {curLaneId}: lanes are connected"); #endif addArrow = true; break; } curLaneId = netManager.m_lanes.m_buffer[curLaneId].m_nextLane; } #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {connectedSegmentId}: finished processing lanes. addArrow={addArrow} arrows (before)={arrows}"); #endif if (addArrow) { switch (dir) { case ArrowDirection.Turn: if (TrafficPriorityManager.IsLeftHandDrive()) { arrows |= Flags.LaneArrows.Right; } else { arrows |= Flags.LaneArrows.Left; } break; case ArrowDirection.Forward: arrows |= Flags.LaneArrows.Forward; break; case ArrowDirection.Left: arrows |= Flags.LaneArrows.Left; break; case ArrowDirection.Right: arrows |= Flags.LaneArrows.Right; break; default: continue; } #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): processing connected segment {connectedSegmentId}: arrows={arrows}"); #endif } } #if DEBUGCONN Log._Debug($"LaneConnectionManager.RecalculateLaneArrows({laneId}, {nodeId}): setting lane arrows to {arrows}"); #endif LaneArrowManager.Instance.SetLaneArrows(laneId, arrows, true); }