diff --git a/TLM/TLM/Patch/_NetLane/CalculateStopPositionAndDirection.cs b/TLM/TLM/Patch/_NetLane/CalculateStopPositionAndDirection.cs new file mode 100644 index 000000000..9a4dd6ba5 --- /dev/null +++ b/TLM/TLM/Patch/_NetLane/CalculateStopPositionAndDirection.cs @@ -0,0 +1,42 @@ +namespace TrafficManager.Patch._NetLane; +using ColossalFramework.Math; +using HarmonyLib; +using System; +using TrafficManager.Util; +using UnityEngine; + +[HarmonyPatch(typeof(NetLane), nameof(NetLane.CalculateStopPositionAndDirection))] +internal static class CalculateStopPositionAndDirection { + internal static bool Prefix(ref NetLane __instance, float laneOffset, float stopOffset, out Vector3 position, out Vector3 direction) { + try { + ref Bezier3 bezier = ref __instance.m_bezier; + position = bezier.Position(laneOffset); + direction = bezier.Tangent(laneOffset); + if (stopOffset != 0) { + Vector3 sideDir = Vector3.Cross(Vector3.up, direction).normalized; + + const float t1 = 0.12f; // bus starts turning from this offset to avoid going over the pavement. + const float t2_0 = 0.20f; // bus does not finish turning until this offset to avoid going over the pavement + float t2 = t1 + 0.7f / (__instance.m_length + 1); // bus finishes turning at this offset for a smooth turn (if segment has space). + t2 = Mathf.Clamp(t2, t2_0, 0.5f); + + float t = laneOffset <= 0.5f ? laneOffset : 1 - laneOffset; + float d; + if (t < t1) { + d = 0; + } else if (t > t2) { + d = 1; + } else { + // t=[t1:t2] => d=[0:1] + d = (t - t1) / (t2 - t1); + } + + position += sideDir * stopOffset * d; + } + return false; + } catch (Exception ex) { + ex.LogException(true); + throw; + } + } +} diff --git a/TLM/TLM/TLM.csproj b/TLM/TLM/TLM.csproj index 3bba16d2d..6e736ff41 100644 --- a/TLM/TLM/TLM.csproj +++ b/TLM/TLM/TLM.csproj @@ -158,6 +158,7 @@ +