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 EnemyLeash v1.0.0
EnemyLeash.dll
Decompiled 14 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using EnemyLeash.Patches; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EnemyLeash { internal struct ChaseAnchor { public Vector3 Origin; public float StartedAt; } internal static class ChaseTracker { private static readonly Dictionary<int, ChaseAnchor> Anchors = new Dictionary<int, ChaseAnchor>(); internal static ChaseAnchor GetOrCreate(int id, Vector3 currentPosition) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (Anchors.TryGetValue(id, out var value)) { return value; } ChaseAnchor chaseAnchor = new ChaseAnchor { Origin = currentPosition, StartedAt = Time.time }; Anchors[id] = chaseAnchor; return chaseAnchor; } internal static void Forget(int id) { if (Anchors.Count != 0) { Anchors.Remove(id); } } internal static void Clear() { Anchors.Clear(); } } [BepInPlugin("benjamin.enemyleash", "EnemyLeash", "1.0.0")] [BepInProcess("REPO.exe")] public class Plugin : BaseUnityPlugin { public const string Guid = "benjamin.enemyleash"; public const string Name = "EnemyLeash"; public const string Version = "1.0.0"; internal static ManualLogSource Log; private Harmony _harmony; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<float> LeashRadius; internal static ConfigEntry<float> MaxChaseSeconds; internal static ConfigEntry<float> GiveUpCooldown; internal static ConfigEntry<bool> BlindOnGiveUp; internal static ConfigEntry<bool> Verbose; private void Awake() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch. Turn off to restore vanilla chase behaviour without uninstalling."); LeashRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Leash", "LeashRadius", 30f, new ConfigDescription("Metres an enemy may travel from where its chase began before it gives up. Set to 0 to disable distance leashing and rely on MaxChaseSeconds alone.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>())); MaxChaseSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Leash", "MaxChaseSeconds", 0f, new ConfigDescription("Hard cap on how long a single chase can last, in seconds. 0 disables the time limit. Note vanilla enemies already have their own per-type chase timers; this only shortens them.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 300f), Array.Empty<object>())); GiveUpCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Leash", "GiveUpCooldown", 8f, new ConfigDescription("Seconds an enemy stays unable to start a new chase after being leashed. Stops it re-acquiring you the instant it turns around.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>())); BlindOnGiveUp = ((BaseUnityPlugin)this).Config.Bind<bool>("Leash", "BlindOnGiveUp", true, "Also blind the enemy for the cooldown duration, not just block chasing. Without this it will still hear and investigate you."); Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Verbose", false, "Log every leash trigger with the distance and duration that caused it."); _harmony = new Harmony("benjamin.enemyleash"); _harmony.PatchAll(typeof(ChaseLeashPatch)); _harmony.PatchAll(typeof(LevelResetPatch)); Log.LogInfo((object)"EnemyLeash v1.0.0 loaded. Monsters have a rope now."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } internal static void Trace(string msg) { if (Verbose != null && Verbose.Value) { Log.LogInfo((object)msg); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "EnemyLeash"; public const string PLUGIN_NAME = "EnemyLeash"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace EnemyLeash.Patches { [HarmonyPatch(typeof(EnemyStateChase))] internal static class ChaseLeashPatch { [HarmonyPostfix] [HarmonyPatch("Update")] private static void AfterUpdate(EnemyStateChase __instance) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled.Value || !SemiFunc.IsMasterClientOrSingleplayer()) { return; } Enemy enemy = __instance.Enemy; if ((Object)(object)enemy == (Object)null) { return; } int instanceID = ((Object)enemy).GetInstanceID(); if (!__instance.Active) { ChaseTracker.Forget(instanceID); return; } Vector3 val = (((Object)(object)enemy.CenterTransform != (Object)null) ? enemy.CenterTransform.position : ((Component)enemy).transform.position); ChaseAnchor orCreate = ChaseTracker.GetOrCreate(instanceID, val); float num = Vector3.Distance(val, orCreate.Origin); float num2 = Time.time - orCreate.StartedAt; float value = Plugin.LeashRadius.Value; float value2 = Plugin.MaxChaseSeconds.Value; bool flag = value > 0f && num > value; bool flag2 = value2 > 0f && num2 > value2; if (flag || flag2) { GiveUp(enemy, instanceID, num, num2, flag); } } private static void GiveUp(Enemy enemy, int id, float travelled, float elapsed, bool tooFar) { float value = Plugin.GiveUpCooldown.Value; enemy.DisableChase(value); if (Plugin.BlindOnGiveUp.Value && enemy.HasVision && (Object)(object)enemy.Vision != (Object)null) { enemy.Vision.DisableVision(value); } ChaseTracker.Forget(id); string arg = (tooFar ? $"travelled {travelled:F1}m (limit {Plugin.LeashRadius.Value:F1}m)" : $"chased for {elapsed:F1}s (limit {Plugin.MaxChaseSeconds.Value:F1}s)"); string arg2 = (((Object)(object)enemy.EnemyParent != (Object)null) ? enemy.EnemyParent.enemyName : "enemy"); Plugin.Trace($"[EnemyLeash] '{arg2}' gave up - {arg}. Cooldown {value:F1}s."); } } [HarmonyPatch(typeof(RunManager))] internal static class LevelResetPatch { [HarmonyPostfix] [HarmonyPatch("ChangeLevel")] private static void AfterChangeLevel() { ChaseTracker.Clear(); } } }