Esempio n. 1
0
        public override void OnLevelUnloading()
        {
            Log.Info("OnLevelUnloading");
            base.OnLevelUnloading();
            Instance = this;
            revertDetours();
            gameLoaded = false;

            Object.Destroy(UI);
            UI = null;

            try {
                TrafficPriority.OnLevelUnloading();
                CustomCarAI.OnLevelUnloading();
                CustomRoadAI.OnLevelUnloading();
                CustomTrafficLights.OnLevelUnloading();
                TrafficLightSimulation.OnLevelUnloading();
                VehicleRestrictionsManager.OnLevelUnloading();
                Flags.OnLevelUnloading();
                Translation.OnLevelUnloading();
            } catch (Exception e) {
                Log.Error("Exception unloading mod. " + e.Message);
                // ignored - prevents collision with other mods
            }
        }
Esempio n. 2
0
        public override void OnLevelUnloading()
        {
            Log.Info("OnLevelUnloading");
            base.OnLevelUnloading();
            if (Instance == null)
            {
                Instance = this;
            }
            revertDetours();
            gameLoaded = false;

            try {
                TrafficPriority.OnLevelUnloading();
                CustomCarAI.OnLevelUnloading();
                CustomRoadAI.OnLevelUnloading();
                CustomTrafficLights.OnLevelUnloading();
                TrafficLightSimulation.OnLevelUnloading();
                Flags.OnLevelUnloading();
                Translation.OnLevelUnloading();

                if (Instance != null)
                {
                    Instance.NodeSimulationLoaded = false;
                }
            } catch (Exception e) {
                Log.Error("Exception unloading mod. " + e.Message);
                // ignored - prevents collision with other mods
            }
        }
        public void ChangeMode()
        {
            var hasLeftSegment    = TrafficPriority.HasLeftSegment(this.segment, this.node) && TrafficPriority.hasLeftLane(this.node, this.segment);
            var hasForwardSegment = TrafficPriority.HasForwardSegment(this.segment, this.node) && TrafficPriority.hasForwardLane(this.node, this.segment);
            var hasRightSegment   = TrafficPriority.HasRightSegment(this.segment, this.node) && TrafficPriority.hasRightLane(this.node, this.segment);

            if (currentMode == ManualSegmentLight.Mode.Simple)
            {
                if (!hasLeftSegment)
                {
                    currentMode = ManualSegmentLight.Mode.RightForwardL;
                }
                else
                {
                    currentMode = ManualSegmentLight.Mode.LeftForwardR;
                }
            }
            else if (currentMode == ManualSegmentLight.Mode.LeftForwardR)
            {
                if (!hasForwardSegment || !hasRightSegment)
                {
                    currentMode = ManualSegmentLight.Mode.Simple;
                }
                else
                {
                    currentMode = ManualSegmentLight.Mode.RightForwardL;
                }
            }
            else if (currentMode == ManualSegmentLight.Mode.RightForwardL)
            {
                if (!hasLeftSegment)
                {
                    currentMode = ManualSegmentLight.Mode.Simple;
                }
                else
                {
                    currentMode = ManualSegmentLight.Mode.All;
                }
            }
            else
            {
                currentMode = ManualSegmentLight.Mode.Simple;
            }

            if (currentMode == Mode.Simple)
            {
                lightLeft       = lightMain;
                lightRight      = lightMain;
                lightPedestrian = _checkPedestrianLight();
            }
        }
Esempio n. 4
0
        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 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}");
                }
            }
        }
Esempio n. 6
0
        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]);
            }
        }
Esempio n. 7
0
        public override void OnLevelLoaded(LoadMode mode)
        {
            Log.Info("OnLevelLoaded");
            base.OnLevelLoaded(mode);

            Log._Debug("OnLevelLoaded Returned from base, calling custom code.");
            Instance = this;

            gameLoaded = false;
            switch (mode)
            {
            case LoadMode.NewGame:
            case LoadMode.LoadGame:
                gameLoaded = true;
                break;

            default:
                return;
            }

            TrafficPriority.OnLevelLoading();
#if !TAM
            determinePathManagerCompatible();

            //SpeedLimitManager.GetDefaultSpeedLimits();

            if (IsPathManagerCompatible && !IsPathManagerReplaced)
            {
                try {
                    Log.Info("Pathfinder Compatible. Setting up CustomPathManager and SimManager.");
                    var pathManagerInstance = typeof(Singleton <PathManager>).GetField("sInstance", BindingFlags.Static | BindingFlags.NonPublic);

                    var stockPathManager = PathManager.instance;
                    Log._Debug($"Got stock PathManager instance {stockPathManager.GetName()}");

                    CustomPathManager = stockPathManager.gameObject.AddComponent <CustomPathManager>();
                    Log._Debug("Added CustomPathManager to gameObject List");

                    if (CustomPathManager == null)
                    {
                        Log.Error("CustomPathManager null. Error creating it.");
                        return;
                    }

                    CustomPathManager.UpdateWithPathManagerValues(stockPathManager);
                    Log._Debug("UpdateWithPathManagerValues success");

                    pathManagerInstance?.SetValue(null, CustomPathManager);

                    Log._Debug("Getting Current SimulationManager");
                    var simManager =
                        typeof(SimulationManager).GetField("m_managers", BindingFlags.Static | BindingFlags.NonPublic)?
                        .GetValue(null) as FastList <ISimulationManager>;

                    Log._Debug("Removing Stock PathManager");
                    simManager?.Remove(stockPathManager);

                    Log._Debug("Adding Custom PathManager");
                    simManager?.Add(CustomPathManager);

                    Object.Destroy(stockPathManager, 10f);

                    Log._Debug("Should be custom: " + Singleton <PathManager> .instance.GetType().ToString());

                    IsPathManagerReplaced = true;
                } catch (Exception ex) {
                    Log.Error($"Path manager replacement error: {ex.ToString()}");
                    UIView.library.ShowModal <ExceptionPanel>("ExceptionPanel").SetMessage("Incompatibility Issue", "Traffic Manager: President Edition detected an incompatibility with another mod! You can continue playing but it's NOT recommended. Traffic Manager will not work as expected.", true);
                    IsPathManagerCompatible = false;
                }
            }

            Log.Info("Adding Controls to UI.");
            UI = ToolsModifierControl.toolController.gameObject.AddComponent <UIBase>();

            initDetours();
            Log.Info("OnLevelLoaded complete.");
#endif
        }
        public void CalculateSegmentPosition(ushort vehicleID, ref Vehicle vehicleData, PathUnit.Position nextPosition,
                                             PathUnit.Position position, uint laneID, byte offset, PathUnit.Position prevPos, uint prevLaneID,
                                             byte prevOffset, out Vector3 pos, out Vector3 dir, out float maxSpeed)
        {
            NetManager instance = Singleton <NetManager> .instance;

            instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CalculatePositionAndDirection((float)offset * 0.003921569f, out pos, out dir);
            Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData();
            Vector3       position2     = lastFrameData.m_position;
            Vector3       b             = instance.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].CalculatePosition((float)prevOffset * 0.003921569f);
            float         num           = 0.5f * lastFrameData.m_velocity.sqrMagnitude / this.m_info.m_braking + this.m_info.m_generatedInfo.m_size.z * 0.5f;

            if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Car)
            {
                if (!TrafficPriority.vehicleList.ContainsKey(vehicleID))
                {
                    TrafficPriority.vehicleList.Add(vehicleID, new PriorityCar());
                }
            }

            if (Vector3.Distance(position2, b) >= num - 1f)
            {
                Segment3 segment;
                segment.a = pos;
                ushort num2;
                ushort num3;
                if (offset < position.m_offset)
                {
                    segment.b = pos + dir.normalized * this.m_info.m_generatedInfo.m_size.z;
                    num2      = instance.m_segments.m_buffer[(int)position.m_segment].m_startNode;
                    num3      = instance.m_segments.m_buffer[(int)position.m_segment].m_endNode;
                }
                else
                {
                    segment.b = pos - dir.normalized * this.m_info.m_generatedInfo.m_size.z;
                    num2      = instance.m_segments.m_buffer[(int)position.m_segment].m_endNode;
                    num3      = instance.m_segments.m_buffer[(int)position.m_segment].m_startNode;
                }
                ushort num4;
                if (prevOffset == 0)
                {
                    num4 = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_startNode;
                }
                else
                {
                    num4 = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_endNode;
                }

                if (num2 == num4)
                {
                    uint currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                    uint num5 = (uint)(((int)num4 << 8) / 32768);
                    uint num6 = currentFrameIndex - num5 & 255u;

                    NetNode.Flags flags  = instance.m_nodes.m_buffer[(int)num2].m_flags;
                    NetLane.Flags flags2 =
                        (NetLane.Flags)instance.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].m_flags;
                    bool flag  = (flags & NetNode.Flags.TrafficLights) != NetNode.Flags.None;
                    bool flag2 = (flags & NetNode.Flags.LevelCrossing) != NetNode.Flags.None;
                    bool flag3 = (flags2 & NetLane.Flags.JoinedJunction) != NetLane.Flags.None;
                    if ((flags & (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) ==
                        NetNode.Flags.Junction && instance.m_nodes.m_buffer[(int)num2].CountSegments() != 2)
                    {
                        float len = vehicleData.CalculateTotalLength(vehicleID) + 2f;
                        if (!instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CheckSpace(len))
                        {
                            bool flag4 = false;
                            if (nextPosition.m_segment != 0 &&
                                instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_length < 30f)
                            {
                                NetNode.Flags flags3 = instance.m_nodes.m_buffer[(int)num3].m_flags;
                                if ((flags3 &
                                     (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) !=
                                    NetNode.Flags.Junction || instance.m_nodes.m_buffer[(int)num3].CountSegments() == 2)
                                {
                                    uint laneID2 = PathManager.GetLaneID(nextPosition);
                                    if (laneID2 != 0u)
                                    {
                                        flag4 = instance.m_lanes.m_buffer[(int)((UIntPtr)laneID2)].CheckSpace(len);
                                    }
                                }
                            }
                            if (!flag4)
                            {
                                maxSpeed = 0f;
                                return;
                            }
                        }
                    }

                    if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Car &&
                        TrafficPriority.vehicleList.ContainsKey(vehicleID) &&
                        TrafficPriority.isPrioritySegment(num2, prevPos.m_segment))
                    {
                        uint currentFrameIndex2 = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                        uint frame = currentFrameIndex2 >> 4;

                        var prioritySegment = TrafficPriority.getPrioritySegment(num2, prevPos.m_segment);
                        if (TrafficPriority.vehicleList[vehicleID].toNode != num2 ||
                            TrafficPriority.vehicleList[vehicleID].fromSegment != prevPos.m_segment)
                        {
                            if (TrafficPriority.vehicleList[vehicleID].toNode != 0 &&
                                TrafficPriority.vehicleList[vehicleID].fromSegment != 0)
                            {
                                var oldNode    = TrafficPriority.vehicleList[vehicleID].toNode;
                                var oldSegment = TrafficPriority.vehicleList[vehicleID].fromSegment;

                                if (TrafficPriority.isPrioritySegment(oldNode, oldSegment))
                                {
                                    var oldPrioritySegment = TrafficPriority.getPrioritySegment(oldNode, oldSegment);
                                    TrafficPriority.vehicleList[vehicleID].waitTime = 0;
                                    TrafficPriority.vehicleList[vehicleID].stopped  = false;
                                    oldPrioritySegment.RemoveCar(vehicleID);
                                }
                            }

                            // prevPos - current segment
                            // position - next segment
                            TrafficPriority.vehicleList[vehicleID].toNode        = num2;
                            TrafficPriority.vehicleList[vehicleID].fromSegment   = prevPos.m_segment;
                            TrafficPriority.vehicleList[vehicleID].toSegment     = position.m_segment;
                            TrafficPriority.vehicleList[vehicleID].toLaneID      = PathManager.GetLaneID(position);
                            TrafficPriority.vehicleList[vehicleID].fromLaneID    = PathManager.GetLaneID(prevPos);
                            TrafficPriority.vehicleList[vehicleID].fromLaneFlags =
                                instance.m_lanes.m_buffer[PathManager.GetLaneID(prevPos)].m_flags;
                            TrafficPriority.vehicleList[vehicleID].yieldSpeedReduce = UnityEngine.Random.Range(13f,
                                                                                                               18f);

                            prioritySegment.AddCar(vehicleID);
                        }

                        TrafficPriority.vehicleList[vehicleID].lastFrame = frame;
                        TrafficPriority.vehicleList[vehicleID].lastSpeed =
                            vehicleData.GetLastFrameData().m_velocity.sqrMagnitude;
                    }

                    if (flag && (!flag3 || flag2))
                    {
                        var nodeSimulation = CustomRoadAI.GetNodeSimulation(num4);

                        NetInfo info = instance.m_nodes.m_buffer[(int)num2].Info;
                        RoadBaseAI.TrafficLightState vehicleLightState;
                        RoadBaseAI.TrafficLightState pedestrianLightState;
                        bool flag5;
                        bool pedestrians;

                        if (nodeSimulation == null || (nodeSimulation.FlagTimedTrafficLights && !nodeSimulation.TimedTrafficLightsActive))
                        {
                            RoadBaseAI.GetTrafficLightState(num4,
                                                            ref instance.m_segments.m_buffer[(int)prevPos.m_segment],
                                                            currentFrameIndex - num5, out vehicleLightState, out pedestrianLightState, out flag5,
                                                            out pedestrians);
                            if (!flag5 && num6 >= 196u)
                            {
                                flag5 = true;
                                RoadBaseAI.SetTrafficLightState(num4,
                                                                ref instance.m_segments.m_buffer[(int)prevPos.m_segment], currentFrameIndex - num5,
                                                                vehicleLightState, pedestrianLightState, flag5, pedestrians);
                            }

                            if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) == Vehicle.Flags.None ||
                                info.m_class.m_service != ItemClass.Service.Road)
                            {
                                switch (vehicleLightState)
                                {
                                case RoadBaseAI.TrafficLightState.RedToGreen:
                                    if (num6 < 60u)
                                    {
                                        maxSpeed = 0f;
                                        return;
                                    }
                                    break;

                                case RoadBaseAI.TrafficLightState.Red:
                                    maxSpeed = 0f;
                                    return;

                                case RoadBaseAI.TrafficLightState.GreenToRed:
                                    if (num6 >= 30u)
                                    {
                                        maxSpeed = 0f;
                                        return;
                                    }
                                    break;
                                }
                            }
                        }
                        else
                        {
                            var stopCar = false;

                            if (TrafficPriority.isLeftSegment(prevPos.m_segment, position.m_segment, num2))
                            {
                                vehicleLightState =
                                    TrafficLightsManual.GetSegmentLight(num4, prevPos.m_segment).GetLightLeft();
                            }
                            else if (TrafficPriority.isRightSegment(prevPos.m_segment, position.m_segment, num2))
                            {
                                vehicleLightState =
                                    TrafficLightsManual.GetSegmentLight(num4, prevPos.m_segment).GetLightRight();
                            }
                            else
                            {
                                vehicleLightState =
                                    TrafficLightsManual.GetSegmentLight(num4, prevPos.m_segment).GetLightMain();
                            }

                            if (vehicleLightState == RoadBaseAI.TrafficLightState.Green)
                            {
                                var hasIncomingCars = TrafficPriority.incomingVehicles(vehicleID, num2);

                                if (hasIncomingCars)
                                {
                                    stopCar = true;
                                }
                            }

                            if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) == Vehicle.Flags.None ||
                                info.m_class.m_service != ItemClass.Service.Road)
                            {
                                switch (vehicleLightState)
                                {
                                case RoadBaseAI.TrafficLightState.RedToGreen:
                                    if (num6 < 60u)
                                    {
                                        stopCar = true;
                                    }
                                    break;

                                case RoadBaseAI.TrafficLightState.Red:
                                    stopCar = true;
                                    break;

                                case RoadBaseAI.TrafficLightState.GreenToRed:
                                    if (num6 >= 30u)
                                    {
                                        stopCar = true;
                                    }
                                    break;
                                }
                            }

                            if (stopCar)
                            {
                                maxSpeed = 0f;
                                return;
                            }
                        }
                    }
                    else
                    {
                        if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Car &&
                            TrafficPriority.vehicleList.ContainsKey(vehicleID) &&
                            TrafficPriority.isPrioritySegment(num2, prevPos.m_segment))
                        {
                            uint currentFrameIndex2 = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                            uint frame = currentFrameIndex2 >> 4;

                            var prioritySegment = TrafficPriority.getPrioritySegment(num2, prevPos.m_segment);

                            if (TrafficPriority.vehicleList[vehicleID].carState == PriorityCar.CarState.None)
                            {
                                TrafficPriority.vehicleList[vehicleID].carState = PriorityCar.CarState.Enter;
                            }

                            if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) == Vehicle.Flags.None &&
                                TrafficPriority.vehicleList[vehicleID].carState != PriorityCar.CarState.Leave)
                            {
                                if (prioritySegment.type == PrioritySegment.PriorityType.Stop)
                                {
                                    if (TrafficPriority.vehicleList[vehicleID].waitTime < 75)
                                    {
                                        TrafficPriority.vehicleList[vehicleID].carState = PriorityCar.CarState.Stop;

                                        if (vehicleData.GetLastFrameData().m_velocity.sqrMagnitude < 0.1f ||
                                            TrafficPriority.vehicleList[vehicleID].stopped)
                                        {
                                            TrafficPriority.vehicleList[vehicleID].stopped = true;
                                            TrafficPriority.vehicleList[vehicleID].waitTime++;

                                            if (TrafficPriority.vehicleList[vehicleID].waitTime > 2)
                                            {
                                                var hasIncomingCars = TrafficPriority.incomingVehicles(vehicleID, num2);

                                                if (hasIncomingCars)
                                                {
                                                    maxSpeed = 0f;
                                                    return;
                                                }
                                            }
                                            else
                                            {
                                                maxSpeed = 0f;
                                                return;
                                            }
                                        }
                                        else
                                        {
                                            maxSpeed = 0f;
                                            return;
                                        }
                                    }
                                    else
                                    {
                                        TrafficPriority.vehicleList[vehicleID].carState = PriorityCar.CarState.Leave;
                                    }
                                }
                                else if (prioritySegment.type == PrioritySegment.PriorityType.Yield)
                                {
                                    if (TrafficPriority.vehicleList[vehicleID].waitTime < 75)
                                    {
                                        TrafficPriority.vehicleList[vehicleID].waitTime++;
                                        TrafficPriority.vehicleList[vehicleID].carState = PriorityCar.CarState.Stop;
                                        maxSpeed = 0f;

                                        if (vehicleData.GetLastFrameData().m_velocity.sqrMagnitude <
                                            TrafficPriority.vehicleList[vehicleID].yieldSpeedReduce)
                                        {
                                            var hasIncomingCars = TrafficPriority.incomingVehicles(vehicleID, num2);

                                            if (hasIncomingCars)
                                            {
                                                return;
                                            }
                                        }
                                        else
                                        {
                                            return;
                                        }
                                    }
                                    else
                                    {
                                        TrafficPriority.vehicleList[vehicleID].carState = PriorityCar.CarState.Leave;
                                    }
                                }
                                else if (prioritySegment.type == PrioritySegment.PriorityType.Main)
                                {
                                    TrafficPriority.vehicleList[vehicleID].waitTime++;
                                    TrafficPriority.vehicleList[vehicleID].carState = PriorityCar.CarState.Stop;
                                    maxSpeed = 0f;

                                    var hasIncomingCars = TrafficPriority.incomingVehicles(vehicleID, num2);

                                    if (hasIncomingCars)
                                    {
                                        TrafficPriority.vehicleList[vehicleID].stopped = true;
                                        return;
                                    }
                                    else
                                    {
                                        TrafficPriority.vehicleList[vehicleID].stopped = false;

                                        NetInfo info3 = instance.m_segments.m_buffer[(int)position.m_segment].Info;
                                        if (info3.m_lanes != null && info3.m_lanes.Length > (int)position.m_lane)
                                        {
                                            maxSpeed =
                                                this.CalculateTargetSpeed(vehicleID, ref vehicleData,
                                                                          info3.m_lanes[(int)position.m_lane].m_speedLimit,
                                                                          instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_curve) * 0.8f;
                                        }
                                        else
                                        {
                                            maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, 1f, 0f) *
                                                       0.8f;
                                        }
                                        return;
                                    }
                                }
                            }
                            else
                            {
                                TrafficPriority.vehicleList[vehicleID].carState = PriorityCar.CarState.Transit;
                            }
                        }
                    }
                }
            }

            NetInfo info2 = instance.m_segments.m_buffer[(int)position.m_segment].Info;

            if (info2.m_lanes != null && info2.m_lanes.Length > (int)position.m_lane)
            {
                var laneSpeedLimit = info2.m_lanes[(int)position.m_lane].m_speedLimit;

                if (TrafficRoadRestrictions.isSegment(position.m_segment))
                {
                    var restrictionSegment = TrafficRoadRestrictions.getSegment(position.m_segment);

                    if (restrictionSegment.speedLimits[(int)position.m_lane] > 0.1f)
                    {
                        laneSpeedLimit = restrictionSegment.speedLimits[(int)position.m_lane];
                    }
                }

                maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, laneSpeedLimit, instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_curve);
            }
            else
            {
                maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, 1f, 0f);
            }
        }