public static bool Prefix(TrainAI __instance,
                                  ushort vehicleID,
                                  ref Vehicle vehicleData,
                                  ref float maxSpeed,
                                  PathUnit.Position position,
                                  uint laneID,
                                  byte offset,
                                  PathUnit.Position prevPos,
                                  uint prevLaneID,
                                  byte prevOffset,
                                  Bezier3 bezier)
        {
            NetManager netManager = NetManager.instance;

            ref NetSegment currentPositionSegment = ref position.m_segment.ToSegment();
 public static bool Prefix(TrainAI __instance,
                           ushort vehicleID,
                           ref Vehicle vehicleData,
                           PathUnit.Position position,
                           uint laneID,
                           byte offset,
                           out Vector3 pos,
                           out Vector3 dir,
                           out float maxSpeed)
 {
     VehicleAICommons.CustomCalculateSegmentPosition(
         __instance,
         vehicleID,
         ref vehicleData,
         position,
         laneID,
         offset,
         out pos,
         out dir,
         out maxSpeed);
     return(false);
 }
コード例 #3
0
ファイル: SimulationStep2Patch.cs プロジェクト: kvakvs/TMPE
        public static bool Prefix(TrainAI __instance,
                                  VehicleInfo ___m_info,
                                  ushort vehicleID,
                                  ref Vehicle vehicleData,
                                  ref Vehicle.Frame frameData,
                                  ushort leaderID,
                                  ref Vehicle leaderData,
                                  int lodPhysics)
        {
            bool        reversed       = (leaderData.m_flags & Vehicle.Flags.Reversed) != 0;
            ushort      frontVehicleId = (!reversed) ? vehicleData.m_leadingVehicle : vehicleData.m_trailingVehicle;
            VehicleInfo vehicleInfo    = leaderID != vehicleID ? leaderData.Info : ___m_info;
            TrainAI     trainAi        = vehicleInfo.m_vehicleAI as TrainAI;

            if (frontVehicleId != 0)
            {
                frameData.m_position += frameData.m_velocity * 0.4f;
            }
            else
            {
                frameData.m_position += frameData.m_velocity * 0.5f;
            }

            frameData.m_swayPosition += frameData.m_swayVelocity * 0.5f;

            Vector3 posBeforeWheelRot = frameData.m_position;
            Vector3 posAfterWheelRot  = frameData.m_position;
            Vector3 wheelBaseRot      = frameData.m_rotation
                                        * new Vector3(0f, 0f, ___m_info.m_generatedInfo.m_wheelBase * 0.5f);

            if (reversed)
            {
                posBeforeWheelRot -= wheelBaseRot;
                posAfterWheelRot  += wheelBaseRot;
            }
            else
            {
                posBeforeWheelRot += wheelBaseRot;
                posAfterWheelRot  -= wheelBaseRot;
            }

            float acceleration = ___m_info.m_acceleration;
            float braking      = ___m_info.m_braking;
            float curSpeed     = frameData.m_velocity.magnitude;

            Vector3 beforeRotToTargetPos1Diff       = (Vector3)vehicleData.m_targetPos1 - posBeforeWheelRot;
            float   beforeRotToTargetPos1DiffSqrMag = beforeRotToTargetPos1Diff.sqrMagnitude;

            Quaternion curInvRot    = Quaternion.Inverse(frameData.m_rotation);
            Vector3    curveTangent = curInvRot * frameData.m_velocity;

            Vector3 forward      = Vector3.forward;
            Vector3 targetMotion = Vector3.zero;
            float   targetSpeed  = 0f;
            float   motionFactor = 0.5f;

            if (frontVehicleId != 0)
            {
                VehicleManager vehMan = VehicleManager.instance;
                Vehicle.Frame  frontVehLastFrameData = vehMan.m_vehicles.m_buffer[frontVehicleId].GetLastFrameData();
                VehicleInfo    frontVehInfo          = vehMan.m_vehicles.m_buffer[frontVehicleId].Info;
                float          attachOffset;

                if ((vehicleData.m_flags & Vehicle.Flags.Inverted) != 0 != reversed)
                {
                    attachOffset = ___m_info.m_attachOffsetBack - (___m_info.m_generatedInfo.m_size.z * 0.5f);
                }
                else
                {
                    attachOffset = ___m_info.m_attachOffsetFront - (___m_info.m_generatedInfo.m_size.z * 0.5f);
                }

                float frontAttachOffset;

                if ((vehMan.m_vehicles.m_buffer[frontVehicleId].m_flags & Vehicle.Flags.Inverted) != 0 != reversed)
                {
                    frontAttachOffset = frontVehInfo.m_attachOffsetFront -
                                        (frontVehInfo.m_generatedInfo.m_size.z * 0.5f);
                }
                else
                {
                    frontAttachOffset =
                        (frontVehInfo.m_attachOffsetBack - (frontVehInfo.m_generatedInfo.m_size.z * 0.5f));
                }

                Vector3 posMinusAttachOffset = frameData.m_position;
                if (reversed)
                {
                    posMinusAttachOffset += frameData.m_rotation * new Vector3(0f, 0f, attachOffset);
                }
                else
                {
                    posMinusAttachOffset -= frameData.m_rotation * new Vector3(0f, 0f, attachOffset);
                }

                Vector3 frontPosPlusAttachOffset = frontVehLastFrameData.m_position;
                if (reversed)
                {
                    frontPosPlusAttachOffset -= frontVehLastFrameData.m_rotation
                                                * new Vector3(0f, 0f, frontAttachOffset);
                }
                else
                {
                    frontPosPlusAttachOffset += frontVehLastFrameData.m_rotation
                                                * new Vector3(0f, 0f, frontAttachOffset);
                }

                Vector3 frontPosMinusWheelBaseRot = frontVehLastFrameData.m_position;
                wheelBaseRot = frontVehLastFrameData.m_rotation * new Vector3(
                    0f,
                    0f,
                    frontVehInfo.m_generatedInfo.m_wheelBase * 0.5f);
                if (reversed)
                {
                    frontPosMinusWheelBaseRot += wheelBaseRot;
                }
                else
                {
                    frontPosMinusWheelBaseRot -= wheelBaseRot;
                }

                if (Vector3.Dot(
                        vehicleData.m_targetPos1 - vehicleData.m_targetPos0,
                        (Vector3)vehicleData.m_targetPos0 - posAfterWheelRot) < 0f &&
                    vehicleData.m_path != 0u &&
                    (leaderData.m_flags & Vehicle.Flags.WaitingPath) == 0)
                {
                    int someIndex = -1;
                    UpdatePathTargetPositions(
                        trainAi,
                        vehicleID,
                        ref vehicleData,
                        vehicleData.m_targetPos0,
                        posAfterWheelRot,
                        0,
                        ref leaderData,
                        ref someIndex,
                        0,
                        0,
                        Vector3.SqrMagnitude(posAfterWheelRot - (Vector3)vehicleData.m_targetPos0) + 1f,
                        1f);
                    beforeRotToTargetPos1DiffSqrMag = 0f;
                }

                float maxAttachDist = Mathf.Max(Vector3.Distance(posMinusAttachOffset,
                                                                 frontPosPlusAttachOffset),
                                                2f);
                const float ONE = 1f;
                float       maxAttachSqrDist = maxAttachDist * maxAttachDist;
                const float ONE_SQR          = ONE * ONE;
                int         i = 0;
                if (beforeRotToTargetPos1DiffSqrMag < maxAttachSqrDist)
                {
                    if (vehicleData.m_path != 0u &&
                        (leaderData.m_flags & Vehicle.Flags.WaitingPath) == 0)
                    {
                        UpdatePathTargetPositions(
                            trainAi,
                            vehicleID,
                            ref vehicleData,
                            posAfterWheelRot,
                            posBeforeWheelRot,
                            0,
                            ref leaderData,
                            ref i,
                            1,
                            2,
                            maxAttachSqrDist,
                            ONE_SQR);
                    }

                    while (i < 4)
                    {
                        vehicleData.SetTargetPos(i, vehicleData.GetTargetPos(i - 1));
                        i++;
                    }

                    beforeRotToTargetPos1Diff       = (Vector3)vehicleData.m_targetPos1 - posBeforeWheelRot;
                    beforeRotToTargetPos1DiffSqrMag = beforeRotToTargetPos1Diff.sqrMagnitude;
                }

                if (vehicleData.m_path != 0u)
                {
                    NetManager netMan         = NetManager.instance;
                    byte       pathPosIndex   = vehicleData.m_pathPositionIndex;
                    byte       lastPathOffset = vehicleData.m_lastPathOffset;
                    if (pathPosIndex == 255)
                    {
                        pathPosIndex = 0;
                    }

                    PathManager pathMan = PathManager.instance;
                    if (pathMan.m_pathUnits.m_buffer[vehicleData.m_path]
                        .GetPosition(pathPosIndex >> 1, out PathUnit.Position curPathPos))
                    {
                        netMan.m_segments.m_buffer[curPathPos.m_segment].AddTraffic(
                            Mathf.RoundToInt(___m_info.m_generatedInfo.m_size.z * 3f),
                            GetNoiseLevel(trainAi));

                        if ((pathPosIndex & 1) == 0 || lastPathOffset == 0 ||
                            (leaderData.m_flags & Vehicle.Flags.WaitingPath) != 0)
                        {
                            uint laneId = PathManager.GetLaneID(curPathPos);
                            if (laneId != 0u)
                            {
                                netMan.m_lanes.m_buffer[laneId].ReserveSpace(___m_info.m_generatedInfo.m_size.z);
                            }
                        }
                        else if (pathMan.m_pathUnits.m_buffer[vehicleData.m_path]
                                 .GetNextPosition(pathPosIndex >> 1, out PathUnit.Position nextPathPos))
                        {
                            // NON-STOCK CODE START
                            ushort transitNodeId;

                            if (curPathPos.m_offset < 128)
                            {
                                transitNodeId = netMan.m_segments.m_buffer[curPathPos.m_segment].m_startNode;
                            }
                            else
                            {
                                transitNodeId = netMan.m_segments.m_buffer[curPathPos.m_segment].m_endNode;
                            }

                            if (VehicleBehaviorManager.Instance.IsSpaceReservationAllowed(
                                    transitNodeId,
                                    curPathPos,
                                    nextPathPos))
                            {
                                // NON-STOCK CODE END
                                uint nextLaneId = PathManager.GetLaneID(nextPathPos);
                                if (nextLaneId != 0u)
                                {
                                    netMan.m_lanes.m_buffer[nextLaneId].ReserveSpace(___m_info.m_generatedInfo.m_size.z);
                                }
                            } // NON-STOCK CODE
                        }
                    }
                }

                beforeRotToTargetPos1Diff = curInvRot * beforeRotToTargetPos1Diff;
                float negTotalAttachLen =
                    -(((___m_info.m_generatedInfo.m_wheelBase +
                        frontVehInfo.m_generatedInfo.m_wheelBase) * 0.5f) + attachOffset +
                      frontAttachOffset);
                bool hasPath = false;

                if (vehicleData.m_path != 0u && (leaderData.m_flags & Vehicle.Flags.WaitingPath) == 0)
                {
                    if (Line3.Intersect(
                            posBeforeWheelRot,
                            vehicleData.m_targetPos1,
                            frontPosMinusWheelBaseRot,
                            negTotalAttachLen,
                            out float u1,
                            out float u2))
                    {
                        targetMotion = beforeRotToTargetPos1Diff
                                       * Mathf.Clamp(Mathf.Min(u1, u2) / 0.6f, 0f, 2f);
                    }
                    else
                    {
                        Line3.DistanceSqr(
                            posBeforeWheelRot,
                            vehicleData.m_targetPos1,
                            frontPosMinusWheelBaseRot,
                            out u1);
                        targetMotion = beforeRotToTargetPos1Diff * Mathf.Clamp(u1 / 0.6f, 0f, 2f);
                    }

                    hasPath = true;
                }

                if (hasPath)
                {
                    if (Vector3.Dot(
                            frontPosMinusWheelBaseRot - posBeforeWheelRot,
                            posBeforeWheelRot - posAfterWheelRot) < 0f)
                    {
                        motionFactor = 0f;
                    }
                }
                else
                {
                    float frontPosBeforeToAfterWheelRotDist = Vector3.Distance(
                        frontPosMinusWheelBaseRot,
                        posBeforeWheelRot);
                    motionFactor = 0f;
                    targetMotion = curInvRot
                                   * ((frontPosMinusWheelBaseRot - posBeforeWheelRot)
                                      * (Mathf.Max(0f, frontPosBeforeToAfterWheelRotDist - negTotalAttachLen)
                                         / Mathf.Max(1f, frontPosBeforeToAfterWheelRotDist * 0.6f)));
                }
            }
コード例 #4
0
        public static bool Prefix(TrainAI __instance,
                                  ushort vehicleID,
                                  ref Vehicle vehicleData,
                                  bool reserveSpace)
        {
            uint pathUnitId = vehicleData.m_path;

            if (pathUnitId == 0u)
            {
                return(false);
            }

            NetManager  netMan       = NetManager.instance;
            PathManager pathMan      = PathManager.instance;
            byte        pathPosIndex = vehicleData.m_pathPositionIndex;

            if (pathPosIndex == 255)
            {
                pathPosIndex = 0;
            }

            pathPosIndex = (byte)(pathPosIndex >> 1);
            bool stopLoop = false; // NON-STOCK CODE

            for (int i = 0; i < 6; i++)
            {
                if (!pathMan.m_pathUnits.m_buffer[pathUnitId].GetPosition(pathPosIndex, out PathUnit.Position position))
                {
                    return(false);
                }

                ref NetSegment positionSegment = ref position.m_segment.ToSegment();

                // NON-STOCK CODE START
                ushort transitNodeId = position.m_offset < 128
                                        ? positionSegment.m_startNode
                                        : positionSegment.m_endNode;

                if (Options.timedLightsEnabled)
                {
                    // when a TTL is active only reserve space if it shows green
                    if (pathMan.m_pathUnits.m_buffer[pathUnitId].GetNextPosition(pathPosIndex, out PathUnit.Position nextPos))
                    {
                        if (!VehicleBehaviorManager.Instance.IsSpaceReservationAllowed(
                                transitNodeId,
                                position,
                                nextPos))
                        {
                            stopLoop = true;
                        }
                    }
                }

                // NON-STOCK CODE END
                if (reserveSpace && i >= 1 && i <= 2)
                {
                    uint laneId = PathManager.GetLaneID(position);
                    if (laneId != 0u)
                    {
                        reserveSpace = laneId.ToLane().ReserveSpace(__instance.m_info.m_generatedInfo.m_size.z, vehicleID);
                    }
                }

                ForceTrafficLights(transitNodeId, position); // NON-STOCK CODE

                // NON-STOCK CODE START
                if (stopLoop)
                {
                    return(false);
                }

                // NON-STOCK CODE END
                if ((pathPosIndex += 1) <
                    pathMan.m_pathUnits.m_buffer[pathUnitId].m_positionCount)
                {
                    continue;
                }

                pathUnitId   = pathMan.m_pathUnits.m_buffer[pathUnitId].m_nextPathUnit;
                pathPosIndex = 0;
                if (pathUnitId == 0u)
                {
                    return(false);
                }
            }
コード例 #5
0
        private static void ResetTargets(ushort vehicleID, ref Vehicle vehicleData, ushort leaderID, ref Vehicle leaderData, bool pushPathPos)
        {
            Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData();
            VehicleInfo   info          = vehicleData.Info;
            TrainAI       trainAI       = info.m_vehicleAI as TrainAI;
            Vector3       vector        = lastFrameData.m_position;
            Vector3       vector2       = lastFrameData.m_position;
            Vector3       b             = lastFrameData.m_rotation * new Vector3(0f, 0f, info.m_generatedInfo.m_wheelBase * 0.5f);

            if ((leaderData.m_flags & Vehicle.Flags.Reversed) != Vehicle.Flags.None)
            {
                vector  -= b;
                vector2 += b;
            }
            else
            {
                vector  += b;
                vector2 -= b;
            }
            vehicleData.m_targetPos0   = vector2;
            vehicleData.m_targetPos0.w = 2f;
            vehicleData.m_targetPos1   = vector;
            vehicleData.m_targetPos1.w = 2f;
            vehicleData.m_targetPos2   = vehicleData.m_targetPos1;
            vehicleData.m_targetPos3   = vehicleData.m_targetPos1;
            if (vehicleData.m_path != 0u)
            {
                PathManager instance = Singleton <PathManager> .instance;
                int         num      = (vehicleData.m_pathPositionIndex >> 1) + 1;
                uint        num2     = vehicleData.m_path;
                if (num >= (int)instance.m_pathUnits.m_buffer [(int)((UIntPtr)num2)].m_positionCount)
                {
                    num  = 0;
                    num2 = instance.m_pathUnits.m_buffer [(int)((UIntPtr)num2)].m_nextPathUnit;
                }
                PathUnit.Position pathPos;
                if (instance.m_pathUnits.m_buffer [(int)((UIntPtr)vehicleData.m_path)].GetPosition(vehicleData.m_pathPositionIndex >> 1, out pathPos))
                {
                    uint laneID = PathManager.GetLaneID(pathPos);
                    PathUnit.Position pathPos2;
                    if (num2 != 0u && instance.m_pathUnits.m_buffer [(int)((UIntPtr)num2)].GetPosition(num, out pathPos2))
                    {
                        uint laneID2 = PathManager.GetLaneID(pathPos2);
                        if (laneID2 == laneID)
                        {
                            if (num2 != vehicleData.m_path)
                            {
                                instance.ReleaseFirstUnit(ref vehicleData.m_path);
                            }
                            vehicleData.m_pathPositionIndex = (byte)(num << 1);
                        }
                    }
                    PathUnit.CalculatePathPositionOffset(laneID, vector2, out vehicleData.m_lastPathOffset);
                }
            }
            if (vehicleData.m_path != 0u)
            {
                int num3 = 0;
                ((FakeTrainAI)trainAI).UpdatePathTargetPositions(vehicleID, ref vehicleData, vector2, vector, 0, ref leaderData, ref num3, 1, 4, 4f, 1f);
            }
        }
コード例 #6
0
        public static bool Prefix(TrainAI __instance,
                                  ushort vehicleID,
                                  ref Vehicle vehicleData,
                                  ref float maxSpeed,
                                  PathUnit.Position position,
                                  uint laneID,
                                  byte offset,
                                  PathUnit.Position prevPos,
                                  uint prevLaneID,
                                  byte prevOffset,
                                  Bezier3 bezier)
        {
            NetManager netManager = NetManager.instance;

            ushort nextSourceNodeId = offset < position.m_offset
                                          ? netManager.m_segments.m_buffer[position.m_segment].m_startNode
                                          : netManager.m_segments.m_buffer[position.m_segment].m_endNode;

            ushort refTargetNodeId = prevOffset == 0
                                         ? netManager.m_segments.m_buffer[prevPos.m_segment].m_startNode
                                         : netManager.m_segments.m_buffer[prevPos.m_segment].m_endNode;

#if DEBUG
            bool logLogic = DebugSwitch.CalculateSegmentPosition.Get() &&
                            (DebugSettings.NodeId <= 0 ||
                             refTargetNodeId == DebugSettings.NodeId) &&
                            (GlobalConfig.Instance.Debug.ApiExtVehicleType == ExtVehicleType.None ||
                             GlobalConfig.Instance.Debug.ApiExtVehicleType == ExtVehicleType.RailVehicle) &&
                            (DebugSettings.VehicleId == 0 ||
                             DebugSettings.VehicleId == vehicleID);

            if (logLogic)
            {
                Log._Debug($"CustomTrainAI.CustomCheckNextLane({vehicleID}) called.\n" +
                           $"\tprevPos.m_segment={prevPos.m_segment}, " +
                           $"prevPos.m_offset={prevPos.m_offset}\n" +
                           $"\tposition.m_segment={position.m_segment}, " +
                           $"position.m_offset={position.m_offset}\n" +
                           $"\tprevLaneID={prevLaneID}, prevOffset={prevOffset}\n" +
                           $"\tprevLaneId={laneID}, prevOffset={offset}\n" +
                           $"\tnextSourceNodeId={nextSourceNodeId}\n" +
                           $"\trefTargetNodeId={refTargetNodeId}, " +
                           $"refTargetNodeId={refTargetNodeId}");
            }
#endif

            Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData();

            Vector3 lastPosPlusRot  = lastFrameData.m_position;
            Vector3 lastPosMinusRot = lastFrameData.m_position;
            Vector3 rotationAdd     = lastFrameData.m_rotation
                                      * new Vector3(0f, 0f, __instance.m_info.m_generatedInfo.m_wheelBase * 0.5f);
            lastPosPlusRot  += rotationAdd;
            lastPosMinusRot -= rotationAdd;
            float breakingDist          = 0.5f * lastFrameData.m_velocity.sqrMagnitude / __instance.m_info.m_braking;
            float distToTargetAfterRot  = Vector3.Distance(lastPosPlusRot, bezier.a);
            float distToTargetBeforeRot = Vector3.Distance(lastPosMinusRot, bezier.a);

#if DEBUG
            if (logLogic)
            {
                Log._Debug($"CustomTrainAI.CustomCheckNextLane({vehicleID}): " +
                           $"lastPos={lastFrameData.m_position} " +
                           $"lastPosMinusRot={lastPosMinusRot} " +
                           $"lastPosPlusRot={lastPosPlusRot} " +
                           $"rotationAdd={rotationAdd} " +
                           $"breakingDist={breakingDist} " +
                           $"distToTargetAfterRot={distToTargetAfterRot} " +
                           $"distToTargetBeforeRot={distToTargetBeforeRot}");
            }
#endif

            if (Mathf.Min(distToTargetAfterRot, distToTargetBeforeRot) >= breakingDist - 5f)
            {
                /*VehicleManager vehMan = Singleton<VehicleManager>.instance;
                 * ushort firstVehicleId = vehicleData.GetFirstVehicle(vehicleID);
                 * if (VehicleBehaviorManager.Instance.MayDespawn(ref vehMan.m_vehicles.m_buffer[firstVehicleId]) || vehMan.m_vehicles.m_buffer[firstVehicleId].m_blockCounter < 100) {*/// NON-STOCK CODE
#if DEBUG
                if (logLogic)
                {
                    Log._Debug($"CustomTrainAI.CustomCheckNextLane({vehicleID}): " +
                               $"Checking for free space on lane {laneID}.");
                }
#endif

                if (!netManager.m_lanes.m_buffer[laneID].CheckSpace(1000f, vehicleID))
                {
#if DEBUG
                    if (logLogic)
                    {
                        Log._Debug($"CustomTrainAI.CustomCheckNextLane({vehicleID}): " +
                                   $"No space available on lane {laneID}. ABORT.");
                    }
#endif
                    vehicleData.m_flags2     |= Vehicle.Flags2.Yielding;
                    vehicleData.m_waitCounter = 0;
                    maxSpeed = 0f;
                    return(false);
                }

                Vector3 bezierMiddlePoint = bezier.Position(0.5f);

                Segment3 segment = Vector3.SqrMagnitude(vehicleData.m_segment.a - bezierMiddlePoint) <
                                   Vector3.SqrMagnitude(bezier.a - bezierMiddlePoint)
                                  ? new Segment3(vehicleData.m_segment.a, bezierMiddlePoint)
                                  : new Segment3(bezier.a, bezierMiddlePoint);

#if DEBUG
                if (logLogic)
                {
                    Log._Debug($"CustomTrainAI.CustomCheckNextLane({vehicleID}): " +
                               $"Checking for overlap (1). segment.a={segment.a} segment.b={segment.b}");
                }
#endif
                if (segment.LengthSqr() >= 3f)
                {
                    segment.a += (segment.b - segment.a).normalized * 2.5f;

                    if (CheckOverlap(vehicleID, ref vehicleData, segment, vehicleID))
                    {
#if DEBUG
                        if (logLogic)
                        {
                            Log._Debug($"CustomTrainAI.CustomCheckNextLane({vehicleID}): " +
                                       $"Overlap detected (1). segment.LengthSqr()={segment.LengthSqr()} " +
                                       $"segment.a={segment.a} ABORT.");
                        }
#endif
                        vehicleData.m_flags2     |= Vehicle.Flags2.Yielding;
                        vehicleData.m_waitCounter = 0;
                        maxSpeed = 0f;
                        return(false);
                    }
                }

                segment = new Segment3(bezierMiddlePoint, bezier.d);
#if DEBUG
                if (logLogic)
                {
                    Log._Debug($"CustomTrainAI.CustomCheckNextLane({vehicleID}): " +
                               $"Checking for overlap (2). segment.a={segment.a} segment.b={segment.b}");
                }
#endif
                if (segment.LengthSqr() >= 1f &&
                    CheckOverlap(vehicleID, ref vehicleData, segment, vehicleID))
                {
#if DEBUG
                    if (logLogic)
                    {
                        Log._Debug($"CustomTrainAI.CustomCheckNextLane({vehicleID}): " +
                                   $"Overlap detected (2). ABORT.");
                    }
#endif
                    vehicleData.m_flags2     |= Vehicle.Flags2.Yielding;
                    vehicleData.m_waitCounter = 0;
                    maxSpeed = 0f;
                    return(false);
                }

                // } // NON-STOCK CODE
                // if (this.m_info.m_vehicleType != VehicleInfo.VehicleType.Monorail) { // NON-STOCK CODE
                if (nextSourceNodeId != refTargetNodeId)
                {
                    return(false);
                }
#if DEBUG
                if (logLogic)
                {
                    Log._Debug($"CustomTrainAI.CustomCheckNextLane({vehicleID}): " +
                               $"Checking if vehicle is allowed to change segment.");
                }
#endif
                float oldMaxSpeed = maxSpeed;
                if (!VehicleBehaviorManager.Instance.MayChangeSegment(
                        vehicleID,
                        ref vehicleData,
                        lastFrameData.m_velocity.sqrMagnitude,
                        ref prevPos,
                        ref netManager.m_segments.m_buffer[prevPos.m_segment],
                        refTargetNodeId,
                        prevLaneID,
                        ref position,
                        refTargetNodeId,
                        ref netManager.m_nodes.m_buffer[refTargetNodeId],
                        laneID,
                        out maxSpeed))
                {
#if DEBUG
                    if (logLogic)
                    {
                        Log._Debug($"CustomTrainAI.CustomCheckNextLane({vehicleID}): " +
                                   $"Vehicle is NOT allowed to change segment. ABORT.");
                    }
#endif
                    maxSpeed = 0;
                    return(false);
                }

                ExtVehicleManager.Instance.UpdateVehiclePosition(
                    vehicleID,
                    ref vehicleData);
                maxSpeed = oldMaxSpeed;

                // NON-STOCK CODE
            }
            return(false);
        }