using 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 HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.PostProcessing; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RemoveHorror")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Remove Horror mod for REPO")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+218effe8b38cbd66ae4e34550e013e15c90af7d7")] [assembly: AssemblyProduct("RemoveHorror")] [assembly: AssemblyTitle("RemoveHorror")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.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 RemoveHorror { public enum VisionMode { LightFollowsYou, Fullbright } [BepInPlugin("com.dan0dfbe.repo.removehorror", "Remove Horror", "1.0.0")] public class RemoveHorrorPlugin : BaseUnityPlugin { public const string PluginGuid = "com.dan0dfbe.repo.removehorror"; public const string PluginName = "Remove Horror"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; private static Harmony _harmony; internal static ConfigEntry ConfigEnableLogging; internal static ConfigEntry ConfigFarClipPlane; internal static ConfigEntry ConfigToggleHotkey; internal static ConfigEntry ConfigVisionMode; internal static ConfigEntry ConfigLightRange; internal static ConfigEntry ConfigLightIntensity; internal static ConfigEntry ConfigDisableFog; internal static ConfigEntry ConfigDisableVignette; internal static ConfigEntry ConfigStripColorFilters; internal static ConfigEntry ConfigDisableAmbienceBreakers; internal static ConfigEntry ConfigDisableAudioScare; internal static ConfigEntry ConfigDisableMusicEnemySighting; internal static ConfigEntry ConfigDisableMusicEnemyNear; internal static ConfigEntry ConfigDisableMusicEnemyCatch; internal static ConfigEntry ConfigDisableAmbienceLoop; internal static ConfigEntry ConfigDisableLevelMusic; internal static ConfigEntry ConfigEnemyColorOverrideEnable; internal static ConfigEntry ConfigEnemyColorString; private void Awake() { //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"=== Remove Horror: Awake Started ==="); ConfigEnableLogging = ((BaseUnityPlugin)this).Config.Bind("General", "EnableVerboseLogging", false, "If true, logs spammy debug messages every frame."); ConfigFarClipPlane = ((BaseUnityPlugin)this).Config.Bind("General", "FarClipPlane", 1000f, "The default far clip plane distance. (1000f is recommended so the main menu isn't culled)"); ConfigToggleHotkey = ((BaseUnityPlugin)this).Config.Bind("General", "ToggleHotkey", (KeyCode)120, "Hotkey to toggle the fullbright mod on and off."); ConfigVisionMode = ((BaseUnityPlugin)this).Config.Bind("Vision - Settings", "VisionMode", VisionMode.LightFollowsYou, "The lighting mode used when the mod is toggled ON."); ConfigLightRange = ((BaseUnityPlugin)this).Config.Bind("Vision - Settings", "LightRange", 100f, "The range of the attached light."); ConfigLightIntensity = ((BaseUnityPlugin)this).Config.Bind("Vision - Settings", "LightIntensity", 1f, "The intensity of the attached light."); ConfigDisableFog = ((BaseUnityPlugin)this).Config.Bind("Vision - Filters", "DisableFog", true, "If true, completely removes distance fog."); ConfigDisableVignette = ((BaseUnityPlugin)this).Config.Bind("Vision - Filters", "DisableVignette", true, "If true, removes the dark vignette screen effect."); ConfigStripColorFilters = ((BaseUnityPlugin)this).Config.Bind("Vision - Filters", "StripColorFilters", true, "If true, resets the post-processing color grading to pure white (removes dark room tints)."); ConfigEnemyColorOverrideEnable = ((BaseUnityPlugin)this).Config.Bind("Enemies", "EnemyColorOverrideEnable", true, "If true, enemy materials will be replaced with a flat color."); ConfigEnemyColorString = ((BaseUnityPlugin)this).Config.Bind("Enemies", "EnemyColor", "#7F7F7F", "The flat color applied to enemies as a hex code (e.g., #FF0000 for red, #00FF00 for green)."); ConfigDisableAmbienceBreakers = ((BaseUnityPlugin)this).Config.Bind("Audio - Ambience", "DisableAmbienceBreakers", true, "If true, occasional horror sounds will be skipped."); ConfigDisableAudioScare = ((BaseUnityPlugin)this).Config.Bind("Audio - Enemies", "DisableAudioScare", true, "If true, jumpscare sounds will be skipped."); ConfigDisableMusicEnemySighting = ((BaseUnityPlugin)this).Config.Bind("Audio - Enemies", "DisableMusicEnemySighting", true, "If true, sighting stinger sounds will be muted."); ConfigDisableMusicEnemyNear = ((BaseUnityPlugin)this).Config.Bind("Audio - Enemies", "DisableMusicEnemyNear", true, "If true, tension music when enemies are near will be muted."); ConfigDisableMusicEnemyCatch = ((BaseUnityPlugin)this).Config.Bind("Audio - Enemies", "DisableMusicEnemyCatch", true, "If true, enemy catch stingers will be skipped."); ConfigDisableAmbienceLoop = ((BaseUnityPlugin)this).Config.Bind("Audio - Ambience", "DisableAmbienceLoop", true, "If true, the continuous background ambience will be muted."); ConfigDisableLevelMusic = ((BaseUnityPlugin)this).Config.Bind("Audio - Ambience", "DisableLevelMusic", true, "If true, the periodic ambient music tracks will be muted."); try { _harmony = new Harmony("com.dan0dfbe.repo.removehorror"); _harmony.PatchAll(); Log.LogInfo((object)"Remove Horror: Harmony patching successful."); } catch (Exception arg) { Log.LogError((object)$"Remove Horror: Harmony patching FAILED! Error: {arg}"); } try { ((Component)this).gameObject.AddComponent(); Log.LogInfo((object)"Remove Horror: ModLogic component successfully attached."); } catch (Exception arg2) { Log.LogError((object)$"Remove Horror: Failed to attach ModLogic! Error: {arg2}"); } Log.LogInfo((object)"=== Remove Horror v1.0.0 loaded successfully ==="); } } public static class ModState { public static bool IsToggledOn = true; } [HarmonyPatch(typeof(EnvironmentDirector))] public static class EnvironmentDirectorPatches { [HarmonyPatch("FogLogic")] [HarmonyPrefix] public static bool Prefix_FogLogic() { if (!ModState.IsToggledOn) { return true; } return false; } [HarmonyPatch("AmbientLightLogic")] [HarmonyPrefix] public static bool Prefix_AmbientLightLogic() { if (!ModState.IsToggledOn) { return true; } return false; } } [HarmonyPatch] public static class AudioPatches { public static HashSet ActiveSightings = new HashSet(); public static HashSet ActiveNears = new HashSet(); [HarmonyPatch(typeof(AmbienceBreakers), "PlaySoundRPC")] [HarmonyPrefix] public static bool Prefix_AmbienceBreakers_PlaySoundRPC() { if (ModState.IsToggledOn) { return !RemoveHorrorPlugin.ConfigDisableAmbienceBreakers.Value; } return true; } [HarmonyPatch(typeof(AudioScare), "PlayImpact")] [HarmonyPrefix] public static bool Prefix_AudioScare_PlayImpact() { if (ModState.IsToggledOn) { return !RemoveHorrorPlugin.ConfigDisableAudioScare.Value; } return true; } [HarmonyPatch(typeof(AudioScare), "PlaySoft")] [HarmonyPrefix] public static bool Prefix_AudioScare_PlaySoft() { if (ModState.IsToggledOn) { return !RemoveHorrorPlugin.ConfigDisableAudioScare.Value; } return true; } [HarmonyPatch(typeof(AudioScare), "PlayCustom")] [HarmonyPrefix] public static bool Prefix_AudioScare_PlayCustom() { if (ModState.IsToggledOn) { return !RemoveHorrorPlugin.ConfigDisableAudioScare.Value; } return true; } [HarmonyPatch(typeof(MusicEnemyCatch), "Play")] [HarmonyPrefix] public static bool Prefix_MusicEnemyCatch_Play() { if (ModState.IsToggledOn) { return !RemoveHorrorPlugin.ConfigDisableMusicEnemyCatch.Value; } return true; } [HarmonyPatch(typeof(AmbienceLoop), "Update")] [HarmonyPrefix] public static bool Prefix_AmbienceLoop_Update(AmbienceLoop __instance) { if (ModState.IsToggledOn && RemoveHorrorPlugin.ConfigDisableAmbienceLoop.Value) { if ((Object)(object)__instance.source != (Object)null) { __instance.source.volume = 0f; } return false; } return true; } [HarmonyPatch(typeof(LevelMusic), "Update")] [HarmonyPrefix] public static bool Prefix_LevelMusic_Update(LevelMusic __instance) { if (ModState.IsToggledOn && RemoveHorrorPlugin.ConfigDisableLevelMusic.Value) { AudioSource component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null && component.isPlaying) { component.Stop(); } return false; } return true; } [HarmonyPatch(typeof(MusicEnemySighting), "Start")] [HarmonyPostfix] public static void Postfix_MusicEnemySighting_Start(MusicEnemySighting __instance) { ActiveSightings.Add(__instance); } [HarmonyPatch(typeof(MusicEnemyNear), "Start")] [HarmonyPostfix] public static void Postfix_MusicEnemyNear_Start(MusicEnemyNear __instance) { ActiveNears.Add(__instance); } } [HarmonyPatch(typeof(EnemyParent))] public static class EnemyPatches { public static Dictionary OriginalEnemyMaterials = new Dictionary(); public static Material SharedEnemyMaterial; public static bool EnemiesScrubbed = false; [HarmonyPatch("Awake")] [HarmonyPostfix] public static void Postfix_Awake(EnemyParent __instance) { if (ModState.IsToggledOn && RemoveHorrorPlugin.ConfigEnemyColorOverrideEnable.Value) { ScrubEnemy(__instance); } } public static void EnsureMaterial() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00b5: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) Color val = Color.red; string value = RemoveHorrorPlugin.ConfigEnemyColorString.Value; if (!string.IsNullOrEmpty(value)) { value = value.Trim(); if (!value.StartsWith("#") && (value.Length == 6 || value.Length == 8)) { value = "#" + value; } Color val2 = default(Color); if (ColorUtility.TryParseHtmlString(value, ref val2)) { val = val2; } else { RemoveHorrorPlugin.Log.LogWarning((object)("[RemoveHorror] Failed to parse color hex code: " + value + ". Falling back to Red.")); } } if ((Object)(object)SharedEnemyMaterial == (Object)null) { Shader val3 = Shader.Find("Standard"); if ((Object)(object)val3 == (Object)null) { RemoveHorrorPlugin.Log.LogError((object)"[RemoveHorror] CRITICAL: Standard shader not found!"); } SharedEnemyMaterial = new Material(val3) { color = val }; } else if (SharedEnemyMaterial.color != val) { SharedEnemyMaterial.color = val; } } public static void ScrubEnemy(EnemyParent enemyParent) { if ((Object)(object)enemyParent == (Object)null) { return; } EnsureMaterial(); Renderer[] componentsInChildren = ((Component)enemyParent).GetComponentsInChildren(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if ((Object)(object)val != (Object)null && (val is MeshRenderer || val is SkinnedMeshRenderer) && !OriginalEnemyMaterials.ContainsKey(val)) { OriginalEnemyMaterials[val] = val.sharedMaterials; Material[] array2 = (Material[])(object)new Material[val.sharedMaterials.Length]; for (int j = 0; j < array2.Length; j++) { array2[j] = SharedEnemyMaterial; } val.sharedMaterials = array2; EnemiesScrubbed = true; } } if (RemoveHorrorPlugin.ConfigEnableLogging.Value) { RemoveHorrorPlugin.Log.LogInfo((object)("[RemoveHorror] Scrubbed materials for spawned enemy: " + ((Object)enemyParent).name)); } } public static void ScrubAllEnemies() { if (!RemoveHorrorPlugin.ConfigEnemyColorOverrideEnable.Value || (Object)(object)EnemyDirector.instance == (Object)null || EnemyDirector.instance.enemiesSpawned == null) { return; } foreach (EnemyParent item in EnemyDirector.instance.enemiesSpawned) { ScrubEnemy(item); } } public static void RestoreEnemies() { if (!EnemiesScrubbed) { return; } foreach (KeyValuePair originalEnemyMaterial in OriginalEnemyMaterials) { Renderer key = originalEnemyMaterial.Key; if (key != null) { key.sharedMaterials = originalEnemyMaterial.Value; } } OriginalEnemyMaterials.Clear(); EnemiesScrubbed = false; RemoveHorrorPlugin.Log.LogInfo((object)"[RemoveHorror] Enemy Materials Restored to Original State."); } } public class ModLogic : MonoBehaviour { private int _frameCount; private GameObject _lightFollowsYouObj; private Light _lightFollowsYouLight; private Dictionary _originalVignettes = new Dictionary(); private Dictionary _originalColorFilters = new Dictionary(); private bool _volumesScrubbed; private Level _cachedLevel; private bool _wasActive; private void OnEnable() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(CamPreCull)); if (RemoveHorrorPlugin.ConfigEnableLogging.Value) { RemoveHorrorPlugin.Log.LogInfo((object)"ModLogic OnEnable: Hooked Camera.onPreCull"); } } private void OnDisable() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(CamPreCull)); if (RemoveHorrorPlugin.ConfigEnableLogging.Value) { RemoveHorrorPlugin.Log.LogInfo((object)"ModLogic OnDisable: Unhooked Camera.onPreCull"); } } private void CamPreCull(Camera cam) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)cam == (Object)null) && ModState.IsToggledOn) { if (RemoveHorrorPlugin.ConfigVisionMode.Value == VisionMode.Fullbright) { RenderSettings.ambientMode = (AmbientMode)3; RenderSettings.ambientLight = Color.white; } else if (RemoveHorrorPlugin.ConfigVisionMode.Value == VisionMode.LightFollowsYou) { RenderSettings.ambientMode = (AmbientMode)3; RenderSettings.ambientLight = new Color(0.15f, 0.15f, 0.15f); } if (RemoveHorrorPlugin.ConfigDisableFog.Value) { RenderSettings.fog = false; RenderSettings.fogEndDistance = 500f; } if ((Object)(object)cam == (Object)(object)Camera.main) { cam.farClipPlane = RemoveHorrorPlugin.ConfigFarClipPlane.Value; } } } private static bool IsNull(Component s) { if (!((Object)(object)s == (Object)null)) { return (Object)(object)s.gameObject == (Object)null; } return true; } private void Update() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown //IL_0164: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(RemoveHorrorPlugin.ConfigToggleHotkey.Value)) { ModState.IsToggledOn = !ModState.IsToggledOn; RemoveHorrorPlugin.Log.LogInfo((object)("[RemoveHorror] Mod Toggled: " + (ModState.IsToggledOn ? "ON" : "OFF"))); } bool isToggledOn = ModState.IsToggledOn; if (isToggledOn && !_wasActive) { EnemyPatches.ScrubAllEnemies(); ScrubVolumes(); } if (!isToggledOn) { RestoreState(); if ((Object)(object)_lightFollowsYouObj != (Object)null && _lightFollowsYouObj.activeSelf) { _lightFollowsYouObj.SetActive(false); } _wasActive = isToggledOn; return; } if ((Object)(object)RunManager.instance != (Object)null && (Object)(object)_cachedLevel != (Object)(object)RunManager.instance.levelCurrent) { _cachedLevel = RunManager.instance.levelCurrent; ScrubVolumes(); } if (RemoveHorrorPlugin.ConfigVisionMode.Value == VisionMode.LightFollowsYou) { if ((Object)(object)_lightFollowsYouObj == (Object)null) { _lightFollowsYouObj = new GameObject("RemoveHorror_LightFollowsYou"); _lightFollowsYouLight = _lightFollowsYouObj.AddComponent(); _lightFollowsYouLight.type = (LightType)2; _lightFollowsYouLight.shadows = (LightShadows)0; } if (!_lightFollowsYouObj.activeSelf) { _lightFollowsYouObj.SetActive(true); } if ((Object)(object)Camera.main != (Object)null) { _lightFollowsYouObj.transform.position = ((Component)Camera.main).transform.position; } _lightFollowsYouLight.range = RemoveHorrorPlugin.ConfigLightRange.Value; _lightFollowsYouLight.intensity = RemoveHorrorPlugin.ConfigLightIntensity.Value; } else if ((Object)(object)_lightFollowsYouObj != (Object)null && _lightFollowsYouObj.activeSelf) { _lightFollowsYouObj.SetActive(false); } _frameCount++; if (_frameCount % 60 == 0) { bool mute = isToggledOn && RemoveHorrorPlugin.ConfigDisableMusicEnemySighting.Value; AudioPatches.ActiveSightings.RemoveWhere(IsNull); foreach (MusicEnemySighting activeSighting in AudioPatches.ActiveSightings) { AudioSource source = activeSighting.Source; if (source != null) { source.mute = mute; } } bool mute2 = isToggledOn && RemoveHorrorPlugin.ConfigDisableMusicEnemyNear.Value; AudioPatches.ActiveNears.RemoveWhere(IsNull); foreach (MusicEnemyNear activeNear in AudioPatches.ActiveNears) { AudioSource source2 = activeNear.Source; if (source2 != null) { source2.mute = mute2; } } } _wasActive = isToggledOn; } private void ScrubVolumes() { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) PostProcessVolume[] array = Object.FindObjectsOfType(); PostProcessVolume[] array2 = array; Vignette val2 = default(Vignette); ColorGrading val3 = default(ColorGrading); foreach (PostProcessVolume val in array2) { if (!((Object)(object)val.profile != (Object)null)) { continue; } if (val.profile.TryGetSettings(ref val2)) { if (!_originalVignettes.ContainsKey(val)) { _originalVignettes[val] = ((PostProcessEffectSettings)val2).active; } if (((PostProcessEffectSettings)val2).active && RemoveHorrorPlugin.ConfigDisableVignette.Value) { ((PostProcessEffectSettings)val2).active = false; } } if (val.profile.TryGetSettings(ref val3)) { if (!_originalColorFilters.ContainsKey(val)) { _originalColorFilters[val] = ((ParameterOverride)(object)val3.colorFilter).value; } if (((ParameterOverride)(object)val3.colorFilter).value != Color.white && RemoveHorrorPlugin.ConfigStripColorFilters.Value) { ((ParameterOverride)(object)val3.colorFilter).value = Color.white; } } } _volumesScrubbed = true; if (RemoveHorrorPlugin.ConfigEnableLogging.Value) { RemoveHorrorPlugin.Log.LogInfo((object)$"[RemoveHorror] Cached and scrubbed {array.Length} PostProcessVolumes for level transition."); } } private void RestoreState() { //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) foreach (MusicEnemySighting activeSighting in AudioPatches.ActiveSightings) { if ((Object)(object)activeSighting != (Object)null && (Object)(object)activeSighting.Source != (Object)null) { activeSighting.Source.mute = false; } } foreach (MusicEnemyNear activeNear in AudioPatches.ActiveNears) { if ((Object)(object)activeNear != (Object)null && (Object)(object)activeNear.Source != (Object)null) { activeNear.Source.mute = false; } } if (_volumesScrubbed) { Vignette val = default(Vignette); foreach (KeyValuePair originalVignette in _originalVignettes) { if ((Object)(object)originalVignette.Key != (Object)null && (Object)(object)originalVignette.Key.profile != (Object)null && originalVignette.Key.profile.TryGetSettings(ref val)) { ((PostProcessEffectSettings)val).active = originalVignette.Value; } } ColorGrading val2 = default(ColorGrading); foreach (KeyValuePair originalColorFilter in _originalColorFilters) { if ((Object)(object)originalColorFilter.Key != (Object)null && (Object)(object)originalColorFilter.Key.profile != (Object)null && originalColorFilter.Key.profile.TryGetSettings(ref val2)) { ((ParameterOverride)(object)val2.colorFilter).value = originalColorFilter.Value; } } _originalVignettes.Clear(); _originalColorFilters.Clear(); _volumesScrubbed = false; RemoveHorrorPlugin.Log.LogInfo((object)"[RemoveHorror] PostProcessVolumes Restored to Original State."); } EnemyPatches.RestoreEnemies(); } } }