Decompiled source of Slaughterhouse v1.2.1

plugins/Slaughterhouse/Nikki.Slaughterhouse.dll

Decompiled 3 days ago
using 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
			};
		}
	}
}