public void SimulationStep(ref NetNode data) { NetManager instance = Singleton <NetManager> .instance; uint currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex; if (TrafficLightsTimed.IsTimedLight(NodeId) && TimedTrafficLightsActive) { var timedNode = TrafficLightsTimed.GetTimedLight(NodeId); timedNode.checkStep(currentFrameIndex >> 6); } for (int l = 0; l < 8; l++) { ushort segment = data.GetSegment(l); if (segment != 0) { if (TrafficLightsManual.IsSegmentLight(NodeId, segment)) { var segmentLight = TrafficLightsManual.GetSegmentLight(NodeId, segment); segmentLight.lastChange = (currentFrameIndex >> 6) - segmentLight.lastChangeFrame; } } } }
public override void OnLevelUnloading() { base.OnLevelUnloading(); if (Instance == null) { Instance = this; } revertDetours(); try { TrafficPriority.OnLevelUnloading(); CustomCarAI.OnLevelUnloading(); TrafficLightsManual.OnLevelUnloading(); TrafficLightsTimed.OnLevelUnloading(); if (Instance != null) { Instance.NodeSimulationLoaded = false; } } catch (Exception e) { Log.Error("Exception unloading mod. " + e.Message); // ignored - prevents collision with other mods } }
private static void AddTimedTrafficLight(int i, Configuration configuration) { try { if (!TrafficLightsTimed.TimedScripts.ContainsKey((ushort)i)) { return; } var timedNode = TrafficLightsTimed.GetTimedLight((ushort)i); configuration.TimedNodes.Add(new[] { timedNode.nodeId, timedNode.CurrentStep, timedNode.NumSteps(), Convert.ToInt32(timedNode.IsStarted()) }); var nodeGroup = new ushort[timedNode.NodeGroup.Count]; for (var j = 0; j < timedNode.NodeGroup.Count; j++) { nodeGroup[j] = timedNode.NodeGroup[j]; } configuration.TimedNodeGroups.Add(nodeGroup); // get segment ids which are still defined but for which real road segments are missing HashSet <ushort> invalidSegmentIds = timedNode.getInvalidSegmentIds(); for (var j = 0; j < timedNode.NumSteps(); j++) { int validCount = timedNode.Steps[j].segmentIds.Count - invalidSegmentIds.Count; configuration.TimedNodeSteps.Add(new[] { timedNode.Steps[j].minTime, timedNode.Steps[j].maxTime, validCount }); for (var k = 0; k < timedNode.Steps[j].segmentIds.Count; k++) { var segmentId = timedNode.Steps[j].segmentIds[k]; if (invalidSegmentIds.Contains(segmentId)) { continue; } var segLight = timedNode.Steps[j].segmentLightStates[segmentId]; configuration.TimedNodeStepSegments.Add(new[] { (int)segLight.LightLeft, (int)segLight.LightMain, (int)segLight.LightRight, (int)segLight.LightPedestrian }); } } } catch (Exception e) { Log.Error($"Error adding TimedTrafficLights to save {e.Message}"); } }
private static void LoadDataState() { Log.Message("Loading State from Config"); if (_configuration == null) { Log.Message("Configuration NULL, Couldn't load save data. Possibly a new game?"); return; } foreach (var segment in _configuration.PrioritySegments) { if (segment.Length < 3) { continue; } if (TrafficPriority.IsPrioritySegment((ushort)segment[0], (ushort)segment[1])) { continue; } Log.Message($"Adding Priority Segment of type: {segment[2].ToString()}"); TrafficPriority.AddPrioritySegment((ushort)segment[0], (ushort)segment[1], (PrioritySegment.PriorityType)segment[2]); } foreach (var node in _configuration.NodeDictionary) { if (node.Length < 4) { continue; } if (TrafficPriority.GetNodeSimulation((ushort)node[0]) != null) { continue; } Log.Message($"Adding Node do Simulation {node[0]}"); try { TrafficPriority.AddNodeToSimulation((ushort)node[0]); var nodeDict = TrafficPriority.GetNodeSimulation((ushort)node[0]); nodeDict.ManualTrafficLights = Convert.ToBoolean(node[1]); nodeDict.TimedTrafficLights = Convert.ToBoolean(node[2]); nodeDict.TimedTrafficLightsActive = Convert.ToBoolean(node[3]); } catch (Exception e) { // if we failed, just means it's old corrupt data. Ignore it and continue. Log.Warning("Error loading data from the NodeDictionary: " + e.Message); } } foreach (var segmentData in _configuration.ManualSegments) { if (segmentData.Length < 10) { continue; } if (TrafficLightsManual.IsSegmentLight((ushort)segmentData[0], (ushort)segmentData[1])) { continue; } Log.Message($"Adding Light to Segment {segmentData[0]}"); try { TrafficLightsManual.AddSegmentLight((ushort)segmentData[0], (ushort)segmentData[1], RoadBaseAI.TrafficLightState.Green); var segment = TrafficLightsManual.GetSegmentLight((ushort)segmentData[0], (ushort)segmentData[1]); segment.CurrentMode = (ManualSegmentLight.Mode)segmentData[2]; segment.LightLeft = (RoadBaseAI.TrafficLightState)segmentData[3]; segment.LightMain = (RoadBaseAI.TrafficLightState)segmentData[4]; segment.LightRight = (RoadBaseAI.TrafficLightState)segmentData[5]; segment.LightPedestrian = (RoadBaseAI.TrafficLightState)segmentData[6]; segment.LastChange = (uint)segmentData[7]; segment.LastChangeFrame = (uint)segmentData[8]; segment.PedestrianEnabled = Convert.ToBoolean(segmentData[9]); } catch (Exception e) { // if we failed, just means it's old corrupt data. Ignore it and continue. Log.Warning("Error loading data from the ManualSegments: " + e.Message); } } var timedStepCount = 0; var timedStepSegmentCount = 0; if (_configuration.TimedNodes.Count > 0) { for (var i = 0; i < _configuration.TimedNodes.Count; i++) { try { var nodeid = (ushort)_configuration.TimedNodes[i][0]; Log.Message($"Adding Timed Node {i} at node {nodeid}"); var nodeGroup = new List <ushort>(); for (var j = 0; j < _configuration.TimedNodeGroups[i].Length; j++) { nodeGroup.Add(_configuration.TimedNodeGroups[i][j]); } if (TrafficLightsTimed.IsTimedLight(nodeid)) { continue; } TrafficLightsTimed.AddTimedLight(nodeid, nodeGroup); var timedNode = TrafficLightsTimed.GetTimedLight(nodeid); timedNode.CurrentStep = _configuration.TimedNodes[i][1]; for (var j = 0; j < _configuration.TimedNodes[i][2]; j++) { var cfgstep = _configuration.TimedNodeSteps[timedStepCount]; // old (pre 1.3.0): // cfgstep[0]: time of step // cfgstep[1]: number of segments // new (post 1.3.0): // cfgstep[0]: min. time of step // cfgstep[1]: max. time of step // cfgstep[2]: number of segments int minTime = 1; int maxTime = 1; int numSegments = 0; if (cfgstep.Length == 2) { minTime = cfgstep[0]; maxTime = cfgstep[0]; numSegments = cfgstep[1]; } else if (cfgstep.Length == 3) { minTime = cfgstep[0]; maxTime = cfgstep[1]; numSegments = cfgstep[2]; } timedNode.AddStep(minTime, maxTime); var step = timedNode.Steps[j]; if (numSegments <= step.segmentIds.Count) { for (var k = 0; k < numSegments; k++) { ushort stepSegmentId = (ushort)step.segmentIds[k]; var leftLightState = (RoadBaseAI.TrafficLightState)_configuration.TimedNodeStepSegments[timedStepSegmentCount][0]; var mainLightState = (RoadBaseAI.TrafficLightState)_configuration.TimedNodeStepSegments[timedStepSegmentCount][1]; var rightLightState = (RoadBaseAI.TrafficLightState)_configuration.TimedNodeStepSegments[timedStepSegmentCount][2]; var pedLightState = (RoadBaseAI.TrafficLightState)_configuration.TimedNodeStepSegments[timedStepSegmentCount][3]; //ManualSegmentLight segmentLight = new ManualSegmentLight(step.NodeId, step.segmentIds[k], mainLightState, leftLightState, rightLightState, pedLightState); step.segmentLightStates[stepSegmentId].LightLeft = leftLightState; step.segmentLightStates[stepSegmentId].LightMain = mainLightState; step.segmentLightStates[stepSegmentId].LightRight = rightLightState; step.segmentLightStates[stepSegmentId].LightPedestrian = pedLightState; timedStepSegmentCount++; } } timedStepCount++; } if (Convert.ToBoolean(_configuration.TimedNodes[i][3])) { timedNode.Start(); } } catch (Exception e) { // ignore, as it's probably corrupt save data. it'll be culled on next save Log.Warning("Error loading data from the TimedNodes: " + e.Message); } } } Log.Message($"Config Nodes: {_configuration.NodeTrafficLights.Length}\nLevel Nodes: {Singleton<NetManager>.instance.m_nodes.m_buffer.Length}"); var saveDataIndex = 0; var nodeCount = Singleton <NetManager> .instance.m_nodes.m_buffer.Length; if (nodeCount > 0) { for (var i = 0; i < nodeCount; i++) { //Log.Message($"Adding NodeTrafficLights iteration: {i1}"); try { if (Singleton <NetManager> .instance.m_nodes.m_buffer[i].Info.m_class.m_service != ItemClass.Service.Road || Singleton <NetManager> .instance.m_nodes.m_buffer[i].m_flags == 0) { continue; } // prevent overflow if (_configuration.NodeTrafficLights.Length > saveDataIndex) { var trafficLight = _configuration.NodeTrafficLights[saveDataIndex]; if (trafficLight == '1') { //Log.Message($"Adding Traffic Light at Segment: {Singleton<NetManager>.instance.m_nodes.m_buffer[i].Info.name}"); Singleton <NetManager> .instance.m_nodes.m_buffer[i].m_flags |= NetNode.Flags.TrafficLights; } else { //Log.Message($"Removing Traffic Light from Segment: {Singleton<NetManager>.instance.m_nodes.m_buffer[i].Info.name}"); Singleton <NetManager> .instance.m_nodes.m_buffer[i].m_flags &= ~NetNode.Flags.TrafficLights; } } if (_configuration.NodeCrosswalk.Length > saveDataIndex) { var crossWalk = _configuration.NodeCrosswalk[saveDataIndex]; if (crossWalk == '1') { Singleton <NetManager> .instance.m_nodes.m_buffer[i].m_flags |= NetNode.Flags.Junction; } else { Singleton <NetManager> .instance.m_nodes.m_buffer[i].m_flags &= ~NetNode.Flags.Junction; } } ++saveDataIndex; } catch (Exception e) { // ignore as it's probably bad save data. Log.Warning("Error setting the NodeTrafficLights: " + e.Message); } } } // For Traffic++ compatibility if (!LoadingExtension.IsPathManagerCompatible) { return; } Log.Message($"LaneFlags: {_configuration.LaneFlags}"); var lanes = _configuration.LaneFlags.Split(','); if (lanes.Length <= 1) { return; } foreach (var split in lanes.Select(lane => lane.Split(':')).Where(split => split.Length > 1)) { try { Log.Message($"Split Data: {split[0]} , {split[1]}"); var laneIndex = Convert.ToInt32(split[0]); //make sure we don't cause any overflows because of bad save data. if (Singleton <NetManager> .instance.m_lanes.m_buffer.Length <= laneIndex) { continue; } if (Convert.ToInt32(split[1]) > ushort.MaxValue) { continue; } Log.Message("Setting flags for lane " + Convert.ToInt32(split[0]) + " to " + Convert.ToUInt16(split[1])); Singleton <NetManager> .instance.m_lanes.m_buffer[Convert.ToInt32(split[0])].m_flags = Convert.ToUInt16(split[1]); } catch (Exception e) { Log.Error( $"Error loading Lane Split data. Length: {split.Length} value: {split}\nError: {e.Message}"); } } }
private static void OnLoadDataTimed(System.Object source, ElapsedEventArgs e) { byte[] data = SerializableData.LoadData(dataID); for (var i = 0; i < data.Length - 3; i++) { uniqueID = BitConverter.ToUInt32(data, i); } var filepath = Path.Combine(Application.dataPath, "trafficManagerSave_" + uniqueID + ".xml"); _timer.Enabled = false; if (!File.Exists(filepath)) { return; } var configuration = Configuration.Deserialize(filepath); for (var i = 0; i < configuration.prioritySegments.Count; i++) { if ( !TrafficPriority.isPrioritySegment((ushort)configuration.prioritySegments[i][0], configuration.prioritySegments[i][1])) { TrafficPriority.addPrioritySegment((ushort)configuration.prioritySegments[i][0], configuration.prioritySegments[i][1], (PrioritySegment.PriorityType)configuration.prioritySegments[i][2]); } } for (var i = 0; i < configuration.nodeDictionary.Count; i++) { if (CustomRoadAI.GetNodeSimulation((ushort)configuration.nodeDictionary[i][0]) == null) { CustomRoadAI.AddNodeToSimulation((ushort)configuration.nodeDictionary[i][0]); var nodeDict = CustomRoadAI.GetNodeSimulation((ushort)configuration.nodeDictionary[i][0]); nodeDict._manualTrafficLights = Convert.ToBoolean(configuration.nodeDictionary[i][1]); nodeDict._timedTrafficLights = Convert.ToBoolean(configuration.nodeDictionary[i][2]); nodeDict.TimedTrafficLightsActive = Convert.ToBoolean(configuration.nodeDictionary[i][3]); } } for (var i = 0; i < configuration.manualSegments.Count; i++) { var segmentData = configuration.manualSegments[i]; if (!TrafficLightsManual.IsSegmentLight((ushort)segmentData[0], segmentData[1])) { TrafficLightsManual.AddSegmentLight((ushort)segmentData[0], segmentData[1], RoadBaseAI.TrafficLightState.Green); var segment = TrafficLightsManual.GetSegmentLight((ushort)segmentData[0], segmentData[1]); segment.currentMode = (ManualSegmentLight.Mode)segmentData[2]; segment.lightLeft = (RoadBaseAI.TrafficLightState)segmentData[3]; segment.lightMain = (RoadBaseAI.TrafficLightState)segmentData[4]; segment.lightRight = (RoadBaseAI.TrafficLightState)segmentData[5]; segment.lightPedestrian = (RoadBaseAI.TrafficLightState)segmentData[6]; segment.lastChange = (uint)segmentData[7]; segment.lastChangeFrame = (uint)segmentData[8]; segment.pedestrianEnabled = Convert.ToBoolean(segmentData[9]); } } var timedStepCount = 0; var timedStepSegmentCount = 0; for (var i = 0; i < configuration.timedNodes.Count; i++) { var nodeid = (ushort)configuration.timedNodes[i][0]; var nodeGroup = new List <ushort>(); for (var j = 0; j < configuration.timedNodeGroups[i].Length; j++) { nodeGroup.Add(configuration.timedNodeGroups[i][j]); } if (!TrafficLightsTimed.IsTimedLight(nodeid)) { TrafficLightsTimed.AddTimedLight(nodeid, nodeGroup); var timedNode = TrafficLightsTimed.GetTimedLight(nodeid); timedNode.currentStep = configuration.timedNodes[i][1]; for (var j = 0; j < configuration.timedNodes[i][2]; j++) { var cfgstep = configuration.timedNodeSteps[timedStepCount]; timedNode.addStep(cfgstep[0]); var step = timedNode.steps[j]; for (var k = 0; k < cfgstep[1]; k++) { step.lightLeft[k] = (RoadBaseAI.TrafficLightState)configuration.timedNodeStepSegments[timedStepSegmentCount][0]; step.lightMain[k] = (RoadBaseAI.TrafficLightState)configuration.timedNodeStepSegments[timedStepSegmentCount][1]; step.lightRight[k] = (RoadBaseAI.TrafficLightState)configuration.timedNodeStepSegments[timedStepSegmentCount][2]; step.lightPedestrian[k] = (RoadBaseAI.TrafficLightState)configuration.timedNodeStepSegments[timedStepSegmentCount][3]; timedStepSegmentCount++; } timedStepCount++; } if (timedNode.isStarted()) { timedNode.start(); } } } var j1 = 0; for (var i1 = 0; i1 < 32768; i1++) { if (Singleton <NetManager> .instance.m_nodes.m_buffer[i1].Info.m_class.m_service == ItemClass.Service.Road && Singleton <NetManager> .instance.m_nodes.m_buffer[i1].m_flags != 0) { var trafficLight = configuration.nodeTrafficLights[j1]; if (trafficLight == '1') { Singleton <NetManager> .instance.m_nodes.m_buffer[i1].m_flags |= NetNode.Flags.TrafficLights; } else { Singleton <NetManager> .instance.m_nodes.m_buffer[i1].m_flags &= ~NetNode.Flags.TrafficLights; } j1++; } } var j2 = 0; for (var i2 = 0; i2 < 32768; i2++) { if (Singleton <NetManager> .instance.m_nodes.m_buffer[i2].Info.m_class.m_service == ItemClass.Service.Road && Singleton <NetManager> .instance.m_nodes.m_buffer[i2].m_flags != 0) { var crossWalk = configuration.nodeCrosswalk[j2]; if (crossWalk == '1') { Singleton <NetManager> .instance.m_nodes.m_buffer[i2].m_flags |= NetNode.Flags.Junction; } else { Singleton <NetManager> .instance.m_nodes.m_buffer[i2].m_flags &= ~NetNode.Flags.Junction; } j2++; } } var lanes = configuration.laneFlags.Split(','); for (var i = 0; i < lanes.Length; i++) { var split = lanes[i].Split(':'); Singleton <NetManager> .instance.m_lanes.m_buffer[Convert.ToInt32(split[0])].m_flags = Convert.ToUInt16(split[1]); } }
public void OnSaveData() { FastList <byte> data = new FastList <byte>(); GenerateUniqueID(); byte[] uniqueIdBytes = BitConverter.GetBytes(uniqueID); foreach (byte uniqueIdByte in uniqueIdBytes) { data.Add(uniqueIdByte); } byte[] dataToSave = data.ToArray(); SerializableData.SaveData(dataID, dataToSave); var filepath = Path.Combine(Application.dataPath, "trafficManagerSave_" + uniqueID + ".xml"); var configuration = new Configuration(); for (var i = 0; i < 32768; i++) { if (TrafficPriority.prioritySegments.ContainsKey(i)) { if (TrafficPriority.prioritySegments[i].node_1 != 0) { configuration.prioritySegments.Add(new int[3] { TrafficPriority.prioritySegments[i].node_1, i, (int)TrafficPriority.prioritySegments[i].instance_1.type }); } if (TrafficPriority.prioritySegments[i].node_2 != 0) { configuration.prioritySegments.Add(new int[3] { TrafficPriority.prioritySegments[i].node_2, i, (int)TrafficPriority.prioritySegments[i].instance_2.type }); } } if (CustomRoadAI.nodeDictionary.ContainsKey((ushort)i)) { var nodeDict = CustomRoadAI.nodeDictionary[(ushort)i]; configuration.nodeDictionary.Add(new int[4] { nodeDict.NodeId, Convert.ToInt32(nodeDict._manualTrafficLights), Convert.ToInt32(nodeDict._timedTrafficLights), Convert.ToInt32(nodeDict.TimedTrafficLightsActive) }); } if (TrafficLightsManual.ManualSegments.ContainsKey(i)) { if (TrafficLightsManual.ManualSegments[i].node_1 != 0) { var manualSegment = TrafficLightsManual.ManualSegments[i].instance_1; configuration.manualSegments.Add(new int[10] { (int)manualSegment.node, manualSegment.segment, (int)manualSegment.currentMode, (int)manualSegment.lightLeft, (int)manualSegment.lightMain, (int)manualSegment.lightRight, (int)manualSegment.lightPedestrian, (int)manualSegment.lastChange, (int)manualSegment.lastChangeFrame, Convert.ToInt32(manualSegment.pedestrianEnabled) }); } if (TrafficLightsManual.ManualSegments[i].node_2 != 0) { var manualSegment = TrafficLightsManual.ManualSegments[i].instance_2; configuration.manualSegments.Add(new int[10] { (int)manualSegment.node, manualSegment.segment, (int)manualSegment.currentMode, (int)manualSegment.lightLeft, (int)manualSegment.lightMain, (int)manualSegment.lightRight, (int)manualSegment.lightPedestrian, (int)manualSegment.lastChange, (int)manualSegment.lastChangeFrame, Convert.ToInt32(manualSegment.pedestrianEnabled) }); } } if (TrafficLightsTimed.timedScripts.ContainsKey((ushort)i)) { var timedNode = TrafficLightsTimed.GetTimedLight((ushort)i); configuration.timedNodes.Add(new int[3] { timedNode.nodeID, timedNode.currentStep, timedNode.NumSteps() }); var nodeGroup = new ushort[timedNode.nodeGroup.Count]; for (var j = 0; j < timedNode.nodeGroup.Count; j++) { nodeGroup[j] = timedNode.nodeGroup[j]; } configuration.timedNodeGroups.Add(nodeGroup); for (var j = 0; j < timedNode.NumSteps(); j++) { configuration.timedNodeSteps.Add(new int[2] { timedNode.steps[j].numSteps, timedNode.steps[j].segments.Count }); for (var k = 0; k < timedNode.steps[j].segments.Count; k++) { configuration.timedNodeStepSegments.Add(new int[4] { (int)timedNode.steps[j].lightLeft[k], (int)timedNode.steps[j].lightMain[k], (int)timedNode.steps[j].lightRight[k], (int)timedNode.steps[j].lightPedestrian[k], }); } } } } for (var i = 0; i < Singleton <NetManager> .instance.m_nodes.m_buffer.Length; i++) { var nodeFlags = Singleton <NetManager> .instance.m_nodes.m_buffer[i].m_flags; if (nodeFlags != 0) { if (Singleton <NetManager> .instance.m_nodes.m_buffer[i].Info.m_class.m_service == ItemClass.Service.Road) { configuration.nodeTrafficLights += Convert.ToInt16((nodeFlags & NetNode.Flags.TrafficLights) != NetNode.Flags.None); configuration.nodeCrosswalk += Convert.ToInt16((nodeFlags & NetNode.Flags.Junction) != NetNode.Flags.None); } } } for (var i = 0; i < Singleton <NetManager> .instance.m_lanes.m_buffer.Length; i++) { var laneSegment = Singleton <NetManager> .instance.m_lanes.m_buffer[i].m_segment; if (TrafficPriority.prioritySegments.ContainsKey(laneSegment)) { configuration.laneFlags += i + ":" + Singleton <NetManager> .instance.m_lanes.m_buffer[i].m_flags + ","; } } Configuration.Serialize(filepath, configuration); }
public void Update() { uint currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex >> 6; if (lastFrame < currentFrameIndex) { lastFrame = currentFrameIndex; List <ushort> clearedNodes = new List <ushort>(); foreach (var nodeID in nodeDictionary.Keys) { var data = TrafficLightTool.GetNetNode(nodeID); try { for (var i = 0; i < 8; i++) { var sgmid = data.GetSegment(i); if (sgmid != 0) { if (!TrafficLightsManual.IsSegmentLight(nodeID, sgmid)) { if (nodeDictionary[nodeID].FlagTimedTrafficLights) { var timedNode = TrafficLightsTimed.GetTimedLight(nodeID); for (var j = 0; j < timedNode.nodeGroup.Count; j++) { var nodeSim = CustomRoadAI.GetNodeSimulation(timedNode.nodeGroup[j]); nodeSim.TimedTrafficLightsActive = false; clearedNodes.Add(timedNode.nodeGroup[j]); TrafficLightsTimed.RemoveTimedLight(timedNode.nodeGroup[j]); } } } } } } catch (Exception e) { //Log.Warning("Error on Update: \n" + e.Message + "\n\nStacktrace:\n\n" + e.StackTrace); } } if (clearedNodes.Count > 0) { for (var i = 0; i < clearedNodes.Count; i++) { CustomRoadAI.RemoveNodeFromSimulation(clearedNodes[i]); } } foreach (var nodeID in nodeDictionary.Keys) { var node = GetNodeSimulation(nodeID); if (node.FlagManualTrafficLights || (node.FlagTimedTrafficLights && node.TimedTrafficLightsActive)) { var data = TrafficLightTool.GetNetNode(nodeID); node.SimulationStep(ref data); TrafficLightTool.SetNetNode(nodeID, data); if (clearedNodes.Count > 0) { break; } } } } }