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 Slaughterhouse v1.2.1
plugins/Slaughterhouse/Nikki.Slaughterhouse.dll
Decompiled 3 days 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 DunGen; using DunGen.Tags; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.SceneManagement; [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("Nikki.Slaughterhouse")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.2.0.0")] [assembly: AssemblyInformationalVersion("1.2.0")] [assembly: AssemblyProduct("Slaughterhouse Scripts")] [assembly: AssemblyTitle("Nikki.Slaughterhouse")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.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.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] [Microsoft.CodeAnalysis.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] [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 SlaughterhouseDunGenExtras { [BepInPlugin("Nikki.Slaughterhouse", "Slaughterhouse Scripts", "1.2.0")] public class SlaughterhouseDunGenExtras : BaseUnityPlugin { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static DungeonGenerationDelegate <>9__17_0; internal void <Awake>b__17_0(DungeonGenerator _) { if (!DoorwayPairFinder.CustomConnectionRules.Contains(ventEntryRule)) { Logger.LogInfo((object)"Adding new rules to Slaughterhouse dungeon generation."); DoorwayPairFinder.CustomConnectionRules.Add(ventEntryRule); } } } public const int slaughterhouseRoomTagID = 43344; public const int ventEntryTagID = 48732; private static readonly Tag slaughterhouseRoomTag = new Tag(43344); private static readonly Tag ventEntryTag = new Tag(48732); private static readonly TileConnectionRule ventEntryRule = new TileConnectionRule(new TileConnectionDelegate(CanTilesConnect), 99); public static SlaughterhouseDunGenExtras Instance { get; private set; } = null; internal static ManualLogSource Logger { get; private set; } = null; internal static Harmony? Harmony { get; set; } private void Awake() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; Instance = this; Patch(); object obj = <>c.<>9__17_0; if (obj == null) { DungeonGenerationDelegate val = delegate { if (!DoorwayPairFinder.CustomConnectionRules.Contains(ventEntryRule)) { Logger.LogInfo((object)"Adding new rules to Slaughterhouse dungeon generation."); DoorwayPairFinder.CustomConnectionRules.Add(ventEntryRule); } }; <>c.<>9__17_0 = val; obj = (object)val; } DungeonGenerator.OnAnyDungeonGenerationStarted += (DungeonGenerationDelegate)obj; Logger.LogInfo((object)"Nikki.Slaughterhouse v1.2.0 has loaded!"); } private static ConnectionResult CanTilesConnect(ProposedConnection proposedConnection) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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) //IL_0081: Unknown result type (might be due to invalid IL or missing references) bool flag = ((ProposedConnection)(ref proposedConnection)).PreviousTile.PrefabTile.Tags.HasTag(slaughterhouseRoomTag); bool flag2 = ((ProposedConnection)(ref proposedConnection)).NextTile.PrefabTile.Tags.HasTag(slaughterhouseRoomTag); if (flag && flag2) { if (((ProposedConnection)(ref proposedConnection)).PreviousDoorway.DoorwayComponent.Tags.HasTag(ventEntryTag) && ((ProposedConnection)(ref proposedConnection)).NextDoorway.DoorwayComponent.Tags.HasTag(ventEntryTag)) { return (ConnectionResult)1; } return (ConnectionResult)2; } return (ConnectionResult)2; } internal static void Patch() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if (Harmony == null) { Harmony = new Harmony("Nikki.Slaughterhouse"); } Logger.LogDebug((object)"Patching..."); Harmony.PatchAll(); Logger.LogDebug((object)"Finished patching!"); } internal static void Unpatch() { Logger.LogDebug((object)"Unpatching..."); Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } Logger.LogDebug((object)"Finished unpatching!"); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "Nikki.Slaughterhouse"; public const string PLUGIN_NAME = "Slaughterhouse Scripts"; public const string PLUGIN_VERSION = "1.2.0"; } } namespace SlaughterhouseDunGenExtras.Zaggy { public class LightController : MonoBehaviour { private class LightSwitcherGroup { internal List<LightSwitcher> lights = new List<LightSwitcher>(); internal bool wasOn = false; internal float timeOffset = 0f; internal float flickerSpeed = 1f; internal bool playedFlickerSound = false; } private enum State { Idle, TurningOff, TurningOn, Flickering } internal static LightController instance; public AnimationCurve flickeringLightEnabledAnimation; public int groupCount; public float flickerTime = 0.37f; private Random random; private LightSwitcherGroup[] lightSwitcherGroups; private State state = State.TurningOn; private float animationTime = 0f; private void Awake() { instance = this; } private void Start() { PopulateLightGroupsAfterDungeonGeneration(); } private DungeonGenerator FindDungeonGenerator(out GameObject root) { Dungeon dungeon = ((Component)this).GetComponentInParent<Tile>().Dungeon; root = ((Component)dungeon).gameObject; RuntimeDungeon[] array = Object.FindObjectsByType<RuntimeDungeon>((FindObjectsInactive)1, (FindObjectsSortMode)0); RuntimeDungeon[] array2 = array; foreach (RuntimeDungeon val in array2) { if (val.Generator != null && (Object)(object)val.Generator.CurrentDungeon == (Object)(object)dungeon) { root = val.Root; return val.Generator; } } return null; } private void PopulateLightGroupsAfterDungeonGeneration() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown GameObject root; DungeonGenerator val = FindDungeonGenerator(out root); if (val == null || (int)val.Status == 8) { PopulateLightGroups(root); return; } val.OnGenerationStatusChanged += (GenerationStatusDelegate)delegate(DungeonGenerator _, GenerationStatus status) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)status == 8) { PopulateLightGroups(root); } }; } private void PopulateLightGroups(GameObject root) { if (lightSwitcherGroups != null) { return; } random = new Random(StartOfRound.Instance.randomMapSeed); List<LightSwitcher> list = new List<LightSwitcher>(); root.GetComponentsInChildren<LightSwitcher>(list); list.Sort((LightSwitcher a, LightSwitcher b) => ((Object)a).GetInstanceID().CompareTo(((Object)b).GetInstanceID())); lightSwitcherGroups = new LightSwitcherGroup[groupCount]; int num = list.Count / groupCount; for (int i = 0; i < groupCount; i++) { List<LightSwitcher> list2 = new List<LightSwitcher>(); for (int j = 0; j < num; j++) { int index = random.Next(0, list.Count); list2.Add(list[index]); list.RemoveAt(index); } lightSwitcherGroups[i] = new LightSwitcherGroup { lights = list2, timeOffset = (float)random.NextDouble() * 0.2f }; } lightSwitcherGroups[^1].lights.AddRange(list); } public void EnableLights() { animationTime = 0f; state = State.TurningOn; } public void DisableLights() { animationTime = 0f; state = State.TurningOff; } public void FlickerLights() { if (lightSwitcherGroups != null) { LightSwitcherGroup[] array = lightSwitcherGroups; foreach (LightSwitcherGroup lightSwitcherGroup in array) { lightSwitcherGroup.flickerSpeed = 0.6f + (float)random.NextDouble() * 0.8f; lightSwitcherGroup.playedFlickerSound = false; } animationTime = 0f; state = State.Flickering; } } private void Update() { if (lightSwitcherGroups == null || state == State.Idle) { return; } animationTime += Time.deltaTime; bool flag = true; for (int i = 0; i < lightSwitcherGroups.Length; i++) { LightSwitcherGroup lightSwitcherGroup = lightSwitcherGroups[i]; bool flag2 = lightSwitcherGroup.wasOn; bool sound = true; float num = animationTime - lightSwitcherGroup.timeOffset; bool flag3 = false; if (state == State.TurningOn) { flag2 = num >= 0f; flag3 = flag2; } else if (state == State.TurningOff) { flag2 = num < 0f; flag3 = !flag2; } else if (state == State.Flickering) { float num2 = Mathf.Min((animationTime - lightSwitcherGroup.timeOffset) / flickerTime * lightSwitcherGroup.flickerSpeed, 1f); if (num2 >= 0f) { if (!lightSwitcherGroup.playedFlickerSound) { foreach (LightSwitcher light in lightSwitcherGroup.lights) { light.PlayFlickerSound(); } lightSwitcherGroup.playedFlickerSound = true; } flag2 = flickeringLightEnabledAnimation.Evaluate(num2) > 0.5f; } flag3 = num2 >= 1f; sound = false; } if (!flag3) { flag = false; } if (flag2 == lightSwitcherGroup.wasOn) { continue; } foreach (LightSwitcher light2 in lightSwitcherGroup.lights) { light2.SwitchLight(flag2, sound); } lightSwitcherGroup.wasOn = flag2; } if (flag) { state = State.Idle; } } } public class LightSwitcher : MonoBehaviour { [Serializable] public struct LightMaterialReference { public Renderer renderer; public int index; public Material onMaterial; public Material offMaterial; } private static AudioClip vanillaOnSound; private static AudioClip vanillaOffSound; private static AudioClip vanillaFlickerSound; public Light[] lights = Array.Empty<Light>(); public LightMaterialReference[] materialReferences = Array.Empty<LightMaterialReference>(); public AudioSource audioSource = null; public bool useVanillaAudio = false; public AudioClip onSound = null; public AudioClip offSound = null; public AudioClip flickerSound = null; internal static void CacheVanillaLightSounds() { if ((Object)(object)vanillaOnSound != (Object)null) { return; } AudioClip[] array = Resources.FindObjectsOfTypeAll<AudioClip>(); AudioClip[] array2 = array; foreach (AudioClip val in array2) { if ((Object)(object)vanillaOnSound == (Object)null && ((Object)val).name == "LightOn") { vanillaOnSound = val; } else if ((Object)(object)vanillaOffSound == (Object)null && ((Object)val).name == "LightOff") { vanillaOffSound = val; } else if ((Object)(object)vanillaFlickerSound == (Object)null && ((Object)val).name == "LightFlicker") { vanillaFlickerSound = val; } } } private void Start() { if (useVanillaAudio) { onSound = vanillaOnSound; offSound = vanillaOffSound; flickerSound = vanillaFlickerSound; } } internal void SwitchLight(bool on, bool sound) { Light[] array = lights; foreach (Light val in array) { if (!((Object)(object)val == (Object)null)) { ((Component)val).gameObject.SetActive(on); } } LightMaterialReference[] array2 = materialReferences; for (int j = 0; j < array2.Length; j++) { LightMaterialReference lightMaterialReference = array2[j]; if (!((Object)(object)lightMaterialReference.renderer == (Object)null)) { Material[] sharedMaterials = lightMaterialReference.renderer.sharedMaterials; if (lightMaterialReference.index >= sharedMaterials.Length) { Debug.LogWarning((object)$"{this} references a material index that is out of bounds ({lightMaterialReference.index})"); continue; } sharedMaterials[lightMaterialReference.index] = (on ? lightMaterialReference.onMaterial : lightMaterialReference.offMaterial); lightMaterialReference.renderer.sharedMaterials = sharedMaterials; } } if (sound) { AudioClip val2 = (on ? onSound : offSound); if ((Object)(object)val2 != (Object)null) { audioSource.PlayOneShot(val2); } } } internal void PlayFlickerSound() { if (!((Object)(object)audioSource == (Object)null) && !((Object)(object)flickerSound == (Object)null)) { audioSource.pitch = Random.Range(0.6f, 1.4f); audioSource.PlayOneShot(flickerSound); } } } [HarmonyPatch(typeof(MenuManager))] internal static class PatchMenuManager { [HarmonyPrefix] [HarmonyPatch("Start")] private static void StartPostfix() { LightSwitcher.CacheVanillaLightSounds(); } } } namespace SlaughterhouseDunGenExtras.MonoB { public class DebugToggler : MonoBehaviour { public bool disableColliders; public bool disableAudioSources; public bool disableRenderers; public bool disableLightAnimators; public bool disableOtherAnimators; private HashSet<Component> disabledComponents = new HashSet<Component>(); private void SetComponentEnabled(Component component, bool enabled) { Collider val = (Collider)(object)((component is Collider) ? component : null); if (val != null) { val.enabled = enabled; return; } AudioSource val2 = (AudioSource)(object)((component is AudioSource) ? component : null); if (val2 != null) { ((Behaviour)val2).enabled = enabled; return; } Renderer val3 = (Renderer)(object)((component is Renderer) ? component : null); if (val3 != null) { val3.enabled = enabled; return; } Behaviour val4 = (Behaviour)(object)((component is Behaviour) ? component : null); if (val4 != null) { val4.enabled = enabled; return; } throw new InvalidOperationException("Unexpected type " + ((object)component).GetType().Name); } private void DisableComponents(IEnumerable<Component> components) { foreach (Component component in components) { SetComponentEnabled(component, enabled: false); disabledComponents.Add(component); } } private IEnumerable<T> FindComponents<T>() where T : Component { T[] source = Object.FindObjectsByType<T>((FindObjectsInactive)1, (FindObjectsSortMode)0); return source.Where(delegate(T c) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) Scene scene = ((Component)c).gameObject.scene; return ((Scene)(ref scene)).name != "SampleSceneRelay"; }); } private void DisableComponents<T>() where T : Component { DisableComponents((IEnumerable<Component>)FindComponents<T>()); } private void DisableComponentsExcluding<T>(HashSet<T> blacklist) where T : Component { DisableComponents((IEnumerable<Component>)FindComponents<T>().Except(blacklist)); } public void OnEnable() { if (disableColliders) { DisableComponents<Collider>(); } if (disableAudioSources) { DisableComponents<AudioSource>(); } if (disableRenderers) { DisableComponents<Renderer>(); } HashSet<Animator> hashSet = new HashSet<Animator>(RoundManager.Instance.allPoweredLightsAnimators); if (disableLightAnimators) { DisableComponents((IEnumerable<Component>)hashSet); } if (disableOtherAnimators) { DisableComponentsExcluding<Animator>(hashSet); } } public void OnDisable() { foreach (Component disabledComponent in disabledComponents) { SetComponentEnabled(disabledComponent, enabled: true); } disabledComponents.Clear(); } } public class RigidBodyCuller : MonoBehaviour { [CompilerGenerated] private sealed class <CheckSpawned>d__6 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public RigidBodyCuller <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CheckSpawned>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitUntil((Func<bool>)(() => RoundManager.Instance.dungeonCompletedGenerating)); <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this.bodies = <>4__this.bodies.Where((Rigidbody x) => (Object)(object)x != (Object)null).ToArray(); <>4__this.active = true; 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 float threshold = 20f; public Rigidbody[] bodies = (Rigidbody[])(object)new Rigidbody[0]; private bool culled = false; private bool active = false; public void Start() { Rigidbody[] array = bodies; foreach (Rigidbody val in array) { if ((Object)(object)val != (Object)null) { val.Sleep(); } } ((MonoBehaviour)this).StartCoroutine(CheckSpawned()); } public void FixedUpdate() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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) if (!active) { return; } if (Vector3.Distance(((Component)StartOfRound.Instance.localPlayerController).transform.position, ((Component)this).transform.position) > threshold) { Rigidbody[] array = bodies; foreach (Rigidbody val in array) { if (!val.IsSleeping()) { val.Sleep(); } } culled = true; return; } if (culled) { Rigidbody[] array2 = bodies; foreach (Rigidbody val2 in array2) { val2.AddForce(Vector3.zero); } } culled = false; } [IteratorStateMachine(typeof(<CheckSpawned>d__6))] private IEnumerator CheckSpawned() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CheckSpawned>d__6(0) { <>4__this = this }; } } }