示例#1
0
        public void RemovePillar()
        {
            for (uint num = 0u; num < PrefabCollection <NetInfo> .LoadedCount(); num++)
            {
                NetInfo loaded = PrefabCollection <NetInfo> .GetLoaded(num);

                if (loaded != null)
                {
                    if (CSURUtil.IsCSUROffset(loaded))
                    {
                        var          roadAI     = loaded.m_netAI as RoadAI;
                        RoadBridgeAI elevatedAI = null;
                        if ((loaded.m_netAI is RoadBridgeAI) && (Regex.Match(loaded.name, "Elevated", RegexOptions.IgnoreCase)).Success)
                        {
                            elevatedAI = loaded.m_netAI as RoadBridgeAI;
                        }
                        else
                        {
                            continue;
                        }
                        elevatedAI.m_bridgePillarInfo = null;// PrefabCollection<BuildingInfo>.FindLoaded("CSUR 2DC.Ama S-1_Data");
                        Debug.Log("Remove pilla for " + loaded.name.ToString());
                    }
                }
            }
        }
示例#2
0
 public static void Prefix(ref NetSegment data)
 {
     if (OptionUI.alignZone)
     {
         if (CSURUtil.IsCSUR(data.Info))
         {
             if (!segmentHalfWidthLock[data.m_infoIndex])
             {
                 segmentHalfWidth[data.m_infoIndex] = data.Info.m_halfWidth;
                 if (data.Info.m_halfWidth < 9f)
                 {
                     data.Info.m_halfWidth = 8f;
                 }
                 else if (data.Info.m_halfWidth < 17f)
                 {
                     data.Info.m_halfWidth = 16f;
                 }
                 else if (data.Info.m_halfWidth < 25f)
                 {
                     data.Info.m_halfWidth = 24f;
                 }
                 else if (data.Info.m_halfWidth < 33f)
                 {
                     data.Info.m_halfWidth = 32f;
                 }
                 else if (data.Info.m_halfWidth < 41f)
                 {
                     data.Info.m_halfWidth = 40f;
                 }
                 segmentHalfWidthLock[data.m_infoIndex] = true;
             }
         }
     }
 }
示例#3
0
        public static float ChangeHalfWidth(float halfWidth0, ushort segment)
        {
            var data = Singleton <NetManager> .instance.m_segments.m_buffer[segment];

            if (OptionUI.alignZone)
            {
                if (CSURUtil.IsCSUR(data.Info))
                {
                    if (data.Info.m_halfWidth < 9f)
                    {
                        return(8f);
                    }
                    else if (data.Info.m_halfWidth < 17f)
                    {
                        return(16f);
                    }
                    else if (data.Info.m_halfWidth < 25f)
                    {
                        return(24f);
                    }
                    else if (data.Info.m_halfWidth < 33f)
                    {
                        return(32f);
                    }
                    else if (data.Info.m_halfWidth < 41f)
                    {
                        return(40f);
                    }
                }
            }
            return(halfWidth0);
        }
        public static IEnumerable <CodeInstruction> Transpiler(ILGenerator il, IEnumerable <CodeInstruction> instructions)
        {
            CodeInstruction ldarg_startNodeID       = CSURUtil.GetLDArg(targetMethod_, "startNodeID"); // push startNodeID into stack,
            CodeInstruction call_GetMinCornerOffset = new CodeInstruction(OpCodes.Call, mGetMinCornerOffset);

            int n = 0;

            foreach (var innstruction in instructions)
            {
                bool is_ldfld_minCornerOffset =
                    innstruction.opcode == OpCodes.Ldfld && innstruction.operand == f_minCornerOffset;
                yield return(innstruction);

                if (is_ldfld_minCornerOffset)
                {
                    n++;
                    yield return(ldarg_startNodeID);

                    yield return(call_GetMinCornerOffset);
                }
            }

            DebugLog.LogToFileOnly($"TRANSPILER CalculateCornerPatch: Successfully patched NetSegment.CalculateCorner(). " +
                                   $"found {n} instances of Ldfld NetInfo.m_minCornerOffset");
            yield break;
        }
示例#5
0
        public static void Load(LoadMode mode = LoadMode.NewGame)
        {
            HelpersExtensions.VERBOSE = false;
            Log.Info("LifeCycle.Load() called");
            CSURUtil.Init();
            HarmonyExtension.InstallHarmony();
            NodeControllerTool.Create();
            if (Settings.GameConfig == null)
            {
                switch (mode)
                {
                case LoadMode.NewGameFromScenario:
                case LoadMode.LoadScenario:
                case LoadMode.LoadMap:
                    // no NC or old NC
                    Settings.GameConfig = GameConfigT.LoadGameDefault;
                    break;

                default:
                    Settings.GameConfig = GameConfigT.NewGameDefault;
                    break;
                }
            }

            NodeManager.Instance.OnLoad();
            SegmentEndManager.Instance.OnLoad();
        }
示例#6
0
        public static IEnumerable <CodeInstruction> Transpiler(ILGenerator il, IEnumerable <CodeInstruction> instructions)
        {
            CodeInstruction ldarg_segment        = CSURUtil.GetLDArg(targetMethod_, "segment"); // push segment into stack,
            CodeInstruction call_ChangeHalfWidth = new CodeInstruction(OpCodes.Call, mChangeHalfWidth);

            int n = 0;

            foreach (var innstruction in instructions)
            {
                yield return(innstruction);

                bool is_ldfld_f_halfWidth =
                    innstruction.opcode == OpCodes.Ldfld && innstruction.operand == f_halfWidth;
                if (is_ldfld_f_halfWidth)
                {
                    n++;
                    yield return(ldarg_segment);

                    yield return(call_ChangeHalfWidth);
                }
            }

            DebugLog.LogToFileOnly($"TRANSPILER CreateZoneBlocksPatch: Successfully patched RoadAI.CreateZoneBlocks(). " +
                                   $"found {n} instances of Ldfld NetInfo.m_halfWidth");
            yield break;
        }
示例#7
0
        public static void SimulationDataReady()
        {
            Log.Info($"LifeCycle.SimulationDataReady() called. mode={Mode} updateMode={UpdateMode}, scene={Scene}");
            System.Threading.Thread.Sleep(1000 * 50); //50 sec
            Log.Info($"LifeCycle.SimulationDataReady() after sleep");

            if (Scene == "ThemeEditor")
            {
                return;
            }
            CSURUtil.Init();
            if (Settings.GameConfig == null)
            {
                switch (Mode)
                {
                case LoadMode.NewGameFromScenario:
                case LoadMode.LoadScenario:
                case LoadMode.LoadMap:
                    // no NC or old NC
                    Settings.GameConfig = GameConfigT.LoadGameDefault;
                    break;

                default:
                    Settings.GameConfig = GameConfigT.NewGameDefault;
                    break;
                }
            }

            HarmonyUtil.InstallHarmony(HARMONY_ID); // game config is checked in patch.

            NodeManager.Instance.OnLoad();
            SegmentEndManager.Instance.OnLoad();
            Loaded = true;
            Log.Info("LifeCycle.SimulationDataReady() sucessful");
        }
示例#8
0
        public static void Prefix(ref NetSegment __instance, ushort segmentID, bool start)
        {
            NetInfo    info      = __instance.Info;
            NetManager instance  = Singleton <NetManager> .instance;
            ushort     num       = (!start) ? __instance.m_endNode : __instance.m_startNode;
            ushort     num2      = (!start) ? __instance.m_startNode : __instance.m_endNode;
            Vector3    position  = instance.m_nodes.m_buffer[(int)num].m_position;
            Vector3    position2 = instance.m_nodes.m_buffer[(int)num2].m_position;
            Vector3    startDir  = (!start) ? __instance.m_endDirection : __instance.m_startDirection;
            Vector3    endDir    = (!start) ? __instance.m_startDirection : __instance.m_endDirection;
            // NON-STOCK CODE STARTS
            float m_minCornerOffset   = 0f;
            float tempMinCornerOffset = 1000f;
            int   segmentCount        = 0;
            bool  isCSURRoad          = false;

            for (int i = 0; i < 8; i++)
            {
                ushort segment1 = instance.m_nodes.m_buffer[num].GetSegment(i);
                if (segment1 != 0)
                {
                    segmentCount++;
                    if (CSURUtil.IsCSUR(Singleton <NetManager> .instance.m_segments.m_buffer[segment1].Info))
                    {
                        isCSURRoad = true;
                    }
                    if (Singleton <NetManager> .instance.m_segments.m_buffer[segment1].Info.m_minCornerOffset < tempMinCornerOffset)
                    {
                        tempMinCornerOffset = Singleton <NetManager> .instance.m_segments.m_buffer[segment1].Info.m_minCornerOffset;
                    }
                }
            }

            if (isCSURRoad)
            {
                if (tempMinCornerOffset != 1000f)
                {
                    m_minCornerOffset = tempMinCornerOffset;
                }
                //direct node
                if (segmentCount == 2)
                {
                    m_minCornerOffset = m_minCornerOffset / 2f;
                    if (m_minCornerOffset > 24f)
                    {
                        m_minCornerOffset = 24f;
                    }
                }

                //DebugLog.LogToFileOnly("Pre m_minCornerOffset = " + m_minCornerOffset.ToString());
                if (!segmentOffsetLock[__instance.m_infoIndex])
                {
                    segmentOffset[__instance.m_infoIndex]     = __instance.Info.m_minCornerOffset;
                    segmentOffsetLock[__instance.m_infoIndex] = true;
                    __instance.Info.m_minCornerOffset         = m_minCornerOffset;
                }
            }
            //DebugLog.LogToFileOnly("Pre m_minCornerOffset = " + __instance.Info.m_minCornerOffset.ToString());
        }
示例#9
0
        public static void Postfix(ushort nodeID, NetInfo.LaneType laneTypes, VehicleInfo.VehicleType vehicleTypes, ref NetSegment __instance, ref int leftIndex, ref int rightIndex, ref uint leftLane, ref uint rightLane)
        {
            if (OptionUI.noJunction)
            {
                if (CSURUtil.IsCSURNoJunction(__instance.Info))
                {
                    if (leftIndex == -1 && rightIndex == -1 && leftLane == 0 && rightLane == 0)
                    {
                        int        debugPedestrianCount = 0;
                        NetManager instance             = Singleton <NetManager> .instance;
                        NetInfo    info  = __instance.Info;
                        int        num   = info.m_lanes.Length;
                        uint       num2  = __instance.m_lanes;
                        int        num10 = 0;
                        while (num10 < num && num2 != 0u)
                        {
                            NetInfo.Lane lane2 = info.m_lanes[num10];
                            if (info.m_lanes[num10].m_laneType.IsFlagSet(NetInfo.LaneType.Pedestrian))
                            {
                                debugPedestrianCount++;
                                if (lane2.m_position > 0)
                                {
                                    //DebugLog.LogToFileOnly($"Fix this case for XR, only one Pedestrian lane {__instance.Info.name}");
                                    //XR case
                                    leftIndex = num10;
                                    leftLane  = num2;
                                }
                                else
                                {
                                    //DebugLog.LogToFileOnly($"Fix this case for XL, only one Pedestrian lane {__instance.Info.name}");
                                    //XL case??
                                    rightIndex = num10;
                                    rightLane  = num2;
                                }
                                break;
                            }
                            num2 = instance.m_lanes.m_buffer[(int)((UIntPtr)num2)].m_nextLane;
                            num10++;
                        }

                        if (debugPedestrianCount == 1)
                        {
                            //DebugLog.LogToFileOnly($"Fix this case, only one Pedestrian lane {__instance.Info.name}");
                        }

                        if (nodeID == __instance.m_startNode != ((__instance.m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None))
                        {
                            int num12 = leftIndex;
                            leftIndex  = rightIndex;
                            rightIndex = num12;
                            uint num13 = leftLane;
                            leftLane  = rightLane;
                            rightLane = num13;
                        }
                    }
                }
            }
        }
示例#10
0
        public void ChangeDefaultSpeedAndConstructionFee()
        {
            if (OptionUI.tempPatchForSpeedAndPrice)
            {
                for (uint num = 0u; num < PrefabCollection <NetInfo> .LoadedCount(); num++)
                {
                    NetInfo asset = PrefabCollection <NetInfo> .GetLoaded(num);

                    if (asset != null)
                    {
                        if (asset.m_netAI is RoadAI)
                        {
                            if (CSURUtil.IsCSUR(asset))
                            {
                                int laneNum = (int)CSURUtil.CountCSURSVehicleLanes(asset);
                                if (CSURUtil.IsCSURDual(asset))
                                {
                                    if (laneNum <= 6)
                                    {
                                        for (int j = 0; j < asset.m_lanes.Length; j++)
                                        {
                                            asset.m_lanes[j].m_speedLimit = 0.6f + (laneNum >> 1) / 5f;
                                        }
                                    }
                                }
                                else
                                {
                                    if (laneNum <= 3)
                                    {
                                        for (int j = 0; j < asset.m_lanes.Length; j++)
                                        {
                                            asset.m_lanes[j].m_speedLimit = 0.6f + laneNum / 5f;
                                        }
                                    }
                                }
                                laneNum += (int)CSURUtil.CountCSURSOtherLanes(asset, true);

                                float width = 0;
                                if (asset.m_lanes.Length > 0)
                                {
                                    width = asset.m_lanes[asset.m_sortedLanes[0]].m_position - asset.m_lanes[asset.m_sortedLanes[asset.m_lanes.Length - 1]].m_position;
                                }

                                if (width < 0)
                                {
                                    width = -width;
                                }

                                PlayerNetAI AI = asset.m_netAI as PlayerNetAI;
                                AI.m_constructionCost = 400 * laneNum + (int)(width * 100);
                            }
                        }
                    }
                }
            }
        }
示例#11
0
 public void RefreshNode()
 {
     for (ushort i = 0; i < Singleton <NetManager> .instance.m_nodes.m_size; i++)
     {
         NetInfo asset = Singleton <NetManager> .instance.m_nodes.m_buffer[i].Info;
         if (CSURUtil.IsCSUR(asset))
         {
             Singleton <NetManager> .instance.UpdateNode(i);
         }
     }
 }
        public static void Prefix(ref NetSegment __instance, bool start)
        {
            if (OptionUI.fixLargeJunction)
            {
                NetManager instance = Singleton <NetManager> .instance;
                ushort     num      = (!start) ? __instance.m_endNode : __instance.m_startNode;
                // NON-STOCK CODE STARTS
                float m_minCornerOffset   = 0f;
                float tempMinCornerOffset = 1000f;
                int   segmentCount        = 0;
                bool  isCSURRoad          = false;
                for (int i = 0; i < 8; i++)
                {
                    ushort segment1 = instance.m_nodes.m_buffer[num].GetSegment(i);
                    if (segment1 != 0)
                    {
                        segmentCount++;
                        if (CSURUtil.IsCSUR(Singleton <NetManager> .instance.m_segments.m_buffer[segment1].Info))
                        {
                            isCSURRoad = true;
                        }
                        if (Singleton <NetManager> .instance.m_segments.m_buffer[segment1].Info.m_minCornerOffset < tempMinCornerOffset)
                        {
                            tempMinCornerOffset = Singleton <NetManager> .instance.m_segments.m_buffer[segment1].Info.m_minCornerOffset;
                        }
                    }
                }

                if (isCSURRoad)
                {
                    if (tempMinCornerOffset != 1000f)
                    {
                        m_minCornerOffset = tempMinCornerOffset;
                    }
                    //direct node
                    if (segmentCount == 2)
                    {
                        m_minCornerOffset = m_minCornerOffset / 2f;
                        if (m_minCornerOffset > 24f)
                        {
                            m_minCornerOffset = 24f;
                        }
                    }

                    if (!segmentOffsetLock[__instance.m_infoIndex])
                    {
                        segmentOffset[__instance.m_infoIndex]     = __instance.Info.m_minCornerOffset;
                        segmentOffsetLock[__instance.m_infoIndex] = true;
                        __instance.Info.m_minCornerOffset         = m_minCornerOffset;
                    }
                }
            }
        }
示例#13
0
 public static void Postfix(ref NetSegment data)
 {
     if (OptionUI.alignZone)
     {
         if (CSURUtil.IsCSUR(data.Info))
         {
             if (segmentHalfWidthLock[data.m_infoIndex])
             {
                 data.Info.m_halfWidth = segmentHalfWidth[data.m_infoIndex];
                 segmentHalfWidthLock[data.m_infoIndex] = false;
             }
         }
     }
 }
示例#14
0
        public static void DisableZone()
        {
            for (uint num = 0u; num < PrefabCollection <NetInfo> .LoadedCount(); num++)
            {
                NetInfo loaded = PrefabCollection <NetInfo> .GetLoaded(num);

                if (CSURUtil.IsCSURNoJunction(loaded) || CSURUtil.IsCSURLaneOffset(loaded) || CSURUtil.IsCSURExpress(loaded))
                {
                    if (loaded.m_netAI is RoadAI)
                    {
                        var AI = loaded.m_netAI as RoadAI;
                        AI.m_enableZoning = false;
                    }
                }
            }

            if (OptionUI.disableZoneUpdateAll)
            {
                for (ushort i = 0; i < Singleton <NetManager> .instance.m_segments.m_size; i++)
                {
                    NetInfo loaded = Singleton <NetManager> .instance.m_segments.m_buffer[i].Info;
                    if (CSURUtil.IsCSURNoJunction(loaded) || CSURUtil.IsCSURLaneOffset(loaded) || CSURUtil.IsCSURExpress(loaded))
                    {
                        if (Singleton <NetManager> .instance.m_segments.m_buffer[i].m_blockEndLeft != 0)
                        {
                            ZoneManager.instance.ReleaseBlock(Singleton <NetManager> .instance.m_segments.m_buffer[i].m_blockEndLeft);
                            Singleton <NetManager> .instance.m_segments.m_buffer[i].m_blockEndLeft = 0;
                        }
                        if (Singleton <NetManager> .instance.m_segments.m_buffer[i].m_blockEndRight != 0)
                        {
                            ZoneManager.instance.ReleaseBlock(Singleton <NetManager> .instance.m_segments.m_buffer[i].m_blockEndRight);
                            Singleton <NetManager> .instance.m_segments.m_buffer[i].m_blockEndRight = 0;
                        }
                        if (Singleton <NetManager> .instance.m_segments.m_buffer[i].m_blockStartLeft != 0)
                        {
                            ZoneManager.instance.ReleaseBlock(Singleton <NetManager> .instance.m_segments.m_buffer[i].m_blockStartLeft);
                            Singleton <NetManager> .instance.m_segments.m_buffer[i].m_blockStartLeft = 0;
                        }
                        if (Singleton <NetManager> .instance.m_segments.m_buffer[i].m_blockStartRight != 0)
                        {
                            ZoneManager.instance.ReleaseBlock(Singleton <NetManager> .instance.m_segments.m_buffer[i].m_blockStartRight);
                            Singleton <NetManager> .instance.m_segments.m_buffer[i].m_blockStartRight = 0;
                        }
                    }
                }
            }
        }
示例#15
0
 public static bool Prefix(ref NetSegment __instance, ushort segmentID)
 {
     if (OptionUI.noJunction)
     {
         NetInfo asset = __instance.Info;
         if (asset != null)
         {
             if (asset.m_netAI is RoadAI)
             {
                 if (CSURUtil.IsCSUR(asset))
                 {
                     CSURUpdateEndSegments(ref __instance, segmentID);
                     return(false);
                 }
             }
         }
     }
     return(true);
 }
 public static void Postfix(ref NetNode __instance)
 {
     if (OptionUI.noJunction)
     {
         NetInfo asset = __instance.Info;
         if (asset != null)
         {
             if (asset.m_netAI is RoadAI)
             {
                 if (CSURUtil.IsCSURNoJunction(asset))
                 {
                     if (__instance.CountSegments() == 2)
                     {
                         __instance.m_flags &= ~NetNode.Flags.Junction;
                     }
                 }
             }
         }
     }
 }
示例#17
0
 public void RefreshSegment()
 {
     for (ushort i = 0; i < Singleton <NetManager> .instance.m_segments.m_size; i++)
     {
         NetInfo asset = Singleton <NetManager> .instance.m_segments.m_buffer[i].Info;
         if (asset != null)
         {
             if (CSURUtil.IsCSUR(asset))
             {
                 if (asset.m_netAI is RoadAI)
                 {
                     Singleton <NetManager> .instance.UpdateSegment(i);
                 }
                 else
                 {
                     Singleton <NetManager> .instance.m_segments.m_buffer[i].UpdateLanes(i, true);
                 }
             }
         }
     }
 }
示例#18
0
        public virtual float CustomGetCollisionHalfWidth()
        {
            // NON-STOCK CODE STARTS
            float laneOffset  = 0;
            float startOffset = 0;
            float endOffset   = 0;
            bool  IsCSURSLane = CSURUtil.IsCSURSLane(m_info.m_netAI.m_info, ref laneOffset, ref startOffset, ref endOffset);

            if (CSURUtil.IsCSUROffset(m_info))
            {
                if (!IsCSURSLane)
                {
                    return((m_info.m_halfWidth - m_info.m_pavementWidth) / 2f);
                }
                else
                {
                    float laneNum = CSURUtil.CountCSURSVehicleLanes(m_info) + CSURUtil.CountCSURSOtherLanes(m_info);
                    return(laneNum * 3.75f / 2f);
                }
            }
            return(m_info.m_halfWidth);
        }
        public static bool Prefix(ref NetAI __instance, ref float __result)
        {
            float laneOffset  = 0;
            float startOffset = 0;
            float endOffset   = 0;
            bool  IsCSURSLane = CSURUtil.IsCSURSLane(__instance.m_info, ref laneOffset, ref startOffset, ref endOffset);

            if (CSURUtil.IsCSUROffset(__instance.m_info))
            {
                if (!IsCSURSLane)
                {
                    __result = (__instance.m_info.m_halfWidth - __instance.m_info.m_pavementWidth) / 2f;
                }
                else
                {
                    float laneNum = CSURUtil.CountCSURSVehicleLanes(__instance.m_info) + CSURUtil.CountCSURSOtherLanes(__instance.m_info);
                    __result = (laneNum * 3.75f / 2f);
                }
                return(false);
            }
            return(true);
        }
示例#20
0
 public static void Postfix(ref NetNode __instance, ref int __result)
 {
     if (OptionUI.noJunction)
     {
         for (int j = 0; j < 8; j++)
         {
             ushort segmentID = __instance.GetSegment(j);
             if (segmentID != 0)
             {
                 NetInfo asset = Singleton <NetManager> .instance.m_segments.m_buffer[segmentID].Info;
                 if (asset != null)
                 {
                     if (asset.m_netAI is RoadAI)
                     {
                         if (CSURUtil.IsCSURNoJunction(asset))
                         {
                             __result = 2;
                         }
                     }
                 }
             }
         }
     }
 }
示例#21
0
        public static bool RayCastNodeMasked(ref NetNode node, Segment3 ray, float snapElevation, bool bothSides, out float t, out float priority)
        {
            bool lht = false;
            //if (SimulationManager.instance.m_metaData.m_invertTraffic == SimulationMetaData.MetaBool.True) lht = true;
            NetInfo info = node.Info;
            float   num  = (float)node.m_elevation + info.m_netAI.GetSnapElevation();
            float   t2;

            if (info.m_netAI.IsUnderground())
            {
                t2 = Mathf.Clamp01(Mathf.Abs(snapElevation + num) / 12f);
            }
            else
            {
                t2 = Mathf.Clamp01(Mathf.Abs(snapElevation - num) / 12f);
            }
            float collisionHalfWidth = Mathf.Max(3f, info.m_halfWidth);
            float maskHalfWidth      = Mathf.Min(collisionHalfWidth - 1.5f, info.m_pavementWidth);
            float num2      = Mathf.Lerp(info.GetMinNodeDistance(), collisionHalfWidth, t2);
            float num2m     = Mathf.Lerp(info.GetMinNodeDistance(), maskHalfWidth, t2);
            float num2delta = Mathf.Lerp(info.GetMinNodeDistance(), collisionHalfWidth - maskHalfWidth, t2);

            if (node.CountSegments() != 0)
            {
                NetManager instance  = Singleton <NetManager> .instance;
                NetSegment mysegment = CSURUtil.GetSameInfoSegment(node);
                Vector3    direction = CSURUtil.CheckNodeEq(mysegment.m_startNode, node) ? mysegment.m_startDirection : -mysegment.m_endDirection;
                //Debug.Log(direction);
                if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0)
                {
                    lht = true;
                }
                // normal to the right hand side
                Vector3 normal         = new Vector3(direction.z, 0, -direction.x).normalized;
                Vector3 trueNodeCenter = node.m_position + (lht ? -collisionHalfWidth : collisionHalfWidth) * normal;
                //Debug.Log($"num2: {num2}, num2m: {num2m}");
                //Debug.Log($"node: {node.m_position}, center: {trueNodeCenter}");
                if (Segment1.Intersect(ray.a.y, ray.b.y, node.m_position.y, out t))
                {
                    float num3 = Vector3.Distance(ray.Position(t), trueNodeCenter);
                    if (num3 < num2delta)
                    {
                        priority = Mathf.Max(0f, num3 - collisionHalfWidth);
                        return(true);
                    }
                }
            }
            else
            {
                if (Segment1.Intersect(ray.a.y, ray.b.y, node.m_position.y, out t))
                {
                    float num3 = Vector3.Distance(ray.Position(t), node.m_position);
                    if (num3 < num2)
                    {
                        priority = Mathf.Max(0f, num3 - collisionHalfWidth);
                        return(true);
                    }
                }
            }
            t        = 0f;
            priority = 0f;
            return(false);
        }
示例#22
0
        //to detour move it
        public static bool MoveItRayCastNode(ref NetNode node, Segment3 ray, float snapElevation, out float t, out float priority)
        {
            NetInfo info = node.Info;
            // NON-STOCK CODE STARTS
            float laneOffset  = 0;
            float startOffset = 0;
            float endOffset   = 0;
            bool  IsCSURSLane = CSURUtil.IsCSURSLane(info.m_netAI.m_info, ref laneOffset, ref startOffset, ref endOffset);

            if (CSURUtil.IsCSUROffset(info.m_netAI.m_info) && !IsCSURSLane)
            {
                return(RayCastNodeMasked(ref node, ray, snapElevation, false, out t, out priority));
            }
            // NON-STOCK CODE ENDS
            //if ((node.m_flags & (NetNode.Flags.Middle | NetNode.Flags.Outside)) == NetNode.Flags.None)
            //{
            float num = (float)node.m_elevation + info.m_netAI.GetSnapElevation();
            float t2;

            if (info.m_netAI.IsUnderground())
            {
                t2 = Mathf.Clamp01(Mathf.Abs(snapElevation + num) / 12f);
            }
            else
            {
                t2 = Mathf.Clamp01(Mathf.Abs(snapElevation - num) / 12f);
            }
            float collisionHalfWidth = Mathf.Max(3f, info.m_netAI.GetCollisionHalfWidth());
            float num2 = Mathf.Lerp(info.GetMinNodeDistance(), collisionHalfWidth, t2);

            if (Segment1.Intersect(ray.a.y, ray.b.y, node.m_position.y, out t))
            {
                float num3 = Vector3.Distance(ray.Position(t), node.m_position);
                // NON-STOCK CODE STARTS
                if (IsCSURSLane)
                {
                    bool       lht       = false;
                    NetManager instance  = Singleton <NetManager> .instance;
                    NetSegment mysegment = CSURUtil.GetSameInfoSegment(node);
                    bool       isStart   = CSURUtil.CheckNodeEq(mysegment.m_startNode, node);
                    Vector3    direction = isStart ? mysegment.m_startDirection : -mysegment.m_endDirection;
                    //Debug.Log(direction);
                    if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0)
                    {
                        lht = true;
                    }
                    Vector3 normal         = new Vector3(direction.z, 0, -direction.x).normalized;
                    float   vehicleLaneNum = CSURUtil.CountCSURSVehicleLanes(info);
                    float   otherLaneNum   = CSURUtil.CountCSURSOtherLanes(info);
                    float   laneNum        = otherLaneNum + vehicleLaneNum;
                    startOffset = startOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                    endOffset   = endOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                    var     Offset         = isStart ? startOffset : endOffset;
                    Vector3 trueNodeCenter = node.m_position + (lht ? -Offset : Offset) * normal;
                    num3 = Vector3.Distance(ray.Position(t), trueNodeCenter);
                }
                // NON-STOCK CODE ENDS

                if (num3 < num2)
                {
                    priority = Mathf.Max(0f, num3 - collisionHalfWidth);
                    return(true);
                }
            }
            //}
            t        = 0f;
            priority = 0f;
            return(false);
        }
示例#23
0
        public void OnGUI()
        {
            if (!(Loader.is1637663252 | Loader.is583429740 | Loader.is1806963141))
            {
                return;
            }

            if ((laterLeftClick == 8) && needLaterLeftClick)
            {
                laterLeftClick = 0;
                MouseSimulater.LeftClick();
                needLaterLeftClick = false;
            }
            else if (needLaterLeftClick)
            {
                laterLeftClick++;
            }

            var e = Event.current;

            // Checking key presses
            if (OptionsKeymappingFunction.m_stayinlane.IsPressed(e))
            {
                Assembly TMPE               = Assembly.Load("TrafficManager");
                var      selectedNodeId     = TMPE.GetType("TrafficManager.UI.TrafficManagerTool").GetProperty("SelectedNodeId");
                var      TrafficManagerTool = TMPE.CreateInstance("TrafficManager.UI.TrafficManagerTool");
                ushort   node               = (ushort)selectedNodeId.GetValue(TrafficManagerTool, null);
                DebugLog.LogToFileOnly("TMPE select node = " + node.ToString());
                NetInfo asset = Singleton <NetManager> .instance.m_nodes.m_buffer[node].Info;
                if (CSURUtil.IsCSUR(asset))
                {
                    bool IsCSURRLane  = false;
                    bool IsCSURDual   = false;
                    bool IsCSURSingle = false;
                    for (int j = 0; j < 8; j++)
                    {
                        ushort segmentID = Singleton <NetManager> .instance.m_nodes.m_buffer[node].GetSegment(j);
                        if (segmentID != 0)
                        {
                            var segment = Singleton <NetManager> .instance.m_segments.m_buffer[segmentID];
                            if (CSURUtil.IsCSUR(segment.Info))
                            {
                                if (CSURUtil.IsCSURDual(segment.Info))
                                {
                                    IsCSURDual = true;
                                }
                                else
                                {
                                    if (CSURUtil.IsCSURRLaneOffset(segment.Info))
                                    {
                                        IsCSURRLane = true;
                                        break;
                                    }
                                    IsCSURSingle = true;
                                }
                            }
                        }
                    }
                    if (IsCSURRLane || (IsCSURDual && IsCSURSingle))
                    {
                        AddLaneConnectionForCSUR(node, TMPE);
                        //refresh
                        MouseSimulater.RightClick();
                        needLaterLeftClick = true;
                    }
                }
            }

            if (OptionsKeymappingFunction.m_stayinlaneAll.IsPressed(e))
            {
                Assembly TMPE = Assembly.Load("TrafficManager");
                for (ushort i = 0; i < Singleton <NetManager> .instance.m_nodes.m_size; i++)
                {
                    bool IsCSURRLane  = false;
                    bool IsCSURDual   = false;
                    bool IsCSURSingle = false;
                    for (int j = 0; j < 8; j++)
                    {
                        ushort segmentID = Singleton <NetManager> .instance.m_nodes.m_buffer[i].GetSegment(j);
                        if (segmentID != 0)
                        {
                            var segment = Singleton <NetManager> .instance.m_segments.m_buffer[segmentID];
                            if (CSURUtil.IsCSUR(segment.Info))
                            {
                                if (CSURUtil.IsCSURDual(segment.Info))
                                {
                                    IsCSURDual = true;
                                }
                                else
                                {
                                    if (CSURUtil.IsCSURRLaneOffset(segment.Info))
                                    {
                                        IsCSURRLane = true;
                                        break;
                                    }
                                    IsCSURSingle = true;
                                }
                            }
                        }
                    }
                    if (IsCSURRLane || (IsCSURDual && IsCSURSingle))
                    {
                        AddLaneConnectionForCSUR(i, TMPE);
                    }
                }
            }
        }
示例#24
0
        public static void Postfix(ref NetSegment __instance)
        {
            if (__instance.m_flags != NetSegment.Flags.None)
            {
                var m_info = __instance.Info;
                if (m_info == null)
                {
                    return;
                }

                if (__instance.m_lanes != 0u || (m_info.m_lanes != null && m_info.m_lanes.Length != 0))
                {
                    //Patch Begin
                    NetManager instance  = Singleton <NetManager> .instance;
                    uint       firstLane = __instance.m_lanes;
                    float      num       = 0f;
                    float      num2      = 0f;
                    if ((m_info.m_netAI is RoadAI) || (m_info.m_netAI is RoadBridgeAI) || (m_info.m_netAI is RoadTunnelAI))
                    {
                        if (CSURUtil.IsCSURLaneOffset(m_info))
                        {
                            for (int i = 0; i < m_info.m_lanes.Length; i++)
                            {
                                if (firstLane == 0)
                                {
                                    break;
                                }
                                float        laneOffset     = 0;
                                NetInfo.Lane lane           = m_info.m_lanes[i];
                                float        laneOffsetUnit = CSURUtil.CSURLaneOffset(m_info, lane);
                                laneOffset = laneOffsetUnit * 3.75f;
                                //DebugLog.LogToFileOnly("lanepostion = " + lane.m_position.ToString() + " laneoffset = " + laneOffset.ToString());
                                float effort = (OptionUI.smoothLevel == 2) ? 0.002f : (OptionUI.smoothLevel == 1) ? 0.01f : 0.05f;
                                //EG: before patch: point1-point4 is 1.5*3.75
                                //After patch, point1-point4 is (1 1.3333 1.6667 2)*3.75
                                var     bezier        = instance.m_lanes.m_buffer[firstLane].m_bezier;
                                Vector3 newBezierA    = bezier.Position(0) + (new Vector3(-bezier.Tangent(0).z, 0, bezier.Tangent(0).x).normalized) * (laneOffset * 0.5f);
                                Vector3 newBezierA1   = bezier.Position(effort) + (new Vector3(-bezier.Tangent(effort).z, 0, bezier.Tangent(effort).x).normalized) * (laneOffset * (0.5f - effort));
                                Vector3 newBezierADir = VectorUtils.NormalizeXZ(newBezierA1 - newBezierA);
                                Vector3 newBezierD    = bezier.Position(1) + (new Vector3(bezier.Tangent(1).z, 0, -bezier.Tangent(1).x).normalized) * (laneOffset * 0.5f);
                                Vector3 newBezierD1   = bezier.Position(1f - effort) + (new Vector3(bezier.Tangent(1f - effort).z, 0, -bezier.Tangent(1f - effort).x).normalized) * (laneOffset * (0.5f - effort));
                                Vector3 newBezierDDir = VectorUtils.NormalizeXZ(newBezierD1 - newBezierD);

                                Bezier3 newBezier = default(Bezier3);
                                newBezier.a = newBezierA;
                                newBezier.d = newBezierD;

                                //Try to get smooth bezier as close as real roadmesh
                                NetSegment.CalculateMiddlePoints(newBezierA, newBezierADir, newBezierD, newBezierDDir, true, true, out newBezier.b, out newBezier.c);

                                instance.m_lanes.m_buffer[firstLane].m_bezier = newBezier;
                                num      += instance.m_lanes.m_buffer[firstLane].UpdateLength();
                                num2     += 1f;
                                firstLane = instance.m_lanes.m_buffer[firstLane].m_nextLane;
                            }

                            if (num2 != 0f)
                            {
                                __instance.m_averageLength = num / num2;
                            }
                            else
                            {
                                __instance.m_averageLength = 0f;
                            }
                            bool flag7 = false;
                            if (__instance.m_averageLength < 11f && (instance.m_nodes.m_buffer[__instance.m_startNode].m_flags & NetNode.Flags.Junction) != 0 && (instance.m_nodes.m_buffer[__instance.m_endNode].m_flags & NetNode.Flags.Junction) != 0)
                            {
                                flag7 = true;
                            }
                            firstLane = __instance.m_lanes;
                            for (int j = 0; j < m_info.m_lanes.Length; j++)
                            {
                                if (firstLane == 0)
                                {
                                    break;
                                }
                                NetLane.Flags flags4 = (NetLane.Flags)(instance.m_lanes.m_buffer[firstLane].m_flags & -9);
                                if (flag7)
                                {
                                    flags4 |= NetLane.Flags.JoinedJunction;
                                }
                                instance.m_lanes.m_buffer[firstLane].m_flags = (ushort)flags4;
                                firstLane = instance.m_lanes.m_buffer[firstLane].m_nextLane;
                            }
                        }
                        //Patch End
                    }
                }
            }
        }
        public static bool Prefix(Quad2 quad, float minY, float maxY, ItemClass.CollisionType collisionType, ItemClass.Layer requireLayers, ItemClass.Layer forbidLayers, ushort ignoreNode1, ushort ignoreNode2, ushort ignoreSegment, ulong[] segmentMask, ref bool __result)
        {
            NetManager instance = Singleton <NetManager> .instance;
            Vector2    vector   = quad.Min();
            Vector2    vector2  = quad.Max();
            int        num      = Mathf.Max((int)((vector.x - 64f) / 64f + 135f), 0);
            int        num2     = Mathf.Max((int)((vector.y - 64f) / 64f + 135f), 0);
            int        num3     = Mathf.Min((int)((vector2.x + 64f) / 64f + 135f), 269);
            int        num4     = Mathf.Min((int)((vector2.y + 64f) / 64f + 135f), 269);
            ushort     num5     = 0;
            ushort     num6     = 0;

            if (ignoreSegment != 0)
            {
                ushort        startNode = instance.m_segments.m_buffer[ignoreSegment].m_startNode;
                ushort        endNode   = instance.m_segments.m_buffer[ignoreSegment].m_endNode;
                NetNode.Flags flags     = instance.m_nodes.m_buffer[startNode].m_flags;
                NetNode.Flags flags2    = instance.m_nodes.m_buffer[endNode].m_flags;
                if ((flags & NetNode.Flags.Middle) != 0)
                {
                    num5 = startNode;
                }
                if ((flags2 & NetNode.Flags.Middle) != 0)
                {
                    num6 = endNode;
                }
            }
            bool result = false;

            for (int i = num2; i <= num4; i++)
            {
                for (int j = num; j <= num3; j++)
                {
                    ushort num7 = instance.m_segmentGrid[i * 270 + j];
                    int    num8 = 0;
                    while (num7 != 0)
                    {
                        if (num7 != ignoreSegment && ((long)instance.m_updatedSegments[num7 >> 6] & (1L << (int)num7)) == 0)
                        {
                            NetInfo info = instance.m_segments.m_buffer[num7].Info;
                            if ((object)info != null)
                            {
                                ItemClass.Layer collisionLayers = info.m_netAI.GetCollisionLayers();
                                if ((object)info != null && (requireLayers == ItemClass.Layer.None || (collisionLayers & requireLayers) != 0) && (collisionLayers & forbidLayers) == ItemClass.Layer.None)
                                {
                                    ushort startNode2 = instance.m_segments.m_buffer[num7].m_startNode;
                                    ushort endNode2   = instance.m_segments.m_buffer[num7].m_endNode;
                                    if (startNode2 != ignoreNode1 && startNode2 != ignoreNode2 && startNode2 != num5 && startNode2 != num6 && endNode2 != ignoreNode1 && endNode2 != ignoreNode2 && endNode2 != num5 && endNode2 != num6)
                                    {
                                        Vector3 position  = instance.m_nodes.m_buffer[startNode2].m_position;
                                        Vector3 position2 = instance.m_nodes.m_buffer[endNode2].m_position;
                                        // NON-STOCK CODE STARTS
                                        if (CSURUtil.IsCSUROffset(instance.m_nodes.m_buffer[startNode2].Info))
                                        {
                                            bool lht = false;
                                            if (instance.m_nodes.m_buffer[startNode2].CountSegments() != 0)
                                            {
                                                float      collisionHalfWidth = Mathf.Max(3f, (instance.m_nodes.m_buffer[startNode2].Info.m_halfWidth + instance.m_nodes.m_buffer[startNode2].Info.m_pavementWidth) / 2f);
                                                NetSegment mysegment          = CSURUtil.GetSameInfoSegment(instance.m_nodes.m_buffer[startNode2]);
                                                Vector3    direction          = CSURUtil.CheckNodeEq(mysegment.m_startNode, instance.m_nodes.m_buffer[startNode2]) ? mysegment.m_startDirection : -mysegment.m_endDirection;
                                                if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0)
                                                {
                                                    lht = true;
                                                }
                                                // normal to the right hand side
                                                Vector3 normal = new Vector3(direction.z, 0, -direction.x).normalized;
                                                position = position + (lht ? -collisionHalfWidth : collisionHalfWidth) * normal;
                                            }
                                        }
                                        if (CSURUtil.IsCSUROffset(instance.m_nodes.m_buffer[endNode2].Info))
                                        {
                                            bool lht = false;
                                            if (instance.m_nodes.m_buffer[endNode2].CountSegments() != 0)
                                            {
                                                float      collisionHalfWidth = Mathf.Max(3f, (instance.m_nodes.m_buffer[endNode2].Info.m_halfWidth + instance.m_nodes.m_buffer[endNode2].Info.m_pavementWidth) / 2f);
                                                NetSegment mysegment          = CSURUtil.GetSameInfoSegment(instance.m_nodes.m_buffer[endNode2]);
                                                Vector3    direction          = CSURUtil.CheckNodeEq(mysegment.m_startNode, instance.m_nodes.m_buffer[endNode2]) ? mysegment.m_startDirection : -mysegment.m_endDirection;
                                                if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0)
                                                {
                                                    lht = true;
                                                }
                                                // normal to the right hand side
                                                Vector3 normal = new Vector3(direction.z, 0, -direction.x).normalized;
                                                position2 = position2 + (lht ? -collisionHalfWidth : collisionHalfWidth) * normal;
                                            }
                                        }
                                        // NON-STOCK CODE ENDS
                                        float num9  = Mathf.Max(Mathf.Max(vector.x - 64f - position.x, vector.y - 64f - position.z), Mathf.Max(position.x - vector2.x - 64f, position.z - vector2.y - 64f));
                                        float num10 = Mathf.Max(Mathf.Max(vector.x - 64f - position2.x, vector.y - 64f - position2.z), Mathf.Max(position2.x - vector2.x - 64f, position2.z - vector2.y - 64f));
                                        if ((num9 < 0f || num10 < 0f) && instance.m_segments.m_buffer[num7].OverlapQuad(num7, quad, minY, maxY, collisionType))
                                        {
                                            if (segmentMask == null)
                                            {
                                                __result = true;
                                                return(false);
                                            }
                                            segmentMask[num7 >> 6] |= (ulong)(1L << (int)num7);
                                            result = true;
                                        }
                                    }
                                }
                            }
                        }
                        num7 = instance.m_segments.m_buffer[num7].m_nextGridSegment;
                        if (++num8 >= 36864)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
            __result = result;
            return(false);
        }
示例#26
0
        public static void Postfix(ref NetSegment __instance)
        {
            if (__instance.m_flags != NetSegment.Flags.None)
            {
                var m_info = __instance.Info;
                if (m_info == null)
                {
                    return;
                }

                if (__instance.m_lanes != 0u || (m_info.m_lanes != null && m_info.m_lanes.Length != 0))
                {
                    //Patch Begin
                    NetManager instance  = Singleton <NetManager> .instance;
                    uint       firstLane = __instance.m_lanes;
                    float      num       = 0f;
                    float      num2      = 0f;
                    if ((m_info.m_netAI is RoadAI) || (m_info.m_netAI is RoadBridgeAI) || (m_info.m_netAI is RoadTunnelAI))
                    {
                        if (CSURUtil.IsCSURLaneOffset(m_info))
                        {
                            for (int i = 0; i < m_info.m_lanes.Length; i++)
                            {
                                if (firstLane == 0)
                                {
                                    break;
                                }

                                //Thanks for macsergey to optimize this
                                var laneInfo       = m_info.m_lanes[i];
                                var laneOffsetUnit = CSURUtil.CSURLaneOffset(m_info, laneInfo);
                                var laneOffset     = laneOffsetUnit * 3.75f;
                                var startDir       = __instance.m_startDirection;
                                var endDir         = __instance.m_endDirection;
                                var bezier         = instance.m_lanes.m_buffer[firstLane].m_bezier;

                                var newBezier = MathLine(startDir, endDir, bezier, laneOffset);
                                //Thanks end.

                                instance.m_lanes.m_buffer[firstLane].m_bezier = newBezier;
                                instance.m_lanes.m_buffer[firstLane].UpdateLength();
                                num2     += 1f;
                                firstLane = instance.m_lanes.m_buffer[firstLane].m_nextLane;
                            }

                            if (num2 != 0f)
                            {
                                __instance.m_averageLength = num / num2;
                            }
                            else
                            {
                                __instance.m_averageLength = 0f;
                            }
                            bool flag7 = false;
                            if (__instance.m_averageLength < 11f && (instance.m_nodes.m_buffer[__instance.m_startNode].m_flags & NetNode.Flags.Junction) != 0 && (instance.m_nodes.m_buffer[__instance.m_endNode].m_flags & NetNode.Flags.Junction) != 0)
                            {
                                flag7 = true;
                            }
                            firstLane = __instance.m_lanes;
                            for (int j = 0; j < m_info.m_lanes.Length; j++)
                            {
                                if (firstLane == 0)
                                {
                                    break;
                                }
                                NetLane.Flags flags4 = (NetLane.Flags)(instance.m_lanes.m_buffer[firstLane].m_flags & -9);
                                if (flag7)
                                {
                                    flags4 |= NetLane.Flags.JoinedJunction;
                                }
                                instance.m_lanes.m_buffer[firstLane].m_flags = (ushort)flags4;
                                firstLane = instance.m_lanes.m_buffer[firstLane].m_nextLane;
                            }
                        }
                        //Patch End
                    }
                }
            }
        }
示例#27
0
        public void InstallPillar()
        {
            for (uint num = 0u; num < PrefabCollection <NetInfo> .LoadedCount(); num++)
            {
                NetInfo loaded = PrefabCollection <NetInfo> .GetLoaded(num);

                if (CSURUtil.IsCSUR(loaded))
                {
                    RoadBridgeAI elevatedAI = null;
                    if ((loaded.m_netAI is RoadBridgeAI) && (Regex.Match(loaded.name, "Elevated", RegexOptions.IgnoreCase)).Success && (loaded.m_segments.Length != 0))
                    {
                        elevatedAI = loaded.m_netAI as RoadBridgeAI;
                    }
                    else
                    {
                        continue;
                    }

                    //Caculate lane num
                    int laneNum = (int)CSURUtil.CountCSURSVehicleLanes(loaded);

                    if (!CSURUtil.IsCSURDual(loaded))
                    {
                        if (Regex.Match(loaded.name, "CSUR-T", RegexOptions.IgnoreCase).Success)
                        {
                            laneNum = laneNum - 1;
                        }

                        if (laneNum < 0)
                        {
                            laneNum = 0;
                        }

                        switch (laneNum)
                        {
                        case 0:
                        case 1:
                            DebugLog.LogToFileOnly(loaded.name.ToString() + "lane num = " + laneNum.ToString());
                            DebugLog.LogToFileOnly("Try to Load pillar Ama S-1_Data");
                            elevatedAI.m_bridgePillarOffset = 0.5f;
                            if (PrefabCollection <BuildingInfo> .FindLoaded("Ama S-1_Data") != null)
                            {
                                elevatedAI.m_bridgePillarInfo = PrefabCollection <BuildingInfo> .FindLoaded("Ama S-1_Data");
                            }
                            else
                            {
                                DebugLog.LogToFileOnly("Failed Load pillar Ama S-1_Data");
                            }
                            break;

                        case 2:
                            DebugLog.LogToFileOnly(loaded.name.ToString() + "lane num = 2");
                            DebugLog.LogToFileOnly("Try to Load pillar Ama S-2_Data");
                            elevatedAI.m_bridgePillarOffset = 1f;
                            if (PrefabCollection <BuildingInfo> .FindLoaded("Ama S-2_Data") != null)
                            {
                                elevatedAI.m_bridgePillarInfo = PrefabCollection <BuildingInfo> .FindLoaded("Ama S-2_Data");
                            }
                            else
                            {
                                DebugLog.LogToFileOnly("Failed Load pillar Ama S-2_Data");
                            }
                            break;

                        case 3:
                            DebugLog.LogToFileOnly(loaded.name.ToString() + "lane num = 3");
                            DebugLog.LogToFileOnly("Try to Load pillar Ama S-3_Data");
                            if (PrefabCollection <BuildingInfo> .FindLoaded("Ama S-3_Data") != null)
                            {
                                elevatedAI.m_bridgePillarInfo = PrefabCollection <BuildingInfo> .FindLoaded("Ama S-3_Data");
                            }
                            else
                            {
                                DebugLog.LogToFileOnly("Failed Load pillar Ama S-3_Data");
                            }
                            break;

                        case 4:
                            DebugLog.LogToFileOnly(loaded.name.ToString() + "lane num = 4");
                            DebugLog.LogToFileOnly("Try to Load pillar Ama G-3_Data");
                            if (PrefabCollection <BuildingInfo> .FindLoaded("Ama G-3_Data") != null)
                            {
                                elevatedAI.m_bridgePillarInfo = PrefabCollection <BuildingInfo> .FindLoaded("Ama G-3_Data");
                            }
                            else
                            {
                                DebugLog.LogToFileOnly("Failed Load pillar Ama G-3_Data");
                            }
                            break;

                        case 5:
                            DebugLog.LogToFileOnly(loaded.name.ToString() + "lane num = 5");
                            DebugLog.LogToFileOnly("Try to Load pillar Ama G-4_Data");
                            if (PrefabCollection <BuildingInfo> .FindLoaded("Ama G-4_Data") != null)
                            {
                                elevatedAI.m_bridgePillarInfo = PrefabCollection <BuildingInfo> .FindLoaded("Ama G-4_Data");
                            }
                            else
                            {
                                DebugLog.LogToFileOnly("Failed Load pillar Ama G-4_Data");
                            }
                            break;

                        default:
                            DebugLog.LogToFileOnly(loaded.name.ToString() + "lane num = " + laneNum.ToString());
                            DebugLog.LogToFileOnly("Try to Load pillar Ama G-5_Data");
                            if (PrefabCollection <BuildingInfo> .FindLoaded("Ama G-5_Data") != null)
                            {
                                elevatedAI.m_bridgePillarInfo = PrefabCollection <BuildingInfo> .FindLoaded("Ama G-5_Data");
                            }
                            else
                            {
                                DebugLog.LogToFileOnly("Failed Load pillar Ama G-5_Data");
                            }
                            break;
                        }
                    }
                    else
                    {
                        /*if (Regex.Match(loaded.name, "CSUR-S", RegexOptions.IgnoreCase).Success)
                         *  laneNum = laneNum - 1;
                         * else if (Regex.Match(loaded.name, "CSUR-T", RegexOptions.IgnoreCase).Success)
                         *  laneNum = laneNum - 1;
                         * else if (Regex.Match(loaded.name, "CSUR-R", RegexOptions.IgnoreCase).Success)
                         *  laneNum = laneNum - 1;*/

                        if (laneNum < 0)
                        {
                            laneNum = 0;
                        }

                        //laneNum = laneNum * 2;
                        switch (laneNum)
                        {
                        case 0:
                        case 2:
                            DebugLog.LogToFileOnly(loaded.name.ToString() + "lane num = " + laneNum.ToString());
                            DebugLog.LogToFileOnly("Try to Load pillar Ama S-2_Data");
                            elevatedAI.m_bridgePillarOffset = 1f;
                            if (PrefabCollection <BuildingInfo> .FindLoaded("Ama S-2_Data") != null)
                            {
                                elevatedAI.m_bridgePillarInfo = PrefabCollection <BuildingInfo> .FindLoaded("Ama S-2_Data");
                            }
                            else
                            {
                                DebugLog.LogToFileOnly("Failed Load pillar Ama S-2_Data");
                            }
                            break;

                        case 4:
                            DebugLog.LogToFileOnly(loaded.name.ToString() + "lane num = 4");
                            DebugLog.LogToFileOnly("Try to Load pillar Ama M-2_Data");
                            if (PrefabCollection <BuildingInfo> .FindLoaded("Ama M-2_Data") != null)
                            {
                                elevatedAI.m_bridgePillarInfo = PrefabCollection <BuildingInfo> .FindLoaded("Ama M-2_Data");
                            }
                            else
                            {
                                DebugLog.LogToFileOnly("Failed Load pillar Ama M-2_Data");
                            }
                            break;

                        case 6:
                            DebugLog.LogToFileOnly(loaded.name.ToString() + "lane num = 6");
                            DebugLog.LogToFileOnly("Try to Load pillar Ama M-2_Data");
                            if (PrefabCollection <BuildingInfo> .FindLoaded("Ama M-2_Data") != null)
                            {
                                elevatedAI.m_bridgePillarInfo = PrefabCollection <BuildingInfo> .FindLoaded("Ama M-2_Data");
                            }
                            else
                            {
                                DebugLog.LogToFileOnly("Failed Load pillar Ama M-2_Data");
                            }
                            break;

                        case 8:
                            DebugLog.LogToFileOnly(loaded.name.ToString() + "lane num = 8");
                            DebugLog.LogToFileOnly("Try to Load pillar Ama M-4_Data");
                            if (PrefabCollection <BuildingInfo> .FindLoaded("Ama M-4_Data") != null)
                            {
                                elevatedAI.m_bridgePillarInfo = PrefabCollection <BuildingInfo> .FindLoaded("Ama M-4_Data");
                            }
                            else
                            {
                                DebugLog.LogToFileOnly("Failed Load pillar Ama M-4_Data");
                            }
                            break;

                        case 10:
                            DebugLog.LogToFileOnly(loaded.name.ToString() + "lane num = 10");
                            DebugLog.LogToFileOnly("Try to Load pillar Ama G-8DR_Data");
                            if (PrefabCollection <BuildingInfo> .FindLoaded("Ama G-8DR_Data") != null)
                            {
                                elevatedAI.m_bridgePillarInfo = PrefabCollection <BuildingInfo> .FindLoaded("Ama G-8DR_Data");
                            }
                            else
                            {
                                DebugLog.LogToFileOnly("Failed Load pillar Ama G-8DR_Data");
                            }
                            break;

                        default:
                            DebugLog.LogToFileOnly(loaded.name.ToString() + "lane num = " + laneNum.ToString());
                            DebugLog.LogToFileOnly("Try to Load pillar Ama G-8DR_Data");
                            if (PrefabCollection <BuildingInfo> .FindLoaded("Ama G-8DR_Data") != null)
                            {
                                elevatedAI.m_bridgePillarInfo = PrefabCollection <BuildingInfo> .FindLoaded("Ama G-8DR_Data");
                            }
                            else
                            {
                                DebugLog.LogToFileOnly("Failed Load pillar Ama G-8DR_Data");
                            }
                            break;
                        }
                    }
                }
            }
        }
示例#28
0
        public static bool Prefix(ref NetNode __instance, ushort nodeID, BuildingInfo newBuilding, float heightOffset)
        {
            float num = 0f;

            if ((object)newBuilding != null)
            {
                NetInfo info = __instance.Info;
                if ((object)info != null)
                {
                    num = info.m_netAI.GetNodeBuildingAngle(nodeID, ref __instance);
                }
            }
            BuildingInfo buildingInfo = null;

            if (__instance.m_building != 0)
            {
                buildingInfo = Singleton <BuildingManager> .instance.m_buildings.m_buffer[__instance.m_building].Info;
            }
            if ((object)newBuilding != buildingInfo)
            {
                if (__instance.m_building != 0)
                {
                    Singleton <BuildingManager> .instance.ReleaseBuilding(__instance.m_building);

                    __instance.m_building = 0;
                }
                if ((object)newBuilding != null)
                {
                    Vector3 position = __instance.m_position;
                    position.y += heightOffset;
                    // NON-STOCK CODE STARTS
                    if (CSURUtil.IsCSUROffset(__instance.Info))
                    {
                        float laneOffset  = 0;
                        float startOffset = 0;
                        float endOffset   = 0;
                        if (CSURUtil.IsCSURSLane(__instance.Info, ref laneOffset, ref startOffset, ref endOffset))
                        {
                            bool lht = false;
                            if (__instance.CountSegments() != 0)
                            {
                                float collisionHalfWidth = 0;
                                float vehicleLaneNum     = CSURUtil.CountCSURSVehicleLanes(__instance.Info);
                                float otherLaneNum       = CSURUtil.CountCSURSOtherLanes(__instance.Info);
                                float laneNum            = otherLaneNum + vehicleLaneNum;
                                if (CSURUtil.isStartNode(nodeID))
                                {
                                    if (startOffset != 0)
                                    {
                                        collisionHalfWidth = startOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                                    }
                                }
                                else
                                {
                                    if (endOffset != 0)
                                    {
                                        collisionHalfWidth = endOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                                    }
                                }
                                NetSegment mysegment = CSURUtil.GetSameInfoSegment(__instance);
                                Vector3    direction = CSURUtil.CheckNodeEq(mysegment.m_startNode, __instance) ? mysegment.m_startDirection : -mysegment.m_endDirection;
                                if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0)
                                {
                                    lht = true;
                                }
                                // normal to the right hand side
                                Vector3 normal = new Vector3(direction.z, 0, -direction.x).normalized;
                                position = position + (lht ? -collisionHalfWidth : collisionHalfWidth) * normal;
                            }
                        }
                        else
                        {
                            bool lht = false;
                            if (__instance.CountSegments() != 0)
                            {
                                float      collisionHalfWidth = Mathf.Max(3f, (__instance.Info.m_halfWidth + __instance.Info.m_pavementWidth) / 2f);
                                NetSegment mysegment          = CSURUtil.GetSameInfoSegment(__instance);
                                Vector3    direction          = CSURUtil.CheckNodeEq(mysegment.m_startNode, __instance) ? mysegment.m_startDirection : -mysegment.m_endDirection;
                                if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0)
                                {
                                    lht = true;
                                }
                                // normal to the right hand side
                                Vector3 normal = new Vector3(direction.z, 0, -direction.x).normalized;
                                position = position + (lht ? -collisionHalfWidth : collisionHalfWidth) * normal;
                            }
                        }
                    }
                    // NON-STOCK CODE ENDS
                    num *= 6.28318548f;
                    if ((object)buildingInfo != null || TestNodeBuilding(nodeID, newBuilding, position, num))
                    {
                        Randomizer randomizer = new Randomizer(nodeID);
                        if (Singleton <BuildingManager> .instance.CreateBuilding(out __instance.m_building, ref randomizer, newBuilding, position, num, 0, __instance.m_buildIndex + 1))
                        {
                            Singleton <BuildingManager> .instance.m_buildings.m_buffer[__instance.m_building].m_flags |= (Building.Flags.Untouchable | Building.Flags.FixedHeight);
                        }
                    }
                }
            }
            else if (__instance.m_building != 0)
            {
                BuildingManager instance  = Singleton <BuildingManager> .instance;
                Vector3         position2 = __instance.m_position;
                position2.y += heightOffset;
                // NON-STOCK CODE STARTS
                if (CSURUtil.IsCSUROffset(__instance.Info))
                {
                    float laneOffset  = 0;
                    float startOffset = 0;
                    float endOffset   = 0;
                    if (CSURUtil.IsCSURSLane(__instance.Info, ref laneOffset, ref startOffset, ref endOffset))
                    {
                        bool lht = false;
                        if (__instance.CountSegments() != 0)
                        {
                            float collisionHalfWidth = 0;
                            float vehicleLaneNum     = CSURUtil.CountCSURSVehicleLanes(__instance.Info);
                            float otherLaneNum       = CSURUtil.CountCSURSOtherLanes(__instance.Info);
                            float laneNum            = otherLaneNum + vehicleLaneNum;
                            if (CSURUtil.isStartNode(nodeID))
                            {
                                if (startOffset != 0)
                                {
                                    collisionHalfWidth = startOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                                }
                            }
                            else
                            {
                                if (endOffset != 0)
                                {
                                    collisionHalfWidth = endOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                                }
                            }
                            NetSegment mysegment = CSURUtil.GetSameInfoSegment(__instance);
                            Vector3    direction = CSURUtil.CheckNodeEq(mysegment.m_startNode, __instance) ? mysegment.m_startDirection : -mysegment.m_endDirection;
                            if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0)
                            {
                                lht = true;
                            }
                            // normal to the right hand side
                            Vector3 normal = new Vector3(direction.z, 0, -direction.x).normalized;
                            position2 = position2 + (lht ? -collisionHalfWidth : collisionHalfWidth) * normal;
                        }
                    }
                    else
                    {
                        bool lht = false;
                        if (__instance.CountSegments() != 0)
                        {
                            float      collisionHalfWidth = Mathf.Max(3f, (__instance.Info.m_halfWidth + __instance.Info.m_pavementWidth) / 2f);
                            NetSegment mysegment          = CSURUtil.GetSameInfoSegment(__instance);
                            Vector3    direction          = CSURUtil.CheckNodeEq(mysegment.m_startNode, __instance) ? mysegment.m_startDirection : -mysegment.m_endDirection;
                            if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0)
                            {
                                lht = true;
                            }
                            // normal to the right hand side
                            Vector3 normal = new Vector3(direction.z, 0, -direction.x).normalized;
                            position2 = position2 + (lht ? -collisionHalfWidth : collisionHalfWidth) * normal;
                        }
                    }
                }
                // NON-STOCK CODE ENDS
                num *= 6.28318548f;
                // NON-STOCK CODE STARTS
                if (CSURUtil.IsCSUROffset(__instance.Info) && (instance.m_buildings.m_buffer[__instance.m_building].m_position != position2 || instance.m_buildings.m_buffer[__instance.m_building].m_angle != num))
                {
                    RemoveFromGrid(__instance.m_building, ref instance.m_buildings.m_buffer[__instance.m_building]);
                    instance.m_buildings.m_buffer[__instance.m_building].m_position = position2;
                    instance.m_buildings.m_buffer[__instance.m_building].m_angle    = num;
                    AddToGrid(__instance.m_building, ref instance.m_buildings.m_buffer[__instance.m_building]);
                    instance.m_buildings.m_buffer[__instance.m_building].CalculateBuilding(__instance.m_building);
                    Singleton <BuildingManager> .instance.UpdateBuildingRenderer(__instance.m_building, true);
                }
                else
                {
                    if (instance.m_buildings.m_buffer[__instance.m_building].m_position.y != position2.y || instance.m_buildings.m_buffer[__instance.m_building].m_angle != num)
                    {
                        instance.m_buildings.m_buffer[__instance.m_building].m_position.y = position2.y;
                        instance.m_buildings.m_buffer[__instance.m_building].m_angle      = num;
                        instance.UpdateBuilding(__instance.m_building);
                    }
                }
                // NON-STOCK CODE ENDS
            }
            return(false);
        }
        public static bool Prefix(ref NetSegment __instance, ushort segmentID, Quad2 quad, float minY, float maxY, ItemClass.CollisionType collisionType)
        {
            if ((__instance.m_flags & (NetSegment.Flags.Created | NetSegment.Flags.Deleted)) != NetSegment.Flags.Created)
            {
                return(false);
            }
            NetInfo info = __instance.Info;

            if (!info.m_canCollide)
            {
                return(false);
            }
            float   collisionHalfWidth = info.m_netAI.GetCollisionHalfWidth();
            Vector2 vector             = quad.Min();
            Vector2 vector2            = quad.Max();
            Bezier3 bezier             = default(Bezier3);

            bezier.a = Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].m_position;
            bezier.d = Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_endNode].m_position;
            // NON-STOCK CODE STARTS
            if (CSURUtil.IsCSUROffset(Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].Info))
            {
                var     width     = (Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].Info.m_halfWidth + Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].Info.m_pavementWidth) / 2f;
                bool    lht       = false;
                Vector3 direction = __instance.m_startDirection;
                if ((__instance.m_flags & NetSegment.Flags.Invert) != 0)
                {
                    lht = true;
                }
                // normal to the right hand side
                Vector3 normal = new Vector3(direction.z, 0, -direction.x).normalized;
                bezier.a = bezier.a + (lht ? -width : width) * normal;
            }
            if (CSURUtil.IsCSUROffset(Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_endNode].Info))
            {
                bool    lht       = false;
                var     width     = (Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_endNode].Info.m_halfWidth + Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_endNode].Info.m_pavementWidth) / 2f;
                Vector3 direction = -__instance.m_endDirection;
                if ((__instance.m_flags & NetSegment.Flags.Invert) != 0)
                {
                    lht = true;
                }
                // normal to the right hand side
                Vector3 normal = new Vector3(direction.z, 0, -direction.x).normalized;
                bezier.d = bezier.d + (lht ? -width : width) * normal;
            }
            // NON-STOCK CODE ENDS
            NetSegment.CalculateMiddlePoints(bezier.a, __instance.m_startDirection, bezier.d, __instance.m_endDirection, true, true, out bezier.b, out bezier.c);
            // NON-STOCK CODE STARTS
            float   laneOffsetS  = 0;
            float   startOffsetS = 0;
            float   endOffsetS   = 0;
            bool    IsCSURSLaneS = CSURUtil.IsCSURSLane(Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].Info, ref laneOffsetS, ref startOffsetS, ref endOffsetS);
            float   laneOffsetE  = 0;
            float   startOffsetE = 0;
            float   endOffsetE   = 0;
            bool    IsCSURSLaneE = CSURUtil.IsCSURSLane(Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_endNode].Info, ref laneOffsetE, ref startOffsetE, ref endOffsetE);
            Vector3 newBezierA1  = Vector3.zero;
            Vector3 newBezierB1  = Vector3.zero;
            Vector3 newBezierC1  = Vector3.zero;
            Vector3 newBezierD1  = Vector3.zero;

            if (IsCSURSLaneS || IsCSURSLaneE)
            {
                float vehicleLaneNum = CSURUtil.CountCSURSVehicleLanes(Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].Info);
                float otherLaneNum   = CSURUtil.CountCSURSOtherLanes(Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].Info);
                float laneNum        = vehicleLaneNum + otherLaneNum;
                startOffsetS = startOffsetS * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                endOffsetE   = endOffsetE * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                if ((__instance.m_flags & NetSegment.Flags.Invert) != 0)
                {
                    startOffsetS = -startOffsetS;
                    endOffsetE   = -endOffsetE;
                }

                if (!IsCSURSLaneS)
                {
                    startOffsetS = 0;
                }
                if (!IsCSURSLaneE)
                {
                    endOffsetE = 0;
                }
                //EG: before patch: point1-point4 is 1.5*3.75
                //After patch, point1-point4 is (1 1.3333 1.6667 2)*3.75
                newBezierA1 = bezier.a + (new Vector3(__instance.m_startDirection.z, 0, -__instance.m_startDirection.x).normalized) * (startOffsetS);
                Vector3 newBezierBDir = VectorUtils.NormalizeXZ(bezier.Tangent(0.333f));
                newBezierB1 = bezier.b + (new Vector3(newBezierBDir.z, 0, -newBezierBDir.x).normalized) * (startOffsetS * 0.667f + endOffsetE * 0.333f);
                Vector3 newBezierCDir = VectorUtils.NormalizeXZ(bezier.Tangent(0.667f));
                newBezierC1 = bezier.c + (new Vector3(newBezierCDir.z, 0, -newBezierCDir.x).normalized) * (startOffsetS * 0.333f + endOffsetE * 0.667f);
                newBezierD1 = bezier.d + (new Vector3(-__instance.m_endDirection.z, 0, __instance.m_endDirection.x).normalized) * (endOffsetE);

                bezier.a = newBezierA1;
                bezier.b = newBezierB1;
                bezier.c = newBezierC1;
                bezier.d = newBezierD1;
            }
            // NON-STOCK CODE ENDS

            Vector3 vector3 = bezier.Min() + new Vector3(0f - collisionHalfWidth, info.m_minHeight, 0f - collisionHalfWidth);
            Vector3 vector4 = bezier.Max() + new Vector3(collisionHalfWidth, info.m_maxHeight, collisionHalfWidth);

            ItemClass.CollisionType collisionType2 = info.m_netAI.GetCollisionType();
            if (vector3.x <= vector2.x && vector3.z <= vector2.y && vector.x <= vector4.x && vector.y <= vector4.z && ItemClass.CheckCollisionType(minY, maxY, vector3.y, vector4.y, collisionType, collisionType2))
            {
                int num = 16;
                info.m_netAI.GetTerrainModifyRange(out float start, out float end);
                start *= 0.5f;
                end    = 1f - (1f - end) * 0.5f;
                float   t       = start;
                Vector3 vector5 = bezier.Position(t);
                Vector3 vector6 = bezier.Tangent(t);
                vector6 = new Vector3(0f - vector6.z, 0f, vector6.x).normalized *collisionHalfWidth;
                Vector3 a         = vector5 + vector6;
                Vector3 vector7   = vector5 - vector6;
                float   endRadius = info.m_netAI.GetEndRadius();
                if (info.m_clipSegmentEnds && endRadius != 0f && start == 0f && (Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_startNode].m_flags & (NetNode.Flags.End | NetNode.Flags.Bend | NetNode.Flags.Junction)) != 0)
                {
                    Vector3 vector8 = vector5;
                    vector8.x += vector6.x * 0.8f - vector6.z * 0.6f * endRadius / collisionHalfWidth;
                    vector8.z += vector6.z * 0.8f + vector6.x * 0.6f * endRadius / collisionHalfWidth;
                    Vector3 vector9 = vector5;
                    vector9.x -= vector6.x * 0.8f + vector6.z * 0.6f * endRadius / collisionHalfWidth;
                    vector9.z -= vector6.z * 0.8f - vector6.x * 0.6f * endRadius / collisionHalfWidth;
                    Vector3 d = vector5;
                    d.x += vector6.x * 0.3f - vector6.z * endRadius / collisionHalfWidth;
                    d.z += vector6.z * 0.3f + vector6.x * endRadius / collisionHalfWidth;
                    Vector3 c = vector5;
                    c.x      -= vector6.x * 0.3f + vector6.z * endRadius / collisionHalfWidth;
                    c.z      -= vector6.z * 0.3f - vector6.x * endRadius / collisionHalfWidth;
                    vector3.y = vector5.y + info.m_minHeight;
                    vector4.y = vector5.y + info.m_maxHeight;
                    if (ItemClass.CheckCollisionType(minY, maxY, vector3.y, vector4.y, collisionType, collisionType2))
                    {
                        if (quad.Intersect(Quad2.XZ(a, vector7, vector9, vector8)))
                        {
                            return(true);
                        }
                        if (quad.Intersect(Quad2.XZ(vector8, vector9, c, d)))
                        {
                            return(true);
                        }
                    }
                }
                for (int i = 1; i <= num; i++)
                {
                    t       = start + (end - start) * (float)i / (float)num;
                    vector5 = bezier.Position(t);
                    vector6 = bezier.Tangent(t);
                    vector6 = new Vector3(0f - vector6.z, 0f, vector6.x).normalized *collisionHalfWidth;
                    Vector3 vector10 = vector5 + vector6;
                    Vector3 vector11 = vector5 - vector6;
                    vector3.y = Mathf.Min(Mathf.Min(a.y, vector10.y), Mathf.Min(vector11.y, vector7.y)) + info.m_minHeight;
                    vector4.y = Mathf.Max(Mathf.Max(a.y, vector10.y), Mathf.Max(vector11.y, vector7.y)) + info.m_maxHeight;
                    if (ItemClass.CheckCollisionType(minY, maxY, vector3.y, vector4.y, collisionType, collisionType2) && quad.Intersect(Quad2.XZ(a, vector10, vector11, vector7)))
                    {
                        return(true);
                    }
                    a       = vector10;
                    vector7 = vector11;
                }
                if (info.m_clipSegmentEnds && endRadius != 0f && end == 1f && (Singleton <NetManager> .instance.m_nodes.m_buffer[__instance.m_endNode].m_flags & (NetNode.Flags.End | NetNode.Flags.Bend | NetNode.Flags.Junction)) != 0)
                {
                    Vector3 vector12 = vector5;
                    vector12.x += vector6.x * 0.8f + vector6.z * 0.6f * endRadius / collisionHalfWidth;
                    vector12.z += vector6.z * 0.8f - vector6.x * 0.6f * endRadius / collisionHalfWidth;
                    Vector3 vector13 = vector5;
                    vector13.x -= vector6.x * 0.8f - vector6.z * 0.6f * endRadius / collisionHalfWidth;
                    vector13.z -= vector6.z * 0.8f + vector6.x * 0.6f * endRadius / collisionHalfWidth;
                    Vector3 b = vector5;
                    b.x += vector6.x * 0.3f + vector6.z * endRadius / collisionHalfWidth;
                    b.z += vector6.z * 0.3f - vector6.x * endRadius / collisionHalfWidth;
                    Vector3 c2 = vector5;
                    c2.x     -= vector6.x * 0.3f - vector6.z * endRadius / collisionHalfWidth;
                    c2.z     -= vector6.z * 0.3f + vector6.x * endRadius / collisionHalfWidth;
                    vector3.y = vector5.y + info.m_minHeight;
                    vector4.y = vector5.y + info.m_maxHeight;
                    if (ItemClass.CheckCollisionType(minY, maxY, vector3.y, vector4.y, collisionType, collisionType2))
                    {
                        if (quad.Intersect(Quad2.XZ(a, vector12, vector13, vector7)))
                        {
                            return(true);
                        }
                        if (quad.Intersect(Quad2.XZ(vector12, b, c2, vector13)))
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
        public static bool Prefix(ref NetSegment __instance, ushort segmentID, Segment3 ray, float snapElevation, bool nameOnly, out float t, out float priority, ref bool __result)
        {
            // NON-STOCK CODE STARTS
            float laneOffset  = 0;
            float startOffset = 0;
            float endOffset   = 0;
            bool  IsCSURSLane = CSURUtil.IsCSURSLane(__instance.Info.m_netAI.m_info, ref laneOffset, ref startOffset, ref endOffset);

            if (CSURUtil.IsCSUROffset(__instance.Info.m_netAI.m_info) && !IsCSURSLane)
            {
                __result = NetSegmentRayCastMasked(__instance, segmentID, ray, -1000f, false, out t, out priority);
                return(false);
            }
            // NON-STOCK CODE ENDS
            NetInfo info = __instance.Info;

            t        = 0f;
            priority = 0f;
            if (nameOnly && (__instance.m_flags & NetSegment.Flags.NameVisible2) == NetSegment.Flags.None)
            {
                __result = false;
                return(false);
            }
            Bounds bounds = __instance.m_bounds;

            bounds.Expand(16f);
            if (!bounds.IntersectRay(new Ray(ray.a, ray.b - ray.a)))
            {
                __result = false;
                return(false);
            }
            NetManager instance = Singleton <NetManager> .instance;
            Bezier3    bezier   = default(Bezier3);

            bezier.a = instance.m_nodes.m_buffer[__instance.m_startNode].m_position;
            bezier.d = instance.m_nodes.m_buffer[__instance.m_endNode].m_position;
            bool result = false;

            if (nameOnly)
            {
                RenderManager instance2 = Singleton <RenderManager> .instance;
                if (instance2.GetInstanceIndex((uint)(49152 + segmentID), out uint instanceIndex))
                {
                    InstanceManager.NameData nameData = instance2.m_instances[instanceIndex].m_nameData;
                    Vector3   position   = instance2.m_instances[instanceIndex].m_position;
                    Matrix4x4 dataMatrix = instance2.m_instances[instanceIndex].m_dataMatrix2;
                    float     num        = Vector3.Distance(position, ray.a);
                    if (nameData != null && num < 1000f)
                    {
                        float snapElevation2 = info.m_netAI.GetSnapElevation();
                        bezier.a.y += snapElevation2;
                        bezier.d.y += snapElevation2;
                        NetSegment.CalculateMiddlePoints(bezier.a, __instance.m_startDirection, bezier.d, __instance.m_endDirection, true, true, out bezier.b, out bezier.c);
                        float   num2   = Mathf.Max(1f, Mathf.Abs(dataMatrix.m33 - dataMatrix.m30));
                        float   d      = num * 0.0002f + 0.05f / (1f + num * 0.001f);
                        Vector2 vector = nameData.m_size * d;
                        float   t2     = Mathf.Max(0f, 0.5f - vector.x / num2 * 0.5f);
                        float   t3     = Mathf.Min(1f, 0.5f + vector.x / num2 * 0.5f);
                        bezier = bezier.Cut(t2, t3);
                        float num3 = bezier.DistanceSqr(ray, out float u, out float _);
                        if (num3 < vector.y * vector.y * 0.25f)
                        {
                            Vector3 b = bezier.Position(u);
                            if (Segment1.Intersect(ray.a.y, ray.b.y, b.y, out u))
                            {
                                num3 = Vector3.SqrMagnitude(ray.Position(u) - b);
                                if (num3 < vector.y * vector.y * 0.25f)
                                {
                                    t      = u;
                                    result = true;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                info.m_netAI.GetRayCastHeights(segmentID, ref __instance, out float leftMin, out float rightMin, out float max);
                bezier.a.y += max;
                bezier.d.y += max;
                bool flag  = (instance.m_nodes.m_buffer[__instance.m_startNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;
                bool flag2 = (instance.m_nodes.m_buffer[__instance.m_endNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;
                NetSegment.CalculateMiddlePoints(bezier.a, __instance.m_startDirection, bezier.d, __instance.m_endDirection, flag, flag2, out bezier.b, out bezier.c);
                // NON-STOCK CODE STARTS
                if (IsCSURSLane)
                {
                    float vehicleLaneNum = CSURUtil.CountCSURSVehicleLanes(info);
                    float otherLaneNum   = CSURUtil.CountCSURSOtherLanes(info);
                    float laneNum        = vehicleLaneNum + otherLaneNum;
                    startOffset = startOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;
                    endOffset   = endOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f;

                    if ((__instance.m_flags & NetSegment.Flags.Invert) != 0)
                    {
                        startOffset = -startOffset;
                        endOffset   = -endOffset;
                    }
                    //EG: before patch: point1-point4 is 1.5*3.75
                    //After patch, point1-point4 is (1 1.3333 1.6667 2)*3.75
                    Vector3 newBezierA    = bezier.a + (new Vector3(__instance.m_startDirection.z, 0, -__instance.m_startDirection.x).normalized) * (startOffset);
                    Vector3 newBezierBDir = VectorUtils.NormalizeXZ(bezier.Tangent(0.333f));
                    Vector3 newBezierB    = bezier.b + (new Vector3(newBezierBDir.z, 0, -newBezierBDir.x).normalized) * (startOffset * 0.667f + endOffset * 0.333f);
                    Vector3 newBezierCDir = VectorUtils.NormalizeXZ(bezier.Tangent(0.667f));
                    Vector3 newBezierC    = bezier.c + (new Vector3(newBezierCDir.z, 0, -newBezierCDir.x).normalized) * (startOffset * 0.333f + endOffset * 0.667f);
                    Vector3 newBezierD    = bezier.d + (new Vector3(-__instance.m_endDirection.z, 0, __instance.m_endDirection.x).normalized) * (endOffset);

                    bezier.a = newBezierA;
                    bezier.b = newBezierB;
                    bezier.c = newBezierC;
                    bezier.d = newBezierD;
                }
                float minNodeDistance    = info.GetMinNodeDistance();
                float collisionHalfWidth = info.m_netAI.GetCollisionHalfWidth();
                float num4 = (float)(int)instance.m_nodes.m_buffer[__instance.m_startNode].m_elevation;
                float num5 = (float)(int)instance.m_nodes.m_buffer[__instance.m_endNode].m_elevation;
                if (info.m_netAI.IsUnderground())
                {
                    num4 = 0f - num4;
                    num5 = 0f - num5;
                }
                num4 += info.m_netAI.GetSnapElevation();
                num5 += info.m_netAI.GetSnapElevation();
                float a    = Mathf.Lerp(minNodeDistance, collisionHalfWidth, Mathf.Clamp01(Mathf.Abs(snapElevation - num4) / 12f));
                float b2   = Mathf.Lerp(minNodeDistance, collisionHalfWidth, Mathf.Clamp01(Mathf.Abs(snapElevation - num5) / 12f));
                float num6 = Mathf.Min(leftMin, rightMin);
                t        = 1000000f;
                priority = 1000000f;
                Segment3 segment = default(Segment3);
                segment.a = bezier.a;
                for (int i = 1; i <= 16; i++)
                {
                    segment.b = bezier.Position((float)i / 16f);
                    float   num7    = ray.DistanceSqr(segment, out float u2, out float v2);
                    float   num8    = Mathf.Lerp(a, b2, ((float)(i - 1) + v2) / 16f);
                    Vector3 vector2 = segment.Position(v2);
                    if (num7 < priority && Segment1.Intersect(ray.a.y, ray.b.y, vector2.y, out u2))
                    {
                        Vector3 vector3 = ray.Position(u2);
                        num7 = Vector3.SqrMagnitude(vector3 - vector2);
                        if (num7 < priority && num7 < num8 * num8)
                        {
                            if (flag && i == 1 && v2 < 0.001f)
                            {
                                Vector3 rhs = segment.a - segment.b;
                                u2 += Mathf.Max(0f, Vector3.Dot(vector3, rhs)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs.sqrMagnitude * ray.LengthSqr()));
                            }
                            if (flag2 && i == 16 && v2 > 0.999f)
                            {
                                Vector3 rhs2 = segment.b - segment.a;
                                u2 += Mathf.Max(0f, Vector3.Dot(vector3, rhs2)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs2.sqrMagnitude * ray.LengthSqr()));
                            }
                            priority = num7;
                            t        = u2;
                            result   = true;
                        }
                    }
                    if (num6 < max)
                    {
                        float num9 = vector2.y + num6 - max;
                        if (Mathf.Max(ray.a.y, ray.b.y) > num9 && Mathf.Min(ray.a.y, ray.b.y) < vector2.y)
                        {
                            Segment2 segment2 = default(Segment2);
                            float    num10;
                            if (Segment1.Intersect(ray.a.y, ray.b.y, vector2.y, out u2))
                            {
                                segment2.a = VectorUtils.XZ(ray.Position(u2));
                                num10      = u2;
                            }
                            else
                            {
                                segment2.a = VectorUtils.XZ(ray.a);
                                num10      = 0f;
                            }
                            float num11;
                            if (Segment1.Intersect(ray.a.y, ray.b.y, num9, out u2))
                            {
                                segment2.b = VectorUtils.XZ(ray.Position(u2));
                                num11      = u2;
                            }
                            else
                            {
                                segment2.b = VectorUtils.XZ(ray.b);
                                num11      = 1f;
                            }
                            num7 = segment2.DistanceSqr(VectorUtils.XZ(vector2), out u2);
                            if (num7 < priority && num7 < num8 * num8)
                            {
                                u2 = num10 + (num11 - num10) * u2;
                                Vector3 lhs = ray.Position(u2);
                                if (flag && i == 1 && v2 < 0.001f)
                                {
                                    Vector3 rhs3 = segment.a - segment.b;
                                    u2 += Mathf.Max(0f, Vector3.Dot(lhs, rhs3)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs3.sqrMagnitude * ray.LengthSqr()));
                                }
                                if (flag2 && i == 16 && v2 > 0.999f)
                                {
                                    Vector3 rhs4 = segment.b - segment.a;
                                    u2 += Mathf.Max(0f, Vector3.Dot(lhs, rhs4)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs4.sqrMagnitude * ray.LengthSqr()));
                                }
                                priority = num7;
                                t        = u2;
                                result   = true;
                            }
                        }
                    }
                    segment.a = segment.b;
                }
                priority = Mathf.Max(0f, Mathf.Sqrt(priority) - collisionHalfWidth);
            }
            __result = result;
            return(false);
        }