static void Postfix(uint __state)
        {
            if (__state == 0)
            {
                return;
            }

            NetLane lane = Singleton <NetManager> .instance.m_lanes.m_buffer[__state];

            int index = Singleton <SharedStopsTool> .instance.sharedStopSegments.FindIndex(s => s.m_lanes.Keys.Contains(__state));

            if (index == -1)
            {
                return;
            }

            foreach (var line in Singleton <SharedStopsTool> .instance.sharedStopSegments[index].m_lanes[__state])
            {
                NetLane.Flags stopflag = Singleton <TransportManager> .instance.m_lines.m_buffer[line].Info.m_stopFlag;
                if (((NetLane.Flags)lane.m_flags & stopflag) == stopflag)
                {
                    continue;
                }

                lane.m_flags |= (ushort)stopflag;
            }
            Singleton <NetManager> .instance.m_lanes.m_buffer[__state].m_flags = lane.m_flags;
            Log.Debug($"lane flags after update: {(NetLane.Flags)Singleton<NetManager>.instance.m_lanes.m_buffer[__state].m_flags}");

            Singleton <NetManager> .instance.UpdateSegmentFlags(Singleton <NetManager> .instance.m_lanes.m_buffer[__state].m_segment);

            Singleton <NetManager> .instance.UpdateSegmentRenderer(Singleton <NetManager> .instance.m_lanes.m_buffer[__state].m_segment, true);
        }
        private static void AddLaneData(int i, Configuration configuration)
        {
            try {
                NetLane       lane  = Singleton <NetManager> .instance.m_lanes.m_buffer[i];
                NetLane.Flags flags = (NetLane.Flags)lane.m_flags;
                if ((flags & NetLane.Flags.LeftForwardRight) == NetLane.Flags.None)                 // only save lanes with explicit lane arrows
                {
                    return;
                }
                var laneSegmentId = lane.m_segment;
                if (laneSegmentId <= 0)
                {
                    return;
                }
                NetSegment segment = Singleton <NetManager> .instance.m_segments.m_buffer[laneSegmentId];
                if (segment.m_flags == NetSegment.Flags.None)
                {
                    return;
                }

                //if (TrafficPriority.PrioritySegments.ContainsKey(laneSegmentId)) {
                Log.Message($"Saving lane data for lane {i}, segment {laneSegmentId}");
                configuration.LaneFlags += $"{i}:{Singleton<NetManager>.instance.m_lanes.m_buffer[i].m_flags},";
                //}
            } catch (Exception e) {
                Log.Error($"Error saving NodeLaneData {e.Message}");
            }
        }
        static void CheckSpawnSignals(ushort segment_id)
        {
            NetManager instance3 = Singleton <NetManager> .instance;

            //activate signal at the end of the single track section
            NetSegment seg = instance3.m_segments.m_buffer[segment_id];

            if (Mod.allowSpawnSignals && !IsSingleTrack2WSegment(segment_id))
            {
                NetNode node1 = instance3.m_nodes.m_buffer[seg.m_startNode];
                NetNode node2 = instance3.m_nodes.m_buffer[seg.m_endNode];
                NetLane lane  = instance3.m_lanes.m_buffer[seg.m_lanes];

                if ((node1.m_flags & NetNode.Flags.Junction) != (NetNode.Flags) 0)
                {
                    seg.m_flags |= NetSegment.Flags.YieldStart;
                }
                if ((node2.m_flags & NetNode.Flags.Junction) != (NetNode.Flags) 0)
                {
                    seg.m_flags |= NetSegment.Flags.YieldEnd;
                }
                seg.UpdateLanes(segment_id, true);
                instance3.m_segments.m_buffer[segment_id] = seg;
            }
        }
Пример #4
0
        void SetLaneMarkers()
        {
            m_hoveredLaneMarkers.Clear();
            if (m_segments.Count == 0)
            {
                return;
            }

            NetSegment segment    = NetManager.instance.m_segments.m_buffer[m_segments.Values.First().m_segmentId];
            NetInfo    info       = segment.Info;
            int        laneCount  = info.m_lanes.Length;
            bool       bothWays   = info.m_hasBackwardVehicleLanes && info.m_hasForwardVehicleLanes;
            bool       isInverted = false;

            for (ushort i = 0; i < laneCount; i++)
            {
                m_hoveredLaneMarkers[i] = new FastList <SegmentLaneMarker>();
            }

            foreach (Segment seg in m_segments.Values)
            {
                segment = NetManager.instance.m_segments.m_buffer[seg.m_segmentId];
                uint laneId = segment.m_lanes;

                if (bothWays)
                {
                    isInverted = seg.m_targetNode == segment.m_startNode;
                    if ((segment.m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.Invert)
                    {
                        isInverted = !isInverted;
                    }
                }

                for (int j = 0; j < laneCount && laneId != 0; j++)
                {
                    NetLane lane = NetManager.instance.m_lanes.m_buffer[laneId];

                    if ((info.m_lanes[j].m_laneType & NetInfo.LaneType.Vehicle) == NetInfo.LaneType.Vehicle)
                    {
                        Bezier3 bezier = lane.m_bezier;
                        bezier.GetBounds().Expand(1f);

                        int index = j;
                        if (bothWays && isInverted)
                        {
                            index += (j % 2 == 0) ? 1 : -1;
                        }

                        m_hoveredLaneMarkers[index].Add(new SegmentLaneMarker()
                        {
                            m_bezier    = bezier,
                            m_lane      = laneId,
                            m_laneIndex = index
                        });
                    }

                    laneId = lane.m_nextLane;
                }
            }
        }
 bool IsLaneValid(ref NetLane lane)
 {
     if ((lane.m_flags & (uint)(NetLane.Flags.Created | NetLane.Flags.Deleted)) != (uint)NetLane.Flags.Created)
     {
         return(false);
     }
     return(IsSegmentValid(lane.m_segment));
 }
Пример #6
0
            public void UpdateArrows()
            {
                VerifyConnections();
                NetLane    lane    = NetManager.instance.m_lanes.m_buffer[m_laneId];
                NetSegment segment = NetManager.instance.m_segments.m_buffer[lane.m_segment];

                if ((m_nodeId == 0 && !FindNode(segment)) || NetManager.instance.m_nodes.m_buffer[m_nodeId].CountSegments() <= 2)
                {
                    return;
                }

                if (ConnectionCount() == 0)
                {
                    if ((lane.m_flags & TrafficManager_ImprovedAI.SerializableDataExtension.CONTROL_BIT) != TrafficManager_ImprovedAI.SerializableDataExtension.CONTROL_BIT)
                    {
                        SetDefaultArrows(lane.m_segment, ref NetManager.instance.m_segments.m_buffer[lane.m_segment]);
                    }
                    return;
                }

                NetLane.Flags flags = (NetLane.Flags)lane.m_flags;
                flags &= ~(NetLane.Flags.LeftForwardRight);

                Vector3 segDir = segment.GetDirection(m_nodeId);

                uint[] connections = GetConnectionsAsArray();
                foreach (uint connection in connections)
                {
                    ushort  seg = NetManager.instance.m_lanes.m_buffer[connection].m_segment;
                    Vector3 dir = NetManager.instance.m_segments.m_buffer[seg].GetDirection(m_nodeId);
                    if (Vector3.Angle(segDir, dir) > 150f)
                    {
                        flags |= NetLane.Flags.Forward;
                    }
                    else
                    {
                        if (Vector3.Dot(Vector3.Cross(segDir, -dir), Vector3.up) > 0f)
                        {
                            flags |= NetLane.Flags.Right;
                        }
                        else
                        {
                            flags |= NetLane.Flags.Left;
                        }
                    }
                }

                NetManager.instance.m_lanes.m_buffer[m_laneId].m_flags = (ushort)flags;
            }
Пример #7
0
        private static void UpdateLaneMarker(NetLane.Flags flag, NetInfo.Direction direction, NetSegment segment)
        {
            NetManager netManager  = NetManager.instance;
            NetLane    currentLane = netManager.m_lanes.m_buffer[segment.m_lanes];
            ulong      laneID      = segment.m_lanes;

            for (int i = 0; i < segment.Info.m_lanes.Length; i++)
            {
                if (segment.Info.m_lanes[i].m_direction == direction && segment.Info.m_lanes[i].m_laneType == NetInfo.LaneType.Vehicle && ((NetLane.Flags)currentLane.m_flags & flag) == flag)
                {
                    NetLane.Flags newFlags = (NetLane.Flags)currentLane.m_flags;
                    newFlags &= ~flag;
                    newFlags |= NetLane.Flags.Forward;
                    netManager.m_lanes.m_buffer[laneID].m_flags = (ushort)newFlags;
                }
                laneID      = currentLane.m_nextLane;
                currentLane = netManager.m_lanes.m_buffer[currentLane.m_nextLane];
            }
        }
Пример #8
0
 void VerifyConnections()
 {
     uint[] connections = GetConnectionsAsArray();
     while (!Monitor.TryEnter(this.m_laneConnections, SimulationManager.SYNCHRONIZE_TIMEOUT))
     {
     }
     try
     {
         foreach (uint laneId in connections)
         {
             NetLane lane = NetManager.instance.m_lanes.m_buffer[laneId];
             if ((lane.m_flags & CONTROL_BIT) != CONTROL_BIT)
             {
                 m_laneConnections.Remove(laneId);
             }
         }
     }
     finally
     {
         Monitor.Exit(this.m_laneConnections);
     }
 }
        /// <summary>Called from Debug Panel.</summary>
        internal static void PrintDebugInfo()
        {
            Log.Info("------------------------");
            Log.Info("--- LANE ARROW FLAGS ---");
            Log.Info("------------------------");
            for (uint i = 0; i < laneArrowFlags.Length; ++i)
            {
                ref NetLane netLane = ref i.ToLane();

                if (highwayLaneArrowFlags[i] != null || laneArrowFlags[i] != null)
                {
                    Log.Info($"Lane {i}: valid? {netLane.IsValidWithSegment()}");
                }

                if (highwayLaneArrowFlags[i] != null)
                {
                    Log.Info($"\thighway arrows: {highwayLaneArrowFlags[i]}");
                }

                if (laneArrowFlags[i] != null)
                {
                    Log.Info($"\tcustom arrows: {laneArrowFlags[i]}");
                }
            }
        private void LaneFlag(uint laneId, NetLane.Flags flag)
        {
            if (!TrafficPriority.IsPrioritySegment(SelectedNode, SelectedSegment))
            {
                TrafficPriority.AddPrioritySegment(SelectedNode, SelectedSegment,
                    PrioritySegment.PriorityType.None);
            }

            var flags = (NetLane.Flags)Singleton<NetManager>.instance.m_lanes.m_buffer[laneId].m_flags;

            if ((flags & flag) == flag)
            {
                Singleton<NetManager>.instance.m_lanes.m_buffer[laneId].m_flags = (ushort) (flags & ~flag);
            }
            else
            {
                Singleton<NetManager>.instance.m_lanes.m_buffer[laneId].m_flags = (ushort)(flags | flag);
            }
        }
 public void ProcessLane(uint laneId, ref NetLane lane, NetLaneHandler handler)
 {
     handler(laneId, ref lane);
 }
        private static List <NodeLaneMarker> GetNodeMarkers(ushort nodeId, ref NetNode node)
        {
            if (nodeId == 0)
            {
                return(null);
            }

            if ((node.m_flags & NetNode.Flags.Created) == NetNode.Flags.None)
            {
                return(null);
            }

            List <NodeLaneMarker> nodeMarkers = new List <NodeLaneMarker>();
            int nodeMarkerColorIndex          = 0;
            LaneConnectionManager connManager = LaneConnectionManager.Instance;

            int offsetMultiplier = node.CountSegments() <= 2 ? 3 : 1;

            for (int i = 0; i < 8; i++)
            {
                ushort segmentId = node.GetSegment(i);

                if (segmentId == 0)
                {
                    continue;
                }

                NetSegment[] segmentsBuffer = NetManager.instance.m_segments.m_buffer;
                bool         startNode      = segmentsBuffer[segmentId].m_startNode == nodeId;
                Vector3      offset         = segmentsBuffer[segmentId]
                                              .FindDirection(segmentId, nodeId) * offsetMultiplier;
                NetInfo.Lane[] lanes  = segmentsBuffer[segmentId].Info.m_lanes;
                uint           laneId = segmentsBuffer[segmentId].m_lanes;

                for (byte laneIndex = 0; (laneIndex < lanes.Length) && (laneId != 0); laneIndex++)
                {
                    NetInfo.Lane laneInfo = lanes[laneIndex];

                    if (((laneInfo.m_laneType & LaneConnectionManager.LANE_TYPES) != NetInfo.LaneType.None) &&
                        ((laneInfo.m_vehicleType & LaneConnectionManager.VEHICLE_TYPES)
                         != VehicleInfo.VehicleType.None))
                    {
                        if (connManager.GetLaneEndPoint(
                                segmentId,
                                startNode,
                                laneIndex,
                                laneId,
                                laneInfo,
                                out bool isSource,
                                out bool isTarget,
                                out Vector3? pos))
                        {
                            pos = pos.Value + offset;

                            float terrainY =
                                Singleton <TerrainManager> .instance.SampleDetailHeightSmooth(pos.Value);

                            var finalPos = new Vector3(pos.Value.x, terrainY, pos.Value.z);

                            Color32 nodeMarkerColor
                                = isSource
                                      ? COLOR_CHOICES[nodeMarkerColorIndex % COLOR_CHOICES.Length]
                                      : default; // or black (not used while rendering)

                            NetLane lane   = NetManager.instance.m_lanes.m_buffer[laneId];
                            Bezier3 bezier = lane.m_bezier;
                            if (startNode)
                            {
                                bezier.a = (Vector3)pos;
                            }
                            else
                            {
                                bezier.d = (Vector3)pos;
                            }
                            SegmentLaneMarker segmentLaneMarker = new SegmentLaneMarker {
                                renderBezier  = bezier,
                                raycastBezier = bezier,
                                laneID        = laneId,
                                laneIndex     = laneIndex,
                            };

                            nodeMarkers.Add(
                                new NodeLaneMarker {
                                SegmentId             = segmentId,
                                LaneId                = laneId,
                                NodeId                = nodeId,
                                StartNode             = startNode,
                                Position              = finalPos,
                                SecondaryPosition     = (Vector3)pos,
                                Color                 = nodeMarkerColor,
                                IsSource              = isSource,
                                IsTarget              = isTarget,
                                LaneType              = laneInfo.m_laneType,
                                VehicleType           = laneInfo.m_vehicleType,
                                InnerSimilarLaneIndex =
                                    ((byte)(laneInfo.m_direction & NetInfo.Direction.Forward) != 0)
                                            ? laneInfo.m_similarLaneIndex
                                            : laneInfo.m_similarLaneCount -
                                    laneInfo.m_similarLaneIndex - 1,
                                SegmentIndex      = i,
                                segmentLaneMarker = segmentLaneMarker,
                            });

                            if (isSource)
                            {
                                nodeMarkerColorIndex++;
                            }
                        }
                    }

                    laneId = NetManager.instance.m_lanes.m_buffer[laneId].m_nextLane;
                }
            }

            if (nodeMarkers.Count == 0)
            {
                return(null);
            }

            foreach (NodeLaneMarker laneMarker1 in nodeMarkers)
            {
                if (!laneMarker1.IsSource)
                {
                    continue;
                }

                uint[] connections =
                    LaneConnectionManager.Instance.GetLaneConnections(
                        laneMarker1.LaneId,
                        laneMarker1.StartNode);

                if ((connections == null) || (connections.Length == 0))
                {
                    continue;
                }

                foreach (NodeLaneMarker laneMarker2 in nodeMarkers)
                {
                    if (!laneMarker2.IsTarget)
                    {
                        continue;
                    }

                    if (connections.Contains(laneMarker2.LaneId))
                    {
                        laneMarker1.ConnectedMarkers.Add(laneMarker2);
                    }
                }
            }

            return(nodeMarkers);
        }
Пример #13
0
        public static bool RenderDestroyedInstancePrefix(NetLane __instance, RenderManager.CameraInfo cameraInfo, ushort segmentID, uint laneID, NetInfo netInfo, NetInfo.Lane laneInfo, NetNode.Flags startFlags, NetNode.Flags endFlags, Color startColor, Color endColor, float startAngle, float endAngle, bool invert, int layerMask, Vector4 objectIndex1, Vector4 objectIndex2, ref RenderManager.Instance data, ref int propIndex)
        {
            NetLaneProps laneProps = laneInfo.m_laneProps;

            if (laneProps != null && laneProps.m_props != null)
            {
                bool flag  = (laneInfo.m_finalDirection & NetInfo.Direction.Both) == NetInfo.Direction.Backward || (laneInfo.m_finalDirection & NetInfo.Direction.AvoidBoth) == NetInfo.Direction.AvoidForward;
                bool flag2 = flag != invert;
                if (flag)
                {
                    NetNode.Flags flags = startFlags;
                    startFlags = endFlags;
                    endFlags   = flags;
                }
                int num = laneProps.m_props.Length;
                for (int i = 0; i < num; i++)
                {
                    NetLaneProps.Prop prop = laneProps.m_props[i];
                    if (__instance.m_length < prop.m_minLength)
                    {
                        continue;
                    }
                    int num2 = 2;
                    if (prop.m_repeatDistance > 1f)
                    {
                        num2 *= Mathf.Max(1, Mathf.RoundToInt(__instance.m_length / prop.m_repeatDistance));
                    }
                    int num3 = propIndex;
                    if (propIndex != -1)
                    {
                        propIndex = num3 + (num2 + 1 >> 1);
                    }
                    if (!prop.CheckFlags((NetLane.Flags)__instance.m_flags, startFlags, endFlags))
                    {
                        continue;
                    }
                    float num4 = prop.m_segmentOffset * 0.5f;
                    if (__instance.m_length != 0f)
                    {
                        num4 = Mathf.Clamp(num4 + prop.m_position.z / __instance.m_length, -0.5f, 0.5f);
                    }
                    if (flag2)
                    {
                        num4 = 0f - num4;
                    }
                    PropInfo finalProp = prop.m_finalProp;
                    if (!(finalProp != null) || (layerMask & (1 << finalProp.m_prefabDataLayer)) == 0)
                    {
                        continue;
                    }
                    Color      color = (prop.m_colorMode != NetLaneProps.ColorMode.EndState) ? startColor : endColor;
                    Randomizer r     = new Randomizer((int)laneID + i);
                    for (int j = 1; j <= num2; j += 2)
                    {
                        if (r.Int32(100u) >= prop.m_probability)
                        {
                            continue;
                        }
                        float    num5      = num4 + (float)j / (float)num2;
                        PropInfo variation = finalProp.GetVariation(ref r);
                        float    scale     = variation.m_minScale + (float)r.Int32(10000u) * (variation.m_maxScale - variation.m_minScale) * 0.0001f;
                        if (prop.m_colorMode == NetLaneProps.ColorMode.Default)
                        {
                            color = variation.GetColor(ref r);
                        }
                        if (!variation.m_isDecal && !variation.m_surviveCollapse)
                        {
                            continue;
                        }
                        Vector3 vector = __instance.m_bezier.Position(num5);
                        if (propIndex != -1)
                        {
                            vector.y = (float)(int)data.m_extraData.GetUShort(num3++) * 0.015625f;
                        }
                        vector.y += prop.m_position.y;
                        if (!cameraInfo.CheckRenderDistance(vector, variation.m_maxRenderDistance))
                        {
                            continue;
                        }
                        Vector3 vector2 = __instance.m_bezier.Tangent(num5);
                        if (!(vector2 != Vector3.zero))
                        {
                            continue;
                        }
                        if (flag2)
                        {
                            vector2 = -vector2;
                        }
                        vector2.y = 0f;
                        if (prop.m_position.x != 0f)
                        {
                            vector2   = Vector3.Normalize(vector2);
                            vector.x += vector2.z * prop.m_position.x;
                            vector.z -= vector2.x * prop.m_position.x;
                        }
                        float num6 = Mathf.Atan2(vector2.x, 0f - vector2.z);
                        if (prop.m_cornerAngle != 0f || prop.m_position.x != 0f)
                        {
                            float num7 = endAngle - startAngle;
                            if (num7 > (float)Math.PI)
                            {
                                num7 -= (float)Math.PI * 2f;
                            }
                            if (num7 < -(float)Math.PI)
                            {
                                num7 += (float)Math.PI * 2f;
                            }
                            float num8 = startAngle + num7 * num5;
                            num7 = num8 - num6;
                            if (num7 > (float)Math.PI)
                            {
                                num7 -= (float)Math.PI * 2f;
                            }
                            if (num7 < -(float)Math.PI)
                            {
                                num7 += (float)Math.PI * 2f;
                            }
                            num6 += num7 * prop.m_cornerAngle;
                            if (num7 != 0f && prop.m_position.x != 0f)
                            {
                                float num9 = Mathf.Tan(num7);
                                vector.x += vector2.x * num9 * prop.m_position.x;
                                vector.z += vector2.z * num9 * prop.m_position.x;
                            }
                        }
                        Vector4 objectIndex3 = (!(num5 > 0.5f)) ? objectIndex1 : objectIndex2;
                        num6 += prop.m_angle * ((float)Math.PI / 180f);
                        InstanceID id = default(InstanceID);
                        id.NetSegment = segmentID;
#if UseTask
                        Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, variation, id, vector, scale, num6, color, objectIndex3, active: true));
#else
                        PropInstance.RenderInstance(cameraInfo, variation, id, vector, scale, num6, color, objectIndex3, active: true);
#endif
                    }
                }
            }
            if ((laneInfo.m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.Parking | NetInfo.LaneType.CargoVehicle | NetInfo.LaneType.TransportVehicle)) == 0 && ((laneInfo.m_laneType & NetInfo.LaneType.Pedestrian) == 0 || netInfo.m_vehicleTypes != 0))
            {
                return(false);
            }
            bool       flag3 = (laneInfo.m_vehicleType & ~VehicleInfo.VehicleType.Bicycle) == 0 || laneInfo.m_verticalOffset >= 0.5f;
            Randomizer r2    = new Randomizer(laneID);
            int        num10 = Mathf.RoundToInt(__instance.m_length * 0.07f);
            for (int k = 0; k < num10; k++)
            {
                PropInfo randomPropInfo = Singleton <PropManager> .instance.GetRandomPropInfo(ref r2, ItemClass.Service.Road);

                randomPropInfo = randomPropInfo.GetVariation(ref r2);
                float num11  = randomPropInfo.m_minScale + (float)r2.Int32(10000u) * (randomPropInfo.m_maxScale - randomPropInfo.m_minScale) * 0.0001f;
                Color color2 = randomPropInfo.GetColor(ref r2);
                float num12  = (float)r2.Int32(1000u) * 0.001f;
                float angle  = (float)r2.Int32(1000u) * 0.006283186f;
                if (!randomPropInfo.m_isDecal)
                {
                    if (flag3)
                    {
                        continue;
                    }
                    if (netInfo.m_netAI.IsOverground())
                    {
                        float num13 = netInfo.m_halfWidth - Mathf.Abs(laneInfo.m_position);
                        float num14 = Mathf.Max(randomPropInfo.m_generatedInfo.m_size.x, randomPropInfo.m_generatedInfo.m_size.z) * num11 * 0.5f - 0.5f;
                        if (num13 < num14)
                        {
                            continue;
                        }
                    }
                }
                Vector3    position     = __instance.m_bezier.Position(num12);
                Vector4    objectIndex4 = (!(num12 > 0.5f)) ? objectIndex1 : objectIndex2;
                InstanceID id2          = default(InstanceID);
                id2.NetSegment = segmentID;
                if (!randomPropInfo.m_requireHeightMap)
                {
#if UseTask
                    Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, randomPropInfo, id2, position, num11, angle, color2, objectIndex4, active: true));
#else
                    PropInstance.RenderInstance(cameraInfo, randomPropInfo, id2, position, num11, angle, color2, objectIndex4, active: true);
#endif
                }
            }

            return(false);
        }
Пример #14
0
        public static bool RenderInstancePrefix(NetLane __instance, RenderManager.CameraInfo cameraInfo, ushort segmentID, uint laneID, NetInfo.Lane laneInfo, NetNode.Flags startFlags, NetNode.Flags endFlags, Color startColor, Color endColor, float startAngle, float endAngle, bool invert, int layerMask, Vector4 objectIndex1, Vector4 objectIndex2, ref RenderManager.Instance data, ref int propIndex)
        {
            NetLaneProps laneProps = laneInfo.m_laneProps;

            if (!(laneProps != null) || laneProps.m_props == null)
            {
                return(false);
            }
            bool flag  = (laneInfo.m_finalDirection & NetInfo.Direction.Both) == NetInfo.Direction.Backward || (laneInfo.m_finalDirection & NetInfo.Direction.AvoidBoth) == NetInfo.Direction.AvoidForward;
            bool flag2 = flag != invert;

            if (flag)
            {
                NetNode.Flags flags = startFlags;
                startFlags = endFlags;
                endFlags   = flags;
            }
            Texture _HeightMap       = null;
            Vector4 _HeightMapping   = Vector4.zero;
            Vector4 _SurfaceMapping  = Vector4.zero;
            Texture _HeightMap2      = null;
            Vector4 _HeightMapping2  = Vector4.zero;
            Vector4 _SurfaceMapping2 = Vector4.zero;
            int     num = laneProps.m_props.Length;

            for (int i = 0; i < num; i++)
            {
                NetLaneProps.Prop prop = laneProps.m_props[i];
                if (__instance.m_length < prop.m_minLength)
                {
                    continue;
                }
                int num2 = 2;
                if (prop.m_repeatDistance > 1f)
                {
                    num2 *= Mathf.Max(1, Mathf.RoundToInt(__instance.m_length / prop.m_repeatDistance));
                }
                int num3 = propIndex;
                if (propIndex != -1)
                {
                    propIndex = num3 + (num2 + 1 >> 1);
                }
                if (!prop.CheckFlags((NetLane.Flags)__instance.m_flags, startFlags, endFlags))
                {
                    continue;
                }
                float num4 = prop.m_segmentOffset * 0.5f;
                if (__instance.m_length != 0f)
                {
                    num4 = Mathf.Clamp(num4 + prop.m_position.z / __instance.m_length, -0.5f, 0.5f);
                }
                if (flag2)
                {
                    num4 = 0f - num4;
                }
                PropInfo finalProp = prop.m_finalProp;
                if (finalProp != null && (layerMask & (1 << finalProp.m_prefabDataLayer)) != 0)
                {
                    Color      color = (prop.m_colorMode != NetLaneProps.ColorMode.EndState) ? startColor : endColor;
                    Randomizer r     = new Randomizer((int)laneID + i);
                    for (int j = 1; j <= num2; j += 2)
                    {
                        if (r.Int32(100u) >= prop.m_probability)
                        {
                            continue;
                        }
                        float    num5      = num4 + (float)j / (float)num2;
                        PropInfo variation = finalProp.GetVariation(ref r);
                        float    scale     = variation.m_minScale + (float)r.Int32(10000u) * (variation.m_maxScale - variation.m_minScale) * 0.0001f;
                        if (prop.m_colorMode == NetLaneProps.ColorMode.Default)
                        {
                            color = variation.GetColor(ref r);
                        }
                        Vector3 vector = __instance.m_bezier.Position(num5);
                        if (propIndex != -1)
                        {
                            vector.y = (float)(int)data.m_extraData.GetUShort(num3++) * 0.015625f;
                        }
                        vector.y += prop.m_position.y;
                        if (!cameraInfo.CheckRenderDistance(vector, variation.m_maxRenderDistance))
                        {
                            continue;
                        }
                        Vector3 vector2 = __instance.m_bezier.Tangent(num5);
                        if (!(vector2 != Vector3.zero))
                        {
                            continue;
                        }
                        if (flag2)
                        {
                            vector2 = -vector2;
                        }
                        vector2.y = 0f;
                        if (prop.m_position.x != 0f)
                        {
                            vector2   = Vector3.Normalize(vector2);
                            vector.x += vector2.z * prop.m_position.x;
                            vector.z -= vector2.x * prop.m_position.x;
                        }
                        float num6 = Mathf.Atan2(vector2.x, 0f - vector2.z);
                        if (prop.m_cornerAngle != 0f || prop.m_position.x != 0f)
                        {
                            float num7 = endAngle - startAngle;
                            if (num7 > (float)Math.PI)
                            {
                                num7 -= (float)Math.PI * 2f;
                            }
                            if (num7 < -(float)Math.PI)
                            {
                                num7 += (float)Math.PI * 2f;
                            }
                            float num8 = startAngle + num7 * num5;
                            num7 = num8 - num6;
                            if (num7 > (float)Math.PI)
                            {
                                num7 -= (float)Math.PI * 2f;
                            }
                            if (num7 < -(float)Math.PI)
                            {
                                num7 += (float)Math.PI * 2f;
                            }
                            num6 += num7 * prop.m_cornerAngle;
                            if (num7 != 0f && prop.m_position.x != 0f)
                            {
                                float num9 = Mathf.Tan(num7);
                                vector.x += vector2.x * num9 * prop.m_position.x;
                                vector.z += vector2.z * num9 * prop.m_position.x;
                            }
                        }
                        Vector4 objectIndex3 = (!(num5 > 0.5f)) ? objectIndex1 : objectIndex2;
                        num6 += prop.m_angle * ((float)Math.PI / 180f);
                        InstanceID id = default(InstanceID);
                        id.NetSegment = segmentID;
                        if (variation.m_requireWaterMap)
                        {
                            if (_HeightMap == null)
                            {
                                Singleton <TerrainManager> .instance.GetHeightMapping(Singleton <NetManager> .instance.m_segments.m_buffer[segmentID].m_middlePosition, out _HeightMap, out _HeightMapping, out _SurfaceMapping);
                            }
                            if (_HeightMap2 == null)
                            {
                                Singleton <TerrainManager> .instance.GetWaterMapping(Singleton <NetManager> .instance.m_segments.m_buffer[segmentID].m_middlePosition, out _HeightMap2, out _HeightMapping2, out _SurfaceMapping2);
                            }
#if UseTask
                            Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, variation, id, vector, scale, num6, color, objectIndex3, active: true, _HeightMap, _HeightMapping, _SurfaceMapping, _HeightMap2, _HeightMapping2, _SurfaceMapping2));
#else
                            PropInstance.RenderInstance(cameraInfo, variation, id, vector, scale, num6, color, objectIndex3, active: true, _HeightMap, _HeightMapping, _SurfaceMapping, _HeightMap2, _HeightMapping2, _SurfaceMapping2);
#endif
                        }
                        else if (!variation.m_requireHeightMap)
                        {
#if UseTask
                            Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, variation, id, vector, scale, num6, color, objectIndex3, active: true));
#else
                            PropInstance.RenderInstance(cameraInfo, variation, id, vector, scale, num6, color, objectIndex3, active: true);
#endif
                        }
                    }
                }
                TreeInfo finalTree = prop.m_finalTree;
                if (!(finalTree != null) || (layerMask & (1 << finalTree.m_prefabDataLayer)) == 0)
                {
                    continue;
                }
                Randomizer r2 = new Randomizer((int)laneID + i);
                for (int k = 1; k <= num2; k += 2)
                {
                    if (r2.Int32(100u) >= prop.m_probability)
                    {
                        continue;
                    }
                    float    t          = num4 + (float)k / (float)num2;
                    TreeInfo variation2 = finalTree.GetVariation(ref r2);
                    float    scale2     = variation2.m_minScale + (float)r2.Int32(10000u) * (variation2.m_maxScale - variation2.m_minScale) * 0.0001f;
                    float    brightness = variation2.m_minBrightness + (float)r2.Int32(10000u) * (variation2.m_maxBrightness - variation2.m_minBrightness) * 0.0001f;
                    Vector3  position   = __instance.m_bezier.Position(t);
                    if (propIndex != -1)
                    {
                        position.y = (float)(int)data.m_extraData.GetUShort(num3++) * 0.015625f;
                    }
                    position.y += prop.m_position.y;
                    if (prop.m_position.x != 0f)
                    {
                        Vector3 vector3 = __instance.m_bezier.Tangent(t);
                        if (flag2)
                        {
                            vector3 = -vector3;
                        }
                        vector3.y   = 0f;
                        vector3     = Vector3.Normalize(vector3);
                        position.x += vector3.z * prop.m_position.x;
                        position.z -= vector3.x * prop.m_position.x;
                    }
#if UseTask
                    Patcher.Dispatcher.Add(() => TreeInstance.RenderInstance(cameraInfo, variation2, position, scale2, brightness, RenderManager.DefaultColorLocation));
#else
                    TreeInstance.RenderInstance(cameraInfo, variation2, position, scale2, brightness, RenderManager.DefaultColorLocation);
#endif
                }
            }
            return(false);
        }
        public void laneFlag(uint laneID, NetLane.Flags flag)
        {
            if (!TrafficPriority.isPrioritySegment(_selectedNetNodeIdx, _selectedSegmentIdx))
            {
                TrafficPriority.addPrioritySegment(_selectedNetNodeIdx, _selectedSegmentIdx,
                    PrioritySegment.PriorityType.None);
            }

            var flags = (NetLane.Flags)Singleton<NetManager>.instance.m_lanes.m_buffer[laneID].m_flags;

            if ((flags & flag) == flag)
            {
                Singleton<NetManager>.instance.m_lanes.m_buffer[laneID].m_flags = (ushort) (flags & ~flag);
            }
            else
            {
                Singleton<NetManager>.instance.m_lanes.m_buffer[laneID].m_flags = (ushort)(flags | flag);
            }
            Singleton<NetManager>.instance.m_lanes.m_buffer[laneID].m_flags |= SerializableDataExtension.CONTROL_BIT;
            //Singleton<NetManager>.instance.m_lanes.m_buffer[laneID].m_flags = (ushort) (Singleton<NetManager>.instance.m_lanes.m_buffer[laneID].m_flags & ~CSL_Traffic.RoadManager.Lane.CONTROL_BIT);

            CSL_Traffic.RoadManager.ClearLaneConnections(laneID);

            /*
            NetLane lane = Singleton<NetManager>.instance.m_lanes.m_buffer [laneID];
            ushort segmentId = lane.m_segment;
            NetSegment segment = Singleton<NetManager>.instance.m_segments.m_buffer [segmentId];
            segment.Info.m_netAI.UpdateLanes(segmentId, ref segment, false);
            */
        }
        public void laneFlag(uint laneID, NetLane.Flags flag)
        {
            if (!TrafficPriority.isPrioritySegment(_selectedNetNodeIdx, _selectedSegmentIdx))
            {
                TrafficPriority.addPrioritySegment(_selectedNetNodeIdx, _selectedSegmentIdx,
                    PrioritySegment.PriorityType.None);
            }

            var flags = (NetLane.Flags)Singleton<NetManager>.instance.m_lanes.m_buffer[laneID].m_flags;

            if ((flags & flag) == flag)
            {
                Singleton<NetManager>.instance.m_lanes.m_buffer[laneID].m_flags = (ushort) (flags & ~flag);
            }
            else
            {
                Singleton<NetManager>.instance.m_lanes.m_buffer[laneID].m_flags = (ushort)(flags | flag);
            }
        }