private static bool RayCastNode(ref NetNode node, Segment3 ray, float snapElevation, out float t, out float priority) { NetInfo info = node.Info; float num = (float)node.m_elevation + info.m_netAI.GetSnapElevation(); float t2; if (info.m_netAI.IsUnderground()) { t2 = Mathf.Clamp01(Mathf.Abs(snapElevation + num) / 12f); } else { t2 = Mathf.Clamp01(Mathf.Abs(snapElevation - num) / 12f); } float collisionHalfWidth = Mathf.Max(3f, info.m_netAI.GetCollisionHalfWidth()); float num2 = Mathf.Lerp(info.GetMinNodeDistance(), collisionHalfWidth, t2); if (Segment1.Intersect(ray.a.y, ray.b.y, node.m_position.y, out t)) { float num3 = Vector3.Distance(ray.Position(t), node.m_position); if (num3 < num2) { priority = Mathf.Max(0f, num3 - collisionHalfWidth); return(true); } } t = 0f; priority = 0f; return(false); }
public static bool IsTrafficHandSideOf(Segment3 segment, Segment3 ray, float tRay, bool invert) { Vector3 segmentVector = segment.b - segment.a; Vector3 rayVector = ray.Position(tRay) - segment.a; // Debug.Log($"startnode->endnode: {segmentVector}, startnode->ray: {rayVector}"); float crossProduct = rayVector.x * segmentVector.z - segmentVector.x * rayVector.z; // Debug.Log($"cross product: {crossProduct}"); return(invert ? crossProduct < 0 : crossProduct > 0); }
private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref CitizenInstance otherData, ref Vector3 pushAmount, ref float pushDivider) { if (otherID == instanceID) { return(otherData.m_nextGridInstance); } if (((citizenData.m_flags | otherData.m_flags) & CitizenInstance.Flags.Transition) == CitizenInstance.Flags.None && (citizenData.m_flags & CitizenInstance.Flags.Underground) != (citizenData.m_flags & CitizenInstance.Flags.Underground)) { return(otherData.m_nextGridInstance); } CitizenInfo info = otherData.Info; CitizenInstance.Frame lastFrameData = otherData.GetLastFrameData(); Vector3 position = lastFrameData.m_position; Vector3 b = lastFrameData.m_position + lastFrameData.m_velocity; Segment3 segment2 = new Segment3(position, b); Vector3 vector = segment2.Min(); vector.x -= info.m_radius; vector.z -= info.m_radius; Vector3 vector2 = segment2.Max(); vector2.x += info.m_radius; vector2.y += info.m_height; vector2.z += info.m_radius; if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y) { float num = this.m_info.m_radius + info.m_radius; float num3; float t; float num2 = segment.DistanceSqr(segment2, out num3, out t); if (num2 < num * num) { float num4 = num - Mathf.Sqrt(num2); float num5 = 1f - num2 / (num * num); Vector3 a = segment.Position(num3 * 0.9f); Vector3 b2 = segment2.Position(t); a.y = 0f; b2.y = 0f; Vector3 vector3 = a - b2; Vector3 vector4 = new Vector3(segment.b.z - segment.a.z, 0f, segment.a.x - segment.b.x); if (Vector3.Dot(vector3, vector4) >= 0f) { vector3 += vector4; } else { vector3 -= vector4; } pushAmount += vector3.normalized * (num4 * num5); pushDivider += num5; } } return(otherData.m_nextGridInstance); }
private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref VehicleParked otherData, ref Vector3 pushAmount, ref float pushDivider) { VehicleInfo info = otherData.Info; Vector3 position = otherData.m_position; Vector3 b = otherData.m_rotation * new Vector3(0f, 0f, Mathf.Max(0.5f, info.m_generatedInfo.m_size.z * 0.5f - 1f)); Segment3 segment2; segment2.a = position - b; segment2.b = position + b; Vector3 vector = segment2.Min(); vector.x -= 1f; vector.z -= 1f; Vector3 vector2 = segment2.Max(); vector2.x += 1f; vector2.y += 1f; vector2.z += 1f; if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y) { float num = this.m_info.m_radius + 1f; float num3; float t; float num2 = segment.DistanceSqr(segment2, out num3, out t); if (num2 < num * num) { float num4 = num - Mathf.Sqrt(num2); float num5 = 1f - num2 / (num * num); Vector3 a = segment.Position(num3 * 0.9f); Vector3 b2 = segment2.Position(t); a.y = 0f; b2.y = 0f; Vector3 vector3 = Vector3.Normalize(a - b2); Vector3 rhs = Vector3.Normalize(new Vector3(segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z)); Vector3 vector4 = new Vector3(rhs.z, 0f, -rhs.x) * Mathf.Abs(Vector3.Dot(vector3, rhs) * 0.5f); if (Vector3.Dot(vector3, vector4) >= 0f) { vector3 += vector4; } else { vector3 -= vector4; } pushAmount += vector3 * (num4 * num5); pushDivider += num5; } } return(otherData.m_nextGridParked); }
//to detour move it public static bool MoveItRayCastNode(ref NetNode node, Segment3 ray, float snapElevation, out float t, out float priority) { NetInfo info = node.Info; // NON-STOCK CODE STARTS if (CSUROffset.IsCSUROffset(info.m_netAI.m_info)) { return(RayCastNodeMasked(ref node, ray, snapElevation, false, out t, out priority)); } // NON-STOCK CODE ENDS //if ((node.m_flags & (NetNode.Flags.Middle | NetNode.Flags.Outside)) == NetNode.Flags.None) //{ float num = (float)node.m_elevation + info.m_netAI.GetSnapElevation(); float t2; if (info.m_netAI.IsUnderground()) { t2 = Mathf.Clamp01(Mathf.Abs(snapElevation + num) / 12f); } else { t2 = Mathf.Clamp01(Mathf.Abs(snapElevation - num) / 12f); } float collisionHalfWidth = Mathf.Max(3f, info.m_netAI.GetCollisionHalfWidth()); float num2 = Mathf.Lerp(info.GetMinNodeDistance(), collisionHalfWidth, t2); if (Segment1.Intersect(ray.a.y, ray.b.y, node.m_position.y, out t)) { float num3 = Vector3.Distance(ray.Position(t), node.m_position); if (num3 < num2) { priority = Mathf.Max(0f, num3 - collisionHalfWidth); return(true); } } //} t = 0f; priority = 0f; return(false); }
public static bool NetSegmentRayCastMasked(NetSegment mysegment, ushort segmentID, Segment3 ray, float snapElevation, bool bothSides, out float t, out float priority) { bool lht = false; //if (SimulationManager.instance.m_metaData.m_invertTraffic == SimulationMetaData.MetaBool.True) lht = true; //Debug.Log(mysegment.m_flags); if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0) { lht = true; } bool isMasked = false; NetInfo info = mysegment.Info; t = 0f; priority = 0f; Bounds bounds = mysegment.m_bounds; bounds.Expand(16f); if (!bounds.IntersectRay(new Ray(ray.a, ray.b - ray.a))) { return(false); } NetManager instance = Singleton <NetManager> .instance; Bezier3 bezier = default(Bezier3); bezier.a = instance.m_nodes.m_buffer[mysegment.m_startNode].m_position; bezier.d = instance.m_nodes.m_buffer[mysegment.m_endNode].m_position; bool result = false; info.m_netAI.GetRayCastHeights(segmentID, ref mysegment, out float leftMin, out float rightMin, out float max); bezier.a.y += max; bezier.d.y += max; bool flag = (instance.m_nodes.m_buffer[mysegment.m_startNode].m_flags & NetNode.Flags.Middle) != 0; bool flag2 = (instance.m_nodes.m_buffer[mysegment.m_endNode].m_flags & NetNode.Flags.Middle) != 0; NetSegment.CalculateMiddlePoints(bezier.a, mysegment.m_startDirection, bezier.d, mysegment.m_endDirection, flag, flag2, out bezier.b, out bezier.c); float minNodeDistance = info.GetMinNodeDistance(); // float collisionHalfWidth = info.m_halfWidth; float maskHalfWidth = info.m_pavementWidth; // float num4 = (int)instance.m_nodes.m_buffer[mysegment.m_startNode].m_elevation; float num5 = (int)instance.m_nodes.m_buffer[mysegment.m_endNode].m_elevation; if (info.m_netAI.IsUnderground()) { num4 = 0f - num4; num5 = 0f - num5; } num4 += info.m_netAI.GetSnapElevation(); num5 += info.m_netAI.GetSnapElevation(); float a = Mathf.Lerp(minNodeDistance, collisionHalfWidth, Mathf.Clamp01(Mathf.Abs(snapElevation - num4) / 12f)); float b2 = Mathf.Lerp(minNodeDistance, collisionHalfWidth, Mathf.Clamp01(Mathf.Abs(snapElevation - num5) / 12f)); float am = Mathf.Lerp(minNodeDistance, maskHalfWidth, Mathf.Clamp01(Mathf.Abs(snapElevation - num4) / 12f)); float b2m = Mathf.Lerp(minNodeDistance, maskHalfWidth, Mathf.Clamp01(Mathf.Abs(snapElevation - num5) / 12f)); float num6 = Mathf.Min(leftMin, rightMin); t = 1000000f; priority = 1000000f; Segment3 segment = default(Segment3); segment.a = bezier.a; Segment2 segment2 = default(Segment2); //Debug.Log($"mouse ray: {ray.a} --> {ray.b}"); //Debug.Log($"segment direction: {bezier.a} --> {bezier.b}"); for (int i = 1; i <= 16; i++) { segment.b = bezier.Position((float)i / 16f); float num7 = ray.DistanceSqr(segment, out float u2, out float v2); float num8 = Mathf.Lerp(a, b2, ((float)(i - 1) + v2) / 16f); float num8m = Mathf.Lerp(am, b2m, ((float)(i - 1) + v2) / 16f); Vector3 vector2 = segment.Position(v2); bool atOffsetSide = bothSides || IsTrafficHandSideOf(segment, ray, u2, lht); if (atOffsetSide && num7 < priority && Segment1.Intersect(ray.a.y, ray.b.y, vector2.y, out u2)) { Vector3 vector3 = ray.Position(u2); num7 = Vector3.SqrMagnitude(vector3 - vector2); //Debug.Log($"num7: {num7}, num8: {num8}, num8m: {num8m}"); if (num7 < priority && num7 < num8 * num8) { if (flag && i == 1 && v2 < 0.001f) { Vector3 rhs = segment.a - segment.b; u2 += Mathf.Max(0f, Vector3.Dot(vector3, rhs)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs.sqrMagnitude * ray.LengthSqr())); } if (flag2 && i == 16 && v2 > 0.999f) { Vector3 rhs2 = segment.b - segment.a; u2 += Mathf.Max(0f, Vector3.Dot(vector3, rhs2)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs2.sqrMagnitude * ray.LengthSqr())); } priority = num7; t = u2; result = true; if (num7 < num8m * num8m) { isMasked = true; } } } if (atOffsetSide && num6 < max) { float num9 = vector2.y + num6 - max; if (Mathf.Max(ray.a.y, ray.b.y) > num9 && Mathf.Min(ray.a.y, ray.b.y) < vector2.y) { float num10; if (Segment1.Intersect(ray.a.y, ray.b.y, vector2.y, out u2)) { segment2.a = VectorUtils.XZ(ray.Position(u2)); num10 = u2; } else { segment2.a = VectorUtils.XZ(ray.a); num10 = 0f; } float num11; if (Segment1.Intersect(ray.a.y, ray.b.y, num9, out u2)) { segment2.b = VectorUtils.XZ(ray.Position(u2)); num11 = u2; } else { segment2.b = VectorUtils.XZ(ray.b); num11 = 1f; } num7 = segment2.DistanceSqr(VectorUtils.XZ(vector2), out u2); if (num7 < priority && num7 < num8 * num8) { u2 = num10 + (num11 - num10) * u2; Vector3 lhs = ray.Position(u2); if (flag && i == 1 && v2 < 0.001f) { Vector3 rhs3 = segment.a - segment.b; u2 += Mathf.Max(0f, Vector3.Dot(lhs, rhs3)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs3.sqrMagnitude * ray.LengthSqr())); } if (flag2 && i == 16 && v2 > 0.999f) { Vector3 rhs4 = segment.b - segment.a; u2 += Mathf.Max(0f, Vector3.Dot(lhs, rhs4)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs4.sqrMagnitude * ray.LengthSqr())); } priority = num7; t = u2; result = true; if (num7 < num8m * num8m) { isMasked = true; } } } } segment.a = segment.b; } priority = Mathf.Max(0f, Mathf.Sqrt(priority) - collisionHalfWidth); if (isMasked) { result = false; } return(result); }
public static bool Prefix(ref NetSegment __instance, ushort segmentID, Segment3 ray, float snapElevation, bool nameOnly, out float t, out float priority, ref bool __result) { // NON-STOCK CODE STARTS float laneOffset = 0; float startOffset = 0; float endOffset = 0; bool IsCSURSLane = CSURUtil.IsCSURSLane(__instance.Info.m_netAI.m_info, ref laneOffset, ref startOffset, ref endOffset); if (CSURUtil.IsCSUROffset(__instance.Info.m_netAI.m_info) && !IsCSURSLane) { __result = NetSegmentRayCastMasked(__instance, segmentID, ray, -1000f, false, out t, out priority); return(false); } // NON-STOCK CODE ENDS NetInfo info = __instance.Info; t = 0f; priority = 0f; if (nameOnly && (__instance.m_flags & NetSegment.Flags.NameVisible2) == NetSegment.Flags.None) { __result = false; return(false); } Bounds bounds = __instance.m_bounds; bounds.Expand(16f); if (!bounds.IntersectRay(new Ray(ray.a, ray.b - ray.a))) { __result = false; return(false); } NetManager instance = Singleton <NetManager> .instance; Bezier3 bezier = default(Bezier3); bezier.a = instance.m_nodes.m_buffer[__instance.m_startNode].m_position; bezier.d = instance.m_nodes.m_buffer[__instance.m_endNode].m_position; bool result = false; if (nameOnly) { RenderManager instance2 = Singleton <RenderManager> .instance; if (instance2.GetInstanceIndex((uint)(49152 + segmentID), out uint instanceIndex)) { InstanceManager.NameData nameData = instance2.m_instances[instanceIndex].m_nameData; Vector3 position = instance2.m_instances[instanceIndex].m_position; Matrix4x4 dataMatrix = instance2.m_instances[instanceIndex].m_dataMatrix2; float num = Vector3.Distance(position, ray.a); if (nameData != null && num < 1000f) { float snapElevation2 = info.m_netAI.GetSnapElevation(); bezier.a.y += snapElevation2; bezier.d.y += snapElevation2; NetSegment.CalculateMiddlePoints(bezier.a, __instance.m_startDirection, bezier.d, __instance.m_endDirection, true, true, out bezier.b, out bezier.c); float num2 = Mathf.Max(1f, Mathf.Abs(dataMatrix.m33 - dataMatrix.m30)); float d = num * 0.0002f + 0.05f / (1f + num * 0.001f); Vector2 vector = nameData.m_size * d; float t2 = Mathf.Max(0f, 0.5f - vector.x / num2 * 0.5f); float t3 = Mathf.Min(1f, 0.5f + vector.x / num2 * 0.5f); bezier = bezier.Cut(t2, t3); float num3 = bezier.DistanceSqr(ray, out float u, out float _); if (num3 < vector.y * vector.y * 0.25f) { Vector3 b = bezier.Position(u); if (Segment1.Intersect(ray.a.y, ray.b.y, b.y, out u)) { num3 = Vector3.SqrMagnitude(ray.Position(u) - b); if (num3 < vector.y * vector.y * 0.25f) { t = u; result = true; } } } } } } else { info.m_netAI.GetRayCastHeights(segmentID, ref __instance, out float leftMin, out float rightMin, out float max); bezier.a.y += max; bezier.d.y += max; bool flag = (instance.m_nodes.m_buffer[__instance.m_startNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None; bool flag2 = (instance.m_nodes.m_buffer[__instance.m_endNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None; NetSegment.CalculateMiddlePoints(bezier.a, __instance.m_startDirection, bezier.d, __instance.m_endDirection, flag, flag2, out bezier.b, out bezier.c); // NON-STOCK CODE STARTS if (IsCSURSLane) { float vehicleLaneNum = CSURUtil.CountCSURSVehicleLanes(info); float otherLaneNum = CSURUtil.CountCSURSOtherLanes(info); float laneNum = vehicleLaneNum + otherLaneNum; startOffset = startOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f; endOffset = endOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f; if ((__instance.m_flags & NetSegment.Flags.Invert) != 0) { startOffset = -startOffset; endOffset = -endOffset; } //EG: before patch: point1-point4 is 1.5*3.75 //After patch, point1-point4 is (1 1.3333 1.6667 2)*3.75 Vector3 newBezierA = bezier.a + (new Vector3(__instance.m_startDirection.z, 0, -__instance.m_startDirection.x).normalized) * (startOffset); Vector3 newBezierBDir = VectorUtils.NormalizeXZ(bezier.Tangent(0.333f)); Vector3 newBezierB = bezier.b + (new Vector3(newBezierBDir.z, 0, -newBezierBDir.x).normalized) * (startOffset * 0.667f + endOffset * 0.333f); Vector3 newBezierCDir = VectorUtils.NormalizeXZ(bezier.Tangent(0.667f)); Vector3 newBezierC = bezier.c + (new Vector3(newBezierCDir.z, 0, -newBezierCDir.x).normalized) * (startOffset * 0.333f + endOffset * 0.667f); Vector3 newBezierD = bezier.d + (new Vector3(-__instance.m_endDirection.z, 0, __instance.m_endDirection.x).normalized) * (endOffset); bezier.a = newBezierA; bezier.b = newBezierB; bezier.c = newBezierC; bezier.d = newBezierD; } float minNodeDistance = info.GetMinNodeDistance(); float collisionHalfWidth = info.m_netAI.GetCollisionHalfWidth(); float num4 = (float)(int)instance.m_nodes.m_buffer[__instance.m_startNode].m_elevation; float num5 = (float)(int)instance.m_nodes.m_buffer[__instance.m_endNode].m_elevation; if (info.m_netAI.IsUnderground()) { num4 = 0f - num4; num5 = 0f - num5; } num4 += info.m_netAI.GetSnapElevation(); num5 += info.m_netAI.GetSnapElevation(); float a = Mathf.Lerp(minNodeDistance, collisionHalfWidth, Mathf.Clamp01(Mathf.Abs(snapElevation - num4) / 12f)); float b2 = Mathf.Lerp(minNodeDistance, collisionHalfWidth, Mathf.Clamp01(Mathf.Abs(snapElevation - num5) / 12f)); float num6 = Mathf.Min(leftMin, rightMin); t = 1000000f; priority = 1000000f; Segment3 segment = default(Segment3); segment.a = bezier.a; for (int i = 1; i <= 16; i++) { segment.b = bezier.Position((float)i / 16f); float num7 = ray.DistanceSqr(segment, out float u2, out float v2); float num8 = Mathf.Lerp(a, b2, ((float)(i - 1) + v2) / 16f); Vector3 vector2 = segment.Position(v2); if (num7 < priority && Segment1.Intersect(ray.a.y, ray.b.y, vector2.y, out u2)) { Vector3 vector3 = ray.Position(u2); num7 = Vector3.SqrMagnitude(vector3 - vector2); if (num7 < priority && num7 < num8 * num8) { if (flag && i == 1 && v2 < 0.001f) { Vector3 rhs = segment.a - segment.b; u2 += Mathf.Max(0f, Vector3.Dot(vector3, rhs)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs.sqrMagnitude * ray.LengthSqr())); } if (flag2 && i == 16 && v2 > 0.999f) { Vector3 rhs2 = segment.b - segment.a; u2 += Mathf.Max(0f, Vector3.Dot(vector3, rhs2)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs2.sqrMagnitude * ray.LengthSqr())); } priority = num7; t = u2; result = true; } } if (num6 < max) { float num9 = vector2.y + num6 - max; if (Mathf.Max(ray.a.y, ray.b.y) > num9 && Mathf.Min(ray.a.y, ray.b.y) < vector2.y) { Segment2 segment2 = default(Segment2); float num10; if (Segment1.Intersect(ray.a.y, ray.b.y, vector2.y, out u2)) { segment2.a = VectorUtils.XZ(ray.Position(u2)); num10 = u2; } else { segment2.a = VectorUtils.XZ(ray.a); num10 = 0f; } float num11; if (Segment1.Intersect(ray.a.y, ray.b.y, num9, out u2)) { segment2.b = VectorUtils.XZ(ray.Position(u2)); num11 = u2; } else { segment2.b = VectorUtils.XZ(ray.b); num11 = 1f; } num7 = segment2.DistanceSqr(VectorUtils.XZ(vector2), out u2); if (num7 < priority && num7 < num8 * num8) { u2 = num10 + (num11 - num10) * u2; Vector3 lhs = ray.Position(u2); if (flag && i == 1 && v2 < 0.001f) { Vector3 rhs3 = segment.a - segment.b; u2 += Mathf.Max(0f, Vector3.Dot(lhs, rhs3)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs3.sqrMagnitude * ray.LengthSqr())); } if (flag2 && i == 16 && v2 > 0.999f) { Vector3 rhs4 = segment.b - segment.a; u2 += Mathf.Max(0f, Vector3.Dot(lhs, rhs4)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs4.sqrMagnitude * ray.LengthSqr())); } priority = num7; t = u2; result = true; } } } segment.a = segment.b; } priority = Mathf.Max(0f, Mathf.Sqrt(priority) - collisionHalfWidth); } __result = result; return(false); }
private static bool RayCast(TreeManager tm, Segment3 ray, ItemClass.Service service, ItemClass.SubService subService, ItemClass.Layer itemLayers, TreeInstance.Flags ignoreFlags, out Vector3 hit, out uint treeIndex) { unsafe { int num; int num1; int num2; int num3; int num4; int num5; float single; float single1; Bounds bound = new Bounds(new Vector3(0f, 512f, 0f), new Vector3(17280f, 1152f, 17280f)); if (ray.Clip(bound)) { Vector3 vector3 = ray.b - ray.a; int num6 = (int)((double)ray.a.x / 32 + 270); int num7 = (int)((double)ray.a.z / 32 + 270); int num8 = (int)((double)ray.b.x / 32 + 270); int num9 = (int)((double)ray.b.z / 32 + 270); float single2 = Mathf.Abs(vector3.x); float single3 = Mathf.Abs(vector3.z); if ((double)single2 < (double)single3) { num = 0; num1 = ((double)vector3.z <= 0 ? -1 : 1); if ((double)single3 != 0) { vector3 = vector3 * (32f / single3); } } else { num = ((double)vector3.x <= 0 ? -1 : 1); num1 = 0; if ((double)single2 != 0) { vector3 = vector3 * (32f / single2); } } float single4 = 2f; float single5 = 10000f; treeIndex = 0; Vector3 vector31 = ray.a; Vector3 vector32 = ray.a; int num10 = num6; int num11 = num7; do { Vector3 vector33 = vector32 + vector3; if (num == 0) { num4 = ((num11 != num7 || num1 <= 0) && (num11 != num9 || num1 >= 0) ? Mathf.Max(num11, 0) : Mathf.Max((int)(((double)vector33.z - 72) / 32 + 270), 0)); num5 = ((num11 != num7 || num1 >= 0) && (num11 != num9 || num1 <= 0) ? Mathf.Min(num11, 539) : Mathf.Min((int)(((double)vector33.z + 72) / 32 + 270), 539)); num2 = Mathf.Max((int)(((double)Mathf.Min(vector31.x, vector33.x) - 72) / 32 + 270), 0); num3 = Mathf.Min((int)(((double)Mathf.Max(vector31.x, vector33.x) + 72) / 32 + 270), 539); } else { num2 = ((num10 != num6 || num <= 0) && (num10 != num8 || num >= 0) ? Mathf.Max(num10, 0) : Mathf.Max((int)(((double)vector33.x - 72) / 32 + 270), 0)); num3 = ((num10 != num6 || num >= 0) && (num10 != num8 || num <= 0) ? Mathf.Min(num10, 539) : Mathf.Min((int)(((double)vector33.x + 72) / 32 + 270), 539)); num4 = Mathf.Max((int)(((double)Mathf.Min(vector31.z, vector33.z) - 72) / 32 + 270), 0); num5 = Mathf.Min((int)(((double)Mathf.Max(vector31.z, vector33.z) + 72) / 32 + 270), 539); } for (int i = num4; i <= num5; i++) { for (int j = num2; j <= num3; j++) { uint mTreeGrid = tm.m_treeGrid[i * 540 + j]; int num12 = 0; while (mTreeGrid != 0) { if ((tm.m_trees.m_buffer[mTreeGrid].m_flags & (ushort)ignoreFlags) == (ushort)TreeInstance.Flags.None && (double)ray.DistanceSqr(tm.m_trees.m_buffer[mTreeGrid].Position) < 2500) { TreeInfo info = tm.m_trees.m_buffer[mTreeGrid].Info; if ((service == ItemClass.Service.None || info.m_class.m_service == service) && (subService == ItemClass.SubService.None || info.m_class.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (info.m_class.m_layer & itemLayers) != ItemClass.Layer.None) && tm.m_trees.m_buffer[mTreeGrid].RayCast(mTreeGrid, ray, out single, out single1) && ((double)single < (double)single4 - 9.99999974737875E-05 || (double)single < (double)single4 + 9.99999974737875E-05 && (double)single1 < (double)single5)) { single4 = single; single5 = single1; treeIndex = mTreeGrid; } } mTreeGrid = tm.m_trees.m_buffer[mTreeGrid].m_nextGridTree; int num13 = num12 + 1; num12 = num13; if (num13 <= LimitTreeManager.Helper.TreeLimit) { continue; } CODebugBase<LogChannel>.Error(LogChannel.Core, string.Concat("Invalid list detected!\n", Environment.StackTrace)); break; } } } vector31 = vector32; vector32 = vector33; num10 = num10 + num; num11 = num11 + num1; } while ((num10 <= num8 || num <= 0) && (num10 >= num8 || num >= 0) && (num11 <= num9 || num1 <= 0) && (num11 >= num9 || num1 >= 0)); if ((double)single4 != 2) { hit = ray.Position(single4); return true; } } hit = Vector3.zero; treeIndex = 0; return false; } }
protected void CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Vector3 sourcePos, Vector3 targetPos, ushort buildingID, ref Vector3 pushAmount, ref float pushDivider) { Segment3 segment = new Segment3(sourcePos, targetPos); Vector3 min = segment.Min(); min.x -= this.m_info.m_radius; min.z -= this.m_info.m_radius; Vector3 max = segment.Max(); max.x += this.m_info.m_radius; max.y += this.m_info.m_height; max.z += this.m_info.m_radius; CitizenManager instance = Singleton <CitizenManager> .instance; int num = Mathf.Max((int)((min.x - 3f) / 8f + 1080f), 0); int num2 = Mathf.Max((int)((min.z - 3f) / 8f + 1080f), 0); int num3 = Mathf.Min((int)((max.x + 3f) / 8f + 1080f), 2159); int num4 = Mathf.Min((int)((max.z + 3f) / 8f + 1080f), 2159); for (int i = num2; i <= num4; i++) { for (int j = num; j <= num3; j++) { ushort num5 = instance.m_citizenGrid [i * 2160 + j]; int num6 = 0; while (num5 != 0) { num5 = this.CheckCollisions(instanceID, ref citizenData, segment, min, max, num5, ref instance.m_instances.m_buffer [(int)num5], ref pushAmount, ref pushDivider); if (++num6 > 65536) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } VehicleManager instance2 = Singleton <VehicleManager> .instance; int num7 = Mathf.Max((int)((min.x - 10f) / 32f + 270f), 0); int num8 = Mathf.Max((int)((min.z - 10f) / 32f + 270f), 0); int num9 = Mathf.Min((int)((max.x + 10f) / 32f + 270f), 539); int num10 = Mathf.Min((int)((max.z + 10f) / 32f + 270f), 539); for (int k = num8; k <= num10; k++) { for (int l = num7; l <= num9; l++) { ushort num11 = instance2.m_vehicleGrid [k * 540 + l]; int num12 = 0; while (num11 != 0) { num11 = this.CheckCollisions(instanceID, ref citizenData, segment, min, max, num11, ref instance2.m_vehicles.m_buffer [(int)num11], ref pushAmount, ref pushDivider); if (++num12 > 65536) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } for (int m = num8; m <= num10; m++) { for (int n = num7; n <= num9; n++) { ushort num13 = instance2.m_parkedGrid [m * 540 + n]; int num14 = 0; while (num13 != 0) { num13 = this.CheckCollisions(instanceID, ref citizenData, segment, min, max, num13, ref instance2.m_parkedVehicles.m_buffer [(int)num13], ref pushAmount, ref pushDivider); if (++num14 > 65536) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } if (buildingID != 0) { BuildingManager instance3 = Singleton <BuildingManager> .instance; BuildingInfo info = instance3.m_buildings.m_buffer [(int)buildingID].Info; if (info.m_props != null) { Vector3 position = instance3.m_buildings.m_buffer [(int)buildingID].m_position; float angle = instance3.m_buildings.m_buffer [(int)buildingID].m_angle; int length = instance3.m_buildings.m_buffer [(int)buildingID].Length; Matrix4x4 matrix4x = default(Matrix4x4); matrix4x.SetTRS(Building.CalculateMeshPosition(info, position, angle, length), Quaternion.AngleAxis(angle * 57.29578f, Vector3.down), Vector3.one); for (int num15 = 0; num15 < info.m_props.Length; num15++) { BuildingInfo.Prop prop = info.m_props [num15]; Randomizer randomizer = new Randomizer((int)buildingID << 6 | prop.m_index); if (randomizer.Int32(100u) < prop.m_probability && length >= prop.m_requiredLength) { Vector3 vector = matrix4x.MultiplyPoint(prop.m_position); if (vector.x >= min.x - 2f && vector.x <= max.x + 2f) { if (vector.z >= min.z - 2f && vector.z <= max.z + 2f) { PropInfo propInfo = prop.m_finalProp; TreeInfo treeInfo = prop.m_finalTree; float num16 = 0f; float num17 = 0f; if (propInfo != null) { propInfo = propInfo.GetVariation(ref randomizer); if (propInfo.m_isMarker || propInfo.m_isDecal || !propInfo.m_hasRenderer) { goto IL_7D3; } num16 = propInfo.m_generatedInfo.m_size.x * 0.5f; num17 = propInfo.m_generatedInfo.m_size.y; } else { if (treeInfo != null) { treeInfo = treeInfo.GetVariation(ref randomizer); num16 = (treeInfo.m_generatedInfo.m_size.x + treeInfo.m_generatedInfo.m_size.z) * 0.125f; num17 = treeInfo.m_generatedInfo.m_size.y; } } if (!prop.m_fixedHeight) { vector.y = Singleton <TerrainManager> .instance.SampleDetailHeight(vector); } else { if (info.m_requireHeightMap) { vector.y = Singleton <TerrainManager> .instance.SampleDetailHeight(vector) + prop.m_position.y; } } if (vector.y + num17 >= min.y && vector.y <= max.y) { num16 = this.m_info.m_radius + num16; float num19; float num18 = segment.DistanceSqr(vector, out num19); if (num18 < num16 * num16) { float num20 = num16 - Mathf.Sqrt(num18); float num21 = 1f - num18 / (num16 * num16); Vector3 a = segment.Position(num19 * 0.9f); a.y = 0f; vector.y = 0f; Vector3 vector2 = Vector3.Normalize(a - vector); Vector3 rhs = Vector3.Normalize(new Vector3(segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z)); Vector3 vector3 = new Vector3(rhs.z, 0f, -rhs.x) * Mathf.Abs(Vector3.Dot(vector2, rhs) * 0.5f); if (Vector3.Dot(vector2, vector3) >= 0f) { vector2 += vector3; } else { vector2 -= vector3; } pushAmount += vector2 * (num20 * num21); pushDivider += num21; } } } } } IL_7D3: ; } } } }
protected void CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Vector3 sourcePos, Vector3 targetPos, ushort buildingID, ref Vector3 pushAmount, ref float pushDivider) { Segment3 segment = new Segment3 (sourcePos, targetPos); Vector3 min = segment.Min (); min.x -= this.m_info.m_radius; min.z -= this.m_info.m_radius; Vector3 max = segment.Max (); max.x += this.m_info.m_radius; max.y += this.m_info.m_height; max.z += this.m_info.m_radius; CitizenManager instance = Singleton<CitizenManager>.instance; int num = Mathf.Max ((int)((min.x - 3f) / 8f + 1080f), 0); int num2 = Mathf.Max ((int)((min.z - 3f) / 8f + 1080f), 0); int num3 = Mathf.Min ((int)((max.x + 3f) / 8f + 1080f), 2159); int num4 = Mathf.Min ((int)((max.z + 3f) / 8f + 1080f), 2159); for (int i = num2; i <= num4; i++) { for (int j = num; j <= num3; j++) { ushort num5 = instance.m_citizenGrid [i * 2160 + j]; int num6 = 0; while (num5 != 0) { num5 = this.CheckCollisions (instanceID, ref citizenData, segment, min, max, num5, ref instance.m_instances.m_buffer [(int)num5], ref pushAmount, ref pushDivider); if (++num6 > 65536) { CODebugBase<LogChannel>.Error (LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } VehicleManager instance2 = Singleton<VehicleManager>.instance; int num7 = Mathf.Max ((int)((min.x - 10f) / 32f + 270f), 0); int num8 = Mathf.Max ((int)((min.z - 10f) / 32f + 270f), 0); int num9 = Mathf.Min ((int)((max.x + 10f) / 32f + 270f), 539); int num10 = Mathf.Min ((int)((max.z + 10f) / 32f + 270f), 539); for (int k = num8; k <= num10; k++) { for (int l = num7; l <= num9; l++) { ushort num11 = instance2.m_vehicleGrid [k * 540 + l]; int num12 = 0; while (num11 != 0) { num11 = this.CheckCollisions (instanceID, ref citizenData, segment, min, max, num11, ref instance2.m_vehicles.m_buffer [(int)num11], ref pushAmount, ref pushDivider); if (++num12 > 65536) { CODebugBase<LogChannel>.Error (LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } for (int m = num8; m <= num10; m++) { for (int n = num7; n <= num9; n++) { ushort num13 = instance2.m_parkedGrid [m * 540 + n]; int num14 = 0; while (num13 != 0) { num13 = this.CheckCollisions (instanceID, ref citizenData, segment, min, max, num13, ref instance2.m_parkedVehicles.m_buffer [(int)num13], ref pushAmount, ref pushDivider); if (++num14 > 65536) { CODebugBase<LogChannel>.Error (LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } if (buildingID != 0) { BuildingManager instance3 = Singleton<BuildingManager>.instance; BuildingInfo info = instance3.m_buildings.m_buffer [(int)buildingID].Info; if (info.m_props != null) { Vector3 position = instance3.m_buildings.m_buffer [(int)buildingID].m_position; float angle = instance3.m_buildings.m_buffer [(int)buildingID].m_angle; int length = instance3.m_buildings.m_buffer [(int)buildingID].Length; Matrix4x4 matrix4x = default(Matrix4x4); matrix4x.SetTRS (Building.CalculateMeshPosition (info, position, angle, length), Quaternion.AngleAxis (angle * 57.29578f, Vector3.down), Vector3.one); for (int num15 = 0; num15 < info.m_props.Length; num15++) { BuildingInfo.Prop prop = info.m_props [num15]; Randomizer randomizer = new Randomizer ((int)buildingID << 6 | prop.m_index); if (randomizer.Int32 (100u) < prop.m_probability && length >= prop.m_requiredLength) { Vector3 vector = matrix4x.MultiplyPoint (prop.m_position); if (vector.x >= min.x - 2f && vector.x <= max.x + 2f) { if (vector.z >= min.z - 2f && vector.z <= max.z + 2f) { PropInfo propInfo = prop.m_finalProp; TreeInfo treeInfo = prop.m_finalTree; float num16 = 0f; float num17 = 0f; if (propInfo != null) { propInfo = propInfo.GetVariation (ref randomizer); if (propInfo.m_isMarker || propInfo.m_isDecal || !propInfo.m_hasRenderer) { goto IL_7D3; } num16 = propInfo.m_generatedInfo.m_size.x * 0.5f; num17 = propInfo.m_generatedInfo.m_size.y; } else { if (treeInfo != null) { treeInfo = treeInfo.GetVariation (ref randomizer); num16 = (treeInfo.m_generatedInfo.m_size.x + treeInfo.m_generatedInfo.m_size.z) * 0.125f; num17 = treeInfo.m_generatedInfo.m_size.y; } } if (!prop.m_fixedHeight) { vector.y = Singleton<TerrainManager>.instance.SampleDetailHeight (vector); } else { if (info.m_requireHeightMap) { vector.y = Singleton<TerrainManager>.instance.SampleDetailHeight (vector) + prop.m_position.y; } } if (vector.y + num17 >= min.y && vector.y <= max.y) { num16 = this.m_info.m_radius + num16; float num19; float num18 = segment.DistanceSqr (vector, out num19); if (num18 < num16 * num16) { float num20 = num16 - Mathf.Sqrt (num18); float num21 = 1f - num18 / (num16 * num16); Vector3 a = segment.Position (num19 * 0.9f); a.y = 0f; vector.y = 0f; Vector3 vector2 = Vector3.Normalize (a - vector); Vector3 rhs = Vector3.Normalize (new Vector3 (segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z)); Vector3 vector3 = new Vector3 (rhs.z, 0f, -rhs.x) * Mathf.Abs (Vector3.Dot (vector2, rhs) * 0.5f); if (Vector3.Dot (vector2, vector3) >= 0f) { vector2 += vector3; } else { vector2 -= vector3; } pushAmount += vector2 * (num20 * num21); pushDivider += num21; } } } } } IL_7D3: ; } } } }
private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref Vehicle otherData, ref Vector3 pushAmount, ref float pushDivider) { VehicleInfo info = otherData.Info; if (info.m_vehicleType == VehicleInfo.VehicleType.Bicycle) { return otherData.m_nextGridVehicle; } if ((otherData.m_flags & Vehicle.Flags.Transition) == Vehicle.Flags.None && (citizenData.m_flags & CitizenInstance.Flags.Transition) == CitizenInstance.Flags.None && (otherData.m_flags & Vehicle.Flags.Underground) != Vehicle.Flags.None != ((citizenData.m_flags & CitizenInstance.Flags.Underground) != CitizenInstance.Flags.None)) { return otherData.m_nextGridVehicle; } Segment3 segment2 = otherData.m_segment; Vector3 vector = Vector3.Min (segment2.Min (), otherData.m_targetPos1); vector.x -= 1f; vector.z -= 1f; Vector3 vector2 = Vector3.Max (segment2.Max (), otherData.m_targetPos1); vector2.x += 1f; vector2.y += 1f; vector2.z += 1f; if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y) { float num = this.m_info.m_radius + 1f; float num3; float t; float num2 = segment.DistanceSqr (segment2, out num3, out t); if (num2 < num * num) { float num4 = num - Mathf.Sqrt (num2); float num5 = 1f - num2 / (num * num); Vector3 a = segment.Position (num3 * 0.9f); Vector3 b = segment2.Position (t); a.y = 0f; b.y = 0f; Vector3 vector3 = Vector3.Normalize (a - b); Vector3 rhs = Vector3.Normalize (new Vector3 (segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z)); Vector3 vector4 = new Vector3 (rhs.z, 0f, -rhs.x) * Mathf.Abs (Vector3.Dot (vector3, rhs) * 0.5f); if (Vector3.Dot (vector3, vector4) >= 0f) { vector3 += vector4; } else { vector3 -= vector4; } pushAmount += vector3 * (num4 * num5); pushDivider += num5; } float magnitude = otherData.GetLastFrameVelocity ().magnitude; if (magnitude > 0.1f) { float num6 = this.m_info.m_radius + 3f; segment2.a = segment2.b; segment2.b += Vector3.ClampMagnitude (((Vector3)otherData.m_targetPos1) - segment2.b, magnitude * 4f); num2 = segment.DistanceSqr (segment2, out num3, out t); if (num2 > num * num && num2 < num6 * num6) { float num7 = num6 - Mathf.Sqrt (num2); float num8 = 1f - num2 / (num6 * num6); Vector3 a2 = segment.Position (num3 * 0.9f); Vector3 b2 = segment2.Position (t); a2.y = 0f; b2.y = 0f; Vector3 vector5 = a2 - b2; pushAmount += vector5.normalized * (num7 * num8); pushDivider += num8; } } } return otherData.m_nextGridVehicle; }
public static bool RayCast(ref NetSegment mysegment, ushort segmentID, Segment3 ray, float snapElevation, bool nameOnly, out float t, out float priority) { if (CSUROffset.IsCSUROffset(mysegment.Info.m_netAI.m_info)) { return(NetSegmentRayCastMasked(mysegment, segmentID, ray, -1000f, false, out t, out priority)); } NetInfo info = mysegment.Info; t = 0f; priority = 0f; if (nameOnly && (mysegment.m_flags & NetSegment.Flags.NameVisible2) == NetSegment.Flags.None) { return(false); } Bounds bounds = mysegment.m_bounds; bounds.Expand(16f); if (!bounds.IntersectRay(new Ray(ray.a, ray.b - ray.a))) { return(false); } NetManager instance = Singleton <NetManager> .instance; Bezier3 bezier = default(Bezier3); bezier.a = instance.m_nodes.m_buffer[mysegment.m_startNode].m_position; bezier.d = instance.m_nodes.m_buffer[mysegment.m_endNode].m_position; bool result = false; if (nameOnly) { RenderManager instance2 = Singleton <RenderManager> .instance; if (instance2.GetInstanceIndex((uint)(49152 + segmentID), out uint instanceIndex)) { InstanceManager.NameData nameData = instance2.m_instances[instanceIndex].m_nameData; Vector3 position = instance2.m_instances[instanceIndex].m_position; Matrix4x4 dataMatrix = instance2.m_instances[instanceIndex].m_dataMatrix2; float num = Vector3.Distance(position, ray.a); if (nameData != null && num < 1000f) { float snapElevation2 = info.m_netAI.GetSnapElevation(); bezier.a.y += snapElevation2; bezier.d.y += snapElevation2; NetSegment.CalculateMiddlePoints(bezier.a, mysegment.m_startDirection, bezier.d, mysegment.m_endDirection, true, true, out bezier.b, out bezier.c); float num2 = Mathf.Max(1f, Mathf.Abs(dataMatrix.m33 - dataMatrix.m30)); float d = num * 0.0002f + 0.05f / (1f + num * 0.001f); Vector2 vector = nameData.m_size * d; float t2 = Mathf.Max(0f, 0.5f - vector.x / num2 * 0.5f); float t3 = Mathf.Min(1f, 0.5f + vector.x / num2 * 0.5f); bezier = bezier.Cut(t2, t3); float num3 = bezier.DistanceSqr(ray, out float u, out float _); if (num3 < vector.y * vector.y * 0.25f) { Vector3 b = bezier.Position(u); if (Segment1.Intersect(ray.a.y, ray.b.y, b.y, out u)) { num3 = Vector3.SqrMagnitude(ray.Position(u) - b); if (num3 < vector.y * vector.y * 0.25f) { t = u; result = true; } } } } } } else { info.m_netAI.GetRayCastHeights(segmentID, ref mysegment, out float leftMin, out float rightMin, out float max); bezier.a.y += max; bezier.d.y += max; bool flag = (instance.m_nodes.m_buffer[mysegment.m_startNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None; bool flag2 = (instance.m_nodes.m_buffer[mysegment.m_endNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None; NetSegment.CalculateMiddlePoints(bezier.a, mysegment.m_startDirection, bezier.d, mysegment.m_endDirection, flag, flag2, out bezier.b, out bezier.c); float minNodeDistance = info.GetMinNodeDistance(); float collisionHalfWidth = info.m_netAI.GetCollisionHalfWidth(); float num4 = (float)(int)instance.m_nodes.m_buffer[mysegment.m_startNode].m_elevation; float num5 = (float)(int)instance.m_nodes.m_buffer[mysegment.m_endNode].m_elevation; if (info.m_netAI.IsUnderground()) { num4 = 0f - num4; num5 = 0f - num5; } num4 += info.m_netAI.GetSnapElevation(); num5 += info.m_netAI.GetSnapElevation(); float a = Mathf.Lerp(minNodeDistance, collisionHalfWidth, Mathf.Clamp01(Mathf.Abs(snapElevation - num4) / 12f)); float b2 = Mathf.Lerp(minNodeDistance, collisionHalfWidth, Mathf.Clamp01(Mathf.Abs(snapElevation - num5) / 12f)); float num6 = Mathf.Min(leftMin, rightMin); t = 1000000f; priority = 1000000f; Segment3 segment = default(Segment3); segment.a = bezier.a; for (int i = 1; i <= 16; i++) { segment.b = bezier.Position((float)i / 16f); float num7 = ray.DistanceSqr(segment, out float u2, out float v2); float num8 = Mathf.Lerp(a, b2, ((float)(i - 1) + v2) / 16f); Vector3 vector2 = segment.Position(v2); if (num7 < priority && Segment1.Intersect(ray.a.y, ray.b.y, vector2.y, out u2)) { Vector3 vector3 = ray.Position(u2); num7 = Vector3.SqrMagnitude(vector3 - vector2); if (num7 < priority && num7 < num8 * num8) { if (flag && i == 1 && v2 < 0.001f) { Vector3 rhs = segment.a - segment.b; u2 += Mathf.Max(0f, Vector3.Dot(vector3, rhs)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs.sqrMagnitude * ray.LengthSqr())); } if (flag2 && i == 16 && v2 > 0.999f) { Vector3 rhs2 = segment.b - segment.a; u2 += Mathf.Max(0f, Vector3.Dot(vector3, rhs2)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs2.sqrMagnitude * ray.LengthSqr())); } priority = num7; t = u2; result = true; } } if (num6 < max) { float num9 = vector2.y + num6 - max; if (Mathf.Max(ray.a.y, ray.b.y) > num9 && Mathf.Min(ray.a.y, ray.b.y) < vector2.y) { Segment2 segment2 = default(Segment2); float num10; if (Segment1.Intersect(ray.a.y, ray.b.y, vector2.y, out u2)) { segment2.a = VectorUtils.XZ(ray.Position(u2)); num10 = u2; } else { segment2.a = VectorUtils.XZ(ray.a); num10 = 0f; } float num11; if (Segment1.Intersect(ray.a.y, ray.b.y, num9, out u2)) { segment2.b = VectorUtils.XZ(ray.Position(u2)); num11 = u2; } else { segment2.b = VectorUtils.XZ(ray.b); num11 = 1f; } num7 = segment2.DistanceSqr(VectorUtils.XZ(vector2), out u2); if (num7 < priority && num7 < num8 * num8) { u2 = num10 + (num11 - num10) * u2; Vector3 lhs = ray.Position(u2); if (flag && i == 1 && v2 < 0.001f) { Vector3 rhs3 = segment.a - segment.b; u2 += Mathf.Max(0f, Vector3.Dot(lhs, rhs3)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs3.sqrMagnitude * ray.LengthSqr())); } if (flag2 && i == 16 && v2 > 0.999f) { Vector3 rhs4 = segment.b - segment.a; u2 += Mathf.Max(0f, Vector3.Dot(lhs, rhs4)) / Mathf.Max(0.001f, Mathf.Sqrt(rhs4.sqrMagnitude * ray.LengthSqr())); } priority = num7; t = u2; result = true; } } } segment.a = segment.b; } priority = Mathf.Max(0f, Mathf.Sqrt(priority) - collisionHalfWidth); } return(result); }
private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref Vehicle otherData, ref Vector3 pushAmount, ref float pushDivider) { VehicleInfo info = otherData.Info; if (info.m_vehicleType == VehicleInfo.VehicleType.Bicycle) { return(otherData.m_nextGridVehicle); } if ((otherData.m_flags & Vehicle.Flags.Transition) == Vehicle.Flags.None && (citizenData.m_flags & CitizenInstance.Flags.Transition) == CitizenInstance.Flags.None && (otherData.m_flags & Vehicle.Flags.Underground) != Vehicle.Flags.None != ((citizenData.m_flags & CitizenInstance.Flags.Underground) != CitizenInstance.Flags.None)) { return(otherData.m_nextGridVehicle); } Segment3 segment2 = otherData.m_segment; Vector3 vector = Vector3.Min(segment2.Min(), otherData.m_targetPos1); vector.x -= 1f; vector.z -= 1f; Vector3 vector2 = Vector3.Max(segment2.Max(), otherData.m_targetPos1); vector2.x += 1f; vector2.y += 1f; vector2.z += 1f; if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y) { float num = this.m_info.m_radius + 1f; float num3; float t; float num2 = segment.DistanceSqr(segment2, out num3, out t); if (num2 < num * num) { float num4 = num - Mathf.Sqrt(num2); float num5 = 1f - num2 / (num * num); Vector3 a = segment.Position(num3 * 0.9f); Vector3 b = segment2.Position(t); a.y = 0f; b.y = 0f; Vector3 vector3 = Vector3.Normalize(a - b); Vector3 rhs = Vector3.Normalize(new Vector3(segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z)); Vector3 vector4 = new Vector3(rhs.z, 0f, -rhs.x) * Mathf.Abs(Vector3.Dot(vector3, rhs) * 0.5f); if (Vector3.Dot(vector3, vector4) >= 0f) { vector3 += vector4; } else { vector3 -= vector4; } pushAmount += vector3 * (num4 * num5); pushDivider += num5; } float magnitude = otherData.GetLastFrameVelocity().magnitude; if (magnitude > 0.1f) { float num6 = this.m_info.m_radius + 3f; segment2.a = segment2.b; segment2.b += Vector3.ClampMagnitude(((Vector3)otherData.m_targetPos1) - segment2.b, magnitude * 4f); num2 = segment.DistanceSqr(segment2, out num3, out t); if (num2 > num * num && num2 < num6 * num6) { float num7 = num6 - Mathf.Sqrt(num2); float num8 = 1f - num2 / (num6 * num6); Vector3 a2 = segment.Position(num3 * 0.9f); Vector3 b2 = segment2.Position(t); a2.y = 0f; b2.y = 0f; Vector3 vector5 = a2 - b2; pushAmount += vector5.normalized * (num7 * num8); pushDivider += num8; } } } return(otherData.m_nextGridVehicle); }
//to detour move it public static bool MoveItRayCastNode(ref NetNode node, Segment3 ray, float snapElevation, out float t, out float priority) { NetInfo info = node.Info; // NON-STOCK CODE STARTS float laneOffset = 0; float startOffset = 0; float endOffset = 0; bool IsCSURSLane = CSURUtil.IsCSURSLane(info.m_netAI.m_info, ref laneOffset, ref startOffset, ref endOffset); if (CSURUtil.IsCSUROffset(info.m_netAI.m_info) && !IsCSURSLane) { return(RayCastNodeMasked(ref node, ray, snapElevation, false, out t, out priority)); } // NON-STOCK CODE ENDS //if ((node.m_flags & (NetNode.Flags.Middle | NetNode.Flags.Outside)) == NetNode.Flags.None) //{ float num = (float)node.m_elevation + info.m_netAI.GetSnapElevation(); float t2; if (info.m_netAI.IsUnderground()) { t2 = Mathf.Clamp01(Mathf.Abs(snapElevation + num) / 12f); } else { t2 = Mathf.Clamp01(Mathf.Abs(snapElevation - num) / 12f); } float collisionHalfWidth = Mathf.Max(3f, info.m_netAI.GetCollisionHalfWidth()); float num2 = Mathf.Lerp(info.GetMinNodeDistance(), collisionHalfWidth, t2); if (Segment1.Intersect(ray.a.y, ray.b.y, node.m_position.y, out t)) { float num3 = Vector3.Distance(ray.Position(t), node.m_position); // NON-STOCK CODE STARTS if (IsCSURSLane) { bool lht = false; NetManager instance = Singleton <NetManager> .instance; NetSegment mysegment = CSURUtil.GetSameInfoSegment(node); bool isStart = CSURUtil.CheckNodeEq(mysegment.m_startNode, node); Vector3 direction = isStart ? mysegment.m_startDirection : -mysegment.m_endDirection; //Debug.Log(direction); if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0) { lht = true; } Vector3 normal = new Vector3(direction.z, 0, -direction.x).normalized; float vehicleLaneNum = CSURUtil.CountCSURSVehicleLanes(info); float otherLaneNum = CSURUtil.CountCSURSOtherLanes(info); float laneNum = otherLaneNum + vehicleLaneNum; startOffset = startOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f; endOffset = endOffset * 3.75f - laneNum * 1.875f + 1.875f + otherLaneNum * 3.75f; var Offset = isStart ? startOffset : endOffset; Vector3 trueNodeCenter = node.m_position + (lht ? -Offset : Offset) * normal; num3 = Vector3.Distance(ray.Position(t), trueNodeCenter); } // NON-STOCK CODE ENDS if (num3 < num2) { priority = Mathf.Max(0f, num3 - collisionHalfWidth); return(true); } } //} t = 0f; priority = 0f; return(false); }
private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref CitizenInstance otherData, ref Vector3 pushAmount, ref float pushDivider) { if (otherID == instanceID) { return otherData.m_nextGridInstance; } if (((citizenData.m_flags | otherData.m_flags) & CitizenInstance.Flags.Transition) == CitizenInstance.Flags.None && (citizenData.m_flags & CitizenInstance.Flags.Underground) != (citizenData.m_flags & CitizenInstance.Flags.Underground)) { return otherData.m_nextGridInstance; } CitizenInfo info = otherData.Info; CitizenInstance.Frame lastFrameData = otherData.GetLastFrameData (); Vector3 position = lastFrameData.m_position; Vector3 b = lastFrameData.m_position + lastFrameData.m_velocity; Segment3 segment2 = new Segment3 (position, b); Vector3 vector = segment2.Min (); vector.x -= info.m_radius; vector.z -= info.m_radius; Vector3 vector2 = segment2.Max (); vector2.x += info.m_radius; vector2.y += info.m_height; vector2.z += info.m_radius; if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y) { float num = this.m_info.m_radius + info.m_radius; float num3; float t; float num2 = segment.DistanceSqr (segment2, out num3, out t); if (num2 < num * num) { float num4 = num - Mathf.Sqrt (num2); float num5 = 1f - num2 / (num * num); Vector3 a = segment.Position (num3 * 0.9f); Vector3 b2 = segment2.Position (t); a.y = 0f; b2.y = 0f; Vector3 vector3 = a - b2; Vector3 vector4 = new Vector3 (segment.b.z - segment.a.z, 0f, segment.a.x - segment.b.x); if (Vector3.Dot (vector3, vector4) >= 0f) { vector3 += vector4; } else { vector3 -= vector4; } pushAmount += vector3.normalized * (num4 * num5); pushDivider += num5; } } return otherData.m_nextGridInstance; }
public static bool RayCastNodeMasked(ref NetNode node, Segment3 ray, float snapElevation, bool bothSides, out float t, out float priority) { bool lht = false; //if (SimulationManager.instance.m_metaData.m_invertTraffic == SimulationMetaData.MetaBool.True) lht = true; NetInfo info = node.Info; float num = (float)node.m_elevation + info.m_netAI.GetSnapElevation(); float t2; if (info.m_netAI.IsUnderground()) { t2 = Mathf.Clamp01(Mathf.Abs(snapElevation + num) / 12f); } else { t2 = Mathf.Clamp01(Mathf.Abs(snapElevation - num) / 12f); } float collisionHalfWidth = Mathf.Max(3f, info.m_halfWidth); float maskHalfWidth = Mathf.Min(collisionHalfWidth - 1.5f, info.m_pavementWidth); float num2 = Mathf.Lerp(info.GetMinNodeDistance(), collisionHalfWidth, t2); float num2m = Mathf.Lerp(info.GetMinNodeDistance(), maskHalfWidth, t2); float num2delta = Mathf.Lerp(info.GetMinNodeDistance(), collisionHalfWidth - maskHalfWidth, t2); if (node.CountSegments() != 0) { NetManager instance = Singleton <NetManager> .instance; NetSegment mysegment = CSURUtil.GetSameInfoSegment(node); Vector3 direction = CSURUtil.CheckNodeEq(mysegment.m_startNode, node) ? mysegment.m_startDirection : -mysegment.m_endDirection; //Debug.Log(direction); if ((mysegment.m_flags & NetSegment.Flags.Invert) != 0) { lht = true; } // normal to the right hand side Vector3 normal = new Vector3(direction.z, 0, -direction.x).normalized; Vector3 trueNodeCenter = node.m_position + (lht ? -collisionHalfWidth : collisionHalfWidth) * normal; //Debug.Log($"num2: {num2}, num2m: {num2m}"); //Debug.Log($"node: {node.m_position}, center: {trueNodeCenter}"); if (Segment1.Intersect(ray.a.y, ray.b.y, node.m_position.y, out t)) { float num3 = Vector3.Distance(ray.Position(t), trueNodeCenter); if (num3 < num2delta) { priority = Mathf.Max(0f, num3 - collisionHalfWidth); return(true); } } } else { if (Segment1.Intersect(ray.a.y, ray.b.y, node.m_position.y, out t)) { float num3 = Vector3.Distance(ray.Position(t), node.m_position); if (num3 < num2) { priority = Mathf.Max(0f, num3 - collisionHalfWidth); return(true); } } } t = 0f; priority = 0f; return(false); }
private ushort CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Segment3 segment, Vector3 min, Vector3 max, ushort otherID, ref VehicleParked otherData, ref Vector3 pushAmount, ref float pushDivider) { VehicleInfo info = otherData.Info; Vector3 position = otherData.m_position; Vector3 b = otherData.m_rotation * new Vector3 (0f, 0f, Mathf.Max (0.5f, info.m_generatedInfo.m_size.z * 0.5f - 1f)); Segment3 segment2; segment2.a = position - b; segment2.b = position + b; Vector3 vector = segment2.Min (); vector.x -= 1f; vector.z -= 1f; Vector3 vector2 = segment2.Max (); vector2.x += 1f; vector2.y += 1f; vector2.z += 1f; if (min.x < vector2.x && max.x > vector.x && min.z < vector2.z && max.z > vector.z && min.y < vector2.y && max.y > vector.y) { float num = this.m_info.m_radius + 1f; float num3; float t; float num2 = segment.DistanceSqr (segment2, out num3, out t); if (num2 < num * num) { float num4 = num - Mathf.Sqrt (num2); float num5 = 1f - num2 / (num * num); Vector3 a = segment.Position (num3 * 0.9f); Vector3 b2 = segment2.Position (t); a.y = 0f; b2.y = 0f; Vector3 vector3 = Vector3.Normalize (a - b2); Vector3 rhs = Vector3.Normalize (new Vector3 (segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z)); Vector3 vector4 = new Vector3 (rhs.z, 0f, -rhs.x) * Mathf.Abs (Vector3.Dot (vector3, rhs) * 0.5f); if (Vector3.Dot (vector3, vector4) >= 0f) { vector3 += vector4; } else { vector3 -= vector4; } pushAmount += vector3 * (num4 * num5); pushDivider += num5; } } return otherData.m_nextGridParked; }
private bool RayCastSegmentAndNode(NetInfo connectedType, Segment3 ray, float snapElevation, bool nameOnly, ItemClass.Service service, ItemClass.Service service2, ItemClass.SubService subService, ItemClass.SubService subService2, ItemClass.Layer itemLayers, ItemClass.Layer itemLayers2, NetNode.Flags ignoreNodeFlags, NetSegment.Flags ignoreSegmentFlags, out Vector3 hit, out ushort nodeIndex, out ushort segmentIndex) { var bounds = new Bounds(new Vector3(0f, 512f, 0f), new Vector3(17280f, 1152f, 17280f)); if (ray.Clip(bounds)) { Vector3 vector = ray.b - ray.a; var num = (int)((ray.a.x / 64f) + 135f); var num2 = (int)((ray.a.z / 64f) + 135f); var num3 = (int)((ray.b.x / 64f) + 135f); var num4 = (int)((ray.b.z / 64f) + 135f); var num5 = Mathf.Abs(vector.x); var num6 = Mathf.Abs(vector.z); int num7; int num8; if (num5 >= num6) { num7 = ((vector.x <= 0f) ? -1 : 1); num8 = 0; if (num5 > 0.001f) { vector *= 64f / num5; } } else { num7 = 0; num8 = ((vector.z <= 0f) ? -1 : 1); if (num6 > 0.001f) { vector *= 64f / num6; } } var num9 = 2f; var num10 = 16f; var num11 = 2f; var num12 = 16f; ushort num13 = 0; ushort num14 = 0; ushort num15 = 0; Vector3 vector2 = ray.a; Vector3 vector3 = ray.a; var num16 = num; var num17 = num2; do { Vector3 vector4 = vector3 + vector; int num18; int num19; int num20; int num21; if (num7 != 0) { if ((num16 == num && num7 > 0) || (num16 == num3 && num7 < 0)) { num18 = Mathf.Max((int)(((vector4.x - 64f) / 64f) + 135f), 0); } else { num18 = Mathf.Max(num16, 0); } if ((num16 == num && num7 < 0) || (num16 == num3 && num7 > 0)) { num19 = Mathf.Min((int)(((vector4.x + 64f) / 64f) + 135f), 269); } else { num19 = Mathf.Min(num16, 269); } num20 = Mathf.Max((int)(((Mathf.Min(vector2.z, vector4.z) - 64f) / 64f) + 135f), 0); num21 = Mathf.Min((int)(((Mathf.Max(vector2.z, vector4.z) + 64f) / 64f) + 135f), 269); } else { if ((num17 == num2 && num8 > 0) || (num17 == num4 && num8 < 0)) { num20 = Mathf.Max((int)(((vector4.z - 64f) / 64f) + 135f), 0); } else { num20 = Mathf.Max(num17, 0); } if ((num17 == num2 && num8 < 0) || (num17 == num4 && num8 > 0)) { num21 = Mathf.Min((int)(((vector4.z + 64f) / 64f) + 135f), 269); } else { num21 = Mathf.Min(num17, 269); } num18 = Mathf.Max((int)(((Mathf.Min(vector2.x, vector4.x) - 64f) / 64f) + 135f), 0); num19 = Mathf.Min((int)(((Mathf.Max(vector2.x, vector4.x) + 64f) / 64f) + 135f), 269); } for (var i = num20; i <= num21; i++) { for (var j = num18; j <= num19; j++) { var num22 = Singleton <NetManager> .instance.m_nodeGrid[(i * 270) + j]; var num23 = 0; while (num22 != 0) { NetNode.Flags flags = NodeBuffer[num22].m_flags; NetInfo info = NodeBuffer[num22].Info; ItemClass connectionClass = info.GetConnectionClass(); if ((((service == ItemClass.Service.None || connectionClass.m_service == service) && (subService == ItemClass.SubService.None || connectionClass.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (connectionClass.m_layer & itemLayers) != ItemClass.Layer.None)) || (info.m_intersectClass != null && (service == ItemClass.Service.None || info.m_intersectClass.m_service == service) && (subService == ItemClass.SubService.None || info.m_intersectClass.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (info.m_intersectClass.m_layer & itemLayers) != ItemClass.Layer.None)) || (info.m_netAI.CanIntersect(connectedType) && connectionClass.m_service == service2 && (subService2 == ItemClass.SubService.None || connectionClass.m_subService == subService2) && (itemLayers2 == ItemClass.Layer.None || (connectionClass.m_layer & itemLayers2) != ItemClass.Layer.None))) && (flags & ignoreNodeFlags) == NetNode.Flags.None && (connectedType == null || (info.m_netAI.CanConnect(connectedType) && connectedType.m_netAI.CanConnect(info)))) { var flag = false; if ((flags & (NetNode.Flags.Middle | NetNode.Flags.Untouchable)) == (NetNode.Flags.Middle | NetNode.Flags.Untouchable) && NodeBuffer[num22].CountSegments(NetSegment.Flags.Untouchable, 0) >= 2) { flag = true; } if (!flag && NodeBuffer[num22].RayCast(ray, snapElevation, out var num24, out var num25) && (num25 < num12 || (num25 == num12 && num24 < num11))) { num11 = num24; num12 = num25; num14 = num22; } } num22 = NodeBuffer[num22].m_nextGridNode; if (++num23 > 32768) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } for (var k = num20; k <= num21; k++) { for (var l = num18; l <= num19; l++) { var num26 = Singleton <NetManager> .instance.m_segmentGrid[(k * 270) + l]; var num27 = 0; while (num26 != 0) { NetSegment.Flags flags2 = SegmentBuffer[num26].m_flags; NetInfo info2 = SegmentBuffer[num26].Info; ItemClass connectionClass2 = info2.GetConnectionClass(); if (((service == ItemClass.Service.None || connectionClass2.m_service == service) && (subService == ItemClass.SubService.None || connectionClass2.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (connectionClass2.m_layer & itemLayers) != ItemClass.Layer.None || nameOnly)) || (info2.m_intersectClass != null && (service == ItemClass.Service.None || info2.m_intersectClass.m_service == service) && (subService == ItemClass.SubService.None || info2.m_intersectClass.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (info2.m_intersectClass.m_layer & itemLayers) != ItemClass.Layer.None || nameOnly)) || (info2.m_netAI.CanIntersect(connectedType) && connectionClass2.m_service == service2 && (subService2 == ItemClass.SubService.None || connectionClass2.m_subService == subService2) && (itemLayers2 == ItemClass.Layer.None || (connectionClass2.m_layer & itemLayers2) != ItemClass.Layer.None || nameOnly))) { var flag2 = (flags2 & ignoreSegmentFlags) != NetSegment.Flags.None && !nameOnly; if ((flags2 & ignoreSegmentFlags) == NetSegment.Flags.None && (connectedType == null || (info2.m_netAI.CanConnect(connectedType) && connectedType.m_netAI.CanConnect(info2))) && SegmentBuffer[num26].RayCast(num26, ray, snapElevation, nameOnly, out var num28, out var num29) && (num29 < num10 || (num29 == num10 && num28 < num9))) { var startNode = SegmentBuffer[num26].m_startNode; var endNode = SegmentBuffer[num26].m_endNode; Vector3 position = NodeBuffer[startNode].m_position; Vector3 position2 = NodeBuffer[endNode].m_position; var num30 = NodeBuffer[startNode].Info.GetMinNodeDistance(); var num31 = NodeBuffer[endNode].Info.GetMinNodeDistance(); num10 = num29; num9 = num28; Vector3 a = ray.a + ((ray.b - ray.a) * num28); NetNode.Flags flags3 = NodeBuffer[startNode].m_flags; if ((flags3 & NetNode.Flags.End) != NetNode.Flags.None) { flags3 &= ~NetNode.Flags.Moveable; } NetNode.Flags flags4 = NodeBuffer[endNode].m_flags; if ((flags4 & NetNode.Flags.End) != NetNode.Flags.None) { flags4 &= ~NetNode.Flags.Moveable; } if (flag2) { num30 = 1000f; num31 = 1000f; } var flag3 = (flags3 & (NetNode.Flags.Moveable | ignoreNodeFlags)) == NetNode.Flags.None; var flag4 = (flags4 & (NetNode.Flags.Moveable | ignoreNodeFlags)) == NetNode.Flags.None; var num32 = VectorUtils.LengthSqrXZ(a - position) / (num30 * num30); var num33 = VectorUtils.LengthSqrXZ(a - position2) / (num31 * num31); if (flag3 && num32 < 1f && (!flag4 || num32 < num33) && !nameOnly) { num13 = startNode; if (!flag2) { num15 = num26; } } else if (flag4 && num33 < 1f && !nameOnly) { num13 = endNode; if (!flag2) { num15 = num26; } } else if (!flag2) { num13 = 0; num15 = num26; } } } num26 = SegmentBuffer[num26].m_nextGridSegment; if (++num27 > 36864) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } vector2 = vector3; vector3 = vector4; num16 += num7; num17 += num8; }while ((num16 <= num3 || num7 <= 0) && (num16 >= num3 || num7 >= 0) && (num17 <= num4 || num8 <= 0) && (num17 >= num4 || num8 >= 0)); if (num12 < num10 || (num12 == num10 && num11 < num9)) { num9 = num11; num13 = num14; } if (num9 != 2f) { hit = ray.Position(num9); nodeIndex = num13; segmentIndex = num15; return(true); } } hit = Vector3.zero; nodeIndex = 0; segmentIndex = 0; return(false); }
public static Vector3 GetRayPosition(this Segment3 ray, float height, out float t) { Segment1.Intersect(ray.a.y, ray.b.y, height, out t); return(ray.Position(t)); }