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 SchizophreniaMod v1.1.0
BepInEx/plugins/SchizophreniaMod.dll
Decompiled 3 hours agousing System; using System.Collections; 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.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.Audio; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SchizophreniaMod")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SchizophreniaMod")] [assembly: AssemblyTitle("SchizophreniaMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 SchizophreniaMod { [BepInPlugin("com.tibby.schizophrenia", "Schizophrenia Mod", "1.1.0")] public class SchizophreniaBase : BaseUnityPlugin { public static ManualLogSource mls; private void Awake() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) mls = Logger.CreateLogSource("SchizoDebug"); new Harmony("com.tibby.schizophrenia").PatchAll(); mls.LogWarning((object)"=== SCHIZOPHRENIA MOD v1.1.0 LOADED ==="); mls.LogInfo((object)"Audio hallucination system initialized."); } } public static class AudioClipDatabase { public static readonly HashSet<string> Blacklist = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "SnareFleaTipChannel", "SlimeIdle", "NutcrackerVentCrawl", "GhostlySynth2", "CrawlerDie", "SpiderDie", "NutcrackerDie", "StingrayDie", "BushWolfDie", "KillCaveDweller", "BugDie", "SporeDamage", "SporeDamageB", "SporeDamageC", "SporeDamageD", "PlantSpores", "HangPlayerOnCeiling", "ClingToPlayerLocal", "LradBrainwashingSignal1", "LradBrainwashingSignal4", "LradBrainwashingSignal6", "LradBrainwashingSignal7", "LradBrainwashingSignal8", "KillPlayerSpring", "MaskComedyAttach", "JackInTheBoxTheme" }; public static readonly Dictionary<string, string[]> EnemyClipPatterns = new Dictionary<string, string[]> { { "Centipede", new string[3] { "centipedewalk", "clingto", "snarebuildup" } }, { "Bunker Spider", new string[8] { "spiderattack", "spiderhit", "stunspider", "hitweb", "breakweb", "spoolinplayerweb", "clickingmandibles", "stuckweb" } }, { "HoarderBug", new string[4] { "hoarderbugcry", "chitter", "bugwalk", "takeitems" } }, { "Flowerman", new string[3] { "flowerman", "bracken", "crackneck" } }, { "Crawler", new string[6] { "hitcrawler", "stuncrawler", "chargeforward", "startchargeforward", "longroar", "shortroar" } }, { "Puffer", new string[4] { "puffsfx", "frighten", "rattletail", "hiss" } }, { "Jester", new string[5] { "jesterstomp", "pop1", "chatteringteeth", "icecreamtruck", "turncrank" } }, { "DressGirl", new string[6] { "monsternoise", "phonescream", "breathe1", "ghostlysynth", "wallrumblevoice", "voicecry" } }, { "Spring", new string[4] { "spring1", "spring2", "spring3", "springwobble" } }, { "Nutcracker", new string[6] { "nutcrackerangry", "nutcrackerhiteye", "nutcrackerturn", "headgoup", "hitmetal", "shotgunreloadnutcracker" } }, { "Butler", new string[7] { "butlerstab", "butlerblowup", "butlersuitrustle", "butlerbeeswarm", "butlerstep", "butleruntuckknife", "butlermurdertheme" } }, { "Masked", new string[5] { "maskattackplayer", "maskfacelightup", "maskpuke", "maskcry", "masklaugh" } }, { "Hygrodere", new string[5] { "walkslime", "hitslime", "slimekillplayer", "slimeangry", "slimedance" } }, { "Barber", new string[2] { "scissorssnip", "scissors" } }, { "Maneater", new string[7] { "babycry", "babypuke", "babysquirm", "babyfootstep", "cavedweller", "chewmeat", "biteplay" } } }; public static readonly Dictionary<string, string[]> MoonIndoorEnemies = new Dictionary<string, string[]> { { "experimentation", new string[9] { "Bunker Spider", "Centipede", "Hygrodere", "HoarderBug", "Puffer", "Crawler", "Flowerman", "DressGirl", "Nutcracker" } }, { "assurance", new string[11] { "Centipede", "HoarderBug", "Bunker Spider", "Hygrodere", "Crawler", "Maneater", "Flowerman", "Puffer", "Barber", "DressGirl", "Nutcracker" } }, { "vow", new string[10] { "Flowerman", "HoarderBug", "Maneater", "Centipede", "Bunker Spider", "Hygrodere", "Puffer", "Barber", "Crawler", "Spring" } }, { "offense", new string[10] { "Crawler", "Bunker Spider", "Hygrodere", "Centipede", "Spring", "HoarderBug", "Puffer", "Maneater", "Flowerman", "Nutcracker" } }, { "march", new string[11] { "Crawler", "Bunker Spider", "Flowerman", "Centipede", "HoarderBug", "Hygrodere", "Spring", "Puffer", "Maneater", "Nutcracker", "Jester" } }, { "adamance", new string[13] { "Bunker Spider", "Centipede", "HoarderBug", "Hygrodere", "Flowerman", "Puffer", "Crawler", "Spring", "Maneater", "Nutcracker", "Masked", "DressGirl", "Jester" } }, { "rend", new string[12] { "Nutcracker", "Jester", "Flowerman", "Bunker Spider", "Spring", "Centipede", "Masked", "DressGirl", "Butler", "Barber", "Puffer", "Hygrodere" } }, { "dine", new string[13] { "Butler", "Barber", "Flowerman", "Centipede", "Hygrodere", "HoarderBug", "Jester", "Nutcracker", "Spring", "DressGirl", "Crawler", "Puffer", "Maneater" } }, { "titan", new string[12] { "Jester", "Nutcracker", "Flowerman", "Bunker Spider", "Spring", "Crawler", "Centipede", "HoarderBug", "Masked", "Hygrodere", "DressGirl", "Puffer" } }, { "artifice", new string[15] { "Bunker Spider", "Flowerman", "Nutcracker", "HoarderBug", "Crawler", "Jester", "Butler", "Puffer", "Masked", "Spring", "Centipede", "Hygrodere", "Barber", "DressGirl", "Maneater" } }, { "embrion", new string[10] { "HoarderBug", "Hygrodere", "Barber", "Puffer", "Crawler", "Spring", "Bunker Spider", "Nutcracker", "Centipede", "Flowerman" } } }; public static string[] GetIndoorEnemiesForMoon(string planetName) { string text = planetName.ToLower(); foreach (KeyValuePair<string, string[]> moonIndoorEnemy in MoonIndoorEnemies) { if (text.Contains(moonIndoorEnemy.Key)) { return moonIndoorEnemy.Value; } } return EnemyClipPatterns.Keys.ToArray(); } } public class GhostAudioMover : MonoBehaviour { [CompilerGenerated] private sealed class <MoveRoutine>d__1 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public AudioSource src; public Vector3 dir; public float speed; public float dur; public GhostAudioMover <>4__this; private float <elapsed>5__1; private float <startVol>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <MoveRoutine>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0066: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <elapsed>5__1 = 0f; <startVol>5__2 = (((Object)(object)src != (Object)null) ? src.volume : 0f); break; case 1: <>1__state = -1; break; } if (<elapsed>5__1 < dur && (Object)(object)src != (Object)null) { Transform transform = ((Component)<>4__this).transform; transform.position += dir * speed * Time.deltaTime; if (<elapsed>5__1 > dur * 0.8f) { src.volume = Mathf.Lerp(<startVol>5__2, 0f, (<elapsed>5__1 - dur * 0.8f) / (dur * 0.2f)); } <elapsed>5__1 += Time.deltaTime; <>2__current = null; <>1__state = 1; return true; } Object.Destroy((Object)(object)((Component)<>4__this).gameObject); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public void Initialize(AudioSource src, Vector3 dir, float speed, float dur) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) ((MonoBehaviour)this).StartCoroutine(MoveRoutine(src, dir, speed, dur)); } [IteratorStateMachine(typeof(<MoveRoutine>d__1))] private IEnumerator MoveRoutine(AudioSource src, Vector3 dir, float speed, float dur) { //IL_0015: 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) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <MoveRoutine>d__1(0) { <>4__this = this, src = src, dir = dir, speed = speed, dur = dur }; } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] public class PlayerSchizoPatch { private static float timer = 0f; private static bool isSystemActive = false; private static float activationCountdown = 120f; private static bool countdownExpired = false; private static float countdownLogTimer = 0f; private static readonly Dictionary<ulong, float> PlayerCooldowns = new Dictionary<ulong, float>(); private const float COOLDOWN_DURATION = 18f; private static List<(AudioClip clip, string enemyName)> _cachedClips = null; private static string _lastPlanetName = ""; private static Dictionary<string, Dictionary<string, int>> PlayerHallucinationStats = new Dictionary<string, Dictionary<string, int>>(); [HarmonyPostfix] private static void Postfix(PlayerControllerB __instance) { if (!((NetworkBehaviour)__instance).IsOwner || !__instance.isPlayerControlled) { return; } ulong playerClientId = __instance.playerClientId; if (PlayerCooldowns.TryGetValue(playerClientId, out var value) && value > 0f) { PlayerCooldowns[playerClientId] = Mathf.Max(0f, value - Time.deltaTime); } if ((Object)(object)StartOfRound.Instance == (Object)null || !StartOfRound.Instance.shipHasLanded) { if (isSystemActive) { ResetSystem(); } return; } SelectableLevel currentLevel = StartOfRound.Instance.currentLevel; if (currentLevel.levelID == 3 || currentLevel.PlanetName.ToLower().Contains("gordion")) { if (isSystemActive) { ResetSystem(); } return; } if (!isSystemActive) { if (StartOfRound.Instance.allPlayerScripts.Any((PlayerControllerB p) => p.isPlayerControlled && p.isInsideFactory)) { isSystemActive = true; SchizophreniaBase.mls.LogWarning((object)"!!! [SYSTEM ACTIVE] A player entered the facility !!!"); return; } if (!countdownExpired) { activationCountdown -= Time.deltaTime; countdownLogTimer -= Time.deltaTime; if (countdownLogTimer <= 0f) { countdownLogTimer = 10f; } if (activationCountdown <= 0f) { activationCountdown = 0f; countdownExpired = true; isSystemActive = true; SchizophreniaBase.mls.LogWarning((object)"!!! [SYSTEM ACTIVE] 120s countdown expired !!!"); } } if (!isSystemActive) { return; } } if (__instance.isInsideFactory && !__instance.isInHangarShipRoom) { timer += Time.deltaTime; if (timer >= 1f) { timer = 0f; ProcessLogic(__instance); } } } private static void ResetSystem() { PrintRoundSummary(); isSystemActive = false; activationCountdown = 120f; countdownExpired = false; countdownLogTimer = 0f; PlayerCooldowns.Clear(); PlayerHallucinationStats.Clear(); _cachedClips = null; _lastPlanetName = ""; } private static void ProcessLogic(PlayerControllerB player) { ulong playerClientId = player.playerClientId; if (!PlayerCooldowns.TryGetValue(playerClientId, out var value) || !(value > 0f)) { float num = Mathf.Clamp(player.insanityLevel / 50f, 0f, 1f); float num2 = 0.0015f + num * 0.0015f; float num3 = CalculateWeight(player); float num4 = num2 * num3; float value2 = Random.value; if (value2 < num4) { PlaySchizoAudio(player); } } } private static float CalculateWeight(PlayerControllerB player) { return StartOfRound.Instance.allPlayerScripts.Count((PlayerControllerB p) => (Object)(object)p != (Object)(object)player && !p.isPlayerDead && p.isPlayerControlled && p.isInsideFactory && Vector3.Distance(((Component)player).transform.position, ((Component)p).transform.position) < 15f) switch { 0 => 2f, 1 => 1f, _ => 0.5f, }; } private static void PlaySchizoAudio(PlayerControllerB player) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) SelectableLevel val = StartOfRound.Instance?.currentLevel; if ((Object)(object)val == (Object)null) { return; } string planetName = val.PlanetName; if (_cachedClips == null || _lastPlanetName != planetName) { _lastPlanetName = planetName; _cachedClips = BuildClipCache(planetName, val); } if (_cachedClips.Count != 0) { (AudioClip, string) tuple = _cachedClips[Random.Range(0, _cachedClips.Count)]; AudioClip item = tuple.Item1; string item2 = tuple.Item2; float num = Random.Range(15f, 25f); Vector3 position = ((Component)player).transform.position; Vector3 val2 = Random.insideUnitSphere; Vector3 val3 = position + ((Vector3)(ref val2)).normalized * num; NavMeshHit val4 = default(NavMeshHit); Vector3 val5 = (NavMesh.SamplePosition(val3, ref val4, 10f, -1) ? ((NavMeshHit)(ref val4)).position : val3); GameObject val6 = new GameObject("SchizoGhost"); val6.transform.position = val5; AudioSource val7 = val6.AddComponent<AudioSource>(); val7.spatialize = false; val7.spatialBlend = 1f; val7.rolloffMode = (AudioRolloffMode)1; val7.minDistance = 10f; val7.maxDistance = 40f; val7.volume = 0.8f; val7.clip = item; AudioMixerGroup val8 = ((IEnumerable<AudioMixerGroup>)Resources.FindObjectsOfTypeAll<AudioMixerGroup>()).FirstOrDefault((Func<AudioMixerGroup, bool>)((AudioMixerGroup g) => ((Object)g).name == "Master")); if ((Object)(object)val8 != (Object)null) { val7.outputAudioMixerGroup = val8; } val2 = val5 - ((Component)player).transform.position; Vector3 normalized = ((Vector3)(ref val2)).normalized; val6.AddComponent<GhostAudioMover>().Initialize(val7, normalized, 3f, item.length); if (!PlayerHallucinationStats.ContainsKey(player.playerUsername)) { PlayerHallucinationStats[player.playerUsername] = new Dictionary<string, int>(); } if (!PlayerHallucinationStats[player.playerUsername].ContainsKey(item2)) { PlayerHallucinationStats[player.playerUsername][item2] = 0; } PlayerHallucinationStats[player.playerUsername][item2]++; val7.Play(); PlayerCooldowns[player.playerClientId] = 18f; } } private static List<(AudioClip, string)> BuildClipCache(string planetName, SelectableLevel level) { List<(AudioClip, string)> list = new List<(AudioClip, string)>(); string[] indoorEnemiesForMoon = AudioClipDatabase.GetIndoorEnemiesForMoon(planetName); AudioClip[] array = Resources.FindObjectsOfTypeAll<AudioClip>(); HashSet<string> hashSet = new HashSet<string>(); AudioClip[] array2 = array; foreach (AudioClip val in array2) { if ((Object)(object)val == (Object)null || val.length < 0.1f || AudioClipDatabase.Blacklist.Contains(((Object)val).name)) { continue; } string clipLower = ((Object)val).name.ToLower(); foreach (KeyValuePair<string, string[]> enemyClipPattern in AudioClipDatabase.EnemyClipPatterns) { string key = enemyClipPattern.Key; if (!indoorEnemiesForMoon.Contains(key) || !enemyClipPattern.Value.Any((string pattern) => clipLower.Contains(pattern))) { continue; } string item = key + "_" + ((Object)val).name; if (hashSet.Add(item)) { list.Add((val, key)); } break; } } if ((Object)(object)level != (Object)null) { HashSet<string> hashSet2 = new HashSet<string>(list.Select(((AudioClip, string) r) => r.Item2)); string[] array3 = indoorEnemiesForMoon; foreach (string enemyKey in array3) { if (hashSet2.Contains(enemyKey)) { continue; } EnemyType val2 = level.Enemies.Select((SpawnableEnemyWithRarity e) => e.enemyType).FirstOrDefault((Func<EnemyType, bool>)((EnemyType e) => (Object)(object)e != (Object)null && e.enemyName != null && AudioClipDatabase.EnemyClipPatterns.ContainsKey(enemyKey) && (e.enemyName.Contains(enemyKey) || enemyKey.Contains(e.enemyName) || NameMatchesKey(e.enemyName, enemyKey)))); if ((Object)(object)val2 == (Object)null || val2.audioClips == null || val2.audioClips.Length == 0) { continue; } int num = 0; AudioClip[] audioClips = val2.audioClips; foreach (AudioClip val3 in audioClips) { if (!((Object)(object)val3 == (Object)null) && !(val3.length < 0.1f) && !AudioClipDatabase.Blacklist.Contains(((Object)val3).name)) { string item2 = enemyKey + "_" + ((Object)val3).name; if (hashSet.Add(item2)) { list.Add((val3, enemyKey)); num++; } } } } } return list; } private static bool NameMatchesKey(string enemyName, string enemyKey) { if (enemyName == null || enemyKey == null) { return false; } string text = enemyName.ToLower().Replace(" ", "").Replace("-", ""); string text2 = enemyKey.ToLower().Replace(" ", "").Replace("-", ""); if (text == text2) { return true; } return text2 switch { "hoarderbug" => text.Contains("hoarding") || text.Contains("hoarder"), "centipede" => text.Contains("centipede") || text.Contains("snare"), "flowerman" => text.Contains("flowerman") || text.Contains("bracken"), "crawler" => text.Contains("crawler") || text.Contains("thumper"), "puffer" => text.Contains("puffer") || text.Contains("spore"), "dressgirl" => text.Contains("dressgirl") || text.Contains("girl"), "spring" => text.Contains("spring") || text.Contains("coil"), "hygrodere" => text.Contains("hygrodere") || text.Contains("blob") || text.Contains("slime"), "maneater" => text.Contains("maneater") || text.Contains("cavedweller") || text.Contains("cave"), "bunker spider" => text.Contains("spider") || text.Contains("bunker"), _ => text.Contains(text2) || text2.Contains(text), }; } private static void PrintRoundSummary() { if (PlayerHallucinationStats.Count == 0) { return; } SchizophreniaBase.mls.LogWarning((object)"========================================"); SchizophreniaBase.mls.LogWarning((object)" HALLUCINATION SUMMARY"); SchizophreniaBase.mls.LogWarning((object)"========================================"); foreach (KeyValuePair<string, Dictionary<string, int>> item in PlayerHallucinationStats.OrderBy((KeyValuePair<string, Dictionary<string, int>> x) => x.Key)) { IOrderedEnumerable<KeyValuePair<string, int>> source = item.Value.OrderByDescending((KeyValuePair<string, int> x) => x.Value); int num = source.Sum((KeyValuePair<string, int> x) => x.Value); string text = string.Join(", ", source.Select((KeyValuePair<string, int> x) => $"{x.Value}x {x.Key}")); SchizophreniaBase.mls.LogWarning((object)(" " + item.Key + ": " + text)); SchizophreniaBase.mls.LogWarning((object)$" Total: {num} hallucination(s)"); } SchizophreniaBase.mls.LogWarning((object)"========================================"); } } }