private static float GetSideOffset(ushort vehicleID, ref Vehicle vehicleData, ref Vehicle.Frame frameData) { VehicleInfo vehicleInfo = vehicleData.Info; Vector3 position = frameData.m_position; Vector2 xz = VectorUtils.XZ(frameData.m_position); float y = position.y; Quaternion rotation = frameData.m_rotation; Vector3 size = vehicleInfo.m_generatedInfo.m_size; float vehicleTopY = y + vehicleInfo.m_generatedInfo.m_size.y - vehicleInfo.m_generatedInfo.m_negativeHeight; Vector2 forwardDir = VectorUtils.XZ(rotation * Vector3.forward).normalized; Vector2 rightDir = VectorUtils.XZ(rotation * Vector3.right).normalized; Quad2 passingQuad = new Quad2 { a = xz - 0.5f * size.z * forwardDir - 0.5f * size.x * rightDir, b = xz - 0.5f * size.z * forwardDir + 0.5f * size.x * rightDir, c = xz + 0.75f * size.z * forwardDir + 0.5f * size.x * rightDir, d = xz + 0.75f * size.z * forwardDir - 0.5f * size.x * rightDir }; float halfWidth = size.x / 2; Quad2 quad01 = QuadUtils.GetSegmentQuad(vehicleData.m_targetPos0, vehicleData.m_targetPos1, halfWidth); Quad2 quad12 = QuadUtils.GetSegmentQuad(vehicleData.m_targetPos1, vehicleData.m_targetPos2, halfWidth); Vector2 quadMin = Vector2.Min(Vector2.Min(passingQuad.Min(), quad01.Min()), quad12.Min()); Vector2 quadMax = Vector2.Max(Vector2.Max(passingQuad.Max(), quad01.Max()), quad12.Max()); float yMin = Mathf.Min(Mathf.Min(vehicleData.m_targetPos0.y, vehicleData.m_targetPos1.y), Mathf.Min(vehicleData.m_targetPos2.y, vehicleData.m_targetPos3.y)); float yMax = Mathf.Max(Mathf.Max(vehicleData.m_targetPos0.y, vehicleData.m_targetPos1.y), Mathf.Max(vehicleData.m_targetPos2.y, vehicleData.m_targetPos3.y)); int minGridX = Math.Max((int)((quadMin.x - 72f) / 64f + 135f), 0); int minGridZ = Math.Max((int)((quadMin.y - 72f) / 64f + 135f), 0); int maxGridX = Math.Min((int)((quadMax.x + 72f) / 64f + 135f), 269); int maxGridZ = Math.Min((int)((quadMax.y + 72f) / 64f + 135f), 269); float minY = yMin - vehicleInfo.m_generatedInfo.m_negativeHeight - 2f; float maxY = yMax + vehicleInfo.m_generatedInfo.m_size.y + 2f; BuildingManager buildingManager = Singleton <BuildingManager> .instance; for (int gridZ = minGridZ; gridZ <= maxGridZ; gridZ++) { for (int gridX = minGridX; gridX <= maxGridX; gridX++) { ushort buildingID = buildingManager.m_buildingGrid[gridZ * 270 + gridX]; while (buildingID != 0) { bool overlap01 = buildingManager.m_buildings.m_buffer[buildingID].OverlapQuad(buildingID, quad01, minY, maxY, ItemClass.CollisionType.Terrain); bool overlap02 = buildingManager.m_buildings.m_buffer[buildingID].OverlapQuad(buildingID, quad12, minY, maxY, ItemClass.CollisionType.Terrain); if (overlap01 || overlap02) { return(0f); } buildingID = buildingManager.m_buildings.m_buffer[buildingID].m_nextGridBuilding; } } } return(20f); }
public static void Prefix(ref Vehicle vehicleData, ref Vehicle.Frame frameData, ref float maxSpeed, float maxBraking) { VehicleInfo vehicleInfo = vehicleData.Info; Vector3 position = frameData.m_position; Vector2 xz = VectorUtils.XZ(frameData.m_position); float y = position.y; Quaternion rotation = frameData.m_rotation; Vector3 size = vehicleInfo.m_generatedInfo.m_size; float vehicleTopY = y + vehicleInfo.m_generatedInfo.m_size.y - vehicleInfo.m_generatedInfo.m_negativeHeight; Vector2 forwardDir = VectorUtils.XZ(rotation * Vector3.forward).normalized; Vector2 rightDir = VectorUtils.XZ(rotation * Vector3.right).normalized; Quad2 passingQuad = new Quad2 { a = xz - 0.5f * size.z * forwardDir - 0.5f * size.x * rightDir, b = xz - 0.5f * size.z * forwardDir + 0.5f * size.x * rightDir, c = xz + 0.5f * size.z * forwardDir + 0.5f * size.x * rightDir, d = xz + 0.5f * size.z * forwardDir - 0.5f * size.x * rightDir }; float halfWidth = size.x / 2; Quad2 quad01 = QuadUtils.GetSegmentQuad(vehicleData.m_targetPos0, vehicleData.m_targetPos1, halfWidth); Quad2 quad12 = QuadUtils.GetSegmentQuad(vehicleData.m_targetPos1, vehicleData.m_targetPos2, halfWidth); Quad2 quad23 = QuadUtils.GetSegmentQuad(vehicleData.m_targetPos2, vehicleData.m_targetPos3, halfWidth); Vector2 quadMin = Vector2.Min(Vector2.Min(passingQuad.Min(), quad01.Min()), Vector2.Min(quad12.Min(), quad23.Min())); Vector2 quadMax = Vector2.Max(Vector2.Max(passingQuad.Max(), quad01.Max()), Vector2.Max(quad12.Max(), quad23.Max())); float yMin = Mathf.Min(Mathf.Min(vehicleData.m_targetPos0.y, vehicleData.m_targetPos1.y), Mathf.Min(vehicleData.m_targetPos2.y, vehicleData.m_targetPos3.y)); float yMax = Mathf.Max(Mathf.Max(vehicleData.m_targetPos0.y, vehicleData.m_targetPos1.y), Mathf.Max(vehicleData.m_targetPos2.y, vehicleData.m_targetPos3.y)); int minGridX = Math.Max((int)((quadMin.x - 72f) / 64f + 135f), 0); int minGridZ = Math.Max((int)((quadMin.y - 72f) / 64f + 135f), 0); int maxGridX = Math.Min((int)((quadMax.x + 72f) / 64f + 135f), 269); int maxGridZ = Math.Min((int)((quadMax.y + 72f) / 64f + 135f), 269); float minY = yMin - vehicleInfo.m_generatedInfo.m_negativeHeight - 2f; float maxY = yMax + vehicleInfo.m_generatedInfo.m_size.y + 2f; BuildingManager buildingManager = Singleton <BuildingManager> .instance; for (int gridZ = minGridZ; gridZ <= maxGridZ; gridZ++) { for (int gridX = minGridX; gridX <= maxGridX; gridX++) { ushort buildingID = buildingManager.m_buildingGrid[gridZ * 270 + gridX]; while (buildingID != 0) { bool passing = buildingManager.m_buildings.m_buffer[buildingID].OverlapQuad(buildingID, passingQuad, minY, maxY, ItemClass.CollisionType.Terrain); bool near1 = buildingManager.m_buildings.m_buffer[buildingID].OverlapQuad(buildingID, quad01, minY, maxY, ItemClass.CollisionType.Terrain) || buildingManager.m_buildings.m_buffer[buildingID].OverlapQuad(buildingID, quad12, minY, maxY, ItemClass.CollisionType.Terrain); bool near2 = buildingManager.m_buildings.m_buffer[buildingID].OverlapQuad(buildingID, quad23, minY, maxY, ItemClass.CollisionType.Terrain); float maxSpeedForBridge = HandleMovableBridge(ref vehicleData, buildingID, ref buildingManager.m_buildings.m_buffer[buildingID], passing, near1, near2, minY, maxY, maxSpeed, vehicleTopY, forwardDir); if (maxSpeedForBridge < maxSpeed) { maxSpeed = CalculateMaxSpeed(0f, maxSpeedForBridge, maxBraking); } buildingID = buildingManager.m_buildings.m_buffer[buildingID].m_nextGridBuilding; } } } #if DEBUG if (InputListener.slowDown) { float targetSpeed = Mathf.Min(maxSpeed, 1f); maxSpeed = CalculateMaxSpeed(0f, targetSpeed, maxBraking); } #endif }