Esempio n. 1
0
        private static bool RayCastNode(ref NetNode node, Segment3 ray, float snapElevation, out float t, out float priority)
        {
            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_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);
                if (num3 < num2)
                {
                    priority = Mathf.Max(0f, num3 - collisionHalfWidth);
                    return(true);
                }
            }
            t        = 0f;
            priority = 0f;
            return(false);
        }
        public static bool IsTrafficHandSideOf(Segment3 segment, Segment3 ray, float tRay, bool invert)
        {
            Vector3 segmentVector = segment.b - segment.a;
            Vector3 rayVector     = ray.Position(tRay) - segment.a;
            // Debug.Log($"startnode->endnode: {segmentVector}, startnode->ray: {rayVector}");
            float crossProduct = rayVector.x * segmentVector.z - segmentVector.x * rayVector.z;

            // Debug.Log($"cross product: {crossProduct}");
            return(invert ? crossProduct < 0 : crossProduct > 0);
        }
        private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref CitizenInstance otherData, ref Vector3 pushAmount, ref float pushDivider)
        {
            if (otherID == instanceID)
            {
                return(otherData.m_nextGridInstance);
            }
            if (((citizenData.m_flags | otherData.m_flags) & CitizenInstance.Flags.Transition) == CitizenInstance.Flags.None && (citizenData.m_flags & CitizenInstance.Flags.Underground) != (citizenData.m_flags & CitizenInstance.Flags.Underground))
            {
                return(otherData.m_nextGridInstance);
            }
            CitizenInfo info = otherData.Info;

            CitizenInstance.Frame lastFrameData = otherData.GetLastFrameData();
            Vector3  position = lastFrameData.m_position;
            Vector3  b        = lastFrameData.m_position + lastFrameData.m_velocity;
            Segment3 segment2 = new Segment3(position, b);
            Vector3  vector   = segment2.Min();

            vector.x -= info.m_radius;
            vector.z -= info.m_radius;
            Vector3 vector2 = segment2.Max();

            vector2.x += info.m_radius;
            vector2.y += info.m_height;
            vector2.z += info.m_radius;
            if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y)
            {
                float num = this.m_info.m_radius + info.m_radius;
                float num3;
                float t;
                float num2 = segment.DistanceSqr(segment2, out num3, out t);
                if (num2 < num * num)
                {
                    float   num4 = num - Mathf.Sqrt(num2);
                    float   num5 = 1f - num2 / (num * num);
                    Vector3 a    = segment.Position(num3 * 0.9f);
                    Vector3 b2   = segment2.Position(t);
                    a.y  = 0f;
                    b2.y = 0f;
                    Vector3 vector3 = a - b2;
                    Vector3 vector4 = new Vector3(segment.b.z - segment.a.z, 0f, segment.a.x - segment.b.x);
                    if (Vector3.Dot(vector3, vector4) >= 0f)
                    {
                        vector3 += vector4;
                    }
                    else
                    {
                        vector3 -= vector4;
                    }
                    pushAmount  += vector3.normalized * (num4 * num5);
                    pushDivider += num5;
                }
            }
            return(otherData.m_nextGridInstance);
        }
        private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref VehicleParked otherData, ref Vector3 pushAmount, ref float pushDivider)
        {
            VehicleInfo info     = otherData.Info;
            Vector3     position = otherData.m_position;
            Vector3     b        = otherData.m_rotation * new Vector3(0f, 0f, Mathf.Max(0.5f, info.m_generatedInfo.m_size.z * 0.5f - 1f));
            Segment3    segment2;

            segment2.a = position - b;
            segment2.b = position + b;
            Vector3 vector = segment2.Min();

            vector.x -= 1f;
            vector.z -= 1f;
            Vector3 vector2 = segment2.Max();

            vector2.x += 1f;
            vector2.y += 1f;
            vector2.z += 1f;
            if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y)
            {
                float num = this.m_info.m_radius + 1f;
                float num3;
                float t;
                float num2 = segment.DistanceSqr(segment2, out num3, out t);
                if (num2 < num * num)
                {
                    float   num4 = num - Mathf.Sqrt(num2);
                    float   num5 = 1f - num2 / (num * num);
                    Vector3 a    = segment.Position(num3 * 0.9f);
                    Vector3 b2   = segment2.Position(t);
                    a.y  = 0f;
                    b2.y = 0f;
                    Vector3 vector3 = Vector3.Normalize(a - b2);
                    Vector3 rhs     = Vector3.Normalize(new Vector3(segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z));
                    Vector3 vector4 = new Vector3(rhs.z, 0f, -rhs.x) * Mathf.Abs(Vector3.Dot(vector3, rhs) * 0.5f);
                    if (Vector3.Dot(vector3, vector4) >= 0f)
                    {
                        vector3 += vector4;
                    }
                    else
                    {
                        vector3 -= vector4;
                    }
                    pushAmount  += vector3 * (num4 * num5);
                    pushDivider += num5;
                }
            }
            return(otherData.m_nextGridParked);
        }
        //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
            if (CSUROffset.IsCSUROffset(info.m_netAI.m_info))
            {
                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);
                if (num3 < num2)
                {
                    priority = Mathf.Max(0f, num3 - collisionHalfWidth);
                    return(true);
                }
            }
            //}
            t        = 0f;
            priority = 0f;
            return(false);
        }
        public static bool NetSegmentRayCastMasked(NetSegment mysegment, ushort segmentID, 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;
            //Debug.Log(mysegment.m_flags);
            if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0)
            {
                lht = true;
            }
            bool    isMasked = false;
            NetInfo info     = mysegment.Info;

            t        = 0f;
            priority = 0f;
            Bounds bounds = mysegment.m_bounds;

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

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

            info.m_netAI.GetRayCastHeights(segmentID, ref mysegment, out float leftMin, out float rightMin, out float max);
            bezier.a.y += max;
            bezier.d.y += max;
            bool flag  = (instance.m_nodes.m_buffer[mysegment.m_startNode].m_flags & NetNode.Flags.Middle) != 0;
            bool flag2 = (instance.m_nodes.m_buffer[mysegment.m_endNode].m_flags & NetNode.Flags.Middle) != 0;

            NetSegment.CalculateMiddlePoints(bezier.a, mysegment.m_startDirection, bezier.d, mysegment.m_endDirection, flag, flag2, out bezier.b, out bezier.c);
            float minNodeDistance = info.GetMinNodeDistance();
            //
            float collisionHalfWidth = info.m_halfWidth;
            float maskHalfWidth      = info.m_pavementWidth;
            //
            float num4 = (int)instance.m_nodes.m_buffer[mysegment.m_startNode].m_elevation;
            float num5 = (int)instance.m_nodes.m_buffer[mysegment.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 am   = Mathf.Lerp(minNodeDistance, maskHalfWidth, Mathf.Clamp01(Mathf.Abs(snapElevation - num4) / 12f));
            float b2m  = Mathf.Lerp(minNodeDistance, maskHalfWidth, 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;
            Segment2 segment2 = default(Segment2);

            //Debug.Log($"mouse ray: {ray.a} --> {ray.b}");
            //Debug.Log($"segment direction: {bezier.a} --> {bezier.b}");
            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);
                float   num8m        = Mathf.Lerp(am, b2m, ((float)(i - 1) + v2) / 16f);
                Vector3 vector2      = segment.Position(v2);
                bool    atOffsetSide = bothSides || IsTrafficHandSideOf(segment, ray, u2, lht);
                if (atOffsetSide && num7 < priority && Segment1.Intersect(ray.a.y, ray.b.y, vector2.y, out u2))
                {
                    Vector3 vector3 = ray.Position(u2);
                    num7 = Vector3.SqrMagnitude(vector3 - vector2);
                    //Debug.Log($"num7: {num7}, num8: {num8}, num8m: {num8m}");
                    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 (num7 < num8m * num8m)
                        {
                            isMasked = true;
                        }
                    }
                }
                if (atOffsetSide && 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)
                    {
                        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;
                            if (num7 < num8m * num8m)
                            {
                                isMasked = true;
                            }
                        }
                    }
                }
                segment.a = segment.b;
            }
            priority = Mathf.Max(0f, Mathf.Sqrt(priority) - collisionHalfWidth);

            if (isMasked)
            {
                result = false;
            }
            return(result);
        }
        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);
        }
		private static bool RayCast(TreeManager tm, Segment3 ray, ItemClass.Service service, ItemClass.SubService subService, ItemClass.Layer itemLayers, TreeInstance.Flags ignoreFlags, out Vector3 hit, out uint treeIndex)
		{
			unsafe
			{
				int num;
				int num1;
				int num2;
				int num3;
				int num4;
				int num5;
				float single;
				float single1;
				Bounds bound = new Bounds(new Vector3(0f, 512f, 0f), new Vector3(17280f, 1152f, 17280f));
				if (ray.Clip(bound))
				{
					Vector3 vector3 = ray.b - ray.a;
					int num6 = (int)((double)ray.a.x / 32 + 270);
					int num7 = (int)((double)ray.a.z / 32 + 270);
					int num8 = (int)((double)ray.b.x / 32 + 270);
					int num9 = (int)((double)ray.b.z / 32 + 270);
					float single2 = Mathf.Abs(vector3.x);
					float single3 = Mathf.Abs(vector3.z);
					if ((double)single2 < (double)single3)
					{
						num = 0;
						num1 = ((double)vector3.z <= 0 ? -1 : 1);
						if ((double)single3 != 0)
						{
							vector3 = vector3 * (32f / single3);
						}
					}
					else
					{
						num = ((double)vector3.x <= 0 ? -1 : 1);
						num1 = 0;
						if ((double)single2 != 0)
						{
							vector3 = vector3 * (32f / single2);
						}
					}
					float single4 = 2f;
					float single5 = 10000f;
					treeIndex = 0;
					Vector3 vector31 = ray.a;
					Vector3 vector32 = ray.a;
					int num10 = num6;
					int num11 = num7;
					do
					{
						Vector3 vector33 = vector32 + vector3;
						if (num == 0)
						{
							num4 = ((num11 != num7 || num1 <= 0) && (num11 != num9 || num1 >= 0) ? Mathf.Max(num11, 0) : Mathf.Max((int)(((double)vector33.z - 72) / 32 + 270), 0));
							num5 = ((num11 != num7 || num1 >= 0) && (num11 != num9 || num1 <= 0) ? Mathf.Min(num11, 539) : Mathf.Min((int)(((double)vector33.z + 72) / 32 + 270), 539));
							num2 = Mathf.Max((int)(((double)Mathf.Min(vector31.x, vector33.x) - 72) / 32 + 270), 0);
							num3 = Mathf.Min((int)(((double)Mathf.Max(vector31.x, vector33.x) + 72) / 32 + 270), 539);
						}
						else
						{
							num2 = ((num10 != num6 || num <= 0) && (num10 != num8 || num >= 0) ? Mathf.Max(num10, 0) : Mathf.Max((int)(((double)vector33.x - 72) / 32 + 270), 0));
							num3 = ((num10 != num6 || num >= 0) && (num10 != num8 || num <= 0) ? Mathf.Min(num10, 539) : Mathf.Min((int)(((double)vector33.x + 72) / 32 + 270), 539));
							num4 = Mathf.Max((int)(((double)Mathf.Min(vector31.z, vector33.z) - 72) / 32 + 270), 0);
							num5 = Mathf.Min((int)(((double)Mathf.Max(vector31.z, vector33.z) + 72) / 32 + 270), 539);
						}
						for (int i = num4; i <= num5; i++)
						{
							for (int j = num2; j <= num3; j++)
							{
								uint mTreeGrid = tm.m_treeGrid[i * 540 + j];
								int num12 = 0;
								while (mTreeGrid != 0)
								{
									if ((tm.m_trees.m_buffer[mTreeGrid].m_flags & (ushort)ignoreFlags) == (ushort)TreeInstance.Flags.None && (double)ray.DistanceSqr(tm.m_trees.m_buffer[mTreeGrid].Position) < 2500)
									{
										TreeInfo info = tm.m_trees.m_buffer[mTreeGrid].Info;
										if ((service == ItemClass.Service.None || info.m_class.m_service == service) && (subService == ItemClass.SubService.None || info.m_class.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (info.m_class.m_layer & itemLayers) != ItemClass.Layer.None) && tm.m_trees.m_buffer[mTreeGrid].RayCast(mTreeGrid, ray, out single, out single1) && ((double)single < (double)single4 - 9.99999974737875E-05 || (double)single < (double)single4 + 9.99999974737875E-05 && (double)single1 < (double)single5))
										{
											single4 = single;
											single5 = single1;
											treeIndex = mTreeGrid;
										}
									}
									mTreeGrid = tm.m_trees.m_buffer[mTreeGrid].m_nextGridTree;
									int num13 = num12 + 1;
									num12 = num13;
									if (num13 <= LimitTreeManager.Helper.TreeLimit)
									{
										continue;
									}
									CODebugBase<LogChannel>.Error(LogChannel.Core, string.Concat("Invalid list detected!\n", Environment.StackTrace));
									break;
								}
							}
						}
						vector31 = vector32;
						vector32 = vector33;
						num10 = num10 + num;
						num11 = num11 + num1;
					}
					while ((num10 <= num8 || num <= 0) && (num10 >= num8 || num >= 0) && (num11 <= num9 || num1 <= 0) && (num11 >= num9 || num1 >= 0));
					if ((double)single4 != 2)
					{
						hit = ray.Position(single4);
						return true;
					}
				}
				hit = Vector3.zero;
				treeIndex = 0;
				return false;
			}
		}
        protected void CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Vector3 sourcePos, Vector3 targetPos, ushort buildingID, ref Vector3 pushAmount, ref float pushDivider)
        {
            Segment3 segment = new Segment3(sourcePos, targetPos);
            Vector3  min     = segment.Min();

            min.x -= this.m_info.m_radius;
            min.z -= this.m_info.m_radius;
            Vector3 max = segment.Max();

            max.x += this.m_info.m_radius;
            max.y += this.m_info.m_height;
            max.z += this.m_info.m_radius;
            CitizenManager instance = Singleton <CitizenManager> .instance;
            int            num      = Mathf.Max((int)((min.x - 3f) / 8f + 1080f), 0);
            int            num2     = Mathf.Max((int)((min.z - 3f) / 8f + 1080f), 0);
            int            num3     = Mathf.Min((int)((max.x + 3f) / 8f + 1080f), 2159);
            int            num4     = Mathf.Min((int)((max.z + 3f) / 8f + 1080f), 2159);

            for (int i = num2; i <= num4; i++)
            {
                for (int j = num; j <= num3; j++)
                {
                    ushort num5 = instance.m_citizenGrid [i * 2160 + j];
                    int    num6 = 0;
                    while (num5 != 0)
                    {
                        num5 = this.CheckCollisions(instanceID, ref citizenData, segment, min, max, num5, ref instance.m_instances.m_buffer [(int)num5], ref pushAmount, ref pushDivider);
                        if (++num6 > 65536)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
            VehicleManager instance2 = Singleton <VehicleManager> .instance;
            int            num7      = Mathf.Max((int)((min.x - 10f) / 32f + 270f), 0);
            int            num8      = Mathf.Max((int)((min.z - 10f) / 32f + 270f), 0);
            int            num9      = Mathf.Min((int)((max.x + 10f) / 32f + 270f), 539);
            int            num10     = Mathf.Min((int)((max.z + 10f) / 32f + 270f), 539);

            for (int k = num8; k <= num10; k++)
            {
                for (int l = num7; l <= num9; l++)
                {
                    ushort num11 = instance2.m_vehicleGrid [k * 540 + l];
                    int    num12 = 0;
                    while (num11 != 0)
                    {
                        num11 = this.CheckCollisions(instanceID, ref citizenData, segment, min, max, num11, ref instance2.m_vehicles.m_buffer [(int)num11], ref pushAmount, ref pushDivider);
                        if (++num12 > 65536)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
            for (int m = num8; m <= num10; m++)
            {
                for (int n = num7; n <= num9; n++)
                {
                    ushort num13 = instance2.m_parkedGrid [m * 540 + n];
                    int    num14 = 0;
                    while (num13 != 0)
                    {
                        num13 = this.CheckCollisions(instanceID, ref citizenData, segment, min, max, num13, ref instance2.m_parkedVehicles.m_buffer [(int)num13], ref pushAmount, ref pushDivider);
                        if (++num14 > 65536)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
            if (buildingID != 0)
            {
                BuildingManager instance3 = Singleton <BuildingManager> .instance;
                BuildingInfo    info      = instance3.m_buildings.m_buffer [(int)buildingID].Info;
                if (info.m_props != null)
                {
                    Vector3   position = instance3.m_buildings.m_buffer [(int)buildingID].m_position;
                    float     angle    = instance3.m_buildings.m_buffer [(int)buildingID].m_angle;
                    int       length   = instance3.m_buildings.m_buffer [(int)buildingID].Length;
                    Matrix4x4 matrix4x = default(Matrix4x4);
                    matrix4x.SetTRS(Building.CalculateMeshPosition(info, position, angle, length), Quaternion.AngleAxis(angle * 57.29578f, Vector3.down), Vector3.one);
                    for (int num15 = 0; num15 < info.m_props.Length; num15++)
                    {
                        BuildingInfo.Prop prop       = info.m_props [num15];
                        Randomizer        randomizer = new Randomizer((int)buildingID << 6 | prop.m_index);
                        if (randomizer.Int32(100u) < prop.m_probability && length >= prop.m_requiredLength)
                        {
                            Vector3 vector = matrix4x.MultiplyPoint(prop.m_position);
                            if (vector.x >= min.x - 2f && vector.x <= max.x + 2f)
                            {
                                if (vector.z >= min.z - 2f && vector.z <= max.z + 2f)
                                {
                                    PropInfo propInfo = prop.m_finalProp;
                                    TreeInfo treeInfo = prop.m_finalTree;
                                    float    num16    = 0f;
                                    float    num17    = 0f;
                                    if (propInfo != null)
                                    {
                                        propInfo = propInfo.GetVariation(ref randomizer);
                                        if (propInfo.m_isMarker || propInfo.m_isDecal || !propInfo.m_hasRenderer)
                                        {
                                            goto IL_7D3;
                                        }
                                        num16 = propInfo.m_generatedInfo.m_size.x * 0.5f;
                                        num17 = propInfo.m_generatedInfo.m_size.y;
                                    }
                                    else
                                    {
                                        if (treeInfo != null)
                                        {
                                            treeInfo = treeInfo.GetVariation(ref randomizer);
                                            num16    = (treeInfo.m_generatedInfo.m_size.x + treeInfo.m_generatedInfo.m_size.z) * 0.125f;
                                            num17    = treeInfo.m_generatedInfo.m_size.y;
                                        }
                                    }
                                    if (!prop.m_fixedHeight)
                                    {
                                        vector.y = Singleton <TerrainManager> .instance.SampleDetailHeight(vector);
                                    }
                                    else
                                    {
                                        if (info.m_requireHeightMap)
                                        {
                                            vector.y = Singleton <TerrainManager> .instance.SampleDetailHeight(vector) + prop.m_position.y;
                                        }
                                    }
                                    if (vector.y + num17 >= min.y && vector.y <= max.y)
                                    {
                                        num16 = this.m_info.m_radius + num16;
                                        float num19;
                                        float num18 = segment.DistanceSqr(vector, out num19);
                                        if (num18 < num16 * num16)
                                        {
                                            float   num20 = num16 - Mathf.Sqrt(num18);
                                            float   num21 = 1f - num18 / (num16 * num16);
                                            Vector3 a     = segment.Position(num19 * 0.9f);
                                            a.y      = 0f;
                                            vector.y = 0f;
                                            Vector3 vector2 = Vector3.Normalize(a - vector);
                                            Vector3 rhs     = Vector3.Normalize(new Vector3(segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z));
                                            Vector3 vector3 = new Vector3(rhs.z, 0f, -rhs.x) * Mathf.Abs(Vector3.Dot(vector2, rhs) * 0.5f);
                                            if (Vector3.Dot(vector2, vector3) >= 0f)
                                            {
                                                vector2 += vector3;
                                            }
                                            else
                                            {
                                                vector2 -= vector3;
                                            }
                                            pushAmount  += vector2 * (num20 * num21);
                                            pushDivider += num21;
                                        }
                                    }
                                }
                            }
                        }
IL_7D3:
                        ;
                    }
                }
            }
        }
 protected void CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Vector3 sourcePos, Vector3 targetPos, ushort buildingID, ref Vector3 pushAmount, ref float pushDivider)
 {
     Segment3 segment = new Segment3 (sourcePos, targetPos);
     Vector3 min = segment.Min ();
     min.x -= this.m_info.m_radius;
     min.z -= this.m_info.m_radius;
     Vector3 max = segment.Max ();
     max.x += this.m_info.m_radius;
     max.y += this.m_info.m_height;
     max.z += this.m_info.m_radius;
     CitizenManager instance = Singleton<CitizenManager>.instance;
     int num = Mathf.Max ((int)((min.x - 3f) / 8f + 1080f), 0);
     int num2 = Mathf.Max ((int)((min.z - 3f) / 8f + 1080f), 0);
     int num3 = Mathf.Min ((int)((max.x + 3f) / 8f + 1080f), 2159);
     int num4 = Mathf.Min ((int)((max.z + 3f) / 8f + 1080f), 2159);
     for (int i = num2; i <= num4; i++) {
         for (int j = num; j <= num3; j++) {
             ushort num5 = instance.m_citizenGrid [i * 2160 + j];
             int num6 = 0;
             while (num5 != 0) {
                 num5 = this.CheckCollisions (instanceID, ref citizenData, segment, min, max, num5, ref instance.m_instances.m_buffer [(int)num5], ref pushAmount, ref pushDivider);
                 if (++num6 > 65536) {
                     CODebugBase<LogChannel>.Error (LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);
                     break;
                 }
             }
         }
     }
     VehicleManager instance2 = Singleton<VehicleManager>.instance;
     int num7 = Mathf.Max ((int)((min.x - 10f) / 32f + 270f), 0);
     int num8 = Mathf.Max ((int)((min.z - 10f) / 32f + 270f), 0);
     int num9 = Mathf.Min ((int)((max.x + 10f) / 32f + 270f), 539);
     int num10 = Mathf.Min ((int)((max.z + 10f) / 32f + 270f), 539);
     for (int k = num8; k <= num10; k++) {
         for (int l = num7; l <= num9; l++) {
             ushort num11 = instance2.m_vehicleGrid [k * 540 + l];
             int num12 = 0;
             while (num11 != 0) {
                 num11 = this.CheckCollisions (instanceID, ref citizenData, segment, min, max, num11, ref instance2.m_vehicles.m_buffer [(int)num11], ref pushAmount, ref pushDivider);
                 if (++num12 > 65536) {
                     CODebugBase<LogChannel>.Error (LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);
                     break;
                 }
             }
         }
     }
     for (int m = num8; m <= num10; m++) {
         for (int n = num7; n <= num9; n++) {
             ushort num13 = instance2.m_parkedGrid [m * 540 + n];
             int num14 = 0;
             while (num13 != 0) {
                 num13 = this.CheckCollisions (instanceID, ref citizenData, segment, min, max, num13, ref instance2.m_parkedVehicles.m_buffer [(int)num13], ref pushAmount, ref pushDivider);
                 if (++num14 > 65536) {
                     CODebugBase<LogChannel>.Error (LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);
                     break;
                 }
             }
         }
     }
     if (buildingID != 0) {
         BuildingManager instance3 = Singleton<BuildingManager>.instance;
         BuildingInfo info = instance3.m_buildings.m_buffer [(int)buildingID].Info;
         if (info.m_props != null) {
             Vector3 position = instance3.m_buildings.m_buffer [(int)buildingID].m_position;
             float angle = instance3.m_buildings.m_buffer [(int)buildingID].m_angle;
             int length = instance3.m_buildings.m_buffer [(int)buildingID].Length;
             Matrix4x4 matrix4x = default(Matrix4x4);
             matrix4x.SetTRS (Building.CalculateMeshPosition (info, position, angle, length), Quaternion.AngleAxis (angle * 57.29578f, Vector3.down), Vector3.one);
             for (int num15 = 0; num15 < info.m_props.Length; num15++) {
                 BuildingInfo.Prop prop = info.m_props [num15];
                 Randomizer randomizer = new Randomizer ((int)buildingID << 6 | prop.m_index);
                 if (randomizer.Int32 (100u) < prop.m_probability && length >= prop.m_requiredLength) {
                     Vector3 vector = matrix4x.MultiplyPoint (prop.m_position);
                     if (vector.x >= min.x - 2f && vector.x <= max.x + 2f) {
                         if (vector.z >= min.z - 2f && vector.z <= max.z + 2f) {
                             PropInfo propInfo = prop.m_finalProp;
                             TreeInfo treeInfo = prop.m_finalTree;
                             float num16 = 0f;
                             float num17 = 0f;
                             if (propInfo != null) {
                                 propInfo = propInfo.GetVariation (ref randomizer);
                                 if (propInfo.m_isMarker || propInfo.m_isDecal || !propInfo.m_hasRenderer) {
                                     goto IL_7D3;
                                 }
                                 num16 = propInfo.m_generatedInfo.m_size.x * 0.5f;
                                 num17 = propInfo.m_generatedInfo.m_size.y;
                             } else {
                                 if (treeInfo != null) {
                                     treeInfo = treeInfo.GetVariation (ref randomizer);
                                     num16 = (treeInfo.m_generatedInfo.m_size.x + treeInfo.m_generatedInfo.m_size.z) * 0.125f;
                                     num17 = treeInfo.m_generatedInfo.m_size.y;
                                 }
                             }
                             if (!prop.m_fixedHeight) {
                                 vector.y = Singleton<TerrainManager>.instance.SampleDetailHeight (vector);
                             } else {
                                 if (info.m_requireHeightMap) {
                                     vector.y = Singleton<TerrainManager>.instance.SampleDetailHeight (vector) + prop.m_position.y;
                                 }
                             }
                             if (vector.y + num17 >= min.y && vector.y <= max.y) {
                                 num16 = this.m_info.m_radius + num16;
                                 float num19;
                                 float num18 = segment.DistanceSqr (vector, out num19);
                                 if (num18 < num16 * num16) {
                                     float num20 = num16 - Mathf.Sqrt (num18);
                                     float num21 = 1f - num18 / (num16 * num16);
                                     Vector3 a = segment.Position (num19 * 0.9f);
                                     a.y = 0f;
                                     vector.y = 0f;
                                     Vector3 vector2 = Vector3.Normalize (a - vector);
                                     Vector3 rhs = Vector3.Normalize (new Vector3 (segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z));
                                     Vector3 vector3 = new Vector3 (rhs.z, 0f, -rhs.x) * Mathf.Abs (Vector3.Dot (vector2, rhs) * 0.5f);
                                     if (Vector3.Dot (vector2, vector3) >= 0f) {
                                         vector2 += vector3;
                                     } else {
                                         vector2 -= vector3;
                                     }
                                     pushAmount += vector2 * (num20 * num21);
                                     pushDivider += num21;
                                 }
                             }
                         }
                     }
                 }
                 IL_7D3:
                 ;
             }
         }
     }
 }
 private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref Vehicle otherData, ref Vector3 pushAmount, ref float pushDivider)
 {
     VehicleInfo info = otherData.Info;
     if (info.m_vehicleType == VehicleInfo.VehicleType.Bicycle)
     {
         return otherData.m_nextGridVehicle;
     }
     if ((otherData.m_flags & Vehicle.Flags.Transition) == Vehicle.Flags.None && (citizenData.m_flags & CitizenInstance.Flags.Transition) == CitizenInstance.Flags.None && (otherData.m_flags & Vehicle.Flags.Underground) != Vehicle.Flags.None != ((citizenData.m_flags & CitizenInstance.Flags.Underground) != CitizenInstance.Flags.None))
     {
         return otherData.m_nextGridVehicle;
     }
     Segment3 segment2 = otherData.m_segment;
     Vector3 vector = Vector3.Min (segment2.Min (), otherData.m_targetPos1);
     vector.x -= 1f;
     vector.z -= 1f;
     Vector3 vector2 = Vector3.Max (segment2.Max (), otherData.m_targetPos1);
     vector2.x += 1f;
     vector2.y += 1f;
     vector2.z += 1f;
     if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y)
     {
         float num = this.m_info.m_radius + 1f;
         float num3;
         float t;
         float num2 = segment.DistanceSqr (segment2, out num3, out t);
         if (num2 < num * num)
         {
             float num4 = num - Mathf.Sqrt (num2);
             float num5 = 1f - num2 / (num * num);
             Vector3 a = segment.Position (num3 * 0.9f);
             Vector3 b = segment2.Position (t);
             a.y = 0f;
             b.y = 0f;
             Vector3 vector3 = Vector3.Normalize (a - b);
             Vector3 rhs = Vector3.Normalize (new Vector3 (segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z));
             Vector3 vector4 = new Vector3 (rhs.z, 0f, -rhs.x) * Mathf.Abs (Vector3.Dot (vector3, rhs) * 0.5f);
             if (Vector3.Dot (vector3, vector4) >= 0f)
             {
                 vector3 += vector4;
             }
             else
             {
                 vector3 -= vector4;
             }
             pushAmount += vector3 * (num4 * num5);
             pushDivider += num5;
         }
         float magnitude = otherData.GetLastFrameVelocity ().magnitude;
         if (magnitude > 0.1f)
         {
             float num6 = this.m_info.m_radius + 3f;
             segment2.a = segment2.b;
             segment2.b += Vector3.ClampMagnitude (((Vector3)otherData.m_targetPos1) - segment2.b, magnitude * 4f);
             num2 = segment.DistanceSqr (segment2, out num3, out t);
             if (num2 > num * num && num2 < num6 * num6)
             {
                 float num7 = num6 - Mathf.Sqrt (num2);
                 float num8 = 1f - num2 / (num6 * num6);
                 Vector3 a2 = segment.Position (num3 * 0.9f);
                 Vector3 b2 = segment2.Position (t);
                 a2.y = 0f;
                 b2.y = 0f;
                 Vector3 vector5 = a2 - b2;
                 pushAmount += vector5.normalized * (num7 * num8);
                 pushDivider += num8;
             }
         }
     }
     return otherData.m_nextGridVehicle;
 }
        public static bool RayCast(ref NetSegment mysegment, ushort segmentID, Segment3 ray, float snapElevation, bool nameOnly, out float t, out float priority)
        {
            if (CSUROffset.IsCSUROffset(mysegment.Info.m_netAI.m_info))
            {
                return(NetSegmentRayCastMasked(mysegment, segmentID, ray, -1000f, false, out t, out priority));
            }
            NetInfo info = mysegment.Info;

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

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

            bezier.a = instance.m_nodes.m_buffer[mysegment.m_startNode].m_position;
            bezier.d = instance.m_nodes.m_buffer[mysegment.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, mysegment.m_startDirection, bezier.d, mysegment.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 mysegment, out float leftMin, out float rightMin, out float max);
                bezier.a.y += max;
                bezier.d.y += max;
                bool flag  = (instance.m_nodes.m_buffer[mysegment.m_startNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;
                bool flag2 = (instance.m_nodes.m_buffer[mysegment.m_endNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;
                NetSegment.CalculateMiddlePoints(bezier.a, mysegment.m_startDirection, bezier.d, mysegment.m_endDirection, flag, flag2, out bezier.b, out bezier.c);
                float minNodeDistance    = info.GetMinNodeDistance();
                float collisionHalfWidth = info.m_netAI.GetCollisionHalfWidth();
                float num4 = (float)(int)instance.m_nodes.m_buffer[mysegment.m_startNode].m_elevation;
                float num5 = (float)(int)instance.m_nodes.m_buffer[mysegment.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);
            }
            return(result);
        }
        private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref Vehicle otherData, ref Vector3 pushAmount, ref float pushDivider)
        {
            VehicleInfo info = otherData.Info;

            if (info.m_vehicleType == VehicleInfo.VehicleType.Bicycle)
            {
                return(otherData.m_nextGridVehicle);
            }
            if ((otherData.m_flags & Vehicle.Flags.Transition) == Vehicle.Flags.None && (citizenData.m_flags & CitizenInstance.Flags.Transition) == CitizenInstance.Flags.None && (otherData.m_flags & Vehicle.Flags.Underground) != Vehicle.Flags.None != ((citizenData.m_flags & CitizenInstance.Flags.Underground) != CitizenInstance.Flags.None))
            {
                return(otherData.m_nextGridVehicle);
            }
            Segment3 segment2 = otherData.m_segment;
            Vector3  vector   = Vector3.Min(segment2.Min(), otherData.m_targetPos1);

            vector.x -= 1f;
            vector.z -= 1f;
            Vector3 vector2 = Vector3.Max(segment2.Max(), otherData.m_targetPos1);

            vector2.x += 1f;
            vector2.y += 1f;
            vector2.z += 1f;
            if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y)
            {
                float num = this.m_info.m_radius + 1f;
                float num3;
                float t;
                float num2 = segment.DistanceSqr(segment2, out num3, out t);
                if (num2 < num * num)
                {
                    float   num4 = num - Mathf.Sqrt(num2);
                    float   num5 = 1f - num2 / (num * num);
                    Vector3 a    = segment.Position(num3 * 0.9f);
                    Vector3 b    = segment2.Position(t);
                    a.y = 0f;
                    b.y = 0f;
                    Vector3 vector3 = Vector3.Normalize(a - b);
                    Vector3 rhs     = Vector3.Normalize(new Vector3(segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z));
                    Vector3 vector4 = new Vector3(rhs.z, 0f, -rhs.x) * Mathf.Abs(Vector3.Dot(vector3, rhs) * 0.5f);
                    if (Vector3.Dot(vector3, vector4) >= 0f)
                    {
                        vector3 += vector4;
                    }
                    else
                    {
                        vector3 -= vector4;
                    }
                    pushAmount  += vector3 * (num4 * num5);
                    pushDivider += num5;
                }
                float magnitude = otherData.GetLastFrameVelocity().magnitude;
                if (magnitude > 0.1f)
                {
                    float num6 = this.m_info.m_radius + 3f;
                    segment2.a  = segment2.b;
                    segment2.b += Vector3.ClampMagnitude(((Vector3)otherData.m_targetPos1) - segment2.b, magnitude * 4f);
                    num2        = segment.DistanceSqr(segment2, out num3, out t);
                    if (num2 > num * num && num2 < num6 * num6)
                    {
                        float   num7 = num6 - Mathf.Sqrt(num2);
                        float   num8 = 1f - num2 / (num6 * num6);
                        Vector3 a2   = segment.Position(num3 * 0.9f);
                        Vector3 b2   = segment2.Position(t);
                        a2.y = 0f;
                        b2.y = 0f;
                        Vector3 vector5 = a2 - b2;
                        pushAmount  += vector5.normalized * (num7 * num8);
                        pushDivider += num8;
                    }
                }
            }
            return(otherData.m_nextGridVehicle);
        }
Esempio n. 14
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);
        }
 private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref CitizenInstance otherData, ref Vector3 pushAmount, ref float pushDivider)
 {
     if (otherID == instanceID)
     {
         return otherData.m_nextGridInstance;
     }
     if (((citizenData.m_flags | otherData.m_flags) & CitizenInstance.Flags.Transition) == CitizenInstance.Flags.None && (citizenData.m_flags & CitizenInstance.Flags.Underground) != (citizenData.m_flags & CitizenInstance.Flags.Underground))
     {
         return otherData.m_nextGridInstance;
     }
     CitizenInfo info = otherData.Info;
     CitizenInstance.Frame lastFrameData = otherData.GetLastFrameData ();
     Vector3 position = lastFrameData.m_position;
     Vector3 b = lastFrameData.m_position + lastFrameData.m_velocity;
     Segment3 segment2 = new Segment3 (position, b);
     Vector3 vector = segment2.Min ();
     vector.x -= info.m_radius;
     vector.z -= info.m_radius;
     Vector3 vector2 = segment2.Max ();
     vector2.x += info.m_radius;
     vector2.y += info.m_height;
     vector2.z += info.m_radius;
     if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y)
     {
         float num = this.m_info.m_radius + info.m_radius;
         float num3;
         float t;
         float num2 = segment.DistanceSqr (segment2, out num3, out t);
         if (num2 < num * num)
         {
             float num4 = num - Mathf.Sqrt (num2);
             float num5 = 1f - num2 / (num * num);
             Vector3 a = segment.Position (num3 * 0.9f);
             Vector3 b2 = segment2.Position (t);
             a.y = 0f;
             b2.y = 0f;
             Vector3 vector3 = a - b2;
             Vector3 vector4 = new Vector3 (segment.b.z - segment.a.z, 0f, segment.a.x - segment.b.x);
             if (Vector3.Dot (vector3, vector4) >= 0f)
             {
                 vector3 += vector4;
             }
             else
             {
                 vector3 -= vector4;
             }
             pushAmount += vector3.normalized * (num4 * num5);
             pushDivider += num5;
         }
     }
     return otherData.m_nextGridInstance;
 }
Esempio n. 16
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);
        }
 private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref VehicleParked otherData, ref Vector3 pushAmount, ref float pushDivider)
 {
     VehicleInfo info = otherData.Info;
     Vector3 position = otherData.m_position;
     Vector3 b = otherData.m_rotation * new Vector3 (0f, 0f, Mathf.Max (0.5f, info.m_generatedInfo.m_size.z * 0.5f - 1f));
     Segment3 segment2;
     segment2.a = position - b;
     segment2.b = position + b;
     Vector3 vector = segment2.Min ();
     vector.x -= 1f;
     vector.z -= 1f;
     Vector3 vector2 = segment2.Max ();
     vector2.x += 1f;
     vector2.y += 1f;
     vector2.z += 1f;
     if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y)
     {
         float num = this.m_info.m_radius + 1f;
         float num3;
         float t;
         float num2 = segment.DistanceSqr (segment2, out num3, out t);
         if (num2 < num * num)
         {
             float num4 = num - Mathf.Sqrt (num2);
             float num5 = 1f - num2 / (num * num);
             Vector3 a = segment.Position (num3 * 0.9f);
             Vector3 b2 = segment2.Position (t);
             a.y = 0f;
             b2.y = 0f;
             Vector3 vector3 = Vector3.Normalize (a - b2);
             Vector3 rhs = Vector3.Normalize (new Vector3 (segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z));
             Vector3 vector4 = new Vector3 (rhs.z, 0f, -rhs.x) * Mathf.Abs (Vector3.Dot (vector3, rhs) * 0.5f);
             if (Vector3.Dot (vector3, vector4) >= 0f)
             {
                 vector3 += vector4;
             }
             else
             {
                 vector3 -= vector4;
             }
             pushAmount += vector3 * (num4 * num5);
             pushDivider += num5;
         }
     }
     return otherData.m_nextGridParked;
 }
        private bool RayCastSegmentAndNode(NetInfo connectedType, Segment3 ray, float snapElevation, bool nameOnly, ItemClass.Service service, ItemClass.Service service2, ItemClass.SubService subService, ItemClass.SubService subService2, ItemClass.Layer itemLayers, ItemClass.Layer itemLayers2, NetNode.Flags ignoreNodeFlags, NetSegment.Flags ignoreSegmentFlags, out Vector3 hit, out ushort nodeIndex, out ushort segmentIndex)
        {
            var bounds = new Bounds(new Vector3(0f, 512f, 0f), new Vector3(17280f, 1152f, 17280f));

            if (ray.Clip(bounds))
            {
                Vector3 vector = ray.b - ray.a;
                var     num    = (int)((ray.a.x / 64f) + 135f);
                var     num2   = (int)((ray.a.z / 64f) + 135f);
                var     num3   = (int)((ray.b.x / 64f) + 135f);
                var     num4   = (int)((ray.b.z / 64f) + 135f);
                var     num5   = Mathf.Abs(vector.x);
                var     num6   = Mathf.Abs(vector.z);
                int     num7;
                int     num8;
                if (num5 >= num6)
                {
                    num7 = ((vector.x <= 0f) ? -1 : 1);
                    num8 = 0;
                    if (num5 > 0.001f)
                    {
                        vector *= 64f / num5;
                    }
                }
                else
                {
                    num7 = 0;
                    num8 = ((vector.z <= 0f) ? -1 : 1);
                    if (num6 > 0.001f)
                    {
                        vector *= 64f / num6;
                    }
                }
                var     num9    = 2f;
                var     num10   = 16f;
                var     num11   = 2f;
                var     num12   = 16f;
                ushort  num13   = 0;
                ushort  num14   = 0;
                ushort  num15   = 0;
                Vector3 vector2 = ray.a;
                Vector3 vector3 = ray.a;
                var     num16   = num;
                var     num17   = num2;
                do
                {
                    Vector3 vector4 = vector3 + vector;
                    int     num18;
                    int     num19;
                    int     num20;
                    int     num21;
                    if (num7 != 0)
                    {
                        if ((num16 == num && num7 > 0) || (num16 == num3 && num7 < 0))
                        {
                            num18 = Mathf.Max((int)(((vector4.x - 64f) / 64f) + 135f), 0);
                        }
                        else
                        {
                            num18 = Mathf.Max(num16, 0);
                        }
                        if ((num16 == num && num7 < 0) || (num16 == num3 && num7 > 0))
                        {
                            num19 = Mathf.Min((int)(((vector4.x + 64f) / 64f) + 135f), 269);
                        }
                        else
                        {
                            num19 = Mathf.Min(num16, 269);
                        }
                        num20 = Mathf.Max((int)(((Mathf.Min(vector2.z, vector4.z) - 64f) / 64f) + 135f), 0);
                        num21 = Mathf.Min((int)(((Mathf.Max(vector2.z, vector4.z) + 64f) / 64f) + 135f), 269);
                    }
                    else
                    {
                        if ((num17 == num2 && num8 > 0) || (num17 == num4 && num8 < 0))
                        {
                            num20 = Mathf.Max((int)(((vector4.z - 64f) / 64f) + 135f), 0);
                        }
                        else
                        {
                            num20 = Mathf.Max(num17, 0);
                        }
                        if ((num17 == num2 && num8 < 0) || (num17 == num4 && num8 > 0))
                        {
                            num21 = Mathf.Min((int)(((vector4.z + 64f) / 64f) + 135f), 269);
                        }
                        else
                        {
                            num21 = Mathf.Min(num17, 269);
                        }
                        num18 = Mathf.Max((int)(((Mathf.Min(vector2.x, vector4.x) - 64f) / 64f) + 135f), 0);
                        num19 = Mathf.Min((int)(((Mathf.Max(vector2.x, vector4.x) + 64f) / 64f) + 135f), 269);
                    }
                    for (var i = num20; i <= num21; i++)
                    {
                        for (var j = num18; j <= num19; j++)
                        {
                            var num22 = Singleton <NetManager> .instance.m_nodeGrid[(i * 270) + j];
                            var num23 = 0;
                            while (num22 != 0)
                            {
                                NetNode.Flags flags           = NodeBuffer[num22].m_flags;
                                NetInfo       info            = NodeBuffer[num22].Info;
                                ItemClass     connectionClass = info.GetConnectionClass();
                                if ((((service == ItemClass.Service.None || connectionClass.m_service == service) && (subService == ItemClass.SubService.None || connectionClass.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (connectionClass.m_layer & itemLayers) != ItemClass.Layer.None)) || (info.m_intersectClass != null && (service == ItemClass.Service.None || info.m_intersectClass.m_service == service) && (subService == ItemClass.SubService.None || info.m_intersectClass.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (info.m_intersectClass.m_layer & itemLayers) != ItemClass.Layer.None)) || (info.m_netAI.CanIntersect(connectedType) && connectionClass.m_service == service2 && (subService2 == ItemClass.SubService.None || connectionClass.m_subService == subService2) && (itemLayers2 == ItemClass.Layer.None || (connectionClass.m_layer & itemLayers2) != ItemClass.Layer.None))) && (flags & ignoreNodeFlags) == NetNode.Flags.None && (connectedType == null || (info.m_netAI.CanConnect(connectedType) && connectedType.m_netAI.CanConnect(info))))
                                {
                                    var flag = false;
                                    if ((flags & (NetNode.Flags.Middle | NetNode.Flags.Untouchable)) == (NetNode.Flags.Middle | NetNode.Flags.Untouchable) && NodeBuffer[num22].CountSegments(NetSegment.Flags.Untouchable, 0) >= 2)
                                    {
                                        flag = true;
                                    }
                                    if (!flag && NodeBuffer[num22].RayCast(ray, snapElevation, out var num24, out var num25) && (num25 < num12 || (num25 == num12 && num24 < num11)))
                                    {
                                        num11 = num24;
                                        num12 = num25;
                                        num14 = num22;
                                    }
                                }
                                num22 = NodeBuffer[num22].m_nextGridNode;
                                if (++num23 > 32768)
                                {
                                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                                    break;
                                }
                            }
                        }
                    }
                    for (var k = num20; k <= num21; k++)
                    {
                        for (var l = num18; l <= num19; l++)
                        {
                            var num26 = Singleton <NetManager> .instance.m_segmentGrid[(k * 270) + l];
                            var num27 = 0;
                            while (num26 != 0)
                            {
                                NetSegment.Flags flags2           = SegmentBuffer[num26].m_flags;
                                NetInfo          info2            = SegmentBuffer[num26].Info;
                                ItemClass        connectionClass2 = info2.GetConnectionClass();
                                if (((service == ItemClass.Service.None || connectionClass2.m_service == service) && (subService == ItemClass.SubService.None || connectionClass2.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (connectionClass2.m_layer & itemLayers) != ItemClass.Layer.None || nameOnly)) || (info2.m_intersectClass != null && (service == ItemClass.Service.None || info2.m_intersectClass.m_service == service) && (subService == ItemClass.SubService.None || info2.m_intersectClass.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (info2.m_intersectClass.m_layer & itemLayers) != ItemClass.Layer.None || nameOnly)) || (info2.m_netAI.CanIntersect(connectedType) && connectionClass2.m_service == service2 && (subService2 == ItemClass.SubService.None || connectionClass2.m_subService == subService2) && (itemLayers2 == ItemClass.Layer.None || (connectionClass2.m_layer & itemLayers2) != ItemClass.Layer.None || nameOnly)))
                                {
                                    var flag2 = (flags2 & ignoreSegmentFlags) != NetSegment.Flags.None && !nameOnly;
                                    if ((flags2 & ignoreSegmentFlags) == NetSegment.Flags.None && (connectedType == null || (info2.m_netAI.CanConnect(connectedType) && connectedType.m_netAI.CanConnect(info2))) && SegmentBuffer[num26].RayCast(num26, ray, snapElevation, nameOnly, out var num28, out var num29) && (num29 < num10 || (num29 == num10 && num28 < num9)))
                                    {
                                        var     startNode = SegmentBuffer[num26].m_startNode;
                                        var     endNode   = SegmentBuffer[num26].m_endNode;
                                        Vector3 position  = NodeBuffer[startNode].m_position;
                                        Vector3 position2 = NodeBuffer[endNode].m_position;
                                        var     num30     = NodeBuffer[startNode].Info.GetMinNodeDistance();
                                        var     num31     = NodeBuffer[endNode].Info.GetMinNodeDistance();
                                        num10 = num29;
                                        num9  = num28;
                                        Vector3       a      = ray.a + ((ray.b - ray.a) * num28);
                                        NetNode.Flags flags3 = NodeBuffer[startNode].m_flags;
                                        if ((flags3 & NetNode.Flags.End) != NetNode.Flags.None)
                                        {
                                            flags3 &= ~NetNode.Flags.Moveable;
                                        }
                                        NetNode.Flags flags4 = NodeBuffer[endNode].m_flags;
                                        if ((flags4 & NetNode.Flags.End) != NetNode.Flags.None)
                                        {
                                            flags4 &= ~NetNode.Flags.Moveable;
                                        }
                                        if (flag2)
                                        {
                                            num30 = 1000f;
                                            num31 = 1000f;
                                        }
                                        var flag3 = (flags3 & (NetNode.Flags.Moveable | ignoreNodeFlags)) == NetNode.Flags.None;
                                        var flag4 = (flags4 & (NetNode.Flags.Moveable | ignoreNodeFlags)) == NetNode.Flags.None;
                                        var num32 = VectorUtils.LengthSqrXZ(a - position) / (num30 * num30);
                                        var num33 = VectorUtils.LengthSqrXZ(a - position2) / (num31 * num31);
                                        if (flag3 && num32 < 1f && (!flag4 || num32 < num33) && !nameOnly)
                                        {
                                            num13 = startNode;
                                            if (!flag2)
                                            {
                                                num15 = num26;
                                            }
                                        }
                                        else if (flag4 && num33 < 1f && !nameOnly)
                                        {
                                            num13 = endNode;
                                            if (!flag2)
                                            {
                                                num15 = num26;
                                            }
                                        }
                                        else if (!flag2)
                                        {
                                            num13 = 0;
                                            num15 = num26;
                                        }
                                    }
                                }
                                num26 = SegmentBuffer[num26].m_nextGridSegment;
                                if (++num27 > 36864)
                                {
                                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                                    break;
                                }
                            }
                        }
                    }
                    vector2 = vector3;
                    vector3 = vector4;
                    num16  += num7;
                    num17  += num8;
                }while ((num16 <= num3 || num7 <= 0) && (num16 >= num3 || num7 >= 0) && (num17 <= num4 || num8 <= 0) && (num17 >= num4 || num8 >= 0));
                if (num12 < num10 || (num12 == num10 && num11 < num9))
                {
                    num9  = num11;
                    num13 = num14;
                }
                if (num9 != 2f)
                {
                    hit          = ray.Position(num9);
                    nodeIndex    = num13;
                    segmentIndex = num15;
                    return(true);
                }
            }
            hit          = Vector3.zero;
            nodeIndex    = 0;
            segmentIndex = 0;
            return(false);
        }
Esempio n. 19
0
 public static Vector3 GetRayPosition(this Segment3 ray, float height, out float t)
 {
     Segment1.Intersect(ray.a.y, ray.b.y, height, out t);
     return(ray.Position(t));
 }