using System.Collections.Generic; namespace Harmony.AIAirDropPatches { [HarmonyPatch(typeof(AIAirDrop))] [HarmonyPatch("SelectCrateCount")] public class SelectCrateCountPatch { public static bool Prefix(AIAirDrop __instance, int _numPlayers, out int _min, out int _max) { _min = 1; _max = 1; if (RebirthVariables.customScenario != "purge") { return false; } return true; } } [HarmonyPatch(typeof(AIAirDrop))] [HarmonyPatch("CreateFlightPaths")] public class CreateFlightPathsPatch { // Helper function to ensure positions stay within a given radius private static Vector2 ClampToRadius(Vector2 center, Vector2 point, float maxRadius) { Vector2 direction = point - center; float distance = direction.magnitude; if (distance > maxRadius) { direction = direction.normalized * maxRadius; point = center + direction; } return point; } public static bool Prefix(AIAirDrop __instance) { if (RebirthVariables.customScenario != "purge") { return true; } float MaxDropDistanceFromPlayer = 100f; // Set your desired maximum distance here __instance.flightPaths = new List(); int _numCrates; int _numPlanes; __instance.CalcSupplyDropMetrics(__instance.numPlayers, __instance.clusters.Count, out _numCrates, out _numPlanes); int num1 = Math.Max(1, _numCrates / _numPlanes); int num2 = _numCrates - _numPlanes * num1; HashSet intSet = new HashSet(); GameRandom random = AIAirDrop.controller.Random; while (_numCrates > 0) { int num3 = Mathf.Min(_numCrates, num1 + num2); _numCrates -= num3; num2 = 0; int index1; do { index1 = random.RandomRange(0, __instance.clusters.Count); } while (intSet.Contains(index1)); AIAirDrop.PlayerCluster cluster = __instance.clusters[index1]; intSet.Add(index1); if (intSet.Count == __instance.clusters.Count) intSet.Clear(); // Get the player's position and adjust the center within the allowed radius Vector2 playerPosition = new Vector2(cluster.Players[0].position.x, cluster.Players[0].position.z);//new Vector2(cluster.XZCenter.x, cluster.XZCenter.y); float PlayerY = cluster.Players[0].position.y; if (RebirthVariables.playerAirDrops.Count > 0) { //Log.Out("===================== USE PLAYER AIRDROPS ======================"); Vector3 removedItem = RebirthVariables.playerAirDrops[0]; RebirthVariables.playerAirDrops.RemoveAt(0); PlayerY = removedItem.y; playerPosition = new Vector2(removedItem.x, removedItem.z); } Vector2 randomDirection = random.RandomOnUnitCircle * random.RandomRange(0f, MaxDropDistanceFromPlayer); Vector2 dropCenter = playerPosition + randomDirection; // Adjust crate spawn points based on the constrained center //float num4 = 50f; // random.RandomRange(150f, 700f); float num4 = random.RandomRange(100f, 200f); float num5 = num4 / 2f; Vector2 tangentDir = random.RandomOnUnitCircle.normalized; Vector2 safePoint1 = dropCenter - tangentDir * num5; Vector2 safePoint2 = dropCenter + tangentDir * num5; safePoint1 = ClampToRadius(playerPosition, safePoint1, MaxDropDistanceFromPlayer); safePoint2 = ClampToRadius(playerPosition, safePoint2, MaxDropDistanceFromPlayer); // Create flight path AIAirDrop.FlightPath flightPath = new AIAirDrop.FlightPath { Start = new Vector3(safePoint1.x, PlayerY + 180f, safePoint1.y), End = new Vector3(safePoint2.x, PlayerY + 180f, safePoint2.y) }; float crateSpacing = num4 / num3; for (int i = 0; i < num3; i++) { Vector2 cratePos = dropCenter + tangentDir * (crateSpacing * i - (crateSpacing * num3) / 2); cratePos = ClampToRadius(playerPosition, cratePos, MaxDropDistanceFromPlayer); AIAirDrop.SupplyCrateSpawn crate = new AIAirDrop.SupplyCrateSpawn { SpawnPos = new Vector3(cratePos.x, PlayerY + 180f - 10f, cratePos.y), Delay = (safePoint1 - cratePos).magnitude / 120f }; flightPath.Crates.Add(crate); } flightPath.Delay = cluster.Delay + random.RandomRange(0f, 15f); cluster.Delay += random.RandomRange(25f, 120f); __instance.flightPaths.Add(flightPath); } return false; } } }