//from source code private static bool CheckOverlap(ushort vehicleID, ref Vehicle vehicleData, Segment3 segment, ushort ignoreVehicle) { VehicleManager instance = Singleton <VehicleManager> .instance; Vector3 min = segment.Min(); Vector3 max = segment.Max(); int num = Mathf.Max((int)((min.x - 30f) / 32f + 270f), 0); int num2 = Mathf.Max((int)((min.z - 30f) / 32f + 270f), 0); int num3 = Mathf.Min((int)((max.x + 30f) / 32f + 270f), 539); int num4 = Mathf.Min((int)((max.z + 30f) / 32f + 270f), 539); bool result = false; for (int i = num2; i <= num4; i++) { for (int j = num; j <= num3; j++) { ushort num5 = instance.m_vehicleGrid[i * 540 + j]; int num6 = 0; while (num5 != 0) { num5 = SingleTrainTrackAI.CheckOverlap(vehicleID, ref vehicleData, segment, ignoreVehicle, num5, ref instance.m_vehicles.m_buffer[(int)num5], ref result, min, max); if (++num6 > 16384) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } return(result); }
// 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 static bool CheckOverlap(Segment3 segment, ushort ignoreVehicle, float maxVelocity) { VehicleManager instance = Singleton <VehicleManager> .instance; Vector3 vector3_1 = segment.Min(); Vector3 vector3_2 = segment.Max(); int num1 = Mathf.Max((int)(((double)vector3_1.x - 10.0) / 32.0 + 270.0), 0); int num2 = Mathf.Max((int)(((double)vector3_1.z - 10.0) / 32.0 + 270.0), 0); int num3 = Mathf.Min((int)(((double)vector3_2.x + 10.0) / 32.0 + 270.0), 539); int num4 = Mathf.Min((int)(((double)vector3_2.z + 10.0) / 32.0 + 270.0), 539); bool overlap = false; for (int index1 = num2; index1 <= num4; ++index1) { for (int index2 = num1; index2 <= num3; ++index2) { ushort otherID = instance.m_vehicleGrid[index1 * 540 + index2]; int num5 = 0; while (otherID != (ushort)0) { otherID = CheckOverlap(segment, ignoreVehicle, maxVelocity, otherID, ref instance.m_vehicles.m_buffer[(int)otherID], ref overlap); if (++num5 > 16384) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace); break; } } } } return(overlap); }
private static bool CheckOverlap(Segment3 segment, ushort ignoreVehicle, float maxVelocity) { VehicleManager instance = Singleton <VehicleManager> .instance; Vector3 vector = segment.Min(); Vector3 vector2 = segment.Max(); int num = Mathf.Max((int)((vector.x - 10f) / 32f + 270f), 0); int num2 = Mathf.Max((int)((vector.z - 10f) / 32f + 270f), 0); int num3 = Mathf.Min((int)((vector2.x + 10f) / 32f + 270f), 539); int num4 = Mathf.Min((int)((vector2.z + 10f) / 32f + 270f), 539); bool result = false; for (int i = num2; i <= num4; i++) { for (int j = num; j <= num3; j++) { ushort num5 = instance.m_vehicleGrid [i * 540 + j]; int num6 = 0; while (num5 != 0) { num5 = CheckOverlap(segment, ignoreVehicle, maxVelocity, num5, ref instance.m_vehicles.m_buffer [(int)num5], ref result); if (++num6 > 65536) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } return(result); }
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 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); }
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; }
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: ; } } } }
// 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 static void CheckOtherVehicles(CarAI carAI, ushort vehicleID, ref Vehicle vehicleData, ref Vehicle.Frame frameData, ref float maxSpeed, ref bool blocked, ref Vector3 collisionPush, float maxDistance, float maxBraking, int lodPhysics) { Vector3 vector = vehicleData.m_targetPos3 - (Vector4)frameData.m_position; Vector3 rhs = frameData.m_position + Vector3.ClampMagnitude(vector, maxDistance); Vector3 min = Vector3.Min(vehicleData.m_segment.Min(), rhs); Vector3 max = Vector3.Max(vehicleData.m_segment.Max(), rhs); VehicleManager instance = Singleton <VehicleManager> .instance; int num = Mathf.Max((int)((min.x - 10f) / 32f + 270f), 0); int num2 = Mathf.Max((int)((min.z - 10f) / 32f + 270f), 0); int num3 = Mathf.Min((int)((max.x + 10f) / 32f + 270f), 539); int num4 = Mathf.Min((int)((max.z + 10f) / 32f + 270f), 539); for (int i = num2; i <= num4; i++) { for (int j = num; j <= num3; j++) { ushort num5 = instance.m_vehicleGrid[i * 540 + j]; int num6 = 0; while (num5 != 0) { num5 = CustomCarAI.CheckOtherVehicle(vehicleID, ref vehicleData, ref frameData, ref maxSpeed, ref blocked, ref collisionPush, maxBraking, num5, ref instance.m_vehicles.m_buffer[(int)num5], min, max, lodPhysics); if (++num6 > 16384) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } if (lodPhysics == 0 && (CSLTraffic.Options & OptionsManager.ModOptions.noStopForCrossing) != OptionsManager.ModOptions.noStopForCrossing) { CitizenManager instance2 = Singleton <CitizenManager> .instance; float num7 = 0f; Vector3 vector2 = vehicleData.m_segment.b; Vector3 lhs = vehicleData.m_segment.b - vehicleData.m_segment.a; for (int k = 0; k < 4; k++) { Vector3 vector3 = vehicleData.GetTargetPos(k); Vector3 vector4 = vector3 - vector2; if (Vector3.Dot(lhs, vector4) > 0f) { float magnitude = vector4.magnitude; if (magnitude > 0.01f) { Segment3 segment = new Segment3(vector2, vector3); min = segment.Min(); max = segment.Max(); int num8 = Mathf.Max((int)((min.x - 3f) / 8f + 1080f), 0); int num9 = Mathf.Max((int)((min.z - 3f) / 8f + 1080f), 0); int num10 = Mathf.Min((int)((max.x + 3f) / 8f + 1080f), 2159); int num11 = Mathf.Min((int)((max.z + 3f) / 8f + 1080f), 2159); for (int l = num9; l <= num11; l++) { for (int m = num8; m <= num10; m++) { ushort num12 = instance2.m_citizenGrid[l * 2160 + m]; int num13 = 0; while (num12 != 0) { num12 = CustomCarAI.CheckCitizen(segment, num7, magnitude, ref maxSpeed, ref blocked, maxBraking, num12, ref instance2.m_instances.m_buffer[(int)num12], min, max); if (++num13 > 65536) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } } lhs = vector4; num7 += magnitude; vector2 = vector3; } } } }
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 static bool CheckOverlap(ushort vehicleID, ref Vehicle vehicleData, Segment3 segment, ushort ignoreVehicle) { VehicleManager instance = Singleton<VehicleManager>.instance; Vector3 min = segment.Min (); Vector3 max = segment.Max (); int num = Mathf.Max ((int)((min.x - 30f) / 32f + 270f), 0); int num2 = Mathf.Max ((int)((min.z - 30f) / 32f + 270f), 0); int num3 = Mathf.Min ((int)((max.x + 30f) / 32f + 270f), 539); int num4 = Mathf.Min ((int)((max.z + 30f) / 32f + 270f), 539); bool result = false; for (int i = num2; i <= num4; i++) { for (int j = num; j <= num3; j++) { ushort num5 = instance.m_vehicleGrid [i * 540 + j]; int num6 = 0; while (num5 != 0) { num5 = CheckOverlap (vehicleID, ref vehicleData, segment, ignoreVehicle, num5, ref instance.m_vehicles.m_buffer [(int)num5], ref result, min, max); if (++num6 > 65536) { CODebugBase<LogChannel>.Error (LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } return result; }
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 static bool CheckOverlap(Segment3 segment, ushort ignoreVehicle) { VehicleManager instance = Singleton<VehicleManager>.instance; Vector3 vector = segment.Min (); Vector3 vector2 = segment.Max (); int num = Mathf.Max ((int)((vector.x - 100f) / 320f + 27f), 0); int num2 = Mathf.Max ((int)((vector.z - 100f) / 320f + 27f), 0); int num3 = Mathf.Min ((int)((vector2.x + 100f) / 320f + 27f), 53); int num4 = Mathf.Min ((int)((vector2.z + 100f) / 320f + 27f), 53); bool result = false; for (int i = num2; i <= num4; i++) { for (int j = num; j <= num3; j++) { ushort num5 = instance.m_vehicleGrid2 [i * 54 + j]; int num6 = 0; while (num5 != 0) { num5 = CheckOverlap (segment, ignoreVehicle, num5, ref instance.m_vehicles.m_buffer [(int)num5], ref result); if (++num6 > 65536) { CODebugBase<LogChannel>.Error (LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } return result; }
private static void CheckOtherVehicles(CarAI carAI, ushort vehicleID, ref Vehicle vehicleData, ref Vehicle.Frame frameData, ref float maxSpeed, ref bool blocked, ref Vector3 collisionPush, float maxDistance, float maxBraking, int lodPhysics) { Vector3 vector = vehicleData.m_targetPos3 - (Vector4)frameData.m_position; Vector3 rhs = frameData.m_position + Vector3.ClampMagnitude(vector, maxDistance); Vector3 min = Vector3.Min(vehicleData.m_segment.Min(), rhs); Vector3 max = Vector3.Max(vehicleData.m_segment.Max(), rhs); VehicleManager instance = Singleton<VehicleManager>.instance; int num = Mathf.Max((int)((min.x - 10f) / 32f + 270f), 0); int num2 = Mathf.Max((int)((min.z - 10f) / 32f + 270f), 0); int num3 = Mathf.Min((int)((max.x + 10f) / 32f + 270f), 539); int num4 = Mathf.Min((int)((max.z + 10f) / 32f + 270f), 539); for (int i = num2; i <= num4; i++) { for (int j = num; j <= num3; j++) { ushort num5 = instance.m_vehicleGrid[i * 540 + j]; int num6 = 0; while (num5 != 0) { num5 = CustomCarAI.CheckOtherVehicle(vehicleID, ref vehicleData, ref frameData, ref maxSpeed, ref blocked, ref collisionPush, maxBraking, num5, ref instance.m_vehicles.m_buffer[(int)num5], min, max, lodPhysics); if (++num6 > 16384) { CODebugBase<LogChannel>.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } if (lodPhysics == 0 && (CSLTraffic.Options & OptionsManager.ModOptions.noStopForCrossing) != OptionsManager.ModOptions.noStopForCrossing) { CitizenManager instance2 = Singleton<CitizenManager>.instance; float num7 = 0f; Vector3 vector2 = vehicleData.m_segment.b; Vector3 lhs = vehicleData.m_segment.b - vehicleData.m_segment.a; for (int k = 0; k < 4; k++) { Vector3 vector3 = vehicleData.GetTargetPos(k); Vector3 vector4 = vector3 - vector2; if (Vector3.Dot(lhs, vector4) > 0f) { float magnitude = vector4.magnitude; if (magnitude > 0.01f) { Segment3 segment = new Segment3(vector2, vector3); min = segment.Min(); max = segment.Max(); int num8 = Mathf.Max((int)((min.x - 3f) / 8f + 1080f), 0); int num9 = Mathf.Max((int)((min.z - 3f) / 8f + 1080f), 0); int num10 = Mathf.Min((int)((max.x + 3f) / 8f + 1080f), 2159); int num11 = Mathf.Min((int)((max.z + 3f) / 8f + 1080f), 2159); for (int l = num9; l <= num11; l++) { for (int m = num8; m <= num10; m++) { ushort num12 = instance2.m_citizenGrid[l * 2160 + m]; int num13 = 0; while (num12 != 0) { num12 = CustomCarAI.CheckCitizen(segment, num7, magnitude, ref maxSpeed, ref blocked, maxBraking, num12, ref instance2.m_instances.m_buffer[(int)num12], min, max); if (++num13 > 65536) { CODebugBase<LogChannel>.Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } } lhs = vector4; num7 += magnitude; vector2 = vector3; } } } }
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); }
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; }
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 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; }
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 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 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); }