Esempio n. 1
0
        /// <summary>
        /// -1: Traffic Light
        ///  0: Nothing
        /// >0: Stop Sign
        /// </summary>
        private int DetectHoveredButtons(RaycastInput input, ushort nodeId, ref NetNode node)
        {
            //Source: RoadBaseAI.RayCastNodeButton
            Vector3  origin     = input.m_ray.origin;
            Vector3  normalized = input.m_ray.direction.normalized;
            Vector3  b          = input.m_ray.origin + normalized * input.m_length;
            Segment3 ray        = new Segment3(origin, b);

            var f = Vector3.Distance(ray.a, node.m_position);

            if (f < 1000.0f)
            {
                bool  flag1 = (node.m_flags & (NetNode.Flags.TrafficLights | NetNode.Flags.OneWayIn)) == NetNode.Flags.None;
                bool  flag2 = Node.CanHaveTrafficLights(nodeId, ref node);
                float num1  = 0.0675f * Mathf.Pow(f, 0.65f);
                if (flag2 && (double)ray.DistanceSqr(node.m_position) < (double)num1 * (double)num1)
                {
                    return(-1);
                }
                if (flag1)
                {
                    var instance = Singleton <NetManager> .instance;
                    var num2     = node.Info.m_halfWidth * 0.75f;
                    for (ushort index = 0; index < 8; ++index)
                    {
                        var segment = node.GetSegment(index);
                        if (segment != 0)
                        {
                            var info = instance.m_segments.m_buffer[segment].Info;
                            if ((info.m_vehicleTypes & VehicleInfo.VehicleType.Car) != VehicleInfo.VehicleType.None)
                            {
                                bool flag3 = instance.m_segments.m_buffer[segment].m_startNode == nodeId;
                                bool flag4 = (instance.m_segments.m_buffer[segment].m_flags & NetSegment.Flags.Invert) !=
                                             NetSegment.Flags.None;
                                if ((flag3 != flag4
                      ? (info.m_hasBackwardVehicleLanes ? 1 : 0)
                      : (info.m_hasForwardVehicleLanes ? 1 : 0)) != 0)
                                {
                                    Vector3 vector3 = !flag3
                    ? instance.m_segments.m_buffer[segment].m_endDirection
                    : instance.m_segments.m_buffer[segment].m_startDirection;
                                    Vector3 p = node.m_position + vector3 * num2;
                                    if ((double)ray.DistanceSqr(p) < (double)num1 * (double)num1)
                                    {
                                        return(index + 1);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(0);
        }
 //from source code
 private static ushort CheckOverlap(ushort vehicleID, ref Vehicle vehicleData, Segment3 segment, ushort ignoreVehicle, ushort otherID, ref Vehicle otherData, ref bool overlap, Vector3 min, Vector3 max)
 {
     if (ignoreVehicle == 0 || (otherID != ignoreVehicle && otherData.m_leadingVehicle != ignoreVehicle && otherData.m_trailingVehicle != ignoreVehicle))
     {
         VehicleInfo info = otherData.Info;
         if (info.m_vehicleType == VehicleInfo.VehicleType.Bicycle)
         {
             return(otherData.m_nextGridVehicle);
         }
         if (((vehicleData.m_flags | otherData.m_flags) & Vehicle.Flags.Transition) == (Vehicle.Flags) 0 && (vehicleData.m_flags & Vehicle.Flags.Underground) != (otherData.m_flags & Vehicle.Flags.Underground))
         {
             return(otherData.m_nextGridVehicle);
         }
         Vector3 vector  = Vector3.Min(otherData.m_segment.Min(), otherData.m_targetPos3);
         Vector3 vector2 = Vector3.Max(otherData.m_segment.Max(), otherData.m_targetPos3);
         if (min.x < vector2.x + 2f && min.y < vector2.y + 2f && min.z < vector2.z + 2f && vector.x < max.x + 2f && vector.y < max.y + 2f && vector.z < max.z + 2f)
         {
             Vector3 rhs  = Vector3.Normalize(segment.b - segment.a);
             Vector3 lhs  = otherData.m_segment.a - vehicleData.m_segment.b;
             Vector3 lhs2 = otherData.m_segment.b - vehicleData.m_segment.b;
             if (Vector3.Dot(lhs, rhs) >= 1f || Vector3.Dot(lhs2, rhs) >= 1f)
             {
                 float num2;
                 float num3;
                 float num = segment.DistanceSqr(otherData.m_segment, out num2, out num3);
                 if (num < 4f)
                 {
                     overlap = true;
                 }
                 Vector3 a = otherData.m_segment.b;
                 segment.a.y = segment.a.y * 0.5f;
                 segment.b.y = segment.b.y * 0.5f;
                 for (int i = 0; i < 4; i++)
                 {
                     Vector3  vector3  = otherData.GetTargetPos(i);
                     Segment3 segment2 = new Segment3(a, vector3);
                     segment2.a.y = segment2.a.y * 0.5f;
                     segment2.b.y = segment2.b.y * 0.5f;
                     if (segment2.LengthSqr() > 0.01f)
                     {
                         num = segment.DistanceSqr(segment2, out num2, out num3);
                         if (num < 4f)
                         {
                             overlap = true;
                             break;
                         }
                     }
                     a = vector3;
                 }
             }
         }
     }
     return(otherData.m_nextGridVehicle);
 }
        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);
        }
Esempio n. 5
0
        public static void GetClosestPositionAndDirectionAndPoint(NetSegment s, Vector3 point, out Vector3 pos, out Vector3 dir, out float length)
        {
            Bezier3 curve = default;

            curve.a = Singleton <NetManager> .instance.m_nodes.m_buffer[s.m_startNode].m_position;
            curve.d = Singleton <NetManager> .instance.m_nodes.m_buffer[s.m_endNode].m_position;
            bool smoothStart = (Singleton <NetManager> .instance.m_nodes.m_buffer[s.m_startNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;
            bool smoothEnd   = (Singleton <NetManager> .instance.m_nodes.m_buffer[s.m_endNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None;

            NetSegment.CalculateMiddlePoints(curve.a, s.m_startDirection, curve.d, s.m_endDirection, smoothStart, smoothEnd, out curve.b, out curve.c);
            float   closestDistance = 1E+11f;
            float   pointPerc       = 0f;
            Vector3 targetA         = curve.a;

            for (int i = 1; i <= 16; i++)
            {
                Vector3 vector = curve.Position(i / 16f);
                float   dist   = Segment3.DistanceSqr(targetA, vector, point, out float distSign);
                if (dist < closestDistance)
                {
                    closestDistance = dist;
                    pointPerc       = (i - 1f + distSign) / 16f;
                }
                targetA = vector;
            }
            float precision = 0.03125f;

            for (int j = 0; j < 4; j++)
            {
                Vector3 a2      = curve.Position(Mathf.Max(0f, pointPerc - precision));
                Vector3 vector2 = curve.Position(pointPerc);
                Vector3 b       = curve.Position(Mathf.Min(1f, pointPerc + precision));
                float   num6    = Segment3.DistanceSqr(a2, vector2, point, out float num7);
                float   num8    = Segment3.DistanceSqr(vector2, b, point, out float num9);
                if (num6 < num8)
                {
                    pointPerc = Mathf.Max(0f, pointPerc - (precision * (1f - num7)));
                }
                else
                {
                    pointPerc = Mathf.Min(1f, pointPerc + (precision * num9));
                }
                precision *= 0.5f;
            }
            pos    = curve.Position(pointPerc);
            dir    = VectorUtils.NormalizeXZ(curve.Tangent(pointPerc));
            length = pointPerc;
        }
Esempio n. 6
0
        bool RaycastDynamicSign(Ray currentPosition, out DynamicSignContainer returnValue)
        {
            Vector3  origin     = currentPosition.origin;
            Vector3  normalized = currentPosition.direction.normalized;
            Vector3  _b         = currentPosition.origin + normalized * Camera.main.farClipPlane;
            Segment3 ray        = new Segment3(origin, _b);

            foreach (DynamicSignContainer container in RouteManager.Instance().m_dynamicSignList)
            {
                if (ray.DistanceSqr(container.pos) < 800)
                {
                    returnValue = container;
                    return(true);
                }
            }

            returnValue = null;
            return(false);
        }
Esempio n. 7
0
        /// <summary>
        /// Checks to see whether a given point is within a specified distance from a line segment. In the XZ-plane. Outputs the closest t-value (to the given point) on the curve.
        /// </summary>
        /// <param name="curve"></param>
        /// <param name="distanceThreshold"></param>
        /// <param name="pointOfInterest"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public static bool IsCloseToSegmentXZ(Segment3 lineSegment, float distanceThreshold, Vector3 pointOfInterest, out float t)
        {
            //constrain to XZ plane
            lineSegment       = SegmentXZ(lineSegment);
            pointOfInterest.y = 0f;

            //initialize output t
            t = 0.5f;

            float _radiusSqr   = distanceThreshold * distanceThreshold;
            float _distanceSqr = lineSegment.DistanceSqr(pointOfInterest, out t);

            if (_distanceSqr <= _radiusSqr)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Esempio n. 8
0
        public static void ClosestPositionAndDirection(this Bezier3 bezier, Vector3 point, out Vector3 position, out Vector3 direction, out float t)
        {
            var distance = 1E+11f;

            t = 0f;
            var prevPosition = bezier.a;

            for (var i = 1; i <= 16; i += 1)
            {
                var currentPosition = bezier.Position(i / 16f);
                var currentDistance = Segment3.DistanceSqr(prevPosition, currentPosition, point, out var u);
                if (currentDistance < distance)
                {
                    distance = currentDistance;
                    t        = (i - 1f + u) / 16f;
                }
                prevPosition = currentPosition;
            }

            float delta = 0.03125f;

            for (var i = 0; i < 4; i += 1)
            {
                var minPosition     = bezier.Position(Mathf.Max(0f, t - delta));
                var currentPosition = bezier.Position(t);
                var maxPosition     = bezier.Position(Mathf.Min(1f, t + delta));

                var minDistance = Segment3.DistanceSqr(minPosition, currentPosition, point, out var minU);
                var maxDistance = Segment3.DistanceSqr(currentPosition, maxPosition, point, out var maxU);

                t = minDistance >= maxDistance?Mathf.Min(1f, t + delta *maxU) : Mathf.Max(0f, t - delta * (1f - minU));

                delta *= 0.5f;
            }

            position  = bezier.Position(t);
            direction = NormalizeXZ(bezier.Tangent(t));
        }
Esempio n. 9
0
        private static ushort CheckOverlap(Segment3 segment, ushort ignoreVehicle, ushort otherID, ref Vehicle otherData, ref bool overlap)
        {
            float num;
            float num2;

            if ((ignoreVehicle == 0 || (otherID != ignoreVehicle && otherData.m_leadingVehicle != ignoreVehicle && otherData.m_trailingVehicle != ignoreVehicle)) && segment.DistanceSqr(otherData.m_segment, out num, out num2) < 400f)
            {
                overlap = true;
            }
            return(otherData.m_nextGridVehicle);
        }
 private ushort CheckOtherVehicle(ushort vehicleID, ref Vehicle vehicleData, ref Vehicle.Frame frameData, ref float maxSpeed, ref bool blocked, float maxBraking, ushort otherID, ref Vehicle otherData, Vector3 min, Vector3 max, int lodPhysics)
 {
     if (otherID != vehicleID && vehicleData.m_leadingVehicle != otherID && vehicleData.m_trailingVehicle != otherID)
     {
         Vector3 vector;
         Vector3 vector2;
         if (lodPhysics >= 1)
         {
             vector = otherData.m_segment.Min ();
             vector2 = otherData.m_segment.Max ();
         }
         else
         {
             vector = Vector3.Min (otherData.m_segment.Min (), otherData.m_targetPos3);
             vector2 = Vector3.Max (otherData.m_segment.Max (), otherData.m_targetPos3);
         }
         if (min.x < vector2.x + 2f && min.y < vector2.y + 2f && min.z < vector2.z + 2f && vector.x < max.x + 2f && vector.y < max.y + 2f && vector.z < max.z + 2f)
         {
             Vehicle.Frame lastFrameData = otherData.GetLastFrameData ();
             VehicleInfo info = otherData.Info;
             float num = frameData.m_velocity.magnitude + 0.01f;
             float num2 = lastFrameData.m_velocity.magnitude;
             float num3 = num2 * (0.5f + 0.5f * num2 / info.m_braking) + info.m_generatedInfo.m_size.z * Mathf.Min (0.5f, num2 * 0.1f);
             num2 += 0.01f;
             float num4 = 0f;
             Vector3 vector3 = frameData.m_position;
             Vector3 lhs = ((Vector3) vehicleData.m_targetPos3) - frameData.m_position;
             for (int i = 1; i < 4; i++)
             {
                 Vector3 vector4 = vehicleData.GetTargetPos (i);
                 Vector3 vector5 = vector4 - vector3;
                 if (Vector3.Dot (lhs, vector5) > 0f)
                 {
                     float magnitude = vector5.magnitude;
                     Segment3 segment = new Segment3 (vector3, vector4);
                     min = segment.Min ();
                     max = segment.Max ();
                     segment.a.y = segment.a.y * 0.5f;
                     segment.b.y = segment.b.y * 0.5f;
                     if (magnitude > 0.01f && min.x < vector2.x + 2f && min.y < vector2.y + 2f && min.z < vector2.z + 2f && vector.x < max.x + 2f && vector.y < max.y + 2f && vector.z < max.z + 2f)
                     {
                         Vector3 a = otherData.m_segment.a;
                         a.y *= 0.5f;
                         float num5;
                         if (segment.DistanceSqr (a, out num5) < 400f)
                         {
                             float num6 = Vector3.Dot (lastFrameData.m_velocity, vector5) / magnitude;
                             float num7 = num4 + magnitude * num5;
                             if (num7 >= 0.01f)
                             {
                                 num7 -= num6 + 30f;
                                 float num8 = Mathf.Max (0f, CalculateMaxSpeed (num7, num6, maxBraking));
                                 if (num8 < 0.01f)
                                 {
                                     blocked = true;
                                 }
                                 Vector3 rhs = Vector3.Normalize (((Vector3)otherData.m_targetPos3) - otherData.GetLastFramePosition ());
                                 float num9 = 1.2f - 1f / ((float)vehicleData.m_blockCounter * 0.02f + 0.5f);
                                 if (Vector3.Dot (vector5, rhs) > num9 * magnitude)
                                 {
                                     maxSpeed = Mathf.Min (maxSpeed, num8);
                                 }
                             }
                             break;
                         }
                         if (lodPhysics == 0)
                         {
                             float num10 = 0f;
                             float num11 = num3;
                             Vector3 vector6 = otherData.GetLastFramePosition ();
                             Vector3 lhs2 = ((Vector3)otherData.m_targetPos3) - vector6;
                             bool flag = false;
                             int num12 = 1;
                             while (num12 < 4 && num11 > 0.1f)
                             {
                                 Vector3 vector7 = otherData.GetTargetPos (num12);
                                 Vector3 vector8 = Vector3.ClampMagnitude (vector7 - vector6, num11);
                                 if (Vector3.Dot (lhs2, vector8) > 0f)
                                 {
                                     vector7 = vector6 + vector8;
                                     float magnitude2 = vector8.magnitude;
                                     num11 -= magnitude2;
                                     Segment3 segment2 = new Segment3 (vector6, vector7);
                                     segment2.a.y = segment2.a.y * 0.5f;
                                     segment2.b.y = segment2.b.y * 0.5f;
                                     if (magnitude2 > 0.01f)
                                     {
                                         float num14;
                                         float num15;
                                         float num13;
                                         if (otherID < vehicleID)
                                         {
                                             num13 = segment2.DistanceSqr (segment, out num14, out num15);
                                         }
                                         else
                                         {
                                             num13 = segment.DistanceSqr (segment2, out num15, out num14);
                                         }
                                         if (num13 < 400f)
                                         {
                                             float num16 = num4 + magnitude * num15;
                                             float num17 = num10 + magnitude2 * num14 + 0.1f;
                                             if (num16 >= 0.01f && num16 * num2 > num17 * num)
                                             {
                                                 float num18 = Vector3.Dot (lastFrameData.m_velocity, vector5) / magnitude;
                                                 if (num16 >= 0.01f)
                                                 {
                                                     num16 -= num18 + 10f + otherData.Info.m_generatedInfo.m_size.z;
                                                     float num19 = Mathf.Max (0f, CalculateMaxSpeed (num16, num18, maxBraking));
                                                     if (num19 < 0.01f)
                                                     {
                                                         blocked = true;
                                                     }
                                                     maxSpeed = Mathf.Min (maxSpeed, num19);
                                                 }
                                             }
                                             flag = true;
                                             break;
                                         }
                                     }
                                     lhs2 = vector8;
                                     num10 += magnitude2;
                                     vector6 = vector7;
                                 }
                                 num12++;
                             }
                             if (flag)
                             {
                                 break;
                             }
                         }
                     }
                     lhs = vector5;
                     num4 += magnitude;
                     vector3 = vector4;
                 }
             }
         }
     }
     return otherData.m_nextGridVehicle;
 }
        private int GetLineCount(Vector3 stopPosition, Vector3 stopDirection, TransportInfo.TransportType transportType)
        {
            NetManager       instance  = Singleton <NetManager> .instance;
            TransportManager instance2 = Singleton <TransportManager> .instance;

            stopDirection.Normalize();
            Segment3 segment = new Segment3(stopPosition - stopDirection * 16, stopPosition + stopDirection * 16);
            Vector3  vector  = segment.Min();
            Vector3  vector2 = segment.Max();
            int      num     = Mathf.Max((int)((vector.x - 4) / 64 + 135), 0);
            int      num2    = Mathf.Max((int)((vector.z - 4) / 64 + 135), 0);
            int      num3    = Mathf.Min((int)((vector2.x + 4) / 64 + 135), 269);
            int      num4    = Mathf.Min((int)((vector2.z + 4) / 64 + 135), 269);
            int      num5    = 0;

            for (int i = num2; i <= num4; i++)
            {
                for (int j = num; j <= num3; j++)
                {
                    ushort num6 = instance.m_nodeGrid[i * 270 + j];
                    int    num7 = 0;
                    while (num6 != 0)
                    {
                        ushort transportLine = instance.m_nodes.m_buffer[(int)num6].m_transportLine;
                        if (transportLine != 0)
                        {
                            TransportInfo info = instance2.m_lines.m_buffer[(int)transportLine].Info;
                            if (info.m_transportType == transportType && (instance2.m_lines.m_buffer[(int)transportLine].m_flags & TransportLine.Flags.Temporary) == TransportLine.Flags.None && segment.DistanceSqr(instance.m_nodes.m_buffer[(int)num6].m_position) < 16)
                            {
                                num5++;
                            }
                        }
                        num6 = instance.m_nodes.m_buffer[(int)num6].m_nextGridNode;
                        if (++num7 >= 32768)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
            return(num5);
        }
Esempio n. 12
0
 // CHECKME: check if this method allows to make people get away from traffic
 private static ushort CheckCitizen(Segment3 segment, float lastLen, float nextLen, ref float maxSpeed, ref bool blocked, float maxBraking, ushort otherID, ref CitizenInstance otherData, Vector3 min, Vector3 max)
 {
     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;
     float num;
     float num2;
     if (min.x < vector2.x + 1f && min.y < vector2.y && min.z < vector2.z + 1f && vector.x < max.x + 1f && vector.y < max.y + 2f && vector.z < max.z + 1f && segment.DistanceSqr(segment2, out num, out num2) < (1f + info.m_radius) * (1f + info.m_radius))
     {
         float num3 = lastLen + nextLen * num;
         if (num3 >= 0.01f)
         {
             num3 -= 2f;
             float b2 = Mathf.Max(1f, CalculateMaxSpeed(num3, 0f, maxBraking));
             maxSpeed = Mathf.Min(maxSpeed, b2);
         }
     }
     return otherData.m_nextGridInstance;
 }
Esempio n. 13
0
 private static ushort CheckOtherVehicle(ushort vehicleID, ref Vehicle vehicleData, ref Vehicle.Frame frameData, ref float maxSpeed, ref bool blocked, ref Vector3 collisionPush, float maxBraking, ushort otherID, ref Vehicle otherData, Vector3 min, Vector3 max, int lodPhysics)
 {
     if (otherID != vehicleID && vehicleData.m_leadingVehicle != otherID && vehicleData.m_trailingVehicle != otherID)
     {
         VehicleInfo info = otherData.Info;
         if (info.m_vehicleType == VehicleInfo.VehicleType.Bicycle)
         {
             return(otherData.m_nextGridVehicle);
         }
         Vector3 vector;
         Vector3 vector2;
         if (lodPhysics >= 2)
         {
             vector  = otherData.m_segment.Min();
             vector2 = otherData.m_segment.Max();
         }
         else
         {
             vector  = Vector3.Min(otherData.m_segment.Min(), otherData.m_targetPos3);
             vector2 = Vector3.Max(otherData.m_segment.Max(), otherData.m_targetPos3);
         }
         if (min.x < vector2.x + 2f && min.y < vector2.y + 2f && min.z < vector2.z + 2f && vector.x < max.x + 2f && vector.y < max.y + 2f && vector.z < max.z + 2f)
         {
             Vehicle.Frame lastFrameData = otherData.GetLastFrameData();
             if (lodPhysics < 2)
             {
                 float num2;
                 float num3;
                 float num = vehicleData.m_segment.DistanceSqr(otherData.m_segment, out num2, out num3);
                 if (num < 4f)
                 {
                     Vector3 a   = vehicleData.m_segment.Position(0.5f);
                     Vector3 b   = otherData.m_segment.Position(0.5f);
                     Vector3 lhs = vehicleData.m_segment.b - vehicleData.m_segment.a;
                     if (Vector3.Dot(lhs, a - b) < 0f)
                     {
                         collisionPush -= lhs.normalized * (0.1f - num * 0.025f);
                     }
                     else
                     {
                         collisionPush += lhs.normalized * (0.1f - num * 0.025f);
                     }
                     blocked = true;
                 }
             }
             float num4 = frameData.m_velocity.magnitude + 0.01f;
             float num5 = lastFrameData.m_velocity.magnitude;
             float num6 = num5 * (0.5f + 0.5f * num5 / info.m_braking) + Mathf.Min(1f, num5);
             num5 += 0.01f;
             float   num7    = 0f;
             Vector3 vector3 = vehicleData.m_segment.b;
             Vector3 lhs2    = vehicleData.m_segment.b - vehicleData.m_segment.a;
             for (int i = 0; i < 4; i++)
             {
                 Vector3 vector4 = vehicleData.GetTargetPos(i);
                 Vector3 vector5 = vector4 - vector3;
                 if (Vector3.Dot(lhs2, vector5) > 0f)
                 {
                     float    magnitude = vector5.magnitude;
                     Segment3 segment   = new Segment3(vector3, vector4);
                     min         = segment.Min();
                     max         = segment.Max();
                     segment.a.y = segment.a.y * 0.5f;
                     segment.b.y = segment.b.y * 0.5f;
                     if (magnitude > 0.01f && min.x < vector2.x + 2f && min.y < vector2.y + 2f && min.z < vector2.z + 2f && vector.x < max.x + 2f && vector.y < max.y + 2f && vector.z < max.z + 2f)
                     {
                         Vector3 a2 = otherData.m_segment.a;
                         a2.y *= 0.5f;
                         float num8;
                         if (segment.DistanceSqr(a2, out num8) < 4f)
                         {
                             float num9  = Vector3.Dot(lastFrameData.m_velocity, vector5) / magnitude;
                             float num10 = num7 + magnitude * num8;
                             if (num10 >= 0.01f)
                             {
                                 num10 -= num9 + 3f;
                                 float num11 = Mathf.Max(0f, CalculateMaxSpeed(num10, num9, maxBraking));
                                 if (num11 < 0.01f)
                                 {
                                     blocked = true;
                                 }
                                 Vector3 rhs   = Vector3.Normalize(otherData.m_targetPos0 - (Vector4)otherData.m_segment.a);
                                 float   num12 = 1.2f - 1f / ((float)vehicleData.m_blockCounter * 0.02f + 0.5f);
                                 if (Vector3.Dot(vector5, rhs) > num12 * magnitude)
                                 {
                                     maxSpeed = Mathf.Min(maxSpeed, num11);
                                 }
                             }
                             break;
                         }
                         if (lodPhysics < 2)
                         {
                             float   num13   = 0f;
                             float   num14   = num6;
                             Vector3 vector6 = otherData.m_segment.b;
                             Vector3 lhs3    = otherData.m_segment.b - otherData.m_segment.a;
                             bool    flag    = false;
                             int     num15   = 0;
                             while (num15 < 4 && num14 > 0.1f)
                             {
                                 Vector3 vector7 = otherData.GetTargetPos(num15);
                                 Vector3 vector8 = Vector3.ClampMagnitude(vector7 - vector6, num14);
                                 if (Vector3.Dot(lhs3, vector8) > 0f)
                                 {
                                     vector7 = vector6 + vector8;
                                     float magnitude2 = vector8.magnitude;
                                     num14 -= magnitude2;
                                     Segment3 segment2 = new Segment3(vector6, vector7);
                                     segment2.a.y = segment2.a.y * 0.5f;
                                     segment2.b.y = segment2.b.y * 0.5f;
                                     if (magnitude2 > 0.01f)
                                     {
                                         float num17;
                                         float num18;
                                         float num16;
                                         if (otherID < vehicleID)
                                         {
                                             num16 = segment2.DistanceSqr(segment, out num17, out num18);
                                         }
                                         else
                                         {
                                             num16 = segment.DistanceSqr(segment2, out num18, out num17);
                                         }
                                         if (num16 < 4f)
                                         {
                                             float num19 = num7 + magnitude * num18;
                                             float num20 = num13 + magnitude2 * num17 + 0.1f;
                                             if (num19 >= 0.01f && num19 * num5 > num20 * num4)
                                             {
                                                 float num21 = Vector3.Dot(lastFrameData.m_velocity, vector5) / magnitude;
                                                 if (num19 >= 0.01f)
                                                 {
                                                     num19 -= num21 + 1f + otherData.Info.m_generatedInfo.m_size.z;
                                                     float num22 = Mathf.Max(0f, CalculateMaxSpeed(num19, num21, maxBraking));
                                                     if (num22 < 0.01f)
                                                     {
                                                         blocked = true;
                                                     }
                                                     maxSpeed = Mathf.Min(maxSpeed, num22);
                                                 }
                                             }
                                             flag = true;
                                             break;
                                         }
                                     }
                                     lhs3    = vector8;
                                     num13  += magnitude2;
                                     vector6 = vector7;
                                 }
                                 num15++;
                             }
                             if (flag)
                             {
                                 break;
                             }
                         }
                     }
                     lhs2    = vector5;
                     num7   += magnitude;
                     vector3 = vector4;
                 }
             }
         }
     }
     return(otherData.m_nextGridVehicle);
 }
        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);
        }
		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;
			}
		}
        private static ushort CheckOverlap(
            Segment3 segment,
            ushort ignoreVehicle,
            float maxVelocity,
            ushort otherID,
            ref Vehicle otherData,
            ref bool overlap)
        {
            float u;
            float v;

            if ((ignoreVehicle == (ushort)0 || (int)otherID != (int)ignoreVehicle && (int)otherData.m_leadingVehicle != (int)ignoreVehicle && (int)otherData.m_trailingVehicle != (int)ignoreVehicle) && ((double)segment.DistanceSqr(otherData.m_segment, out u, out v) < 4.0 && otherData.Info.m_vehicleType != VehicleInfo.VehicleType.Bicycle) && (double)otherData.GetLastFrameData().m_velocity.sqrMagnitude < (double)maxVelocity * (double)maxVelocity)
            {
                overlap = true;
            }
            return(otherData.m_nextGridVehicle);
        }
        private static ushort CheckOverlap(Segment3 segment, ushort ignoreVehicle, float maxVelocity, ushort otherID, ref Vehicle otherData, ref bool overlap)
        {
            float num;
            float num2;

            if ((ignoreVehicle == 0 || (otherID != ignoreVehicle && otherData.m_leadingVehicle != ignoreVehicle && otherData.m_trailingVehicle != ignoreVehicle)) && segment.DistanceSqr(otherData.m_segment, out num, out num2) < 4f)
            {
                VehicleInfo info = otherData.Info;
                if (info.m_vehicleType == VehicleInfo.VehicleType.Bicycle)
                {
                    return(otherData.m_nextGridVehicle);
                }
                if (otherData.GetLastFrameData().m_velocity.sqrMagnitude < maxVelocity * maxVelocity)
                {
                    overlap = true;
                }
            }
            return(otherData.m_nextGridVehicle);
        }
        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);
        }
        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 static ushort CheckOverlap(ushort vehicleID, ref Vehicle vehicleData, Segment3 segment, ushort ignoreVehicle, ushort otherID, ref Vehicle otherData, ref bool overlap, Vector3 min, Vector3 max)
 {
     if (ignoreVehicle == 0 || (otherID != ignoreVehicle && otherData.m_leadingVehicle != ignoreVehicle && otherData.m_trailingVehicle != ignoreVehicle))
     {
         VehicleInfo info = otherData.Info;
         if (info.m_vehicleType == VehicleInfo.VehicleType.Bicycle)
         {
             return otherData.m_nextGridVehicle;
         }
         if (((vehicleData.m_flags | otherData.m_flags) & Vehicle.Flags.Transition) == Vehicle.Flags.None && (vehicleData.m_flags & Vehicle.Flags.Underground) != (otherData.m_flags & Vehicle.Flags.Underground))
         {
             return otherData.m_nextGridVehicle;
         }
         Vector3 vector = Vector3.Min (otherData.m_segment.Min (), otherData.m_targetPos3);
         Vector3 vector2 = Vector3.Max (otherData.m_segment.Max (), otherData.m_targetPos3);
         if (min.x < vector2.x + 2f && min.y < vector2.y + 2f && min.z < vector2.z + 2f && vector.x < max.x + 2f && vector.y < max.y + 2f && vector.z < max.z + 2f)
         {
             Vector3 rhs = Vector3.Normalize (segment.b - segment.a);
             Vector3 lhs = otherData.m_segment.a - vehicleData.m_segment.b;
             Vector3 lhs2 = otherData.m_segment.b - vehicleData.m_segment.b;
             if (Vector3.Dot (lhs, rhs) >= 1f || Vector3.Dot (lhs2, rhs) >= 1f)
             {
                 float num2;
                 float num3;
                 float num = segment.DistanceSqr (otherData.m_segment, out num2, out num3);
                 if (num < 4f)
                 {
                     overlap = true;
                 }
                 Vector3 a = otherData.m_segment.b;
                 segment.a.y = segment.a.y * 0.5f;
                 segment.b.y = segment.b.y * 0.5f;
                 for (int i = 0; i < 4; i++)
                 {
                     Vector3 vector3 = otherData.GetTargetPos (i);
                     Segment3 segment2 = new Segment3 (a, vector3);
                     segment2.a.y = segment2.a.y * 0.5f;
                     segment2.b.y = segment2.b.y * 0.5f;
                     if (segment2.LengthSqr () > 0.01f)
                     {
                         num = segment.DistanceSqr (segment2, out num2, out num3);
                         if (num < 4f)
                         {
                             overlap = true;
                             break;
                         }
                     }
                     a = vector3;
                 }
             }
         }
     }
     return otherData.m_nextGridVehicle;
 }
 private ushort CheckCitizen(ushort vehicleID, ref Vehicle vehicleData, Segment3 segment, float lastLen, float nextLen, ref float maxSpeed, ref bool blocked, float maxBraking, ushort otherID, ref CitizenInstance otherData, Vector3 min, Vector3 max)
 {
     if ((vehicleData.m_flags & Vehicle.Flags.Transition) == Vehicle.Flags.None && (otherData.m_flags & CitizenInstance.Flags.Transition) == CitizenInstance.Flags.None && (vehicleData.m_flags & Vehicle.Flags.Underground) != Vehicle.Flags.None != ((otherData.m_flags & CitizenInstance.Flags.Underground) != CitizenInstance.Flags.None))
     {
         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;
     float num;
     float num2;
     if (min.x < vector2.x + 1f && min.y < vector2.y && min.z < vector2.z + 1f && vector.x < max.x + 1f && vector.y < max.y + 2f && vector.z < max.z + 1f && segment.DistanceSqr(segment2, out num, out num2) < (1f + info.m_radius) * (1f + info.m_radius))
     {
         float num3 = lastLen + nextLen * num;
         if (num3 >= 0.01f)
         {
             num3 -= 2f;
             float b2 = Mathf.Max(1f, CustomCarAI.CalculateMaxSpeed(num3, 0f, maxBraking));
             maxSpeed = Mathf.Min(maxSpeed, b2);
         }
     }
     return otherData.m_nextGridInstance;
 }
        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);
        }
Esempio n. 23
0
 private int GetLineCount(Vector3 stopPosition, Vector3 stopDirection, TransportInfo.TransportType transportType)
 {
     NetManager instance = Singleton<NetManager>.instance;
     TransportManager instance2 = Singleton<TransportManager>.instance;
     stopDirection.Normalize();
     Segment3 segment = new Segment3(stopPosition - stopDirection * 16f, stopPosition + stopDirection * 16f);
     Vector3 vector = segment.Min();
     Vector3 vector2 = segment.Max();
     int num = Mathf.Max((int)((vector.x - 4f) / 64f + 135f), 0);
     int num2 = Mathf.Max((int)((vector.z - 4f) / 64f + 135f), 0);
     int num3 = Mathf.Min((int)((vector2.x + 4f) / 64f + 135f), 269);
     int num4 = Mathf.Min((int)((vector2.z + 4f) / 64f + 135f), 269);
     int num5 = 0;
     for (int i = num2; i <= num4; i++)
     {
         for (int j = num; j <= num3; j++)
         {
             ushort num6 = instance.m_nodeGrid[i * 270 + j];
             int num7 = 0;
             while (num6 != 0)
             {
                 ushort transportLine = instance.m_nodes.m_buffer[(int)num6].m_transportLine;
                 if (transportLine != 0)
                 {
                     TransportInfo info = instance2.m_lines.m_buffer[(int)transportLine].Info;
                     if (info.m_transportType == transportType && (instance2.m_lines.m_buffer[(int)transportLine].m_flags & TransportLine.Flags.Temporary) == TransportLine.Flags.None && segment.DistanceSqr(instance.m_nodes.m_buffer[(int)num6].m_position) < 16f)
                     {
                         num5++;
                     }
                 }
                 num6 = instance.m_nodes.m_buffer[(int)num6].m_nextGridNode;
                 if (++num7 >= 32768)
                 {
                     CODebugBase<LogChannel>.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);
                     break;
                 }
             }
         }
     }
     return num5;
 }
 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 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);
        }
 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:
                 ;
             }
         }
     }
 }
        public static ushort CustomCheckOtherVehicle(ushort vehicleId,
                                                     ref Vehicle vehicleData,
                                                     ref Vehicle.Frame frameData,
                                                     ref float maxSpeed,
                                                     ref bool blocked,
                                                     ref Vector3 collisionPush,
                                                     float maxBraking,
                                                     ushort otherID,
                                                     ref Vehicle otherData,
                                                     Vector3 min,
                                                     Vector3 max,
                                                     int lodPhysics)
        {
            if (otherID == vehicleId ||
                vehicleData.m_leadingVehicle == otherID ||
                vehicleData.m_trailingVehicle == otherID)
            {
                return(otherData.m_nextGridVehicle);
            }

            VehicleInfo info = otherData.Info;

            if (info.m_vehicleType == VehicleInfo.VehicleType.Bicycle)
            {
                return(otherData.m_nextGridVehicle);
            }

            if (((vehicleData.m_flags | otherData.m_flags) & Vehicle.Flags.Transition) == 0 &&
                (vehicleData.m_flags & Vehicle.Flags.Underground) !=
                (otherData.m_flags & Vehicle.Flags.Underground))
            {
                return(otherData.m_nextGridVehicle);
            }

#if DEBUG
            bool logLogic = DebugSwitch.ResourceLoading.Get() &&
                            (GlobalConfig.Instance.Debug.ApiExtVehicleType == ExtVehicleType.None ||
                             GlobalConfig.Instance.Debug.ApiExtVehicleType == ExtVehicleType.RoadVehicle) &&
                            (DebugSettings.VehicleId == 0 ||
                             DebugSettings.VehicleId == vehicleId);
#else
            const bool logLogic = false;
#endif
            Log._DebugIf(
                logLogic,
                () => $"CustomCarAI.CustomCheckOtherVehicle({vehicleId}, {otherID}) called.");

            Vector3 otherSegMin;
            Vector3 otherSegMax;
            if (lodPhysics >= 2)
            {
                otherSegMin = otherData.m_segment.Min();
                otherSegMax = otherData.m_segment.Max();
            }
            else
            {
                otherSegMin = Vector3.Min(otherData.m_segment.Min(), otherData.m_targetPos3);
                otherSegMax = Vector3.Max(otherData.m_segment.Max(), otherData.m_targetPos3);
            }

            if (min.x >= otherSegMax.x + 2f &&
                min.y >= otherSegMax.y + 2f &&
                min.z >= otherSegMax.z + 2f &&
                otherSegMin.x >= max.x + 2f &&
                otherSegMin.y >= max.y + 2f &&
                otherSegMin.z >= max.z + 2f)
            {
                return(otherData.m_nextGridVehicle);
            }

            Vehicle.Frame otherFrameData = otherData.GetLastFrameData();
            if (lodPhysics < 2)
            {
                float segSqrDist = vehicleData.m_segment.DistanceSqr(otherData.m_segment, out _, out _);

                if (segSqrDist < 4f)
                {
                    Vector3 vehPos    = vehicleData.m_segment.Position(0.5f);
                    Vector3 otherPos  = otherData.m_segment.Position(0.5f);
                    Vector3 vehBounds = vehicleData.m_segment.b - vehicleData.m_segment.a;
                    if (Vector3.Dot(vehBounds, vehPos - otherPos) < 0f)
                    {
                        collisionPush -= vehBounds.normalized * (0.1f - (segSqrDist * 0.025f));
                    }
                    else
                    {
                        collisionPush += vehBounds.normalized * (0.1f - (segSqrDist * 0.025f));
                    }

                    blocked = true;
                }
            }

            float vehVelocity       = frameData.m_velocity.magnitude + 0.01f;
            float otherVehVelocity  = otherFrameData.m_velocity.magnitude;
            float otherBreakingDist =
                (otherVehVelocity * (0.5f + (0.5f * otherVehVelocity / info.m_braking)))
                + Mathf.Min(1f, otherVehVelocity);
            otherVehVelocity += 0.01f;

            float   prevLength    = 0f;
            Vector3 prevTargetPos = vehicleData.m_segment.b;
            Vector3 prevBounds    = vehicleData.m_segment.b - vehicleData.m_segment.a;
            int     startI        = (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Tram) ? 1 : 0;

            for (int i = startI; i < 4; i++)
            {
                Vector3 targetPos     = vehicleData.GetTargetPos(i);
                Vector3 targetPosDiff = targetPos - prevTargetPos;
                if (Vector3.Dot(prevBounds, targetPosDiff) <= 0f)
                {
                    continue;
                }

                float    targetPosDiffLen = targetPosDiff.magnitude;
                Segment3 curSegment       = new Segment3(prevTargetPos, targetPos);
                min             = curSegment.Min();
                max             = curSegment.Max();
                curSegment.a.y *= 0.5f;
                curSegment.b.y *= 0.5f;

                if (targetPosDiffLen > 0.01f &&
                    min.x < otherSegMax.x + 2f &&
                    min.y < otherSegMax.y + 2f &&
                    min.z < otherSegMax.z + 2f &&
                    otherSegMin.x < max.x + 2f &&
                    otherSegMin.y < max.y + 2f &&
                    otherSegMin.z < max.z + 2f)
                {
                    Vector3 otherVehFrontPos = otherData.m_segment.a;
                    otherVehFrontPos.y *= 0.5f;

                    if (curSegment.DistanceSqr(otherVehFrontPos, out float u) < 4f)
                    {
                        float otherCosAngleToTargetPosDiff =
                            Vector3.Dot(otherFrameData.m_velocity, targetPosDiff) / targetPosDiffLen;
                        float uDist = prevLength + (targetPosDiffLen * u);

                        if (uDist >= 0.01f)
                        {
                            uDist -= otherCosAngleToTargetPosDiff + 3f;
                            float speed = Mathf.Max(
                                0f,
                                CalculateMaxSpeed(uDist,
                                                  otherCosAngleToTargetPosDiff,
                                                  maxBraking));
                            if (speed < 0.01f)
                            {
                                blocked = true;
                            }

                            Vector3 normOtherDir =
                                Vector3.Normalize((Vector3)otherData.m_targetPos0 - otherData.m_segment.a);

                            float blockFactor = 1.2f - (1f / ((vehicleData.m_blockCounter * 0.02f) + 0.5f));

                            if (Vector3.Dot(targetPosDiff, normOtherDir) > blockFactor * targetPosDiffLen)
                            {
                                maxSpeed = Mathf.Min(maxSpeed, speed);
                            }
                        }

                        break;
                    }

                    if (lodPhysics < 2)
                    {
                        float   totalDist                = 0f;
                        float   otherBreakDist           = otherBreakingDist;
                        Vector3 otherFrontPos            = otherData.m_segment.b;
                        Vector3 otherBounds              = otherData.m_segment.b - otherData.m_segment.a;
                        int     startOtherTargetPosIndex = (info.m_vehicleType == VehicleInfo.VehicleType.Tram) ? 1 : 0;
                        bool    exitTargetPosLoop        = false;
                        int     otherTargetPosIndex      = startOtherTargetPosIndex;

                        while (otherTargetPosIndex < 4 && otherBreakDist > 0.1f)
                        {
                            Vector3 otherTargetPos;
                            if (otherData.m_leadingVehicle == 0)
                            {
                                otherTargetPos = otherData.GetTargetPos(otherTargetPosIndex);
                            }
                            else
                            {
                                if (otherTargetPosIndex != startOtherTargetPosIndex)
                                {
                                    break;
                                }

                                Vehicle[] vehiclesBuffer = Singleton <VehicleManager> .instance.m_vehicles.m_buffer;
                                otherTargetPos = vehiclesBuffer[otherData.m_leadingVehicle].m_segment.b;
                            }

                            Vector3 minBreakPos = Vector3.ClampMagnitude(otherTargetPos - otherFrontPos,
                                                                         otherBreakDist);

                            if (Vector3.Dot(otherBounds, minBreakPos) > 0f)
                            {
                                otherTargetPos = otherFrontPos + minBreakPos;

                                float breakPosDist = minBreakPos.magnitude;
                                otherBreakDist -= breakPosDist;

                                Segment3 otherVehNextSegment = new Segment3(otherFrontPos, otherTargetPos);
                                otherVehNextSegment.a.y *= 0.5f;
                                otherVehNextSegment.b.y *= 0.5f;

                                if (breakPosDist > 0.01f)
                                {
                                    float otherVehNextSegmentDistToCurSegment
                                        = otherID >= vehicleId
                                              ? curSegment.DistanceSqr(
                                              otherVehNextSegment,
                                              out float otherVehNextSegU,
                                              out float otherVehNextSegV)
                                              : otherVehNextSegment.DistanceSqr(
                                              curSegment,
                                              out otherVehNextSegV,
                                              out otherVehNextSegU);

                                    if (otherVehNextSegmentDistToCurSegment < 4f)
                                    {
                                        float uDist = prevLength + (targetPosDiffLen * otherVehNextSegU);
                                        float vDist = totalDist + (breakPosDist * otherVehNextSegV) + 0.1f;

                                        if (uDist >= 0.01f && uDist * otherVehVelocity > vDist * vehVelocity)
                                        {
                                            float otherCosAngleToTargetPosDiff =
                                                Vector3.Dot(
                                                    otherFrameData.m_velocity,
                                                    targetPosDiff) / targetPosDiffLen;
                                            if (uDist >= 0.01f)
                                            {
                                                uDist -= otherCosAngleToTargetPosDiff
                                                         + 1f
                                                         + otherData.Info.m_generatedInfo.m_size.z;
                                                float speed = Mathf.Max(
                                                    0f,
                                                    CalculateMaxSpeed(uDist,
                                                                      otherCosAngleToTargetPosDiff,
                                                                      maxBraking));

                                                if (speed < 0.01f)
                                                {
                                                    blocked = true;
                                                }

                                                maxSpeed = Mathf.Min(maxSpeed, speed);
                                            }
                                        }

                                        exitTargetPosLoop = true;
                                        break;
                                    }
                                }

                                otherBounds   = minBreakPos;
                                totalDist    += breakPosDist;
                                otherFrontPos = otherTargetPos;
                            }

                            otherTargetPosIndex++;
                        }

                        if (exitTargetPosLoop)
                        {
                            break;
                        }
                    }
                }

                prevBounds    = targetPosDiff;
                prevLength   += targetPosDiffLen;
                prevTargetPos = targetPos;
            }

            return(otherData.m_nextGridVehicle);
        }
 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. 29
0
        // CHECKME: check if this method allows to make people get away from traffic
        private static ushort CheckCitizen(Segment3 segment, float lastLen, float nextLen, ref float maxSpeed, ref bool blocked, float maxBraking, ushort otherID, ref CitizenInstance otherData, Vector3 min, Vector3 max)
        {
            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;
            float num;
            float num2;

            if (min.x < vector2.x + 1f && min.y < vector2.y && min.z < vector2.z + 1f && vector.x < max.x + 1f && vector.y < max.y + 2f && vector.z < max.z + 1f && segment.DistanceSqr(segment2, out num, out num2) < (1f + info.m_radius) * (1f + info.m_radius))
            {
                float num3 = lastLen + nextLen * num;
                if (num3 >= 0.01f)
                {
                    num3 -= 2f;
                    float b2 = Mathf.Max(1f, CalculateMaxSpeed(num3, 0f, maxBraking));
                    maxSpeed = Mathf.Min(maxSpeed, b2);
                }
            }
            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;
 }
Esempio n. 31
0
 private static ushort CheckOtherVehicle(ushort vehicleID, ref Vehicle vehicleData, ref Vehicle.Frame frameData, ref float maxSpeed, ref bool blocked, ref Vector3 collisionPush, float maxBraking, ushort otherID, ref Vehicle otherData, Vector3 min, Vector3 max, int lodPhysics)
 {
     if (otherID != vehicleID && vehicleData.m_leadingVehicle != otherID && vehicleData.m_trailingVehicle != otherID)
     {
         VehicleInfo info = otherData.Info;
         if (info.m_vehicleType == VehicleInfo.VehicleType.Bicycle)
         {
             return otherData.m_nextGridVehicle;
         }
         Vector3 vector;
         Vector3 vector2;
         if (lodPhysics >= 2)
         {
             vector = otherData.m_segment.Min();
             vector2 = otherData.m_segment.Max();
         }
         else
         {
             vector = Vector3.Min(otherData.m_segment.Min(), otherData.m_targetPos3);
             vector2 = Vector3.Max(otherData.m_segment.Max(), otherData.m_targetPos3);
         }
         if (min.x < vector2.x + 2f && min.y < vector2.y + 2f && min.z < vector2.z + 2f && vector.x < max.x + 2f && vector.y < max.y + 2f && vector.z < max.z + 2f)
         {
             Vehicle.Frame lastFrameData = otherData.GetLastFrameData();
             if (lodPhysics < 2)
             {
                 float num2;
                 float num3;
                 float num = vehicleData.m_segment.DistanceSqr(otherData.m_segment, out num2, out num3);
                 if (num < 4f)
                 {
                     Vector3 a = vehicleData.m_segment.Position(0.5f);
                     Vector3 b = otherData.m_segment.Position(0.5f);
                     Vector3 lhs = vehicleData.m_segment.b - vehicleData.m_segment.a;
                     if (Vector3.Dot(lhs, a - b) < 0f)
                     {
                         collisionPush -= lhs.normalized * (0.1f - num * 0.025f);
                     }
                     else
                     {
                         collisionPush += lhs.normalized * (0.1f - num * 0.025f);
                     }
                     blocked = true;
                 }
             }
             float num4 = frameData.m_velocity.magnitude + 0.01f;
             float num5 = lastFrameData.m_velocity.magnitude;
             float num6 = num5 * (0.5f + 0.5f * num5 / info.m_braking) + Mathf.Min(1f, num5);
             num5 += 0.01f;
             float num7 = 0f;
             Vector3 vector3 = vehicleData.m_segment.b;
             Vector3 lhs2 = vehicleData.m_segment.b - vehicleData.m_segment.a;
             for (int i = 0; i < 4; i++)
             {
                 Vector3 vector4 = vehicleData.GetTargetPos(i);
                 Vector3 vector5 = vector4 - vector3;
                 if (Vector3.Dot(lhs2, vector5) > 0f)
                 {
                     float magnitude = vector5.magnitude;
                     Segment3 segment = new Segment3(vector3, vector4);
                     min = segment.Min();
                     max = segment.Max();
                     segment.a.y = segment.a.y * 0.5f;
                     segment.b.y = segment.b.y * 0.5f;
                     if (magnitude > 0.01f && min.x < vector2.x + 2f && min.y < vector2.y + 2f && min.z < vector2.z + 2f && vector.x < max.x + 2f && vector.y < max.y + 2f && vector.z < max.z + 2f)
                     {
                         Vector3 a2 = otherData.m_segment.a;
                         a2.y *= 0.5f;
                         float num8;
                         if (segment.DistanceSqr(a2, out num8) < 4f)
                         {
                             float num9 = Vector3.Dot(lastFrameData.m_velocity, vector5) / magnitude;
                             float num10 = num7 + magnitude * num8;
                             if (num10 >= 0.01f)
                             {
                                 num10 -= num9 + 3f;
                                 float num11 = Mathf.Max(0f, CalculateMaxSpeed(num10, num9, maxBraking));
                                 if (num11 < 0.01f)
                                 {
                                     blocked = true;
                                 }
                                 Vector3 rhs = Vector3.Normalize(otherData.m_targetPos0 - (Vector4)otherData.m_segment.a);
                                 float num12 = 1.2f - 1f / ((float)vehicleData.m_blockCounter * 0.02f + 0.5f);
                                 if (Vector3.Dot(vector5, rhs) > num12 * magnitude)
                                 {
                                     maxSpeed = Mathf.Min(maxSpeed, num11);
                                 }
                             }
                             break;
                         }
                         if (lodPhysics < 2)
                         {
                             float num13 = 0f;
                             float num14 = num6;
                             Vector3 vector6 = otherData.m_segment.b;
                             Vector3 lhs3 = otherData.m_segment.b - otherData.m_segment.a;
                             bool flag = false;
                             int num15 = 0;
                             while (num15 < 4 && num14 > 0.1f)
                             {
                                 Vector3 vector7 = otherData.GetTargetPos(num15);
                                 Vector3 vector8 = Vector3.ClampMagnitude(vector7 - vector6, num14);
                                 if (Vector3.Dot(lhs3, vector8) > 0f)
                                 {
                                     vector7 = vector6 + vector8;
                                     float magnitude2 = vector8.magnitude;
                                     num14 -= magnitude2;
                                     Segment3 segment2 = new Segment3(vector6, vector7);
                                     segment2.a.y = segment2.a.y * 0.5f;
                                     segment2.b.y = segment2.b.y * 0.5f;
                                     if (magnitude2 > 0.01f)
                                     {
                                         float num17;
                                         float num18;
                                         float num16;
                                         if (otherID < vehicleID)
                                         {
                                             num16 = segment2.DistanceSqr(segment, out num17, out num18);
                                         }
                                         else
                                         {
                                             num16 = segment.DistanceSqr(segment2, out num18, out num17);
                                         }
                                         if (num16 < 4f)
                                         {
                                             float num19 = num7 + magnitude * num18;
                                             float num20 = num13 + magnitude2 * num17 + 0.1f;
                                             if (num19 >= 0.01f && num19 * num5 > num20 * num4)
                                             {
                                                 float num21 = Vector3.Dot(lastFrameData.m_velocity, vector5) / magnitude;
                                                 if (num19 >= 0.01f)
                                                 {
                                                     num19 -= num21 + 1f + otherData.Info.m_generatedInfo.m_size.z;
                                                     float num22 = Mathf.Max(0f, CalculateMaxSpeed(num19, num21, maxBraking));
                                                     if (num22 < 0.01f)
                                                     {
                                                         blocked = true;
                                                     }
                                                     maxSpeed = Mathf.Min(maxSpeed, num22);
                                                 }
                                             }
                                             flag = true;
                                             break;
                                         }
                                     }
                                     lhs3 = vector8;
                                     num13 += magnitude2;
                                     vector6 = vector7;
                                 }
                                 num15++;
                             }
                             if (flag)
                             {
                                 break;
                             }
                         }
                     }
                     lhs2 = vector5;
                     num7 += magnitude;
                     vector3 = vector4;
                 }
             }
         }
     }
     return otherData.m_nextGridVehicle;
 }
        private void ApplyBrush(byte district)
        {
            GameAreaManager instance = Singleton <GameAreaManager> .instance;

            //begin mod
            DistrictManager.Cell[] districtGrid = FakeDistrictManager.districtGrid;
            //end mod
            float num  = 19.2f;
            float num2 = this.m_brushSize * 0.35f + num;
            int   num3 = FakeDistrictManager.GRID;

            Vector3 vector        = (Vector3)m_lastPaintPosition.GetValue(this);
            Vector3 mousePosition = (Vector3)m_mousePosition.GetValue(this);

            if (vector.x < -50000f)
            {
                vector = mousePosition;
            }
            vector.y        = 0f;
            mousePosition.y = 0f;
            Vector3 vector2 = Vector3.Min(vector, mousePosition);
            Vector3 vector3 = Vector3.Max(vector, mousePosition);
            int     num4    = Mathf.Max((int)((vector2.x - num2) / num + (float)num3 * 0.5f), 0);
            int     num5    = Mathf.Max((int)((vector2.z - num2) / num + (float)num3 * 0.5f), 0);
            int     num6    = Mathf.Min((int)((vector3.x + num2) / num + (float)num3 * 0.5f), num3 - 1);
            int     num7    = Mathf.Min((int)((vector3.z + num2) / num + (float)num3 * 0.5f), num3 - 1);
            int     num8    = num3;
            int     num9    = -1;
            int     num10   = num3;
            int     num11   = -1;

            for (int i = num5; i <= num7; i++)
            {
                for (int j = num4; j <= num6; j++)
                {
                    Vector3 vector4 = new Vector3(((float)j - (float)num3 * 0.5f + 0.5f) * num, 0f, ((float)i - (float)num3 * 0.5f + 0.5f) * num);
                    Vector3 a       = vector4;
                    if (instance.ClampPoint(ref a))
                    {
                        float a2    = Mathf.Sqrt(Segment3.DistanceSqr(vector, mousePosition, vector4)) - num2 + num * 2f;
                        float num12 = Vector3.Distance(a, vector4);
                        float num13 = Mathf.Max(a2, num12) - num * 2f;
                        float num14 = Mathf.Clamp01(-num13 / (num * 2f));
                        if (num14 != 0f)
                        {
                            int  min = Mathf.Clamp((int)(256f * num14), 0, 255); //TODO(earalov): should that 256f be replaced with HALFGRID?
                            bool flag;
                            if (num12 > 1f && district != 0)
                            {
                                flag = ForceDistrictAlpha(j, i, district, min, 255);
                            }
                            else
                            {
                                flag = SetDistrictAlpha(j, i, district, min, 255);
                            }
                            if (flag)
                            {
                                num8  = Mathf.Min(num8, j);
                                num9  = Mathf.Max(num9, j);
                                num10 = Mathf.Min(num10, i);
                                num11 = Mathf.Max(num11, i);
                            }
                        }
                    }
                }
            }
            int  num15 = num8;
            int  num16 = num9;
            int  num17 = num10;
            int  num18 = num11;
            int  num19 = 0;
            bool flag2;

            do
            {
                num4  = Mathf.Max(num8 - 1, 0);
                num6  = Mathf.Min(num9 + 1, num3 - 1);
                num5  = Mathf.Max(num10 - 1, 0);
                num7  = Mathf.Min(num11 + 1, num3 - 1);
                num8  = num3;
                num9  = -1;
                num10 = num3;
                num11 = -1;
                flag2 = false;
                for (int k = num5; k <= num7; k++)
                {
                    for (int l = num4; l <= num6; l++)
                    {
                        DistrictManager.Cell cell = districtGrid[k * num3 + l];
                        bool flag3 = false;
                        bool flag4 = false;
                        if (cell.m_alpha1 != 0)
                        {
                            bool flag5 = cell.m_district1 == district;
                            int  num20;
                            int  num21;
                            CheckNeighbourCells(l, k, cell.m_district1, out num20, out num21);
                            if (!flag5 && Mathf.Min((int)(cell.m_alpha1 + 120), 255) > num21)
                            {
                                flag4 = (flag4 || SetDistrictAlpha(l, k, cell.m_district1, 0, Mathf.Max(0, num21 - 120)));
                            }
                            else if (flag5 && Mathf.Max((int)(cell.m_alpha1 - 120), 0) < num20)
                            {
                                flag4 = (flag4 || SetDistrictAlpha(l, k, cell.m_district1, Mathf.Min(255, num20 + 120), 255));
                            }
                            if (flag5)
                            {
                                flag3 = true;
                            }
                        }
                        if (cell.m_alpha2 != 0)
                        {
                            bool flag6 = cell.m_district2 == district;
                            int  num22;
                            int  num23;
                            CheckNeighbourCells(l, k, cell.m_district2, out num22, out num23);
                            if (!flag6 && Mathf.Min((int)(cell.m_alpha2 + 120), 255) > num23)
                            {
                                flag4 = (flag4 || SetDistrictAlpha(l, k, cell.m_district2, 0, Mathf.Max(0, num23 - 120)));
                            }
                            else if (flag6 && Mathf.Max((int)(cell.m_alpha2 - 120), 0) < num22)
                            {
                                flag4 = (flag4 || SetDistrictAlpha(l, k, cell.m_district2, Mathf.Min(255, num22 + 120), 255));
                            }
                            if (flag6)
                            {
                                flag3 = true;
                            }
                        }
                        if (cell.m_alpha3 != 0)
                        {
                            bool flag7 = cell.m_district3 == district;
                            int  num24;
                            int  num25;
                            CheckNeighbourCells(l, k, cell.m_district3, out num24, out num25);
                            if (!flag7 && Mathf.Min((int)(cell.m_alpha3 + 120), 255) > num25)
                            {
                                flag4 = (flag4 || SetDistrictAlpha(l, k, cell.m_district3, 0, Mathf.Max(0, num25 - 120)));
                            }
                            else if (flag7 && Mathf.Max((int)(cell.m_alpha3 - 120), 0) < num24)
                            {
                                flag4 = (flag4 || SetDistrictAlpha(l, k, cell.m_district3, Mathf.Min(255, num24 + 120), 255));
                            }
                            if (flag7)
                            {
                                flag3 = true;
                            }
                        }
                        if (cell.m_alpha4 != 0)
                        {
                            bool flag8 = cell.m_district4 == district;
                            int  num26;
                            int  num27;
                            CheckNeighbourCells(l, k, cell.m_district4, out num26, out num27);
                            if (!flag8 && Mathf.Min((int)(cell.m_alpha4 + 120), 255) > num27)
                            {
                                flag4 = (flag4 || SetDistrictAlpha(l, k, cell.m_district4, 0, Mathf.Max(0, num27 - 120)));
                            }
                            else if (flag8 && Mathf.Max((int)(cell.m_alpha4 - 120), 0) < num26)
                            {
                                flag4 = (flag4 || SetDistrictAlpha(l, k, cell.m_district4, Mathf.Min(255, num26 + 120), 255));
                            }
                            if (flag8)
                            {
                                flag3 = true;
                            }
                        }
                        if (!flag3)
                        {
                            int num28;
                            int num29;
                            CheckNeighbourCells(l, k, district, out num28, out num29);
                            if (0 < num28)
                            {
                                flag4 = (flag4 || SetDistrictAlpha(l, k, district, Mathf.Min(255, num28 + 120), 255));
                            }
                        }
                        if (flag4)
                        {
                            num8  = Mathf.Min(num8, l);
                            num9  = Mathf.Max(num9, l);
                            num10 = Mathf.Min(num10, k);
                            num11 = Mathf.Max(num11, k);
                            flag2 = true;
                        }
                    }
                }
                num15 = Mathf.Min(num15, num8);
                num16 = Mathf.Max(num16, num9);
                num17 = Mathf.Min(num17, num10);
                num18 = Mathf.Max(num18, num11);
            }while (++num19 < 10 && flag2);
            Singleton <DistrictManager> .instance.AreaModified(num15, num17, num16, num18, true);

            Singleton <DistrictManager> .instance.m_districtsNotUsed.Disable();
        }
Esempio n. 33
0
        public static void ApplyBrush(DistrictTool.Layer layer, byte district, float brushRadius, Vector3 startPosition, Vector3 endPosition)
        {
            GameAreaManager instance = Singleton <GameAreaManager> .instance;

            //begin mod
            DistrictManager.Cell[] cellArray = layer != DistrictTool.Layer.Districts ? FakeDistrictManager.parkGrid : FakeDistrictManager.districtGrid;
            //end mod
            float num1 = 19.2f;
            //begin mod
            int num2 = FakeDistrictManager.GRID;

            //end mod
            if ((double)startPosition.x < -50000.0)
            {
                startPosition = endPosition;
            }
            startPosition.y = 0.0f;
            endPosition.y   = 0.0f;
            Vector3 vector3_1 = Vector3.Min(startPosition, endPosition);
            Vector3 vector3_2 = Vector3.Max(startPosition, endPosition);
            int     num3      = Mathf.Max((int)(((double)vector3_1.x - (double)brushRadius) / (double)num1 + (double)num2 * 0.5), 0);
            int     num4      = Mathf.Max((int)(((double)vector3_1.z - (double)brushRadius) / (double)num1 + (double)num2 * 0.5), 0);
            int     num5      = Mathf.Min((int)(((double)vector3_2.x + (double)brushRadius) / (double)num1 + (double)num2 * 0.5), num2 - 1);
            int     num6      = Mathf.Min((int)(((double)vector3_2.z + (double)brushRadius) / (double)num1 + (double)num2 * 0.5), num2 - 1);
            int     num7      = num2;
            int     num8      = -1;
            int     num9      = num2;
            int     num10     = -1;

            for (int index1 = num4; index1 <= num6; ++index1)
            {
                for (int index2 = num3; index2 <= num5; ++index2)
                {
                    Vector3 vector3_3 = new Vector3((float)((double)index2 - (double)num2 * 0.5 + 0.5) * num1, 0.0f, (float)((double)index1 - (double)num2 * 0.5 + 0.5) * num1);
                    Vector3 position  = vector3_3;
                    if (instance.ClampPoint(ref position))
                    {
                        float a     = (float)((double)Mathf.Sqrt(Segment3.DistanceSqr(startPosition, endPosition, vector3_3)) - (double)brushRadius + (double)num1 * 2.0);
                        float b     = Vector3.Distance(position, vector3_3);
                        float num11 = Mathf.Clamp01((float)(-(double)(Mathf.Max(a, b) - num1 * 2f) / ((double)num1 * 2.0)));
                        if ((double)num11 != 0.0)
                        {
                            int min = Mathf.Clamp((int)(256.0 * (double)num11), 0, (int)byte.MaxValue);
                            if ((double)b <= 1.0 || (int)district == 0 ? SetDistrictAlpha(index2, index1, layer, district, min, (int)byte.MaxValue) : ForceDistrictAlpha(index2, index1, layer, district, min, (int)byte.MaxValue))
                            {
                                num7  = Mathf.Min(num7, index2);
                                num8  = Mathf.Max(num8, index2);
                                num9  = Mathf.Min(num9, index1);
                                num10 = Mathf.Max(num10, index1);
                            }
                        }
                    }
                }
            }
            int  num12 = num7;
            int  num13 = num8;
            int  num14 = num9;
            int  num15 = num10;
            int  num16 = 0;
            bool flag1;

            do
            {
                int num11 = Mathf.Max(num7 - 1, 0);
                int num17 = Mathf.Min(num8 + 1, num2 - 1);
                int num18 = Mathf.Max(num9 - 1, 0);
                int num19 = Mathf.Min(num10 + 1, num2 - 1);
                num7  = num2;
                num8  = -1;
                num9  = num2;
                num10 = -1;
                flag1 = false;
                for (int index1 = num18; index1 <= num19; ++index1)
                {
                    for (int index2 = num11; index2 <= num17; ++index2)
                    {
                        DistrictManager.Cell cell = cellArray[index1 * num2 + index2];
                        bool flag2 = false;
                        bool flag3 = false;
                        if ((int)cell.m_alpha1 != 0)
                        {
                            bool flag4 = (int)cell.m_district1 == (int)district;
                            int  min;
                            int  max;
                            CheckNeighbourCells(index2, index1, layer, cell.m_district1, out min, out max);
                            if (!flag4 && Mathf.Min((int)cell.m_alpha1 + 120, (int)byte.MaxValue) > max)
                            {
                                flag3 = flag3 || SetDistrictAlpha(index2, index1, layer, cell.m_district1, 0, Mathf.Max(0, max - 120));
                            }
                            else if (flag4 && Mathf.Max((int)cell.m_alpha1 - 120, 0) < min)
                            {
                                flag3 = flag3 || SetDistrictAlpha(index2, index1, layer, cell.m_district1, Mathf.Min((int)byte.MaxValue, min + 120), (int)byte.MaxValue);
                            }
                            if (flag4)
                            {
                                flag2 = true;
                            }
                        }
                        if ((int)cell.m_alpha2 != 0)
                        {
                            bool flag4 = (int)cell.m_district2 == (int)district;
                            int  min;
                            int  max;
                            CheckNeighbourCells(index2, index1, layer, cell.m_district2, out min, out max);
                            if (!flag4 && Mathf.Min((int)cell.m_alpha2 + 120, (int)byte.MaxValue) > max)
                            {
                                flag3 = flag3 || SetDistrictAlpha(index2, index1, layer, cell.m_district2, 0, Mathf.Max(0, max - 120));
                            }
                            else if (flag4 && Mathf.Max((int)cell.m_alpha2 - 120, 0) < min)
                            {
                                flag3 = flag3 || SetDistrictAlpha(index2, index1, layer, cell.m_district2, Mathf.Min((int)byte.MaxValue, min + 120), (int)byte.MaxValue);
                            }
                            if (flag4)
                            {
                                flag2 = true;
                            }
                        }
                        if ((int)cell.m_alpha3 != 0)
                        {
                            bool flag4 = (int)cell.m_district3 == (int)district;
                            int  min;
                            int  max;
                            CheckNeighbourCells(index2, index1, layer, cell.m_district3, out min, out max);
                            if (!flag4 && Mathf.Min((int)cell.m_alpha3 + 120, (int)byte.MaxValue) > max)
                            {
                                flag3 = flag3 || SetDistrictAlpha(index2, index1, layer, cell.m_district3, 0, Mathf.Max(0, max - 120));
                            }
                            else if (flag4 && Mathf.Max((int)cell.m_alpha3 - 120, 0) < min)
                            {
                                flag3 = flag3 || SetDistrictAlpha(index2, index1, layer, cell.m_district3, Mathf.Min((int)byte.MaxValue, min + 120), (int)byte.MaxValue);
                            }
                            if (flag4)
                            {
                                flag2 = true;
                            }
                        }
                        if ((int)cell.m_alpha4 != 0)
                        {
                            bool flag4 = (int)cell.m_district4 == (int)district;
                            int  min;
                            int  max;
                            CheckNeighbourCells(index2, index1, layer, cell.m_district4, out min, out max);
                            if (!flag4 && Mathf.Min((int)cell.m_alpha4 + 120, (int)byte.MaxValue) > max)
                            {
                                flag3 = flag3 || SetDistrictAlpha(index2, index1, layer, cell.m_district4, 0, Mathf.Max(0, max - 120));
                            }
                            else if (flag4 && Mathf.Max((int)cell.m_alpha4 - 120, 0) < min)
                            {
                                flag3 = flag3 || SetDistrictAlpha(index2, index1, layer, cell.m_district4, Mathf.Min((int)byte.MaxValue, min + 120), (int)byte.MaxValue);
                            }
                            if (flag4)
                            {
                                flag2 = true;
                            }
                        }
                        if (!flag2)
                        {
                            int min;
                            int max;
                            CheckNeighbourCells(index2, index1, layer, district, out min, out max);
                            if (0 < min)
                            {
                                flag3 = flag3 || SetDistrictAlpha(index2, index1, layer, district, Mathf.Min((int)byte.MaxValue, min + 120), (int)byte.MaxValue);
                            }
                        }
                        if (flag3)
                        {
                            num7  = Mathf.Min(num7, index2);
                            num8  = Mathf.Max(num8, index2);
                            num9  = Mathf.Min(num9, index1);
                            num10 = Mathf.Max(num10, index1);
                            flag1 = true;
                        }
                    }
                }
                num12 = Mathf.Min(num12, num7);
                num13 = Mathf.Max(num13, num8);
                num14 = Mathf.Min(num14, num9);
                num15 = Mathf.Max(num15, num10);
            }while (++num16 < 10 && flag1);
            if (layer == DistrictTool.Layer.Districts)
            {
                Singleton <DistrictManager> .instance.AreaModified(num12, num14, num13, num15, true);

                Singleton <DistrictManager> .instance.m_districtsNotUsed.Disable();
            }
            else
            {
                Singleton <DistrictManager> .instance.ParksAreaModified(num12, num14, num13, num15, true);
            }
        }
Esempio n. 34
0
 private static ushort CheckOverlap(Segment3 segment, ushort ignoreVehicle, float maxVelocity, ushort otherID, ref Vehicle otherData, ref bool overlap)
 {
     float num;
     float num2;
     if ((ignoreVehicle == 0 || (otherID != ignoreVehicle && otherData.m_leadingVehicle != ignoreVehicle && otherData.m_trailingVehicle != ignoreVehicle)) && segment.DistanceSqr (otherData.m_segment, out num, out num2) < 4f)
     {
         VehicleInfo info = otherData.Info;
         if (info.m_vehicleType == VehicleInfo.VehicleType.Bicycle)
         {
             return otherData.m_nextGridVehicle;
         }
         if (otherData.GetLastFrameData ().m_velocity.sqrMagnitude < maxVelocity * maxVelocity)
         {
             overlap = true;
         }
     }
     return otherData.m_nextGridVehicle;
 }
 private static ushort CheckOverlap(Segment3 segment, ushort ignoreVehicle, ushort otherID, ref Vehicle otherData, ref bool overlap)
 {
     float num;
     float num2;
     if ((ignoreVehicle == 0 || (otherID != ignoreVehicle && otherData.m_leadingVehicle != ignoreVehicle && otherData.m_trailingVehicle != ignoreVehicle)) && segment.DistanceSqr (otherData.m_segment, out num, out num2) < 400f)
     {
         overlap = true;
     }
     return otherData.m_nextGridVehicle;
 }
Esempio n. 36
0
 private ushort CheckOtherVehicle(ushort vehicleID, ref Vehicle vehicleData, ref Vehicle.Frame frameData, ref float maxSpeed, ref bool blocked, float maxBraking, ushort otherID, ref Vehicle otherData, Vector3 min, Vector3 max, int lodPhysics)
 {
     if (otherID != vehicleID && vehicleData.m_leadingVehicle != otherID && vehicleData.m_trailingVehicle != otherID)
     {
         Vector3 vector;
         Vector3 vector2;
         if (lodPhysics >= 1)
         {
             vector  = otherData.m_segment.Min();
             vector2 = otherData.m_segment.Max();
         }
         else
         {
             vector  = Vector3.Min(otherData.m_segment.Min(), otherData.m_targetPos3);
             vector2 = Vector3.Max(otherData.m_segment.Max(), otherData.m_targetPos3);
         }
         if (min.x < vector2.x + 2f && min.y < vector2.y + 2f && min.z < vector2.z + 2f && vector.x < max.x + 2f && vector.y < max.y + 2f && vector.z < max.z + 2f)
         {
             Vehicle.Frame lastFrameData = otherData.GetLastFrameData();
             VehicleInfo   info          = otherData.Info;
             float         num           = frameData.m_velocity.magnitude + 0.01f;
             float         num2          = lastFrameData.m_velocity.magnitude;
             float         num3          = num2 * (0.5f + 0.5f * num2 / info.m_braking) + info.m_generatedInfo.m_size.z * Mathf.Min(0.5f, num2 * 0.1f);
             num2 += 0.01f;
             float   num4    = 0f;
             Vector3 vector3 = frameData.m_position;
             Vector3 lhs     = ((Vector3)vehicleData.m_targetPos3) - frameData.m_position;
             for (int i = 1; i < 4; i++)
             {
                 Vector3 vector4 = vehicleData.GetTargetPos(i);
                 Vector3 vector5 = vector4 - vector3;
                 if (Vector3.Dot(lhs, vector5) > 0f)
                 {
                     float    magnitude = vector5.magnitude;
                     Segment3 segment   = new Segment3(vector3, vector4);
                     min         = segment.Min();
                     max         = segment.Max();
                     segment.a.y = segment.a.y * 0.5f;
                     segment.b.y = segment.b.y * 0.5f;
                     if (magnitude > 0.01f && min.x < vector2.x + 2f && min.y < vector2.y + 2f && min.z < vector2.z + 2f && vector.x < max.x + 2f && vector.y < max.y + 2f && vector.z < max.z + 2f)
                     {
                         Vector3 a = otherData.m_segment.a;
                         a.y *= 0.5f;
                         float num5;
                         if (segment.DistanceSqr(a, out num5) < 400f)
                         {
                             float num6 = Vector3.Dot(lastFrameData.m_velocity, vector5) / magnitude;
                             float num7 = num4 + magnitude * num5;
                             if (num7 >= 0.01f)
                             {
                                 num7 -= num6 + 30f;
                                 float num8 = Mathf.Max(0f, CalculateMaxSpeed(num7, num6, maxBraking));
                                 if (num8 < 0.01f)
                                 {
                                     blocked = true;
                                 }
                                 Vector3 rhs  = Vector3.Normalize(((Vector3)otherData.m_targetPos3) - otherData.GetLastFramePosition());
                                 float   num9 = 1.2f - 1f / ((float)vehicleData.m_blockCounter * 0.02f + 0.5f);
                                 if (Vector3.Dot(vector5, rhs) > num9 * magnitude)
                                 {
                                     maxSpeed = Mathf.Min(maxSpeed, num8);
                                 }
                             }
                             break;
                         }
                         if (lodPhysics == 0)
                         {
                             float   num10   = 0f;
                             float   num11   = num3;
                             Vector3 vector6 = otherData.GetLastFramePosition();
                             Vector3 lhs2    = ((Vector3)otherData.m_targetPos3) - vector6;
                             bool    flag    = false;
                             int     num12   = 1;
                             while (num12 < 4 && num11 > 0.1f)
                             {
                                 Vector3 vector7 = otherData.GetTargetPos(num12);
                                 Vector3 vector8 = Vector3.ClampMagnitude(vector7 - vector6, num11);
                                 if (Vector3.Dot(lhs2, vector8) > 0f)
                                 {
                                     vector7 = vector6 + vector8;
                                     float magnitude2 = vector8.magnitude;
                                     num11 -= magnitude2;
                                     Segment3 segment2 = new Segment3(vector6, vector7);
                                     segment2.a.y = segment2.a.y * 0.5f;
                                     segment2.b.y = segment2.b.y * 0.5f;
                                     if (magnitude2 > 0.01f)
                                     {
                                         float num14;
                                         float num15;
                                         float num13;
                                         if (otherID < vehicleID)
                                         {
                                             num13 = segment2.DistanceSqr(segment, out num14, out num15);
                                         }
                                         else
                                         {
                                             num13 = segment.DistanceSqr(segment2, out num15, out num14);
                                         }
                                         if (num13 < 400f)
                                         {
                                             float num16 = num4 + magnitude * num15;
                                             float num17 = num10 + magnitude2 * num14 + 0.1f;
                                             if (num16 >= 0.01f && num16 * num2 > num17 * num)
                                             {
                                                 float num18 = Vector3.Dot(lastFrameData.m_velocity, vector5) / magnitude;
                                                 if (num16 >= 0.01f)
                                                 {
                                                     num16 -= num18 + 10f + otherData.Info.m_generatedInfo.m_size.z;
                                                     float num19 = Mathf.Max(0f, CalculateMaxSpeed(num16, num18, maxBraking));
                                                     if (num19 < 0.01f)
                                                     {
                                                         blocked = true;
                                                     }
                                                     maxSpeed = Mathf.Min(maxSpeed, num19);
                                                 }
                                             }
                                             flag = true;
                                             break;
                                         }
                                     }
                                     lhs2    = vector8;
                                     num10  += magnitude2;
                                     vector6 = vector7;
                                 }
                                 num12++;
                             }
                             if (flag)
                             {
                                 break;
                             }
                         }
                     }
                     lhs     = vector5;
                     num4   += magnitude;
                     vector3 = vector4;
                 }
             }
         }
     }
     return(otherData.m_nextGridVehicle);
 }