/// <summary>
        /// Resets lane arrows to their default value for the given segment end.
        /// </summary>
        /// <param name="segmentId">segment to reset</param>
        /// <param name="startNode">determines the segment end to reset. if <c>null</c>
        /// both ends are reset</param>
        public void ResetLaneArrows(ushort segmentId, bool?startNode = null)
        {
            ExtSegmentManager extSegmentManager = ExtSegmentManager.Instance;

            foreach (var lane in extSegmentManager.GetSortedLanes(
                         segmentId,
                         ref segmentId.ToSegment(),
                         startNode,
                         LANE_TYPES,
                         VEHICLE_TYPES))
            {
                ResetLaneArrows(lane.laneId);
            }
        }
示例#2
0
        public void MarkAllAsUpdated()
        {
            ExtSegmentManager extSegmentManager = ExtSegmentManager.Instance;

            for (uint segmentId = 0; segmentId < NetManager.MAX_SEGMENT_COUNT; ++segmentId)
            {
                ref NetSegment netSegment = ref ((ushort)segmentId).ToSegment();

                if (!netSegment.IsValid())
                {
                    continue;
                }

                MarkAsUpdated(
                    ref Constants.ManagerFactory.ExtSegmentManager.ExtSegments[segmentId],
                    true);
            }
        public override void OnBeforeLoadData()
        {
            base.OnBeforeLoadData();

            ExtSegmentManager extSegmentManager = ExtSegmentManager.Instance;

            // JunctionRestrictionsManager requires our data during loading of custom data
            for (uint i = 0; i < NetManager.MAX_SEGMENT_COUNT; ++i)
            {
                ref NetSegment netSegment = ref ((ushort)i).ToSegment();

                if (!netSegment.IsValid())
                {
                    continue;
                }

                HandleValidSegment(ref Constants.ManagerFactory.ExtSegmentManager.ExtSegments[i]);
            }
示例#4
0
 static ExtSegmentManager()
 {
     Instance = new ExtSegmentManager();
 }
        public bool FindPathPositionWithSpiralLoop(Vector3 position,
                                                   Vector3?secondaryPosition,
                                                   ItemClass.Service service,
                                                   NetInfo.LaneType laneType,
                                                   VehicleInfo.VehicleType vehicleType,
                                                   NetInfo.LaneType otherLaneType,
                                                   VehicleInfo.VehicleType otherVehicleType,
                                                   VehicleInfo.VehicleType stopType,
                                                   bool allowUnderground,
                                                   bool requireConnect,
                                                   float maxDistance,
                                                   out PathUnit.Position pathPosA,
                                                   out PathUnit.Position pathPosB,
                                                   out float distanceSqrA,
                                                   out float distanceSqrB)
        {
            int iMin = Mathf.Max(
                (int)(((position.z - NetManager.NODEGRID_CELL_SIZE) / NetManager.NODEGRID_CELL_SIZE) +
                      (NetManager.NODEGRID_RESOLUTION / 2f)),
                0);
            int iMax = Mathf.Min(
                (int)(((position.z + NetManager.NODEGRID_CELL_SIZE) / NetManager.NODEGRID_CELL_SIZE) +
                      (NetManager.NODEGRID_RESOLUTION / 2f)),
                NetManager.NODEGRID_RESOLUTION - 1);

            int jMin = Mathf.Max(
                (int)(((position.x - NetManager.NODEGRID_CELL_SIZE) / NetManager.NODEGRID_CELL_SIZE) +
                      (NetManager.NODEGRID_RESOLUTION / 2f)),
                0);
            int jMax = Mathf.Min(
                (int)(((position.x + NetManager.NODEGRID_CELL_SIZE) / NetManager.NODEGRID_CELL_SIZE) +
                      (NetManager.NODEGRID_RESOLUTION / 2f)),
                NetManager.NODEGRID_RESOLUTION - 1);

            int width  = iMax - iMin + 1;
            int height = jMax - jMin + 1;

            int centerI = (int)(position.z / NetManager.NODEGRID_CELL_SIZE +
                                NetManager.NODEGRID_RESOLUTION / 2f);
            int centerJ = (int)(position.x / NetManager.NODEGRID_CELL_SIZE +
                                NetManager.NODEGRID_RESOLUTION / 2f);

            int radius = Math.Max(1, (int)(maxDistance / (BuildingManager.BUILDINGGRID_CELL_SIZE / 2f)) + 1);

            NetManager netManager = Singleton <NetManager> .instance;

            /*pathPosA.m_segment = 0;
             * pathPosA.m_lane = 0;
             * pathPosA.m_offset = 0;*/
            distanceSqrA = 1E+10f;

            /*pathPosB.m_segment = 0;
             * pathPosB.m_lane = 0;
             * pathPosB.m_offset = 0;*/
            distanceSqrB = 1E+10f;
            float minDist = float.MaxValue;

            PathUnit.Position myPathPosA     = default;
            float             myDistanceSqrA = float.MaxValue;

            PathUnit.Position myPathPosB     = default;
            float             myDistanceSqrB = float.MaxValue;

            int  lastSpiralDist = 0;
            bool found          = false;

            bool FindHelper(int i, int j)
            {
                if (i < 0 || i >= NetManager.NODEGRID_RESOLUTION ||
                    j < 0 || j >= NetManager.NODEGRID_RESOLUTION)
                {
                    return(true);
                }

                int spiralDist = Math.Max(Math.Abs(i - centerI), Math.Abs(j - centerJ)); // maximum norm

                if (found && spiralDist > lastSpiralDist)
                {
                    // last iteration
                    return(false);
                }

                ushort segmentId  = netManager.m_segmentGrid[i * NetManager.NODEGRID_RESOLUTION + j];
                int    iterations = 0;

                ExtSegmentManager extSegmentManager = ExtSegmentManager.Instance;

                while (segmentId != 0)
                {
                    ref NetSegment netSegment  = ref segmentId.ToSegment();
                    NetInfo        segmentInfo = netSegment.Info;

                    if (segmentInfo != null && segmentInfo.m_class.m_service == service &&
                        (netSegment.m_flags & (NetSegment.Flags.Collapsed | NetSegment.Flags.Flooded)) == NetSegment.Flags.None &&
                        (allowUnderground || !segmentInfo.m_netAI.IsUnderground()))
                    {
                        bool otherPassed = true;
                        if (otherLaneType != NetInfo.LaneType.None ||
                            otherVehicleType != VehicleInfo.VehicleType.None)
                        {
                            // check if any lane is present that matches the given conditions
                            otherPassed = false;

                            foreach (LaneIdAndIndex laneIdAndIndex in extSegmentManager.GetSegmentLaneIdsAndLaneIndexes(segmentId))
                            {
                                NetInfo.Lane laneInfo = segmentInfo.m_lanes[laneIdAndIndex.laneIndex];
                                if ((otherLaneType == NetInfo.LaneType.None ||
                                     (laneInfo.m_laneType & otherLaneType) !=
                                     NetInfo.LaneType.None) &&
                                    (otherVehicleType ==
                                     VehicleInfo.VehicleType.None ||
                                     (laneInfo.m_vehicleType & otherVehicleType) !=
                                     VehicleInfo.VehicleType.None))
                                {
                                    otherPassed = true;
                                    break;
                                }
                            }
                        }

                        if (otherPassed)
                        {
                            if (netSegment.GetClosestLanePosition(
                                    position,
                                    laneType,
                                    vehicleType,
                                    stopType,
                                    requireConnect,
                                    out Vector3 posA,
                                    out int laneIndexA,
                                    out float laneOffsetA,
                                    out Vector3 posB,
                                    out int laneIndexB,
                                    out float laneOffsetB))
                            {
                                float dist = Vector3.SqrMagnitude(position - posA);
                                if (secondaryPosition != null)
                                {
                                    dist += Vector3.SqrMagnitude((Vector3)secondaryPosition - posA);
                                }

                                if (dist < minDist)
                                {
                                    found = true;

                                    minDist = dist;
                                    myPathPosA.m_segment = segmentId;
                                    myPathPosA.m_lane    = (byte)laneIndexA;
                                    myPathPosA.m_offset  = (byte)Mathf.Clamp(
                                        Mathf.RoundToInt(laneOffsetA * 255f),
                                        0,
                                        255);
                                    myDistanceSqrA = dist;

                                    dist = Vector3.SqrMagnitude(position - posB);
                                    if (secondaryPosition != null)
                                    {
                                        dist += Vector3.SqrMagnitude(
                                            (Vector3)secondaryPosition - posB);
                                    }

                                    if (laneIndexB < 0)
                                    {
                                        myPathPosB.m_segment = 0;
                                        myPathPosB.m_lane    = 0;
                                        myPathPosB.m_offset  = 0;
                                        myDistanceSqrB       = float.MaxValue;
                                    }
                                    else
                                    {
                                        myPathPosB.m_segment = segmentId;
                                        myPathPosB.m_lane    = (byte)laneIndexB;
                                        myPathPosB.m_offset  = (byte)Mathf.Clamp(
                                            Mathf.RoundToInt(laneOffsetB * 255f),
                                            0,
                                            255);
                                        myDistanceSqrB = dist;
                                    }
                                }
                            } // if GetClosestLanePosition
                        }     // if othersPassed
                    }         // if

                    segmentId = netSegment.m_nextGridSegment;
                    if (++iterations >= NetManager.MAX_SEGMENT_COUNT)
                    {
                        CODebugBase <LogChannel> .Error(
                            LogChannel.Core,
                            "Invalid list detected!\n" + Environment.StackTrace);

                        break;
                    }
                }

                lastSpiralDist = spiralDist;
                return(true);
            }