Decompiled source of Dantors Mental Hospital v1.2.2

BepInEx/plugins/DantorsMentalHospitalDunGen/MentalHospital.dll

Decompiled 9 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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 DunGen;
using DunGen.Graph;
using HarmonyLib;
using LethalLevelLoader;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;

[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("MentalHospital")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MentalHospital")]
[assembly: AssemblyTitle("MentalHospital")]
[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 MentalHospital
{
	[BepInPlugin("MentalHospital", "MentalHospital", "1.0.0")]
	public class MentalHospitalDunGen : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(RoundManager))]
		internal class RoundManagerPatch
		{
			[HarmonyPatch("SpawnScrapInLevel")]
			[HarmonyPrefix]
			private static bool SetItemSpawnPoints(ref RuntimeDungeon ___dungeonGenerator)
			{
				string name = ((Object)DungeonManager.CurrentExtendedDungeonFlow).name;
				if (name != "HospitalExtendedDungeonFlow")
				{
					return true;
				}
				StartOfRound instance = StartOfRound.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					Instance.mls.LogError((object)"Failed to get start of round instance. Scrap spawns may not work correctly.");
					return true;
				}
				Item val = instance.allItemsList.itemsList.Find((Item x) => x.itemName == "Bottles");
				if ((Object)(object)val == (Object)null)
				{
					Instance.mls.LogError((object)"Failed to find bottle bin item for reference snatching; scrap spawn may be significantly lower than expected.");
					return true;
				}
				Item val2 = instance.allItemsList.itemsList.Find((Item x) => x.itemName == "Golden cup");
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				ItemGroup spawnableItems = val.spawnPositionTypes.Find((ItemGroup x) => ((Object)x).name == "GeneralItemClass");
				ItemGroup val3 = val.spawnPositionTypes.Find((ItemGroup x) => ((Object)x).name == "TabletopItems");
				ItemGroup spawnableItems2 = (ItemGroup)(((Object)(object)val2 == (Object)null) ? ((object)val3) : ((object)val2.spawnPositionTypes.Find((ItemGroup x) => ((Object)x).name == "SmallItems")));
				RandomScrapSpawn[] array = Object.FindObjectsOfType<RandomScrapSpawn>();
				RandomScrapSpawn[] array2 = array;
				foreach (RandomScrapSpawn val4 in array2)
				{
					switch (((Object)val4.spawnableItems).name)
					{
					case "GeneralItemClassDUMMY":
						val4.spawnableItems = spawnableItems;
						num++;
						break;
					case "TabletopItemsDUMMY":
						val4.spawnableItems = val3;
						num2++;
						break;
					case "SmallItemsDUMMY":
						val4.spawnableItems = spawnableItems2;
						num3++;
						break;
					}
				}
				Instance.mls.LogInfo((object)$"Totals for scrap replacement: General: {num}, Tabletop: {num2}, Small: {num3}");
				if (num + num2 + num3 < 10)
				{
					Instance.mls.LogWarning((object)"Unusually low scrap spawn count; scrap may be sparse.");
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(SteamValveHazard))]
		[HarmonyPatch("BurstValve")]
		public class BurstValveColorPatch
		{
			private static void Postfix(SteamValveHazard __instance)
			{
				//IL_0076: 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)
				string name = ((Object)DungeonManager.CurrentExtendedDungeonFlow).name;
				if (!(name == "HospitalExtendedDungeonFlow") || !configGreenFog.Value)
				{
					return;
				}
				string text = "749B3B";
				Color albedo = default(Color);
				if (ColorUtility.TryParseHtmlString("#" + text, ref albedo))
				{
					LocalVolumetricFog component = ((Component)__instance.fogAnimator).GetComponent<LocalVolumetricFog>();
					if ((Object)(object)component != (Object)null)
					{
						((Component)__instance.fogAnimator).GetComponent<LocalVolumetricFog>().parameters.albedo = albedo;
					}
					else
					{
						Debug.LogError((object)"LocalVolumetricFog component not found on fogAnimator.");
					}
				}
				else
				{
					Debug.LogError((object)("Invalid hexadecimal color value: " + text));
				}
			}
		}

		[HarmonyPatch(typeof(SteamValveHazard))]
		[HarmonyPatch("Update")]
		public class SteamValveHazard_Update_Patch
		{
			private class SteamValveState
			{
				public float timeInsideFog = 0f;

				public float damageTimer = 0f;

				public bool isInsideFog = false;
			}

			private static readonly FieldInfo valveHasBurstField = AccessTools.Field(typeof(SteamValveHazard), "valveHasBurst");

			private static readonly FieldInfo valveHasBeenRepairedField = AccessTools.Field(typeof(SteamValveHazard), "valveHasBeenRepaired");

			private static Dictionary<int, SteamValveState> valveStates = new Dictionary<int, SteamValveState>();

			[HarmonyPrefix]
			public static bool Prefix(SteamValveHazard __instance)
			{
				//IL_00a2: 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)
				bool flag = (bool)valveHasBurstField.GetValue(__instance);
				int instanceID = ((Object)__instance).GetInstanceID();
				bool flag2 = (bool)valveHasBeenRepairedField.GetValue(__instance);
				string name = ((Object)DungeonManager.CurrentExtendedDungeonFlow).name;
				if (flag && name == "HospitalExtendedDungeonFlow" && !flag2 && configFogDamage.Value)
				{
					if (!valveStates.ContainsKey(instanceID))
					{
						valveStates[instanceID] = new SteamValveState();
					}
					SteamValveState steamValveState = valveStates[instanceID];
					if (Vector3.Distance(((Component)GameNetworkManager.Instance.localPlayerController).transform.position, ((Component)__instance.valveAudio).transform.position) < 10f)
					{
						steamValveState.timeInsideFog += Time.deltaTime;
						if (steamValveState.timeInsideFog >= 5f && !steamValveState.isInsideFog)
						{
							steamValveState.isInsideFog = true;
							steamValveState.damageTimer = 0f;
						}
						if (steamValveState.isInsideFog)
						{
							steamValveState.damageTimer += Time.deltaTime;
							if (steamValveState.damageTimer >= 1f)
							{
								steamValveState.damageTimer = 0f;
								ApplyDamageToPlayer();
							}
						}
					}
					else
					{
						steamValveState.timeInsideFog = 0f;
						steamValveState.damageTimer = 0f;
						steamValveState.isInsideFog = false;
					}
					return true;
				}
				return true;
			}

			private static void ApplyDamageToPlayer()
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				GameNetworkManager.Instance.localPlayerController.DamagePlayer(5, true, true, (CauseOfDeath)0, 0, false, default(Vector3));
			}
		}

		private const string modGUID = "DantorMentalHospital";

		private const string modName = "Dantor's Mental Hospital";

		private const string modVersion = "1.2.0";

		private static MentalHospitalDunGen Instance;

		private readonly Harmony harmony = new Harmony("Dantor's Mental Hospital");

		public static ConfigEntry<int> configRarity;

		public static ConfigEntry<string> configMoons;

		public static ConfigEntry<bool> configGuaranteed;

		public static ConfigEntry<float> configMinSize;

		public static ConfigEntry<float> configMaxSize;

		public static ConfigEntry<float> configDynamicValue;

		public static ConfigEntry<bool> configDynamicToggle;

		public static ConfigEntry<bool> configGreenFog;

		public static ConfigEntry<bool> configFogDamage;

		internal ManualLogSource mls;

		public static AssetBundle Assets;

		private void Awake()
		{
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Expected O, but got Unknown
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Expected O, but got Unknown
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Expected O, but got Unknown
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Expected O, but got Unknown
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Expected O, but got Unknown
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Expected O, but got Unknown
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Expected O, but got Unknown
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Expected O, but got Unknown
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Expected O, but got Unknown
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Expected O, but got Unknown
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Expected O, but got Unknown
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Expected O, but got Unknown
			//IL_041b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_042c: Expected O, but got Unknown
			//IL_0467: Unknown result type (might be due to invalid IL or missing references)
			//IL_046e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0478: Expected O, but got Unknown
			//IL_0543: Unknown result type (might be due to invalid IL or missing references)
			//IL_054d: Expected O, but got Unknown
			//IL_05d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05dd: Expected O, but got Unknown
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			mls = Logger.CreateLogSource("MentalHospital");
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			Assets = AssetBundle.LoadFromFile(Path.Combine(directoryName, "hospitalbundle"));
			if ((Object)(object)Assets == (Object)null)
			{
				mls.LogError((object)"Failed to load DantorsMentalHospital assets.");
				return;
			}
			DungeonFlow val = Assets.LoadAsset<DungeonFlow>("Assets/Abandoned_Psychiatric_Hospitals/DunGen Data/HospitalFlow.asset");
			if ((Object)(object)val == (Object)null)
			{
				mls.LogError((object)"Failed to load DantorsMentalHospital Dungeon Flow.");
				return;
			}
			configRarity = ((BaseUnityPlugin)this).Config.Bind<int>("General", "HospitalDefaultRarity", 100, new ConfigDescription("How rare it is for the mental hospital to be chosen. Higher values increases the chance of spawning the mental hospital. Vanillas' main dungeons use a value of 300. Google Weighted Random if you don't know how it works, as that's how Lethal Company rarities function.", (AcceptableValueBase)null, Array.Empty<object>()));
			configMoons = ((BaseUnityPlugin)this).Config.Bind<string>("General", "HospitalMoonsList", "Assurance@100,Vow@100,Offense@100,March@100,Rend@100,Dine@100,Titan@100,PsychSanctum@9999", new ConfigDescription("The moon(s) that the hospital can spawn on, in the form of a comma separated list of selectable level names and optionally a weight value by using an '@' and weight value after it (e.g. \"Titan@300,Dine,Rend@10,PsychSanctum@9999\")\nThe name matching is lenient and should pick it up if you use the terminal name or internal mod name. If no rarity is specified, the HospitalRarity parameter is used.\nThe following strings: \"all\", \"vanilla\", \"modded\", \"paid\", \"free\" are dynamic presets which add the dungeon to that specified group (string must only contain one of these, or a manual moon name list).\n", (AcceptableValueBase)null, Array.Empty<object>()));
			configGuaranteed = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "HospitalGuaranteed", false, new ConfigDescription("\nSet it to true to guarantee the interior to spawn on any moon you visit. It works in any case except when if you use list mode", (AcceptableValueBase)null, Array.Empty<object>()));
			configDynamicToggle = ((BaseUnityPlugin)this).Config.Bind<bool>("Size", "DynamicScaleToggle", true, new ConfigDescription("Enables the next 3 options. \nATTENTION: READ CAREFULLY HOW IT WORKS. This adjust the dungeon size accordingly to which moon you visit, it is recommended to let it on true\nDefault: true", (AcceptableValueBase)null, Array.Empty<object>()));
			configDynamicValue = ((BaseUnityPlugin)this).Config.Bind<float>("Size", "DynamicScaleValue", 0.8f, new ConfigDescription("If the DungeonMinSize/DungeonMaxSize is above or below the next two settings, the dungeon size multiplier will aproximate to the value between the moon's specific dungeon size and this value.\nExample 1: If set to 0, the dungeon size will not be higher than DungeonMaxSize.\nExample 2: If set to 0.5, the dungeon size will be between the DungeonMaxSize and the moon's dungeon size multiplier.\nExample 3: If Set To 1, the dungeon size will be the moon's dungeon size multiplier with no restrictions.\nATTENTION: It is recommended to let it at default value or lower, the closer to 1 the bigger the dungeon.\nDefault: 0.8", (AcceptableValueBase)null, Array.Empty<object>()));
			configMinSize = ((BaseUnityPlugin)this).Config.Bind<float>("Size", "DungeonMinSize", 0.5f, new ConfigDescription("Input the minimum's dungeon size multiplier.\nDefault: 0.5", (AcceptableValueBase)null, Array.Empty<object>()));
			configMaxSize = ((BaseUnityPlugin)this).Config.Bind<float>("Size", "DungeonMaxSize", 0.65f, new ConfigDescription("Input the maximum's dungeon size multiplier.\nDefault: 0.65", (AcceptableValueBase)null, Array.Empty<object>()));
			configGreenFog = ((BaseUnityPlugin)this).Config.Bind<bool>("Interior Settings", "GreenFogToggle", true, new ConfigDescription("Sets the Hospital fog from steams valves to green, this is just an aesthetic change", (AcceptableValueBase)null, Array.Empty<object>()));
			configFogDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("Interior Settings", "FogDamageToggle", true, new ConfigDescription("Enables the damage over time if you are inside the fog for too long (It only works in the Mental Hospital)", (AcceptableValueBase)null, Array.Empty<object>()));
			ExtendedDungeonFlow val2 = ScriptableObject.CreateInstance<ExtendedDungeonFlow>();
			val2.contentSourceName = "Dantors Mental Hospital";
			val2.dungeonFlow = val;
			val2.dungeonDefaultRarity = configRarity.Value;
			int num = (configGuaranteed.Value ? 99999 : configRarity.Value);
			switch (configMoons.Value.ToLower())
			{
			case "all":
				val2.dynamicLevelTagsList.Add(new StringWithRarity("Vanilla", num));
				val2.dynamicLevelTagsList.Add(new StringWithRarity("Custom", num));
				mls.LogInfo((object)"Registered DantorsMentalHospital dungeon for all moons.");
				break;
			case "vanilla":
				val2.manualContentSourceNameReferenceList.Add(new StringWithRarity("Lethal Company", num));
				mls.LogInfo((object)"Registered DantorsMentalHospital dungeon for all vanilla moons.");
				break;
			case "modded":
				val2.manualContentSourceNameReferenceList.Add(new StringWithRarity("Custom", num));
				mls.LogInfo((object)"Registered DantorsMentalHospital dungeon for all modded moons.");
				break;
			case "paid":
				val2.dynamicRoutePricesList.Add(new Vector2WithRarity(new Vector2(1f, 9999f), num));
				mls.LogInfo((object)"Registered DantorsMentalHospital dungeon for all paid moons.");
				break;
			case "free":
				val2.dynamicRoutePricesList.Add(new Vector2WithRarity(new Vector2(0f, 0f), num));
				mls.LogInfo((object)"Registered DantorsMentalHospital dungeon for all free moons.");
				break;
			default:
			{
				mls.LogInfo((object)"Registering DantorsMentalHospital dungeon for predefined moon list.");
				string[] array3 = configMoons.Value.Split(',', StringSplitOptions.RemoveEmptyEntries);
				List<StringWithRarity> list = new List<StringWithRarity>();
				for (int k = 0; k < array3.Length; k++)
				{
					string[] array4 = array3[k].Split('@', StringSplitOptions.RemoveEmptyEntries);
					int num2 = array4.Length;
					int result;
					if (num2 > 2)
					{
						mls.LogError((object)("Invalid setup for moon rarity config: " + array3[k] + ". Skipping."));
					}
					else if (num2 == 1)
					{
						mls.LogInfo((object)$"Registering DantorsMentalHospital dungeon for moon {array3[k]} at default rarity {num}");
						list.Add(new StringWithRarity(array3[k], num));
					}
					else if (!int.TryParse(array4[1], out result))
					{
						mls.LogError((object)("Failed to parse rarity value for moon " + array4[0] + ": " + array4[1] + ". Skipping."));
					}
					else
					{
						mls.LogInfo((object)$"Registering DantorsMentalHospital dungeon for moon {array3[k]} at rarity {result}");
						list.Add(new StringWithRarity(array4[0], result));
					}
				}
				val2.manualPlanetNameReferenceList = list;
				break;
			}
			}
			val2.dungeonDisplayName = "Mental Hospital";
			val2.dungeonSizeMin = configMinSize.Value;
			val2.dungeonSizeMax = configMaxSize.Value;
			val2.dungeonSizeLerpPercentage = configDynamicValue.Value;
			val2.enableDynamicDungeonSizeRestriction = configDynamicToggle.Value;
			PatchedContent.RegisterExtendedDungeonFlow(val2);
			harmony.PatchAll(typeof(MentalHospitalDunGen));
			harmony.PatchAll(typeof(RoundManagerPatch));
			harmony.PatchAll(typeof(BurstValveColorPatch));
			harmony.PatchAll(typeof(SteamValveHazard_Update_Patch));
			mls.LogInfo((object)"DantorsMentalHospital DunGen for Lethal Company [Version 1.0.0] successfully loaded.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin MentalHospital is loaded!");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "MentalHospital";

		public const string PLUGIN_NAME = "MentalHospital";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}