public bool SetUpTimedTrafficLight(ref TrafficLightSimulation sim, IEnumerable <ushort> nodeGroup) { if (sim.IsManualLight()) { DestroyManualTrafficLight(ref sim); } if (sim.IsTimedLight()) { return(false); } Constants.ServiceFactory.NetService.ProcessNode( sim.nodeId, (ushort nId, ref NetNode node) => { Constants.ManagerFactory.TrafficLightManager.AddTrafficLight( nId, ref node); return(true); }); Constants.ManagerFactory.CustomSegmentLightsManager.AddNodeLights(sim.nodeId); sim.timedLight = new TimedTrafficLights(sim.nodeId, nodeGroup); sim.type = TrafficLightSimulationType.Timed; return(true); }
public override void OnPrimaryClickOverlay() { if (IsCursorInPanel()) { return; } 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); TrafficLightManager.Instance.ToggleTrafficLight(HoveredNodeId); }
public override void OnPrimaryClickOverlay() { if (SelectedNodeId != 0) { return; } TrafficLightSimulation sim = TrafficLightSimulation.GetNodeSimulation(HoveredNodeId); if (sim == null || !sim.IsTimedLight()) { if ((Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_flags & NetNode.Flags.TrafficLights) == NetNode.Flags.None) { TrafficPriority.RemovePrioritySegments(HoveredNodeId); Flags.setNodeTrafficLight(HoveredNodeId, true); } SelectedNodeId = HoveredNodeId; sim = TrafficLightSimulation.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 bool HasTimedSimulation(ushort nodeId) { TrafficLightSimulation sim = TrafficLightSimulations[nodeId]; if (sim == null) { return(false); } return(sim.IsTimedLight()); }
public bool SetUpManualTrafficLight(ref TrafficLightSimulation sim) { if (sim.IsTimedLight()) { return(false); } Constants.ManagerFactory.TrafficLightManager.AddTrafficLight( sim.nodeId, ref sim.nodeId.ToNode()); Constants.ManagerFactory.CustomSegmentLightsManager.AddNodeLights(sim.nodeId); sim.type = TrafficLightSimulationType.Manual; return(true); }
public bool DestroyTimedTrafficLight(ref TrafficLightSimulation sim) { if (!sim.IsTimedLight()) { return(false); } sim.type = TrafficLightSimulationType.None; ITimedTrafficLights timedLight = sim.timedLight; sim.timedLight = null; timedLight?.Destroy(); return(true); }
public bool DestroyManualTrafficLight(ref TrafficLightSimulation sim) { if (sim.IsTimedLight()) { return(false); } if (!sim.IsManualLight()) { return(false); } sim.type = TrafficLightSimulationType.None; Constants.ManagerFactory.CustomSegmentLightsManager.RemoveNodeLights(sim.nodeId); return(true); }
public bool SetUpManualTrafficLight(ref TrafficLightSimulation sim) { if (sim.IsTimedLight()) { return(false); } Constants.ServiceFactory.NetService.ProcessNode( sim.nodeId, (ushort nId, ref NetNode node) => { Constants.ManagerFactory.TrafficLightManager.AddTrafficLight( nId, ref node); return(true); }); Constants.ManagerFactory.CustomSegmentLightsManager.AddNodeLights(sim.nodeId); sim.type = TrafficLightSimulationType.Manual; return(true); }
public override void OnClickOverlay() { if ((Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_flags & NetNode.Flags.Junction) != NetNode.Flags.None) { if ((Singleton <NetManager> .instance.m_nodes.m_buffer[HoveredNodeId].m_flags & NetNode.Flags.TrafficLights) != NetNode.Flags.None) { TrafficLightSimulation sim = TrafficLightSimulation.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); } else { TrafficLightSimulation.RemoveNodeFromSimulation(HoveredNodeId, true); // TODO refactor! Flags.setNodeTrafficLight(HoveredNodeId, false); // TODO refactor! } } else { TrafficPriority.RemovePrioritySegments(HoveredNodeId); Flags.setNodeTrafficLight(HoveredNodeId, true); } } }
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 static void SaveTimedTrafficLight(ushort i, Configuration configuration) { try { TrafficLightSimulation sim = TrafficLightSimulation.GetNodeSimulation(i); if (sim == null || !sim.IsTimedLight()) { return; } Log._Debug($"Going to save timed light at node {i}."); var timedNode = sim.TimedLight; timedNode.handleNewSegments(); Configuration.TimedTrafficLights cnfTimedLights = new Configuration.TimedTrafficLights(); configuration.TimedLights.Add(cnfTimedLights); cnfTimedLights.nodeId = timedNode.NodeId; cnfTimedLights.nodeGroup = timedNode.NodeGroup; cnfTimedLights.started = timedNode.IsStarted(); cnfTimedLights.timedSteps = new List <Configuration.TimedTrafficLightsStep>(); for (var j = 0; j < timedNode.NumSteps(); j++) { Log._Debug($"Saving timed light step {j} at node {i}."); TimedTrafficLightsStep timedStep = timedNode.Steps[j]; Configuration.TimedTrafficLightsStep cnfTimedStep = new Configuration.TimedTrafficLightsStep(); cnfTimedLights.timedSteps.Add(cnfTimedStep); cnfTimedStep.minTime = timedStep.minTime; cnfTimedStep.maxTime = timedStep.maxTime; cnfTimedStep.waitFlowBalance = timedStep.waitFlowBalance; cnfTimedStep.segmentLights = new Dictionary <ushort, Configuration.CustomSegmentLights>(); foreach (KeyValuePair <ushort, CustomSegmentLights> e in timedStep.segmentLights) { Log._Debug($"Saving timed light step {j}, segment {e.Key} at node {i}."); CustomSegmentLights segLights = e.Value; Configuration.CustomSegmentLights cnfSegLights = new Configuration.CustomSegmentLights(); cnfTimedStep.segmentLights.Add(e.Key, cnfSegLights); cnfSegLights.nodeId = segLights.NodeId; cnfSegLights.segmentId = segLights.SegmentId; cnfSegLights.customLights = new Dictionary <ExtVehicleType, Configuration.CustomSegmentLight>(); cnfSegLights.pedestrianLightState = segLights.PedestrianLightState; cnfSegLights.manualPedestrianMode = segLights.ManualPedestrianMode; Log._Debug($"Saving pedestrian light @ seg. {e.Key}, step {j}: {cnfSegLights.pedestrianLightState} {cnfSegLights.manualPedestrianMode}"); foreach (KeyValuePair <Traffic.ExtVehicleType, CustomSegmentLight> e2 in segLights.CustomLights) { Log._Debug($"Saving timed light step {j}, segment {e.Key}, vehicleType {e2.Key} at node {i}."); CustomSegmentLight segLight = e2.Value; Configuration.CustomSegmentLight cnfSegLight = new Configuration.CustomSegmentLight(); cnfSegLights.customLights.Add(e2.Key, cnfSegLight); cnfSegLight.nodeId = segLight.NodeId; cnfSegLight.segmentId = segLight.SegmentId; cnfSegLight.currentMode = (int)segLight.CurrentMode; cnfSegLight.leftLight = segLight.LightLeft; cnfSegLight.mainLight = segLight.LightMain; cnfSegLight.rightLight = segLight.LightRight; } } } } catch (Exception e) { Log.Error($"Error adding TimedTrafficLights to save {e.Message}"); } }
public override void OnSaveData() { Log.Info("Recalculating segment geometries"); SegmentGeometry.OnBeforeSaveData(); Log.Info("Saving Mod Data."); var configuration = new Configuration(); if (TrafficPriority.TrafficSegments != null) { for (ushort i = 0; i < Singleton <NetManager> .instance.m_segments.m_size; i++) { try { SavePrioritySegment(i, configuration); } catch (Exception e) { Log.Error($"Exception occurred while saving priority segment @ {i}: {e.ToString()}"); } try { SaveSegmentNodeFlags(i, configuration); } catch (Exception e) { Log.Error($"Exception occurred while saving segment node flags @ {i}: {e.ToString()}"); } } } for (ushort i = 0; i < Singleton <NetManager> .instance.m_nodes.m_size; i++) { /*if (TrafficLightSimulation.LightSimulationByNodeId != null) { * SaveTrafficLightSimulation(i, configuration); * }*/ /*if (TrafficLightsManual.ManualSegments != null) { * SaveManualTrafficLight(i, configuration); * }*/ TrafficLightSimulation sim = TrafficLightSimulation.GetNodeSimulation(i); if (sim != null && sim.IsTimedLight()) { try { SaveTimedTrafficLight(i, configuration); } catch (Exception e) { Log.Error($"Exception occurred while saving timed traffic light @ {i}: {e.ToString()}"); } // TODO save new traffic lights } try { SaveNodeLights(i, configuration); } catch (Exception e) { Log.Error($"Exception occurred while saving node traffic light @ {i}: {e.ToString()}"); } } #if !TAM if (LoadingExtension.IsPathManagerCompatible) { #endif for (uint i = 0; i < Singleton <NetManager> .instance.m_lanes.m_buffer.Length; i++) { try { SaveLaneData(i, configuration); } catch (Exception e) { Log.Error($"Exception occurred while saving lane data @ {i}: {e.ToString()}"); } } #if !TAM } #endif foreach (KeyValuePair <uint, ushort> e in Flags.getAllLaneSpeedLimits()) { try { SaveLaneSpeedLimit(new Configuration.LaneSpeedLimit(e.Key, e.Value), configuration); } catch (Exception ex) { Log.Error($"Exception occurred while saving lane speed limit @ {e.Key}: {ex.ToString()}"); } } foreach (KeyValuePair <uint, ExtVehicleType> e in Flags.getAllLaneAllowedVehicleTypes()) { try { SaveLaneAllowedVehicleTypes(new Configuration.LaneVehicleTypes(e.Key, e.Value), configuration); } catch (Exception ex) { Log.Error($"Exception occurred while saving lane vehicle restrictions @ {e.Key}: {ex.ToString()}"); } } 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()); // save options _serializableData.SaveData("TMPE_Options", new byte[] { (byte)Options.simAccuracy, (byte)0, //Options.laneChangingRandomization, (byte)Options.recklessDrivers, (byte)(Options.relaxedBusses ? 1 : 0), (byte)(Options.nodesOverlay ? 1 : 0), (byte)(Options.allowEnterBlockedJunctions ? 1 : 0), (byte)(Options.advancedAI ? 1 : 0), (byte)(Options.highwayRules ? 1 : 0), (byte)(Options.prioritySignsOverlay ? 1 : 0), (byte)(Options.timedLightsOverlay ? 1 : 0), (byte)(Options.speedLimitsOverlay ? 1 : 0), (byte)(Options.vehicleRestrictionsOverlay ? 1 : 0), (byte)(Options.strongerRoadConditionEffects ? 1 : 0), (byte)(Options.allowUTurns ? 1 : 0), (byte)(Options.allowLaneChangesWhileGoingStraight ? 1 : 0), (byte)(Options.enableDespawning ? 1 : 0), (byte)(Options.IsDynamicPathRecalculationActive() ? 1 : 0), (byte)(Options.connectedLanesOverlay ? 1 : 0) }); } catch (Exception ex) { Log.Error("Unexpected error saving data: " + ex.Message); } finally { memoryStream.Close(); } }
/// <summary> /// Handles vehicle path information in order to manage special nodes (nodes with priority signs or traffic lights). /// Data like "vehicle X is on segment S0 and is going to segment S1" is collected. /// </summary> /// <param name="vehicleId"></param> /// <param name="vehicleData"></param> internal static void HandleVehicle(ushort vehicleId, ref Vehicle vehicleData, bool addTraffic, bool realTraffic, byte maxUpcomingPathPositions, bool debug = false) { if (maxUpcomingPathPositions <= 0) { maxUpcomingPathPositions = 1; // we need at least one upcoming path position } var netManager = Singleton <NetManager> .instance; var lastFrameData = vehicleData.GetLastFrameData(); var lastFrameVehiclePos = lastFrameData.m_position; #if DEBUGV var camPos = Camera.main.transform.position; //debug = (lastFrameVehiclePos - camPos).sqrMagnitude < CloseLod; debug = false; List <String> logBuffer = new List <String>(); bool logme = false; #endif if ((vehicleData.m_flags & Vehicle.Flags.Created) == 0) { TrafficPriority.RemoveVehicleFromSegments(vehicleId); return; } if (vehicleData.Info.m_vehicleType != VehicleInfo.VehicleType.Car && vehicleData.Info.m_vehicleType != VehicleInfo.VehicleType.Train && vehicleData.Info.m_vehicleType != VehicleInfo.VehicleType.Tram) { //Log._Debug($"HandleVehicle does not handle vehicles of type {vehicleData.Info.m_vehicleType}"); return; } #if DEBUGV logBuffer.Add("Calculating prio info for vehicleId " + vehicleId); #endif ExtVehicleType?vehicleType = CustomVehicleAI.DetermineVehicleTypeFromVehicle(vehicleId, ref vehicleData); if (vehicleType == null) { Log.Warning($"Could not determine vehicle type of vehicle {vehicleId}!"); } if (vehicleType == null || vehicleType == ExtVehicleType.None) { return; } // add vehicle to our vehicle list VehiclePosition vehiclePos = TrafficPriority.GetVehiclePosition(vehicleId); // we extract the segment information directly from the vehicle var currentPathUnitId = vehicleData.m_path; List <ushort> realTimeDestinationNodes = new List <ushort>(); // current and upcoming node ids List <PathUnit.Position> realTimePositions = new List <PathUnit.Position>(); // current and upcoming vehicle positions #if DEBUGV logBuffer.Add("* vehicleId " + vehicleId + ". currentPathId: " + currentPathUnitId + " pathPositionIndex: " + vehicleData.m_pathPositionIndex); #endif if (currentPathUnitId > 0) { // vehicle has a path... if ((Singleton <PathManager> .instance.m_pathUnits.m_buffer[currentPathUnitId].m_pathFindFlags & PathUnit.FLAG_READY) != 0) { // The path(unit) is established and is ready for use: get the vehicle's current position in terms of segment and lane realTimePositions.Add(Singleton <PathManager> .instance.m_pathUnits.m_buffer[currentPathUnitId].GetPosition(vehicleData.m_pathPositionIndex >> 1)); if (realTimePositions[0].m_offset == 0) { realTimeDestinationNodes.Add(netManager.m_segments.m_buffer[realTimePositions[0].m_segment].m_startNode); } else { realTimeDestinationNodes.Add(netManager.m_segments.m_buffer[realTimePositions[0].m_segment].m_endNode); } if (maxUpcomingPathPositions > 0) { // evaluate upcoming path units byte i = 0; uint pathUnitId = currentPathUnitId; int pathPos = (byte)((vehicleData.m_pathPositionIndex >> 1) + 1); while (true) { if (pathPos > 11) { // go to next path unit pathPos = 0; pathUnitId = Singleton <PathManager> .instance.m_pathUnits.m_buffer[pathUnitId].m_nextPathUnit; #if DEBUGV logBuffer.Add("* vehicleId " + vehicleId + ". Going to next path unit (1). pathUnitId=" + pathUnitId); #endif if (pathUnitId <= 0) { break; } } PathUnit.Position nextRealTimePosition = default(PathUnit.Position); if (!Singleton <PathManager> .instance.m_pathUnits.m_buffer[pathUnitId].GetPosition(pathPos, out nextRealTimePosition)) // if this returns false, there is no next path unit { #if DEBUGV logBuffer.Add("* vehicleId " + vehicleId + ". No next path unit! pathPos=" + pathPos + ", pathUnitId=" + pathUnitId); #endif break; } ushort destNodeId = 0; if (nextRealTimePosition.m_segment > 0) { if (nextRealTimePosition.m_offset == 0) { destNodeId = netManager.m_segments.m_buffer[nextRealTimePosition.m_segment].m_startNode; } else { destNodeId = netManager.m_segments.m_buffer[nextRealTimePosition.m_segment].m_endNode; } } #if DEBUGV logBuffer.Add("* vehicleId " + vehicleId + ". Next path unit! node " + destNodeId + ", seg. " + nextRealTimePosition.m_segment + ", pathUnitId=" + pathUnitId + ", pathPos: " + pathPos); #endif realTimePositions.Add(nextRealTimePosition); realTimeDestinationNodes.Add(destNodeId); if (i >= maxUpcomingPathPositions - 1) { break; // we calculate up to 2 upcoming path units at the moment } ++pathPos; ++i; } } // please don't ask why we use "m_pathPositionIndex >> 1" (which equals to "m_pathPositionIndex / 2") here (Though it would // be interesting to know why they used such an ugly indexing scheme!!). I assume the oddness of m_pathPositionIndex relates // to the car's position on the segment. If it is even the car might be in the segment's first half and if it is odd, it might // be in the segment's second half. #if DEBUGV logBuffer.Add("* vehicleId " + vehicleId + ". *INFO* rtPos.seg=" + realTimePositions[0].m_segment + " nrtPos.seg=" + (realTimePositions.Count > 1 ? "" + realTimePositions[1].m_segment : "n/a")); #endif } } // we have seen the car! vehiclePos.LastFrame = Singleton <SimulationManager> .instance.m_currentFrameIndex; #if DEBUGV logBuffer.Add("* vehicleId " + vehicleId + ". ToNode: " + vehiclePos.ToNode + ". FromSegment: " + vehiclePos.FromSegment /* + ". FromLaneId: " + TrafficPriority.Vehicles[vehicleId].FromLaneId*/); #endif if (addTraffic && vehicleData.m_leadingVehicle == 0 && realTimePositions.Count > 0) { // add traffic to lane uint laneId = PathManager.GetLaneID(realTimePositions[0]); CustomRoadAI.AddTraffic(laneId, (ushort)Mathf.RoundToInt(vehicleData.CalculateTotalLength(vehicleId)), (ushort)Mathf.RoundToInt(lastFrameData.m_velocity.magnitude), realTraffic); } #if DEBUGV logBuffer.Add("* vehicleId " + vehicleId + ". Real time positions: " + realTimePositions.Count + ", Destination nodes: " + realTimeDestinationNodes.Count); #endif if (realTimePositions.Count >= 1) { // we found a valid path unit var sourceLaneIndex = realTimePositions[0].m_lane; if ( !vehiclePos.Valid || vehiclePos.ToNode != realTimeDestinationNodes[0] || vehiclePos.FromSegment != realTimePositions[0].m_segment || vehiclePos.FromLaneIndex != sourceLaneIndex) { // vehicle information is not up-to-date. remove the car from old priority segments (if existing)... TrafficPriority.RemoveVehicleFromSegments(vehicleId); if (realTimePositions.Count >= 2) { // save vehicle information for priority rule handling vehiclePos.Valid = true; vehiclePos.CarState = VehicleJunctionTransitState.None; vehiclePos.WaitTime = 0; vehiclePos.Stopped = false; vehiclePos.ToNode = realTimeDestinationNodes[0]; vehiclePos.FromSegment = realTimePositions[0].m_segment; vehiclePos.FromLaneIndex = realTimePositions[0].m_lane; vehiclePos.ToSegment = realTimePositions[1].m_segment; vehiclePos.ToLaneIndex = realTimePositions[1].m_lane; vehiclePos.ReduceSpeedByValueToYield = UnityEngine.Random.Range(16f, 28f); vehiclePos.OnEmergency = (vehicleData.m_flags & Vehicle.Flags.Emergency2) != 0; vehiclePos.VehicleType = (ExtVehicleType)vehicleType; #if DEBUGV logBuffer.Add($"* vehicleId {vehicleId}. Setting current position to: from {vehiclePos.FromSegment} (lane {vehiclePos.FromLaneIndex}), going over {vehiclePos.ToNode}, to {vehiclePos.ToSegment} (lane {vehiclePos.ToLaneIndex})"); #endif //if (!Options.disableSomething) { // add the vehicle to upcoming priority segments that have timed traffic lights for (int i = 0; i < realTimePositions.Count - 1; ++i) { var prioritySegment = TrafficPriority.GetPrioritySegment(realTimeDestinationNodes[i], realTimePositions[i].m_segment); if (prioritySegment == null) { continue; } // add upcoming segments only if there is a timed traffic light TrafficLightSimulation nodeSim = TrafficLightSimulation.GetNodeSimulation(realTimeDestinationNodes[i]); if (i > 0 && (nodeSim == null || !nodeSim.IsTimedLight() || !nodeSim.IsTimedLightActive())) { continue; } VehiclePosition upcomingVehiclePos = new VehiclePosition(); upcomingVehiclePos.Valid = true; upcomingVehiclePos.CarState = VehicleJunctionTransitState.None; upcomingVehiclePos.LastFrame = vehiclePos.LastFrame; upcomingVehiclePos.ToNode = realTimeDestinationNodes[i]; upcomingVehiclePos.FromSegment = realTimePositions[i].m_segment; upcomingVehiclePos.FromLaneIndex = realTimePositions[i].m_lane; upcomingVehiclePos.ToSegment = realTimePositions[i + 1].m_segment; upcomingVehiclePos.ToLaneIndex = realTimePositions[i + 1].m_lane; upcomingVehiclePos.ReduceSpeedByValueToYield = UnityEngine.Random.Range(16f, 28f); upcomingVehiclePos.OnEmergency = (vehicleData.m_flags & Vehicle.Flags.Emergency2) != 0; upcomingVehiclePos.VehicleType = (ExtVehicleType)vehicleType; #if DEBUGV logBuffer.Add($"* vehicleId {vehicleId}. Adding future position: from {upcomingVehiclePos.FromSegment} (lane {upcomingVehiclePos.FromLaneIndex}), going over {upcomingVehiclePos.ToNode}, to {upcomingVehiclePos.ToSegment} (lane {upcomingVehiclePos.ToLaneIndex})"); #endif prioritySegment.AddVehicle(vehicleId, upcomingVehiclePos); } } //} } else { #if DEBUGV logBuffer.Add($"* vehicleId {vehicleId}. Nothing has changed. from {vehiclePos.FromSegment} (lane {vehiclePos.FromLaneIndex}), going over {vehiclePos.ToNode}, to {vehiclePos.ToSegment} (lane {vehiclePos.ToLaneIndex})"); logme = false; #endif } } else { #if DEBUGV logBuffer.Add($"* vehicleId {vehicleId}. Insufficient path unit positions."); #endif TrafficPriority.RemoveVehicleFromSegments(vehicleId); } #if DEBUGV if (logme) { Log._Debug("vehicleId: " + vehicleId + " ============================================"); foreach (String logBuf in logBuffer) { Log._Debug(logBuf); } Log._Debug("vehicleId: " + vehicleId + " ============================================"); } #endif }
public override void OnSaveData() { bool error = false; /*try { * Log.Info("Recalculating segment geometries"); * SegmentGeometry.OnBeforeSaveData(); * } catch (Exception e) { * Log.Error($"OnSaveData: Exception occurred while calling SegmentGeometry.OnBeforeSaveData: {e.ToString()}"); * error = true; * }*/ try { Log.Info("Applying all flags"); Flags.applyAllFlags(); } catch (Exception e) { Log.Error($"OnSaveData: Exception occurred while applying all flags: {e.ToString()}"); error = true; } try { Log.Info("Saving Mod Data."); var configuration = new Configuration(); TrafficPriorityManager prioMan = TrafficPriorityManager.Instance(); if (prioMan.TrafficSegments != null) { for (ushort i = 0; i < Singleton <NetManager> .instance.m_segments.m_size; i++) { try { SavePrioritySegment(i, configuration); } catch (Exception e) { Log.Error($"Exception occurred while saving priority segment @ {i}: {e.ToString()}"); error = true; } try { SaveSegmentNodeFlags(i, configuration); } catch (Exception e) { Log.Error($"Exception occurred while saving segment node flags @ {i}: {e.ToString()}"); error = true; } } } TrafficLightSimulationManager tlsMan = TrafficLightSimulationManager.Instance(); for (ushort i = 0; i < Singleton <NetManager> .instance.m_nodes.m_size; i++) { /*if (TrafficLightSimulation.LightSimulationByNodeId != null) { * SaveTrafficLightSimulation(i, configuration); * }*/ /*if (TrafficLightsManual.ManualSegments != null) { * SaveManualTrafficLight(i, configuration); * }*/ TrafficLightSimulation sim = tlsMan.GetNodeSimulation(i); if (sim != null && sim.IsTimedLight()) { try { SaveTimedTrafficLight(i, configuration); } catch (Exception e) { Log.Error($"Exception occurred while saving timed traffic light @ {i}: {e.ToString()}"); error = true; } // TODO save new traffic lights } try { SaveNodeLights(i, configuration); } catch (Exception e) { Log.Error($"Exception occurred while saving node traffic light @ {i}: {e.ToString()}"); error = true; } } #if !TAM if (LoadingExtension.IsPathManagerCompatible) { #endif for (uint i = 0; i < Singleton <NetManager> .instance.m_lanes.m_buffer.Length; i++) { try { SaveLaneData(i, configuration); } catch (Exception e) { Log.Error($"Exception occurred while saving lane data @ {i}: {e.ToString()}"); error = true; } } #if !TAM } #endif foreach (KeyValuePair <uint, ushort> e in Flags.getAllLaneSpeedLimits()) { try { SaveLaneSpeedLimit(new Configuration.LaneSpeedLimit(e.Key, e.Value), configuration); } catch (Exception ex) { Log.Error($"Exception occurred while saving lane speed limit @ {e.Key}: {ex.ToString()}"); error = true; } } foreach (KeyValuePair <uint, ExtVehicleType> e in Flags.getAllLaneAllowedVehicleTypes()) { try { SaveLaneAllowedVehicleTypes(new Configuration.LaneVehicleTypes(e.Key, e.Value), configuration); } catch (Exception ex) { Log.Error($"Exception occurred while saving lane vehicle restrictions @ {e.Key}: {ex.ToString()}"); error = true; } } 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()); error = true; } finally { memoryStream.Close(); } try { // save options _serializableData.SaveData("TMPE_Options", new byte[] { (byte)Options.simAccuracy, (byte)0, //Options.laneChangingRandomization, (byte)Options.recklessDrivers, (byte)(Options.relaxedBusses ? 1 : 0), (byte)(Options.nodesOverlay ? 1 : 0), (byte)(Options.allowEnterBlockedJunctions ? 1 : 0), (byte)(Options.advancedAI ? 1 : 0), (byte)(Options.highwayRules ? 1 : 0), (byte)(Options.prioritySignsOverlay ? 1 : 0), (byte)(Options.timedLightsOverlay ? 1 : 0), (byte)(Options.speedLimitsOverlay ? 1 : 0), (byte)(Options.vehicleRestrictionsOverlay ? 1 : 0), (byte)(Options.strongerRoadConditionEffects ? 1 : 0), (byte)(Options.allowUTurns ? 1 : 0), (byte)(Options.allowLaneChangesWhileGoingStraight ? 1 : 0), (byte)(Options.enableDespawning ? 1 : 0), (byte)(Options.IsDynamicPathRecalculationActive() ? 1 : 0), (byte)(Options.connectedLanesOverlay ? 1 : 0), (byte)(Options.prioritySignsEnabled ? 1 : 0), (byte)(Options.timedLightsEnabled ? 1 : 0), (byte)(Options.customSpeedLimitsEnabled ? 1 : 0), (byte)(Options.vehicleRestrictionsEnabled ? 1 : 0), (byte)(Options.laneConnectorEnabled ? 1 : 0), (byte)(Options.junctionRestrictionsOverlay ? 1 : 0), (byte)(Options.junctionRestrictionsEnabled ? 1 : 0) }); } catch (Exception ex) { Log.Error("Unexpected error while saving options: " + ex.Message); error = true; } } catch (Exception e) { error = true; 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); } }
public List <Configuration.TimedTrafficLights> SaveData(ref bool success) { List <Configuration.TimedTrafficLights> ret = new List <Configuration.TimedTrafficLights>(); for (ushort nodeId = 0; nodeId < NetManager.MAX_NODE_COUNT; ++nodeId) { try { TrafficLightSimulation sim = GetNodeSimulation(nodeId); if (sim == null || !sim.IsTimedLight()) { continue; } Log._Debug($"Going to save timed light at node {nodeId}."); var timedNode = sim.TimedLight; timedNode.handleNewSegments(); Configuration.TimedTrafficLights cnfTimedLights = new Configuration.TimedTrafficLights(); ret.Add(cnfTimedLights); cnfTimedLights.nodeId = timedNode.NodeId; cnfTimedLights.nodeGroup = timedNode.NodeGroup; cnfTimedLights.started = timedNode.IsStarted(); cnfTimedLights.timedSteps = new List <Configuration.TimedTrafficLightsStep>(); for (var j = 0; j < timedNode.NumSteps(); j++) { Log._Debug($"Saving timed light step {j} at node {nodeId}."); TimedTrafficLightsStep timedStep = timedNode.Steps[j]; Configuration.TimedTrafficLightsStep cnfTimedStep = new Configuration.TimedTrafficLightsStep(); cnfTimedLights.timedSteps.Add(cnfTimedStep); cnfTimedStep.minTime = timedStep.minTime; cnfTimedStep.maxTime = timedStep.maxTime; cnfTimedStep.waitFlowBalance = timedStep.waitFlowBalance; cnfTimedStep.segmentLights = new Dictionary <ushort, Configuration.CustomSegmentLights>(); foreach (KeyValuePair <ushort, CustomSegmentLights> e in timedStep.segmentLights) { Log._Debug($"Saving timed light step {j}, segment {e.Key} at node {nodeId}."); CustomSegmentLights segLights = e.Value; Configuration.CustomSegmentLights cnfSegLights = new Configuration.CustomSegmentLights(); cnfTimedStep.segmentLights.Add(e.Key, cnfSegLights); cnfSegLights.nodeId = segLights.NodeId; cnfSegLights.segmentId = segLights.SegmentId; cnfSegLights.customLights = new Dictionary <ExtVehicleType, Configuration.CustomSegmentLight>(); cnfSegLights.pedestrianLightState = segLights.PedestrianLightState; cnfSegLights.manualPedestrianMode = segLights.ManualPedestrianMode; Log._Debug($"Saving pedestrian light @ seg. {e.Key}, step {j}: {cnfSegLights.pedestrianLightState} {cnfSegLights.manualPedestrianMode}"); foreach (KeyValuePair <ExtVehicleType, CustomSegmentLight> e2 in segLights.CustomLights) { Log._Debug($"Saving timed light step {j}, segment {e.Key}, vehicleType {e2.Key} at node {nodeId}."); CustomSegmentLight segLight = e2.Value; Configuration.CustomSegmentLight cnfSegLight = new Configuration.CustomSegmentLight(); cnfSegLights.customLights.Add(e2.Key, cnfSegLight); cnfSegLight.nodeId = segLight.NodeId; cnfSegLight.segmentId = segLight.SegmentId; cnfSegLight.currentMode = (int)segLight.CurrentMode; cnfSegLight.leftLight = segLight.LightLeft; cnfSegLight.mainLight = segLight.LightMain; cnfSegLight.rightLight = segLight.LightRight; } } } } catch (Exception e) { Log.Error($"Exception occurred while saving timed traffic light @ {nodeId}: {e.ToString()}"); success = false; } } return(ret); }