using 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>)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>)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>)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 enemyList = __instance.enemyList; if (enemyList.Any((EnemySetup setup) => setup.spawnObjects.Select((PrefabRef so) => ((PrefabRef)(object)so).Prefab.GetComponent()).Any((EnemyParent ep) => (Object)(object)ep != (Object)null && ep.enemyName == "Elsa"))) { return; } EnemySetup val = ((IEnumerable)Enemies.AllEnemies).FirstOrDefault((Func)((EnemySetup setup) => ((Object)setup).name == "Enemy - Elsa")); if (!Object.op_Implicit((Object)(object)val)) { return; } IList list = enemyList.Where(delegate(EnemySetup setup) { IEnumerable source = from so in setup.spawnObjects select ((PrefabRef)(object)so).Prefab.GetComponent() 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() ?? ((Component)__instance).gameObject.AddComponent(); 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 EnemySounds = new HashSet(); private static readonly Dictionary> SoundsByParentId = new Dictionary>(); private static readonly Dictionary SoundFieldsByType = new Dictionary(); private static readonly Dictionary WesleyMutedAudioSourceFields = new Dictionary { ["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((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(true) != (Object)null)) { return (Object)(object)((Component)root).GetComponentInParent(true) != (Object)null; } return true; } private static void RegisterEnemySounds(EnemyParent parent) { int instanceID = ((Object)parent).GetInstanceID(); if (SoundsByParentId.ContainsKey(instanceID)) { return; } HashSet hashSet = new HashSet(); MonoBehaviour[] componentsInChildren = ((Component)parent).GetComponentsInChildren(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(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(true); foreach (Transform val in componentsInChildren) { if (!(((Object)val).name != "Ambience")) { AudioSource[] components = ((Component)val).GetComponents(); 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 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 list = new List(); 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((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 TransformCooldown { get; private set; } internal static void BindConfig(ConfigFile config) { TransformCooldown = config.Bind("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; } } }