public void TmCalculateSegmentPositionPathFinder(ushort vehicleId, ref Vehicle vehicleData,
                                                         PathUnit.Position position, uint laneId, byte offset, out Vector3 pos, out Vector3 dir, out float maxSpeed)
        {
            var instance = Singleton <NetManager> .instance;

            instance.m_lanes.m_buffer[(int)((UIntPtr)laneId)].CalculatePositionAndDirection(offset * 0.003921569f,
                                                                                            out pos, out dir);
            var info = instance.m_segments.m_buffer[position.m_segment].Info;

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

                if (TrafficRoadRestrictions.IsSegment(position.m_segment))
                {
                    var restrictionSegment = TrafficRoadRestrictions.GetSegment(position.m_segment);

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

                maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, laneSpeedLimit,
                                                instance.m_lanes.m_buffer[(int)((UIntPtr)laneId)].m_curve);
            }
            else
            {
                maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f);
            }
        }
        public void TmCalculateSegmentPosition(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)
        {
            var netManager = Singleton <NetManager> .instance;

            //var vehicleManager = Singleton<VehicleManager>.instance;
            netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CalculatePositionAndDirection(offset * 0.003921569f, out pos, out dir);

            var lastFrameData       = vehicleData.GetLastFrameData();
            var lastFrameVehiclePos = lastFrameData.m_position;

            if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Car)
            {
                // add vehicle to our vehicle list
                if (!TrafficPriority.VehicleList.ContainsKey(vehicleId))
                {
                    TrafficPriority.VehicleList.Add(vehicleId, new PriorityCar());
                }
            }

            HandleVehicle(vehicleId, ref vehicleData);

            // I think this is supposed to be the lane position?
            // [VN, 12/23/2015] It's the 3D car position on the Bezier curve of the lane.
            // This crazy 0.003921569f equals to 1f/255 and prevOffset is the byte value (0..255) of the car position.
            var vehiclePosOnBezier = netManager.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].CalculatePosition(prevOffset * 0.003921569f);
            //ushort currentSegmentId = netManager.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].m_segment;

            ushort destinationNodeId;
            ushort sourceNodeId;

            if (offset < position.m_offset)
            {
                destinationNodeId = netManager.m_segments.m_buffer[position.m_segment].m_startNode;
                sourceNodeId      = netManager.m_segments.m_buffer[position.m_segment].m_endNode;
            }
            else
            {
                destinationNodeId = netManager.m_segments.m_buffer[position.m_segment].m_endNode;
                sourceNodeId      = netManager.m_segments.m_buffer[position.m_segment].m_startNode;
            }
            var interestingNodeId = prevOffset == 0 ? netManager.m_segments.m_buffer[prevPos.m_segment].m_startNode :
                                    netManager.m_segments.m_buffer[prevPos.m_segment].m_endNode;

            // this seems to be like the required braking force in order to stop the vehicle within its half length.
            var crazyValue = 0.5f * lastFrameData.m_velocity.sqrMagnitude / m_info.m_braking + m_info.m_generatedInfo.m_size.z * 0.5f;

            // Essentially, this is true if the car has enough time and space to brake (e.g. for a red traffic light)
            if (destinationNodeId == interestingNodeId)
            {
                if (Vector3.Distance(lastFrameVehiclePos, vehiclePosOnBezier) >= crazyValue - 1f)
                {
                    var currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                    var num5 = (uint)((interestingNodeId << 8) / 32768);
                    var num6 = currentFrameIndex - num5 & 255u;

                    var nodeFlags        = netManager.m_nodes.m_buffer[destinationNodeId].m_flags;
                    var prevLaneFlags    = (NetLane.Flags)netManager.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].m_flags;
                    var hasTrafficLight  = (nodeFlags & NetNode.Flags.TrafficLights) != NetNode.Flags.None;
                    var hasCrossing      = (nodeFlags & NetNode.Flags.LevelCrossing) != NetNode.Flags.None;
                    var isJoinedJunction = (prevLaneFlags & NetLane.Flags.JoinedJunction) != NetLane.Flags.None;
                    if ((nodeFlags & (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) ==
                        NetNode.Flags.Junction && netManager.m_nodes.m_buffer[destinationNodeId].CountSegments() != 2)
                    {
                        var len = vehicleData.CalculateTotalLength(vehicleId) + 2f;
                        if (!netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CheckSpace(len))
                        {
                            var sufficientSpace = false;
                            if (nextPosition.m_segment != 0 &&
                                netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_length < 30f)
                            {
                                var flags3 = netManager.m_nodes.m_buffer[sourceNodeId].m_flags;
                                if ((flags3 &
                                     (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) !=
                                    NetNode.Flags.Junction || netManager.m_nodes.m_buffer[sourceNodeId].CountSegments() == 2)
                                {
                                    var laneId2 = PathManager.GetLaneID(nextPosition);
                                    if (laneId2 != 0u)
                                    {
                                        sufficientSpace = netManager.m_lanes.m_buffer[(int)((UIntPtr)laneId2)].CheckSpace(len);
                                    }
                                }
                            }
                            if (!sufficientSpace)
                            {
                                maxSpeed = 0f;
                                return;
                            }
                        }
                    }

                    if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Car)
                    {
                        if (hasTrafficLight && (!isJoinedJunction || hasCrossing))
                        {
                            var nodeSimulation = TrafficPriority.GetNodeSimulation(interestingNodeId);

                            var destinationInfo = netManager.m_nodes.m_buffer[destinationNodeId].Info;
                            RoadBaseAI.TrafficLightState vehicleLightState;
                            ManualSegmentLight           light = TrafficLightsManual.GetSegmentLight(interestingNodeId, prevPos.m_segment);                   // TODO rework

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

                                if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) == Vehicle.Flags.None ||
                                    destinationInfo.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
                            {
                                // traffic light simulation is active
                                var stopCar = false;

                                // determine responsible traffic light (left, right or main)
                                if (TrafficPriority.IsLeftSegment(prevPos.m_segment, position.m_segment, destinationNodeId))
                                {
                                    vehicleLightState = light.GetLightLeft();
                                }
                                else if (TrafficPriority.IsRightSegment(prevPos.m_segment, position.m_segment, destinationNodeId))
                                {
                                    vehicleLightState = light.GetLightRight();
                                }
                                else
                                {
                                    vehicleLightState = light.GetLightMain();
                                }

                                if (vehicleLightState == RoadBaseAI.TrafficLightState.Green)
                                {
                                    var hasIncomingCars = TrafficPriority.HasIncomingVehicles(vehicleId, destinationNodeId);

                                    if (hasIncomingCars)
                                    {
                                        // green light but other cars are incoming: slow approach
                                        maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f) * 0.01f;
                                        //stopCar = true;
                                    }
                                }

                                if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) == Vehicle.Flags.None ||
                                    destinationInfo.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 (TrafficPriority.VehicleList.ContainsKey(vehicleId) &&
                                TrafficPriority.IsPrioritySegment(destinationNodeId, prevPos.m_segment))
                            {
                                var currentFrameIndex2 = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                                var frame = currentFrameIndex2 >> 4;

                                var prioritySegment = TrafficPriority.GetPrioritySegment(destinationNodeId, prevPos.m_segment);

                                if (TrafficPriority.VehicleList[vehicleId].CarState == CarState.None)
                                {
                                    TrafficPriority.VehicleList[vehicleId].CarState = CarState.Enter;
                                }

                                if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) == Vehicle.Flags.None &&
                                    TrafficPriority.VehicleList[vehicleId].CarState != CarState.Leave)
                                {
                                    bool hasIncomingCars;
                                    switch (prioritySegment.Type)
                                    {
                                    case PrioritySegment.PriorityType.Stop:
                                        if (TrafficPriority.VehicleList[vehicleId].WaitTime < 75)
                                        {
                                            TrafficPriority.VehicleList[vehicleId].CarState = CarState.Stop;

                                            if (lastFrameData.m_velocity.sqrMagnitude < 0.1f ||
                                                TrafficPriority.VehicleList[vehicleId].Stopped)
                                            {
                                                TrafficPriority.VehicleList[vehicleId].Stopped = true;
                                                TrafficPriority.VehicleList[vehicleId].WaitTime++;

                                                if (TrafficPriority.VehicleList[vehicleId].WaitTime > 2)
                                                {
                                                    hasIncomingCars = TrafficPriority.HasIncomingVehicles(vehicleId, destinationNodeId);

                                                    if (hasIncomingCars)
                                                    {
                                                        maxSpeed = 0f;
                                                        return;
                                                    }
                                                    TrafficPriority.VehicleList[vehicleId].CarState =
                                                        CarState.Leave;
                                                }
                                                else
                                                {
                                                    maxSpeed = 0f;
                                                    return;
                                                }
                                            }
                                            else
                                            {
                                                maxSpeed = 0f;
                                                return;
                                            }
                                        }
                                        else
                                        {
                                            TrafficPriority.VehicleList[vehicleId].CarState = CarState.Leave;
                                        }
                                        break;

                                    case PrioritySegment.PriorityType.Yield:
                                        if (TrafficPriority.VehicleList[vehicleId].WaitTime < 75)
                                        {
                                            TrafficPriority.VehicleList[vehicleId].WaitTime++;
                                            TrafficPriority.VehicleList[vehicleId].CarState = CarState.Stop;
                                            maxSpeed = 0f;

                                            if (lastFrameData.m_velocity.sqrMagnitude <
                                                TrafficPriority.VehicleList[vehicleId].ReduceSpeedByValueToYield)
                                            {
                                                hasIncomingCars = TrafficPriority.HasIncomingVehicles(vehicleId, destinationNodeId);

                                                if (hasIncomingCars)
                                                {
                                                    return;
                                                }
                                            }
                                            else
                                            {
                                                maxSpeed = lastFrameData.m_velocity.sqrMagnitude -
                                                           TrafficPriority.VehicleList[vehicleId]
                                                           .ReduceSpeedByValueToYield;
                                                return;
                                            }
                                        }
                                        else
                                        {
                                            TrafficPriority.VehicleList[vehicleId].CarState = CarState.Leave;
                                        }
                                        break;

                                    case PrioritySegment.PriorityType.Main:
                                        TrafficPriority.VehicleList[vehicleId].WaitTime++;
                                        TrafficPriority.VehicleList[vehicleId].CarState = CarState.Stop;
                                        maxSpeed = 0f;

                                        hasIncomingCars = TrafficPriority.HasIncomingVehicles(vehicleId, destinationNodeId);

                                        if (hasIncomingCars)
                                        {
                                            TrafficPriority.VehicleList[vehicleId].Stopped = true;
                                            return;
                                        }
                                        TrafficPriority.VehicleList[vehicleId].Stopped = false;

                                        var info3 = netManager.m_segments.m_buffer[position.m_segment].Info;
                                        if (info3.m_lanes != null && info3.m_lanes.Length > position.m_lane)
                                        {
                                            maxSpeed =
                                                CalculateTargetSpeed(vehicleId, ref vehicleData,
                                                                     info3.m_lanes[position.m_lane].m_speedLimit,
                                                                     netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_curve) * 0.8f;
                                        }
                                        else
                                        {
                                            maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f) *
                                                       0.8f;
                                        }
                                        return;
                                    }
                                }
                                else
                                {
                                    TrafficPriority.VehicleList[vehicleId].CarState = CarState.Transit;
                                }
                            }
                        }
                    }
                }
            }

            var info2 = netManager.m_segments.m_buffer[position.m_segment].Info;

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

                if (TrafficRoadRestrictions.IsSegment(position.m_segment))
                {
                    var restrictionSegment = TrafficRoadRestrictions.GetSegment(position.m_segment);

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

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