Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of DryBeehives v1.0.0
DryBeehives.dll
Decompiled an hour agousing System; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Unity.AI.Navigation; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace DryBeehives { [BepInPlugin("lethalcompany.drybeehives", "DryBeehives", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "lethalcompany.drybeehives"; public const string PluginName = "DryBeehives"; public const string PluginVersion = "1.0.0"; private Harmony _harmony; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } public ConfigEntry<bool> ModEnabled { get; private set; } public ConfigEntry<float> ShoreBufferDistance { get; private set; } public ConfigEntry<float> MaxSearchRadius { get; private set; } public ConfigEntry<bool> VerboseLogging { get; private set; } private void Awake() { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "If true, beehives (and their Circuit Bees) that try to spawn inside static water bodies (ponds/lakes) will be moved to the nearest dry shore/ground."); ShoreBufferDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Placement", "ShoreBufferDistance", 2f, "Minimum distance (in meters) from the edge of a static water collider to place a relocated beehive so it stays safely on dry land."); MaxSearchRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Placement", "MaxSearchRadius", 80f, "Maximum outward search radius (in meters) when looking for the nearest dry NavMesh position."); VerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogging", true, "Log whenever a beehive or bee swarm is detected in static water and relocated to dry ground."); _harmony = new Harmony("lethalcompany.drybeehives"); _harmony.PatchAll(typeof(Plugin).Assembly); Log.LogInfo((object)string.Format("{0} v{1} loaded! Static pond/lake beehive relocation is {2}.", "DryBeehives", "1.0.0", ModEnabled.Value ? "ENABLED" : "DISABLED")); } } public struct WaterVolume { public Bounds Bounds; public Func<Vector3, Vector3> ClosestPointFunc; public string SourceName; public WaterVolume(Bounds bounds, Func<Vector3, Vector3> closestPointFunc, string sourceName = "") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) Bounds = bounds; ClosestPointFunc = closestPointFunc; SourceName = sourceName ?? ""; } } public delegate bool TerrainRaycastDelegate(Vector3 rayOrigin, float maxDistance, out Vector3 hitPoint); public delegate bool NavMeshSampleDelegate(Vector3 probePoint, float maxDistance, int navMeshMask, out Vector3 navMeshPoint); public static class WaterHelper { public const int DefaultWaterNavMeshAreaIndex = 12; public const int DefaultWaterNavMeshAreaMask = 4096; private static readonly int[] AngleStepsCountByTier = new int[3] { 16, 24, 32 }; [MethodImpl(MethodImplOptions.NoInlining)] private static int QueryUnityWaterAreaIndex() { return NavMesh.GetAreaFromName("Water"); } public static int GetWaterNavMeshAreaMask() { int num = 4096; try { int num2 = QueryUnityWaterAreaIndex(); if (num2 >= 0 && num2 < 32) { num |= 1 << num2; } } catch { } return num; } public static int GetDryNavMeshMask(int navMeshMask) { return navMeshMask & ~GetWaterNavMeshAreaMask(); } public static bool ShouldIncludeWaterTrigger(bool isActive, bool isWater, bool isInsideWater, bool hasFloodWeatherParent) { if (isActive && isWater && !isInsideWater) { return !hasFloodWeatherParent; } return false; } public static List<WaterVolume> GetStaticWaterVolumes() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) List<WaterVolume> list = new List<WaterVolume>(); if ((Object)(object)RoundManager.Instance != (Object)null) { if (RoundManager.Instance.underwaterBounds == null || RoundManager.Instance.underwaterBounds.Length == 0) { try { RoundManager.Instance.GetOutsideAINodes(true); } catch { } } if (RoundManager.Instance.underwaterBounds != null) { Bounds[] underwaterBounds = RoundManager.Instance.underwaterBounds; for (int i = 0; i < underwaterBounds.Length; i++) { Bounds bounds = NormalizeBounds(underwaterBounds[i]); Vector3 size = ((Bounds)(ref bounds)).size; if (((Vector3)(ref size)).sqrMagnitude > 0.01f) { list.Add(new WaterVolume(bounds, null, "RoundManager.underwaterBounds")); } } } } NavMeshModifierVolume[] array = Object.FindObjectsOfType<NavMeshModifierVolume>(); if (array != null) { Vector3 val3 = default(Vector3); Bounds bounds2 = default(Bounds); foreach (NavMeshModifierVolume val in array) { if (!((Object)(object)val == (Object)null) && ((Behaviour)val).isActiveAndEnabled && ((Component)val).gameObject.activeInHierarchy && val.area == 12) { Vector3 val2 = ((Component)val).transform.TransformPoint(val.center); Vector3 lossyScale = ((Component)val).transform.lossyScale; ((Vector3)(ref val3))..ctor(Mathf.Abs(val.size.x * lossyScale.x), Mathf.Abs(val.size.y * lossyScale.y), Mathf.Abs(val.size.z * lossyScale.z)); ((Bounds)(ref bounds2))..ctor(val2, val3); list.Add(new WaterVolume(bounds2, null, "NavMeshModifierVolume:" + ((Object)((Component)val).gameObject).name)); } } } QuicksandTrigger[] array2 = Object.FindObjectsOfType<QuicksandTrigger>(); if (array2 != null) { foreach (QuicksandTrigger val4 in array2) { if (!((Object)(object)val4 != (Object)null) || !((Behaviour)val4).isActiveAndEnabled || !((Component)val4).gameObject.activeInHierarchy) { continue; } bool hasFloodWeatherParent = (Object)(object)((Component)val4).GetComponentInParent<FloodWeather>() != (Object)null; if (!ShouldIncludeWaterTrigger(isActive: true, val4.isWater, val4.isInsideWater, hasFloodWeatherParent)) { continue; } Collider[] componentsInChildren = ((Component)val4).GetComponentsInChildren<Collider>(false); if (componentsInChildren == null) { continue; } foreach (Collider val5 in componentsInChildren) { if ((Object)(object)val5 != (Object)null && val5.enabled) { Bounds bounds3 = NormalizeBounds(val5.bounds); list.Add(new WaterVolume(bounds3, null, "QuicksandTrigger:" + ((Object)((Component)val4).gameObject).name)); } } } } return list; } public static bool IsPositionInStaticWater(Vector3 position, IList<WaterVolume> waterVolumes, float shoreBuffer, out float highestWaterSurfaceY) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) bool flag = IsPositionInWaterVolumes(position, waterVolumes, shoreBuffer, out highestWaterSurfaceY); if (IsNearWaterNavMesh(position, shoreBuffer, out var waterNavMeshY)) { if (!flag || waterNavMeshY > highestWaterSurfaceY) { highestWaterSurfaceY = waterNavMeshY; } return true; } return flag; } public static bool IsNearWaterNavMesh(Vector3 position, float shoreBuffer, out float waterNavMeshY) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) waterNavMeshY = position.y; float num = Mathf.Max(0.25f, shoreBuffer); int waterNavMeshAreaMask = GetWaterNavMeshAreaMask(); NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(position, ref val, num + 1.5f, waterNavMeshAreaMask)) { Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(((NavMeshHit)(ref val)).position.x - position.x, ((NavMeshHit)(ref val)).position.z - position.z); float num2 = Mathf.Abs(((NavMeshHit)(ref val)).position.y - position.y); if (((Vector2)(ref val2)).sqrMagnitude <= num * num && num2 <= 4f) { waterNavMeshY = ((NavMeshHit)(ref val)).position.y; return true; } } return false; } public static bool IsPositionInWaterVolumes(Vector3 position, IList<WaterVolume> waterVolumes, float shoreBuffer, out float highestWaterSurfaceY) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) highestWaterSurfaceY = position.y; if (waterVolumes == null || waterVolumes.Count == 0) { return false; } float num = Mathf.Max(0.1f, shoreBuffer); float num2 = num * num; bool result = false; Vector3 val = default(Vector3); Vector2 val3 = default(Vector2); Vector2 val5 = default(Vector2); for (int i = 0; i < waterVolumes.Count; i++) { WaterVolume waterVolume = waterVolumes[i]; Bounds bounds = NormalizeBounds(waterVolume.Bounds); bool flag = ((Bounds)(ref bounds)).size.x >= 40f || ((Bounds)(ref bounds)).size.z >= 40f; float num3 = ((Bounds)(ref bounds)).max.y + 0.65f; float num4 = (flag ? num3 : (((Bounds)(ref bounds)).max.y + 3.8f)); if (position.y > num4 || position.x < ((Bounds)(ref bounds)).min.x - num || position.x > ((Bounds)(ref bounds)).max.x + num || position.z < ((Bounds)(ref bounds)).min.z - num || position.z > ((Bounds)(ref bounds)).max.z + num) { continue; } float num5 = Mathf.Clamp(position.y, ((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).max.y); ((Vector3)(ref val))..ctor(position.x, num5, position.z); if (waterVolume.ClosestPointFunc != null) { Vector3 val2 = waterVolume.ClosestPointFunc(val); ((Vector2)(ref val3))..ctor(val2.x - val.x, val2.z - val.z); float num6 = Mathf.Abs(val2.y - val.y); if (((Vector2)(ref val3)).sqrMagnitude <= num2 && num6 <= num + 0.5f) { result = true; if (num3 > highestWaterSurfaceY) { highestWaterSurfaceY = num3; } } continue; } Vector3 val4 = ClampPointToAABB(bounds, val); ((Vector2)(ref val5))..ctor(val4.x - val.x, val4.z - val.z); float num7 = Mathf.Abs(val4.y - val.y); if (((Vector2)(ref val5)).sqrMagnitude <= num2 && num7 <= num + 0.5f) { result = true; if (num3 > highestWaterSurfaceY) { highestWaterSurfaceY = num3; } } } return result; } public static bool TryFindNearestDryNavMeshPosition(Vector3 origin, int navMeshMask, IList<WaterVolume> waterVolumes, float shoreBuffer, float maxSearchRadius, out Vector3 dryPosition) { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) int dryNavMeshMask = GetDryNavMeshMask(navMeshMask); int terrainMask = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.collidersAndRoomMaskAndDefault : (-1)); TerrainRaycastDelegate raycastTerrain = delegate(Vector3 rayOrigin, float maxDist, out Vector3 hitPt) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) RaycastHit val = default(RaycastHit); if (Physics.Raycast(rayOrigin, Vector3.down, ref val, maxDist, terrainMask, (QueryTriggerInteraction)1)) { hitPt = ((RaycastHit)(ref val)).point; return true; } hitPt = Vector3.zero; return false; }; NavMeshSampleDelegate sampleNavMesh = delegate(Vector3 probePt, float maxDist, int mask, out Vector3 navPt) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(probePt, ref val, maxDist, mask)) { if (IsNearWaterNavMesh(((NavMeshHit)(ref val)).position, shoreBuffer, out var _)) { navPt = Vector3.zero; return false; } navPt = ((NavMeshHit)(ref val)).position; return true; } navPt = Vector3.zero; return false; }; List<Vector3> list = null; if ((Object)(object)RoundManager.Instance != (Object)null) { GameObject[] array = ((RoundManager.Instance.outsideAIDryNodes != null && RoundManager.Instance.outsideAIDryNodes.Length > 0) ? RoundManager.Instance.outsideAIDryNodes : RoundManager.Instance.outsideAINodes); if (array != null) { list = new List<Vector3>(array.Length); for (int num = 0; num < array.Length; num++) { if ((Object)(object)array[num] != (Object)null) { list.Add(array[num].transform.position); } } } } return TryFindNearestDryPosition(origin, dryNavMeshMask, waterVolumes, shoreBuffer, maxSearchRadius, raycastTerrain, sampleNavMesh, list, out dryPosition, checkRuntimeWaterNavMesh: true); } public static bool TryFindNearestDryPosition(Vector3 origin, int navMeshMask, IList<WaterVolume> waterVolumes, float shoreBuffer, float maxSearchRadius, TerrainRaycastDelegate raycastTerrain, NavMeshSampleDelegate sampleNavMesh, IList<Vector3> fallbackNodes, out Vector3 dryPosition, bool checkRuntimeWaterNavMesh = false) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) dryPosition = origin; if (!(checkRuntimeWaterNavMesh ? IsPositionInStaticWater(origin, waterVolumes, shoreBuffer, out var highestWaterSurfaceY) : IsPositionInWaterVolumes(origin, waterVolumes, shoreBuffer, out highestWaterSurfaceY))) { return true; } if (sampleNavMesh == null) { return false; } int dryNavMeshMask = GetDryNavMeshMask(navMeshMask); float num = Mathf.Max(15f, maxSearchRadius); float num2 = 2f; bool flag = false; float num3 = float.MaxValue; Vector3 val = origin; float num4 = num; Vector3 probePoint = default(Vector3); for (float num5 = num2; num5 <= num4; num5 += num2) { int num6 = ((num5 <= 12f) ? AngleStepsCountByTier[0] : ((num5 <= 30f) ? AngleStepsCountByTier[1] : AngleStepsCountByTier[2])); float num7 = 360f / (float)num6; for (int i = 0; i < num6; i++) { float num8 = (float)i * num7 * ((float)Math.PI / 180f); float num9 = origin.x + Mathf.Cos(num8) * num5; float num10 = origin.z + Mathf.Sin(num8) * num5; float num11 = Mathf.Max(origin.y, highestWaterSurfaceY) + 18f; ((Vector3)(ref probePoint))..ctor(num9, Mathf.Max(origin.y, highestWaterSurfaceY), num10); if (raycastTerrain != null && raycastTerrain(new Vector3(num9, num11, num10), 45f, out var hitPoint)) { probePoint = hitPoint; } if (!TrySampleDryPointAt(probePoint, 5f, dryNavMeshMask, waterVolumes, shoreBuffer, raycastTerrain, sampleNavMesh, out var validDryNavMeshPoint) && !TrySampleDryPointAt(new Vector3(num9, highestWaterSurfaceY, num10), 6.5f, dryNavMeshMask, waterVolumes, shoreBuffer, raycastTerrain, sampleNavMesh, out validDryNavMeshPoint) && !TrySampleDryPointAt(new Vector3(num9, origin.y, num10), 6.5f, dryNavMeshMask, waterVolumes, shoreBuffer, raycastTerrain, sampleNavMesh, out validDryNavMeshPoint)) { continue; } float num12 = Vector3.Distance(origin, validDryNavMeshPoint); if (num12 < num3) { num3 = num12; val = validDryNavMeshPoint; if (!flag) { flag = true; num4 = Mathf.Min(num, num5 + num2 * 2f); } } } } if (flag) { dryPosition = val; return true; } if (fallbackNodes != null && fallbackNodes.Count > 0) { float num13 = float.MaxValue; Vector3 val2 = origin; bool flag2 = false; for (int j = 0; j < fallbackNodes.Count; j++) { Vector3 probePoint2 = fallbackNodes[j]; if (TrySampleDryPointAt(probePoint2, 8f, dryNavMeshMask, waterVolumes, shoreBuffer, raycastTerrain, sampleNavMesh, out var validDryNavMeshPoint2)) { float num14 = Vector3.Distance(origin, validDryNavMeshPoint2); if (num14 < num13) { num13 = num14; val2 = validDryNavMeshPoint2; flag2 = true; } } } if (flag2) { dryPosition = val2; return true; } } return false; } public static bool ShouldRelocateBeesToHive(Vector3 beePosition, Vector3 hivePosition, float maxAllowedDistance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Vector3.Distance(beePosition, hivePosition) > maxAllowedDistance; } public static bool ShouldCorrectLastKnownHivePosition(Vector3 lastKnownHivePosition, Vector3 actualHivePosition, float threshold, out Vector3 correctedPosition) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (Vector3.Distance(lastKnownHivePosition, actualHivePosition) > threshold) { correctedPosition = actualHivePosition + Vector3.up * 0.5f; return true; } correctedPosition = lastKnownHivePosition; return false; } public static Bounds NormalizeBounds(Bounds bounds) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) Vector3 size = ((Bounds)(ref bounds)).size; return new Bounds(((Bounds)(ref bounds)).center, new Vector3(Mathf.Abs(size.x), Mathf.Abs(size.y), Mathf.Abs(size.z))); } public static bool ContainsPointAABB(Bounds bounds, Vector3 point) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) Vector3 min = ((Bounds)(ref bounds)).min; Vector3 max = ((Bounds)(ref bounds)).max; if (point.x >= min.x && point.x <= max.x && point.y >= min.y && point.y <= max.y && point.z >= min.z) { return point.z <= max.z; } return false; } public static Vector3 ClampPointToAABB(Bounds bounds, Vector3 point) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) Vector3 min = ((Bounds)(ref bounds)).min; Vector3 max = ((Bounds)(ref bounds)).max; return new Vector3(Mathf.Clamp(point.x, min.x, max.x), Mathf.Clamp(point.y, min.y, max.y), Mathf.Clamp(point.z, min.z, max.z)); } public static bool IsOverLargeWaterTable(Vector3 point, IList<WaterVolume> waterVolumes) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) if (waterVolumes == null) { return false; } for (int i = 0; i < waterVolumes.Count; i++) { Bounds val = NormalizeBounds(waterVolumes[i].Bounds); if ((((Bounds)(ref val)).size.x >= 40f || ((Bounds)(ref val)).size.z >= 40f) && point.x >= ((Bounds)(ref val)).min.x && point.x <= ((Bounds)(ref val)).max.x && point.z >= ((Bounds)(ref val)).min.z && point.z <= ((Bounds)(ref val)).max.z) { return true; } } return false; } private static bool TrySampleDryPointAt(Vector3 probePoint, float maxSampleDistance, int navMeshMask, IList<WaterVolume> waterVolumes, float shoreBuffer, TerrainRaycastDelegate raycastTerrain, NavMeshSampleDelegate sampleNavMesh, out Vector3 validDryNavMeshPoint) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) validDryNavMeshPoint = probePoint; if (!sampleNavMesh(probePoint, maxSampleDistance, navMeshMask, out var navMeshPoint)) { return false; } if (IsPositionInWaterVolumes(navMeshPoint, waterVolumes, shoreBuffer, out var _)) { return false; } float num = Mathf.Max(0.5f, shoreBuffer); if (raycastTerrain != null && IsOverLargeWaterTable(navMeshPoint, waterVolumes)) { float num2 = navMeshPoint.y + 8f; float num3 = num * 0.70710677f; Vector2[] array = (Vector2[])(object)new Vector2[8] { new Vector2(num, 0f), new Vector2(0f - num, 0f), new Vector2(0f, num), new Vector2(0f, 0f - num), new Vector2(num3, num3), new Vector2(0f - num3, num3), new Vector2(num3, 0f - num3), new Vector2(0f - num3, 0f - num3) }; Vector3 rayOrigin = default(Vector3); for (int i = 0; i < array.Length; i++) { ((Vector3)(ref rayOrigin))..ctor(navMeshPoint.x + array[i].x, num2, navMeshPoint.z + array[i].y); if (raycastTerrain(rayOrigin, 20f, out var hitPoint) && IsPositionInWaterVolumes(hitPoint, waterVolumes, 0.1f, out var _)) { return false; } } } validDryNavMeshPoint = navMeshPoint; return true; } } } namespace DryBeehives.Patches { [HarmonyPatch] internal static class RedLocustBeesPatch { private static RedLocustBees _activeSpawningBees; private static List<WaterVolume> _cachedWaterVolumes; [HarmonyPatch(typeof(RedLocustBees), "SpawnHiveNearEnemy")] [HarmonyPrefix] private static void SpawnHiveNearEnemy_Prefix(RedLocustBees __instance) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) _activeSpawningBees = null; _cachedWaterVolumes = null; if ((Object)(object)Plugin.Instance == (Object)null || !Plugin.Instance.ModEnabled.Value || (Object)(object)__instance == (Object)null || !((NetworkBehaviour)__instance).IsServer) { return; } _activeSpawningBees = __instance; _cachedWaterVolumes = WaterHelper.GetStaticWaterVolumes(); float value = Plugin.Instance.ShoreBufferDistance.Value; float value2 = Plugin.Instance.MaxSearchRadius.Value; int dryNavMeshMask = WaterHelper.GetDryNavMeshMask(((EnemyAI)__instance).agentMask & -17); Vector3 position = ((Component)__instance).transform.position; if (Plugin.Instance.VerboseLogging.Value) { Plugin.Log.LogInfo((object)$"[DryBeehives] Inspecting Circuit Bees spawn at {position} (waterVolumes={_cachedWaterVolumes.Count}, agentMask={((EnemyAI)__instance).agentMask} -> dryMask={dryNavMeshMask})."); } if (!WaterHelper.IsPositionInStaticWater(position, _cachedWaterVolumes, value, out var _)) { return; } if (WaterHelper.TryFindNearestDryNavMeshPosition(position, dryNavMeshMask, _cachedWaterVolumes, value, value2, out var dryPosition)) { RelocateBeesToPosition(__instance, dryPosition); if (Plugin.Instance.VerboseLogging.Value) { Plugin.Log.LogInfo((object)$"[DryBeehives] Circuit Bees spawned in static water at {position}; relocated bees to nearest dry shore at {dryPosition} (moved {Vector3.Distance(position, dryPosition):F1}m)."); } } else { Plugin.Log.LogWarning((object)$"[DryBeehives] Circuit Bees spawned in static water at {position}, but no dry NavMesh position was found within {value2:F1}m."); } } [HarmonyPatch(typeof(RedLocustBees), "SpawnHiveNearEnemy")] [HarmonyFinalizer] private static void SpawnHiveNearEnemy_Finalizer() { _activeSpawningBees = null; _cachedWaterVolumes = null; } [HarmonyPatch(typeof(RoundManager), "GetRandomNavMeshPositionInBoxPredictable", new Type[] { typeof(Vector3), typeof(float), typeof(NavMeshHit), typeof(Random), typeof(int), typeof(float) })] [HarmonyPrefix] private static void GetRandomNavMeshPositionInBoxPredictable_Prefix(ref Vector3 pos, ref int layerMask) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_activeSpawningBees == (Object)null)) { layerMask = WaterHelper.GetDryNavMeshMask(layerMask); pos = ((Component)_activeSpawningBees).transform.position; } } [HarmonyPostfix] [HarmonyPatch(typeof(RoundManager), "GetRandomNavMeshPositionInBoxPredictable", new Type[] { typeof(Vector3), typeof(float), typeof(NavMeshHit), typeof(Random), typeof(int), typeof(float) })] private static void GetRandomNavMeshPositionInBoxPredictable_Postfix(ref Vector3 __result, int layerMask) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_activeSpawningBees == (Object)null) { return; } float value = Plugin.Instance.ShoreBufferDistance.Value; float value2 = Plugin.Instance.MaxSearchRadius.Value; Vector3 val = __result; Vector3 dryPosition; if (!WaterHelper.IsPositionInStaticWater(val, _cachedWaterVolumes, value, out var _)) { if (Plugin.Instance.VerboseLogging.Value) { Plugin.Log.LogInfo((object)$"[DryBeehives] Beehive candidate position {val} verified dry."); } } else if (WaterHelper.TryFindNearestDryNavMeshPosition(val, layerMask, _cachedWaterVolumes, value, value2, out dryPosition)) { __result = dryPosition; if (WaterHelper.ShouldRelocateBeesToHive(((Component)_activeSpawningBees).transform.position, dryPosition, 6.5f)) { RelocateBeesToPosition(_activeSpawningBees, dryPosition); } if (Plugin.Instance.VerboseLogging.Value) { Plugin.Log.LogInfo((object)$"[DryBeehives] Beehive candidate position {val} was in static water; moved hive to nearest dry ground at {dryPosition} (moved {Vector3.Distance(val, dryPosition):F1}m)."); } } else { Plugin.Log.LogWarning((object)$"[DryBeehives] Beehive candidate position {val} was in static water, but no dry NavMesh spot was found within {value2:F1}m."); } } [HarmonyPatch(typeof(RedLocustBees), "SpawnHiveClientRpc")] [HarmonyPostfix] private static void SpawnHiveClientRpc_Postfix(RedLocustBees __instance) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Plugin.Instance == (Object)null) && Plugin.Instance.ModEnabled.Value && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.hive == (Object)null)) { Vector3 position = ((Component)__instance.hive).transform.position; if (WaterHelper.ShouldCorrectLastKnownHivePosition(__instance.lastKnownHivePosition, position, 3.5f, out var correctedPosition)) { __instance.lastKnownHivePosition = correctedPosition; } } } private static void RelocateBeesToPosition(RedLocustBees bees, Vector3 targetPosition) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)bees == (Object)null)) { if ((Object)(object)((EnemyAI)bees).agent != (Object)null && ((Behaviour)((EnemyAI)bees).agent).isActiveAndEnabled) { ((EnemyAI)bees).agent.Warp(targetPosition); } ((Component)bees).transform.position = targetPosition; ((EnemyAI)bees).SyncPositionToClients(); } } } }