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 Mutators Addon v0.1.0
BepInEx/plugins/GastrodonGroup-Mutators_Addon/MutatorsAddon.dll
Decompiled 9 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GastrodonGroup.MutatorsAddon.Behaviours; using GastrodonGroup.MutatorsAddon.MutatorDefinitions.BadDog; using GastrodonGroup.MutatorsAddon.Patches; using HarmonyLib; using Microsoft.CodeAnalysis; using Mutators.Enums; using Mutators.Managers; using Mutators.Mutators; using Mutators.Settings; using REPOLib.Modules; 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: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("GastrodonGroup")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+17998fb6623b18b883f128654cfbd0327516ed81")] [assembly: AssemblyProduct("MutatorsAddon")] [assembly: AssemblyTitle("MutatorsAddon")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 GastrodonGroup.MutatorsAddon { [BepInDependency("Xepos.REPO-Mutators", "1.0.2")] [BepInPlugin("GastrodonGroup.MutatorsAddon", "Mutators Addon", "0.1.0")] public class MutatorsAddonPlugin : BaseUnityPlugin { internal static MutatorsAddonPlugin Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; RegisterBadDog(); RegisterWrongWayMap(); RegisterSilentStalkers(); Logger.LogInfo((object)string.Format("{0} v{1} has loaded! Build: {2}", ((BaseUnityPlugin)this).Info.Metadata.GUID, ((BaseUnityPlugin)this).Info.Metadata.Version, "2026-07-04 08:20")); } private static void RegisterWrongWayMap() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown IMutator val = (IMutator)new Mutator((AbstractMutatorSettings)new GenericMutatorSettings("GastrodonGroup.MutatorsAddon", "MAP-side Down", "The minimap screen is rotated 180 degrees", ((BaseUnityPlugin)Instance).Config), typeof(WrongWayMapPatch), (MutatorDifficulty)3, (IList<Func<bool>>)null, false); MutatorManager.Instance.RegisterMutator(val); Logger.LogInfo((object)"Registered mutator: MAP-side Down"); } private static void RegisterSilentStalkers() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown IMutator val = (IMutator)new Mutator((AbstractMutatorSettings)new GenericMutatorSettings("GastrodonGroup.MutatorsAddon", "Silent Stalkers", "You cannot hear the enemy sounds", ((BaseUnityPlugin)Instance).Config), typeof(SilentStalkersPatch), (MutatorDifficulty)2, (IList<Func<bool>>)null, false); MutatorManager.Instance.RegisterMutator(val); Logger.LogInfo((object)"Registered mutator: Silent Stalkers"); } private static void RegisterBadDog() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown BadDogMutator.BindConfig(((BaseUnityPlugin)Instance).Config); IMutator val = (IMutator)new Mutator((AbstractMutatorSettings)new GenericMutatorSettings("GastrodonGroup.MutatorsAddon", "Watchdog Out!", "Elsa transforms on sight instead of waiting for pets", ((BaseUnityPlugin)Instance).Config), typeof(BadDogPatch), (MutatorDifficulty)3, (IList<Func<bool>>)null, false); MutatorManager.Instance.RegisterMutator(val); Logger.LogInfo((object)"Registered mutator: Watchdog Out!"); } } internal static class PluginInfo { internal const string PLUGIN_GUID = "GastrodonGroup.MutatorsAddon"; internal const string PLUGIN_NAME = "Mutators Addon"; internal const string PLUGIN_VERSION = "0.1.0"; internal const string THUNDERSTORE_PACKAGE_NAME = "Mutators_Addon"; } internal static class BuildInfo { internal const string Timestamp = "2026-07-04 08:20"; } } namespace GastrodonGroup.MutatorsAddon.Patches { internal class BadDogPatch { private const string ElsaEnemyName = "Elsa"; private const string ElsaSetupName = "Enemy - Elsa"; [HarmonyPostfix] [HarmonyPriority(99)] [HarmonyPatch(typeof(EnemyDirector), "AmountSetup")] private static void EnemyDirectorAmountSetupPostfix(EnemyDirector __instance) { if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } IList<EnemySetup> enemyList = __instance.enemyList; if (enemyList.Any((EnemySetup setup) => setup.spawnObjects.Select((PrefabRef so) => ((PrefabRef<GameObject>)(object)so).Prefab.GetComponent<EnemyParent>()).Any((EnemyParent ep) => (Object)(object)ep != (Object)null && ep.enemyName == "Elsa"))) { return; } EnemySetup val = ((IEnumerable<EnemySetup>)Enemies.AllEnemies).FirstOrDefault((Func<EnemySetup, bool>)((EnemySetup setup) => ((Object)setup).name == "Enemy - Elsa")); if (!Object.op_Implicit((Object)(object)val)) { return; } IList<EnemySetup> list = enemyList.Where(delegate(EnemySetup setup) { IEnumerable<EnemyParent> source = from so in setup.spawnObjects select ((PrefabRef<GameObject>)(object)so).Prefab.GetComponent<EnemyParent>() into ep where (Object)(object)ep != (Object)null select ep; return source.All((EnemyParent ep) => (int)ep.difficulty == 0) && source.All((EnemyParent ep) => ep.enemyName != "Elsa"); }).ToList(); if (list.Count == 0) { MutatorsAddonPlugin.Logger.LogWarning((object)"No suitable enemies found to replace with Elsa"); return; } EnemySetup item = list[Random.Range(0, list.Count)]; if (enemyList.Remove(item)) { enemyList.Add(val); } } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyElsa), "Update")] private static void EnemyElsaUpdatePrefix(EnemyElsa __instance) { //IL_001f: 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_0025: 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_0029: Invalid comparison between Unknown and I4 //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Invalid comparison between Unknown and I4 if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } BadDogBehaviour badDogBehaviour = ((Component)__instance).GetComponent<BadDogBehaviour>() ?? ((Component)__instance).gameObject.AddComponent<BadDogBehaviour>(); State currentState = __instance.currentState; if (currentState - 6 <= 2) { if (badDogBehaviour.CanNotice()) { __instance.UpdateState((State)24); } } else if ((int)__instance.currentState == 25) { badDogBehaviour.PendingLeaveAfterShrink = true; } else if ((int)__instance.currentState == 1 && badDogBehaviour.PendingLeaveAfterShrink) { badDogBehaviour.PendingLeaveAfterShrink = false; __instance.playerTarget = null; __instance.UpdateState((State)16); badDogBehaviour.NoticeCooldown = BadDogMutator.TransformCooldown.Value; } } } internal class SilentStalkersPatch { private const string WesleysEnemiesPluginGuid = "WesleysEnemies"; private static readonly HashSet<Sound> EnemySounds = new HashSet<Sound>(); private static readonly Dictionary<int, HashSet<Sound>> SoundsByParentId = new Dictionary<int, HashSet<Sound>>(); private static readonly Dictionary<Type, FieldInfo[]> SoundFieldsByType = new Dictionary<Type, FieldInfo[]>(); private static readonly Dictionary<string, string[]> WesleyMutedAudioSourceFields = new Dictionary<string, string[]> { ["Shotgunner"] = new string[1] { "ambientAudio" } }; [HarmonyPostfix] [HarmonyPatch(typeof(EnemyParent), "SpawnRPC")] private static void EnemyParentSpawnPostfix(EnemyParent __instance) { RegisterEnemySounds(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyParent), "DespawnRPC")] private static void EnemyParentDespawnPostfix(EnemyParent __instance) { UnregisterEnemySounds(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(Sound), "Play", new Type[] { typeof(Vector3), typeof(float), typeof(float), typeof(float), typeof(float) })] private static bool SoundPlayVector3Prefix(Sound __instance) { return !ShouldMuteSound(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(Sound), "Play", new Type[] { typeof(Transform), typeof(float), typeof(float), typeof(float), typeof(float) })] private static bool SoundPlayTransformPrefix(Sound __instance, Transform followTarget) { return !ShouldMuteSound(__instance, followTarget); } [HarmonyPrefix] [HarmonyPatch(typeof(Sound), "Play", new Type[] { typeof(Transform), typeof(Vector3), typeof(float), typeof(float), typeof(float), typeof(float) })] private static bool SoundPlayTransformContactPrefix(Sound __instance, Transform followTarget) { return !ShouldMuteSound(__instance, followTarget); } [HarmonyPrefix] [HarmonyPatch(typeof(Sound), "PlayLoop")] private static bool SoundPlayLoopPrefix(Sound __instance, bool playing) { if (!playing) { return true; } return !ShouldMuteSound(__instance); } internal static void AfterPatchAll() { ClearRegistry(); EnemyParent[] array = Object.FindObjectsByType<EnemyParent>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (EnemyParent parent in array) { RegisterEnemySounds(parent); } } internal static void AfterUnpatchAll() { ClearRegistry(); } private static bool ShouldMuteSound(Sound sound, Transform? followTarget = null) { if (EnemySounds.Contains(sound)) { return true; } if ((Object)(object)followTarget != (Object)null && IsUnderEnemyHierarchy(followTarget)) { return true; } if ((Object)(object)sound.Source != (Object)null) { return IsUnderEnemyHierarchy(((Component)sound.Source).transform); } return false; } private static bool IsUnderEnemyHierarchy(Transform root) { if (!((Object)(object)((Component)root).GetComponentInParent<EnemyParent>(true) != (Object)null)) { return (Object)(object)((Component)root).GetComponentInParent<Enemy>(true) != (Object)null; } return true; } private static void RegisterEnemySounds(EnemyParent parent) { int instanceID = ((Object)parent).GetInstanceID(); if (SoundsByParentId.ContainsKey(instanceID)) { return; } HashSet<Sound> hashSet = new HashSet<Sound>(); MonoBehaviour[] componentsInChildren = ((Component)parent).GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } FieldInfo[] soundFields = GetSoundFields(((object)val).GetType()); foreach (FieldInfo fieldInfo in soundFields) { object? value = fieldInfo.GetValue(val); Sound val2 = (Sound)((value is Sound) ? value : null); if (val2 != null) { hashSet.Add(val2); } } } SoundsByParentId[instanceID] = hashSet; foreach (Sound item in hashSet) { EnemySounds.Add(item); } if (Chainloader.PluginInfos.ContainsKey("WesleysEnemies")) { MuteWesleyExtraAudio(parent); } } private static void MuteWesleyExtraAudio(EnemyParent parent) { bool flag = false; MonoBehaviour[] componentsInChildren = ((Component)parent).GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val == (Object)null || ((object)val).GetType().Assembly.GetName().Name != "WesleysEnemies") { continue; } if (WesleyMutedAudioSourceFields.TryGetValue(((object)val).GetType().Name, out string[] value)) { string[] array = value; foreach (string fieldName in array) { TryMuteAudioSourceField(val, fieldName); } } if (((object)val).GetType().Name == "Gusher") { flag = true; } } if (flag) { MuteGusherAmbienceAudioSources(parent); } } private static void MuteGusherAmbienceAudioSources(EnemyParent parent) { Transform[] componentsInChildren = ((Component)parent).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if (!(((Object)val).name != "Ambience")) { AudioSource[] components = ((Component)val).GetComponents<AudioSource>(); foreach (AudioSource val2 in components) { val2.mute = true; } } } } private static void TryMuteAudioSourceField(MonoBehaviour mb, string fieldName) { object? obj = ((object)mb).GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(mb); AudioSource val = (AudioSource)((obj is AudioSource) ? obj : null); if (val != null) { val.mute = true; } } private static void UnregisterEnemySounds(EnemyParent parent) { int instanceID = ((Object)parent).GetInstanceID(); if (!SoundsByParentId.Remove(instanceID, out HashSet<Sound> value)) { return; } foreach (Sound item in value) { EnemySounds.Remove(item); } } private static void ClearRegistry() { EnemySounds.Clear(); SoundsByParentId.Clear(); } private static FieldInfo[] GetSoundFields(Type type) { if (SoundFieldsByType.TryGetValue(type, out FieldInfo[] value)) { return value; } List<FieldInfo> list = new List<FieldInfo>(); Type type2 = type; while (type2 != null && type2 != typeof(MonoBehaviour)) { FieldInfo[] fields = type2.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType == typeof(Sound)) { list.Add(fieldInfo); } } type2 = type2.BaseType; } FieldInfo[] array = list.ToArray(); SoundFieldsByType[type] = array; return array; } } internal class WrongWayMapPatch { private static readonly int MainTexStId = Shader.PropertyToID("_MainTex_ST"); private static readonly Vector4 FlippedMainTexSt = new Vector4(-1f, -1f, 1f, 1f); private static readonly MaterialPropertyBlock FlipPropertyBlock = new MaterialPropertyBlock(); private static int _flippedDisplayMeshId; [HarmonyPostfix] [HarmonyPriority(0)] [HarmonyPatch(typeof(MapToolController), "Update")] private static void MapToolControllerUpdatePostfix(MapToolController __instance) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance.PlayerAvatar != (Object)(object)PlayerAvatar.instance) { return; } MeshRenderer displayMesh = __instance.DisplayMesh; if (!((Object)(object)displayMesh == (Object)null)) { int instanceID = ((Object)displayMesh).GetInstanceID(); if (ShouldFlipDisplay(__instance)) { ((Renderer)displayMesh).GetPropertyBlock(FlipPropertyBlock); FlipPropertyBlock.SetVector(MainTexStId, FlippedMainTexSt); ((Renderer)displayMesh).SetPropertyBlock(FlipPropertyBlock); _flippedDisplayMeshId = instanceID; } else if (_flippedDisplayMeshId == instanceID) { ((Renderer)displayMesh).SetPropertyBlock((MaterialPropertyBlock)null); _flippedDisplayMeshId = 0; } } } private static bool ShouldFlipDisplay(MapToolController controller) { if (((Component)controller.VisualTransform).gameObject.activeSelf) { return controller.HideLerp < 1f; } return false; } internal static void AfterUnpatchAll() { _flippedDisplayMeshId = 0; MapToolController[] array = Object.FindObjectsByType<MapToolController>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (MapToolController val in array) { if ((Object)(object)val.DisplayMesh != (Object)null) { ((Renderer)val.DisplayMesh).SetPropertyBlock((MaterialPropertyBlock)null); } } } } } namespace GastrodonGroup.MutatorsAddon.MutatorDefinitions.WrongWayMap { internal static class WrongWayMapMutator { internal const string Name = "MAP-side Down"; internal const string Description = "The minimap screen is rotated 180 degrees"; } } namespace GastrodonGroup.MutatorsAddon.MutatorDefinitions.SilentStalkers { internal static class SilentStalkersMutator { internal const string Name = "Silent Stalkers"; internal const string Description = "You cannot hear the enemy sounds"; } } namespace GastrodonGroup.MutatorsAddon.MutatorDefinitions.BadDog { internal static class BadDogMutator { internal const string Name = "Watchdog Out!"; internal const string Description = "Elsa transforms on sight instead of waiting for pets"; internal static ConfigEntry<float> TransformCooldown { get; private set; } internal static void BindConfig(ConfigFile config) { TransformCooldown = config.Bind<float>("Watchdog Out!", "Transform cooldown", 50f, "Seconds before Elsa can instantly transform again after leaving."); } } } namespace GastrodonGroup.MutatorsAddon.Behaviours { internal class BadDogBehaviour : MonoBehaviour { public float NoticeCooldown { get; internal set; } internal bool PendingLeaveAfterShrink { get; set; } private void Update() { if (!(NoticeCooldown <= 0f) && SemiFunc.IsMasterClientOrSingleplayer()) { NoticeCooldown -= Time.deltaTime; } } internal bool CanNotice() { return NoticeCooldown <= 0f; } } }