Decompiled source of PoolRooms v0.1.22

plugins/PoolRooms/PoolRooms.dll

Decompiled 6 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 GameNetcodeStuff;
using HarmonyLib;
using LethalLevelLoader;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using PoolRooms.NetcodePatcher;
using UnityEngine;
using UnityEngine.UIElements.Collections;

[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("PoolRooms")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A pool rooms dungeon for Lethal Company")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PoolRooms")]
[assembly: AssemblyTitle("PoolRooms")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
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 PoolRooms
{
	[BepInPlugin("skidz.PoolRooms", "PoolRooms", "0.1.22")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class PoolRooms : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(RoundManager))]
		internal class RoundManagerPatch
		{
			[HarmonyPatch("SpawnScrapInLevel")]
			[HarmonyPrefix]
			private static void SpawnScrapInLevelPre(ref SelectableLevel ___currentLevel, ref RuntimeDungeon ___dungeonGenerator)
			{
				//IL_029e: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a5: Expected O, but got Unknown
				if (((Object)___dungeonGenerator.Generator.DungeonFlow).name != "PoolRoomsFlow")
				{
					return;
				}
				StartOfRound obj = Object.FindObjectOfType<StartOfRound>();
				Item val = null;
				Item val2 = null;
				foreach (Item items in obj.allItemsList.itemsList)
				{
					if (items.itemName == "Bottles")
					{
						val = items;
					}
					else if (items.itemName == "Golden cup")
					{
						val2 = items;
					}
					if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2))
					{
						break;
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					Instance.mls.LogError((object)"Unable to find the Bottles item with spawn positions to pull from. No junk will spawn in this dungeon!");
					return;
				}
				if ((Object)(object)val2 == (Object)null)
				{
					Instance.mls.LogWarning((object)"Unable to find the GoldenCup item with spawn positions to pull from. No small items will be able to spawn!");
				}
				ItemGroup val3 = val.spawnPositionTypes.Find((ItemGroup x) => ((Object)x).name == "GeneralItemClass");
				ItemGroup val4 = val.spawnPositionTypes.Find((ItemGroup x) => ((Object)x).name == "TabletopItems");
				if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val4))
				{
					Instance.mls.LogError((object)("Found an item '" + ((Object)val).name + "' that is suppose to have both general and table top items but no longer does..."));
					return;
				}
				ItemGroup val5 = (ItemGroup)(((Object)(object)val2 == (Object)null) ? ((object)val4) : ((object)val2.spawnPositionTypes.Find((ItemGroup x) => ((Object)x).name == "SmallItems")));
				if (Instance.configEnableCustomScrap.Value && !Instance.configUseCustomScrapGlobally.Value)
				{
					int num = 0;
					foreach (Item poolItem in PoolItems)
					{
						List<ItemGroup> list = new List<ItemGroup>();
						using (List<ItemGroup>.Enumerator enumerator2 = poolItem.spawnPositionTypes.GetEnumerator())
						{
							while (enumerator2.MoveNext())
							{
								switch (((Object)enumerator2.Current).name)
								{
								case "PoolRooms_GeneralItemClass_DUMMY":
									list.Add(val3);
									break;
								case "PoolRooms_TabletopItems_DUMMY":
									list.Add(val4);
									break;
								case "PoolRooms_SmallItems_DUMMY":
									list.Add(val5);
									break;
								}
							}
						}
						if (list.Count > 0)
						{
							Instance.mls.LogInfo((object)("Fixing pool item '" + ((Object)poolItem).name + "' item groups"));
							poolItem.spawnPositionTypes = list;
						}
						SpawnableItemWithRarity val6 = new SpawnableItemWithRarity();
						val6.spawnableItem = poolItem;
						val6.rarity = PoolItemRarities[num];
						___currentLevel.spawnableScrap.Add(val6);
						PoolItemsAdded.Add(val6);
						Instance.mls.LogInfo((object)("Added pool rooms item '" + ((Object)poolItem).name + "' to spawnable scrap!"));
						num++;
					}
				}
				RandomScrapSpawn[] array = Object.FindObjectsOfType<RandomScrapSpawn>();
				foreach (RandomScrapSpawn val7 in array)
				{
					switch (((Object)val7.spawnableItems).name)
					{
					case "PoolRooms_GeneralItemClass_DUMMY":
						val7.spawnableItems = val3;
						break;
					case "PoolRooms_TabletopItems_DUMMY":
						val7.spawnableItems = val4;
						break;
					case "PoolRooms_SmallItems_DUMMY":
						val7.spawnableItems = val5;
						break;
					}
				}
			}

			[HarmonyPatch("SpawnScrapInLevel")]
			[HarmonyPostfix]
			private static void SpawnScrapInLevelPost(ref SelectableLevel ___currentLevel, ref RuntimeDungeon ___dungeonGenerator)
			{
				if (((Object)___dungeonGenerator.Generator.DungeonFlow).name != "PoolRoomsFlow" || !Instance.configEnableCustomScrap.Value || Instance.configUseCustomScrapGlobally.Value)
				{
					return;
				}
				foreach (SpawnableItemWithRarity item in PoolItemsAdded)
				{
					if (___currentLevel.spawnableScrap.Remove(item))
					{
						Instance.mls.LogInfo((object)("Removed pool rooms item '" + ((Object)item.spawnableItem).name + "' from spawnable scrap!"));
					}
					else
					{
						Instance.mls.LogError((object)("Unable to remove pool rooms item '" + ((Object)item.spawnableItem).name + "' from spawnable scrap!"));
					}
				}
				PoolItemsAdded.Clear();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB))]
		internal class PlayerControllerPatch
		{
			private static int footstepSurfaceStorage;

			[HarmonyPatch("CheckConditionsForSinkingInQuicksand")]
			[HarmonyPrefix]
			private static void CheckPrefix(ref PlayerControllerB __instance)
			{
				if (GameNetworkManager.Instance.localPlayerController.isInsideFactory)
				{
					footstepSurfaceStorage = __instance.currentFootstepSurfaceIndex;
					__instance.currentFootstepSurfaceIndex = 1;
				}
			}
		}

		[HarmonyPatch(typeof(EntranceTeleport))]
		internal class EntranceTeleportPatch
		{
			[HarmonyPatch("TeleportPlayer")]
			[HarmonyPrefix]
			private static void TeleportPlayerPre()
			{
				BroadcastPlayerTeleported(GameNetworkManager.Instance.localPlayerController);
			}

			[HarmonyPatch("TeleportPlayerClientRpc")]
			[HarmonyPrefix]
			private static void TeleportPlayerClientPre(int playerObj)
			{
				StartOfRound val = Object.FindObjectOfType<StartOfRound>();
				if (Object.op_Implicit((Object)(object)val) && playerObj >= 0 && playerObj < val.allPlayerScripts.Length)
				{
					BroadcastPlayerTeleported(val.allPlayerScripts[playerObj]);
				}
				else
				{
					Instance.mls.LogWarning((object)"Unable to find the client player script!");
				}
			}

			private static void BroadcastPlayerTeleported(PlayerControllerB player)
			{
				PoolRoomsWaterTrigger[] array = Object.FindObjectsOfType<PoolRoomsWaterTrigger>();
				foreach (PoolRoomsWaterTrigger val in array)
				{
					if ((Object)(object)val != (Object)null)
					{
						val.OnLocalPlayerTeleported(player);
					}
				}
			}
		}

		private const string modGUID = "skidz.PoolRooms";

		private const string modName = "PoolRooms";

		private const string modVersion = "0.1.22";

		private readonly Harmony harmony = new Harmony("skidz.PoolRooms");

		private static PoolRooms Instance;

		internal ManualLogSource mls;

		public static AssetBundle DungeonAssets;

		private ConfigEntry<bool> configUsePoolRoomsMoonsConfig;

		private ConfigEntry<int> configBaseRarity;

		private ConfigEntry<float> configMinGenerationScale;

		private ConfigEntry<float> configMaxGenerationScale;

		private ConfigEntry<string> configMoons;

		private ConfigEntry<bool> configGuaranteed;

		private ConfigEntry<bool> configEnableCustomScrap;

		private ConfigEntry<bool> configUseCustomScrapGlobally;

		private ConfigEntry<int> configPoolBallWeighting;

		private ConfigEntry<int> configPoolNetWeighting;

		private ConfigEntry<int> configLifeBuoyWeighting;

		private ConfigEntry<int> configWetFloorSignWeighting;

		private static DungeonFlow DungeonFlow = null;

		private static List<Item> PoolItems = new List<Item>();

		private static List<int> PoolItemRarities = new List<int>();

		private static List<SpawnableItemWithRarity> PoolItemsAdded = new List<SpawnableItemWithRarity>();

		private string[] MoonIdentifiers = new string[16]
		{
			"Vanilla", "All", "Custom", "Free", "Paid", "Tier1", "Tier2", "Tier3", "Titan", "Rend",
			"Dine", "Experimentation", "Assurance", "Vow", "Offense", "March"
		};

		private Dictionary<string, string[]> MoonIDToMoonsMapping = new Dictionary<string, string[]>
		{
			{
				"free",
				new string[5] { "Experimentation", "Assurance", "Vow", "Offense", "March" }
			},
			{
				"paid",
				new string[3] { "Rend", "Dine", "Titan" }
			},
			{
				"tier1",
				new string[3] { "Experimentation", "Assurance", "Vow" }
			},
			{
				"tier2",
				new string[2] { "Offense", "March" }
			},
			{
				"tier3",
				new string[3] { "Rend", "Dine", "Titan" }
			},
			{
				"titan",
				new string[1] { "Titan" }
			},
			{
				"rend",
				new string[1] { "Rend" }
			},
			{
				"dine",
				new string[1] { "Dine" }
			},
			{
				"experimentation",
				new string[1] { "Experimentation" }
			},
			{
				"assurance",
				new string[1] { "Assurance" }
			},
			{
				"vow",
				new string[1] { "Vow" }
			},
			{
				"offense",
				new string[1] { "Offense" }
			},
			{
				"march",
				new string[1] { "March" }
			}
		};

		private void Awake()
		{
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Expected O, but got Unknown
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Expected O, but got Unknown
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Expected O, but got Unknown
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Expected O, but got Unknown
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Expected O, but got Unknown
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Expected O, but got Unknown
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Expected O, but got Unknown
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Expected O, but got Unknown
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Expected O, but got Unknown
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Expected O, but got Unknown
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dd: Expected O, but got Unknown
			//IL_04ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f9: Expected O, but got Unknown
			//IL_054d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Expected O, but got Unknown
			//IL_059d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a7: Expected O, but got Unknown
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("PoolRooms");
			mls.LogInfo((object)("Behaviors Version " + PoolRoomsWaterBehaviour.BehaviorsVer + " Loaded!"));
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				MethodInfo[] methods = types[i].GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			harmony.PatchAll(typeof(PoolRooms));
			harmony.PatchAll(typeof(RoundManagerPatch));
			harmony.PatchAll(typeof(EntranceTeleportPatch));
			configUsePoolRoomsMoonsConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "UsePoolRoomsMoonsConfig", false, new ConfigDescription("If true, will use the plugins moon config over Lethal Level Loaders config generation.", (AcceptableValueBase)null, Array.Empty<object>()));
			configMoons = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Moons", "All:100", new ConfigDescription("The moon(s) that the dungeon can spawn on with rarity weight, from the given presets or combined comma sep list ex 'Vow:100,March:50,Paid:30'. Custom moons should be supported if you know the name. A list of acceptable IDs not including custom: " + string.Join(", ", MoonIdentifiers), (AcceptableValueBase)null, Array.Empty<object>()));
			configBaseRarity = ((BaseUnityPlugin)this).Config.Bind<int>("General", "BaseRarity", 100, new ConfigDescription("A baseline rarity weight for each moon. Only used if Guaranteed is false and a moon doesn't have an explicit rarity weight.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 9999), Array.Empty<object>()));
			configMinGenerationScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MinGenerationScale", 1f, new ConfigDescription("The minimum scale to generate the dungeon.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
			configMaxGenerationScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MaxGenerationScale", 2.5f, new ConfigDescription("The maximum scale to generate the dungeon.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
			configGuaranteed = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Guaranteed", false, new ConfigDescription("If true the dungeons rarity will be defaulted to a high weighting which will most likely trump all other weights and guarantee this dungeon flow.", (AcceptableValueBase)null, Array.Empty<object>()));
			configEnableCustomScrap = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableCustomScrap", true, new ConfigDescription("If true, custom pool rooms scrap will be spawned. EnableCustomScrap must also be true for this to function.", (AcceptableValueBase)null, Array.Empty<object>()));
			configUseCustomScrapGlobally = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "UseCustomScrapGlobally", false, new ConfigDescription("If true, the custom pool rooms scrap will be added to all interiors.", (AcceptableValueBase)null, Array.Empty<object>()));
			configPoolBallWeighting = ((BaseUnityPlugin)this).Config.Bind<int>("General", "PoolBallWeighting", 100, new ConfigDescription("The pool ball spawning weight", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 9999), Array.Empty<object>()));
			configPoolNetWeighting = ((BaseUnityPlugin)this).Config.Bind<int>("General", "PoolNetWeighting", 100, new ConfigDescription("The pool net spawning weight", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 9999), Array.Empty<object>()));
			configLifeBuoyWeighting = ((BaseUnityPlugin)this).Config.Bind<int>("General", "LifeBuoyWeighting", 60, new ConfigDescription("The Life Buoy spawning weight", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 9999), Array.Empty<object>()));
			configWetFloorSignWeighting = ((BaseUnityPlugin)this).Config.Bind<int>("General", "WetFloorSignWeighting", 60, new ConfigDescription("The Wet Floor Sign spawning weight", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 9999), Array.Empty<object>()));
			DungeonAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "poolrooms"));
			if ((Object)(object)DungeonAssets == (Object)null)
			{
				mls.LogError((object)"Failed to load Dungeon assets.");
				return;
			}
			DungeonFlow = DungeonAssets.LoadAsset<DungeonFlow>("assets/PoolRooms/Flow/PoolRoomsFlow.asset");
			if ((Object)(object)DungeonFlow == (Object)null)
			{
				mls.LogError((object)"Failed to load Dungeon Flow.");
				return;
			}
			AudioClip firstTimeDungeonAudio = DungeonAssets.LoadAsset<AudioClip>("Assets/PoolRooms/Sound/PoolRoomsFirstTime.wav");
			ExtendedDungeonFlow val = ScriptableObject.CreateInstance<ExtendedDungeonFlow>();
			val.DungeonFlow = DungeonFlow;
			val.FirstTimeDungeonAudio = firstTimeDungeonAudio;
			val.DynamicDungeonSizeMinMax = new Vector2(configMinGenerationScale.Value, Math.Max(configMinGenerationScale.Value, configMaxGenerationScale.Value));
			val.DungeonName = "Pool Rooms";
			val.GenerateAutomaticConfigurationOptions = !configUsePoolRoomsMoonsConfig.Value;
			LevelMatchingProperties val2 = LevelMatchingProperties.Create((ExtendedContent)(object)val);
			foreach (StringWithRarity item in GetLevelStringsWithRarity(configMoons.Value.ToLowerInvariant(), configBaseRarity.Value, configGuaranteed.Value ? 99999 : (-1)))
			{
				switch (item.Name.ToLowerInvariant())
				{
				case "all":
					val2.levelTags.Add(new StringWithRarity("Vanilla", item.Rarity));
					val2.levelTags.Add(new StringWithRarity("Custom", item.Rarity));
					mls.LogInfo((object)$"Added all moons + custom with a rarity weight of {item.Rarity}");
					break;
				case "custom":
				case "modded":
					val2.levelTags.Add(new StringWithRarity("Custom", item.Rarity));
					mls.LogInfo((object)$"Added all custom moons with a rarity weight of {item.Rarity}");
					break;
				case "vanilla":
					val2.levelTags.Add(new StringWithRarity("Vanilla", item.Rarity));
					mls.LogInfo((object)$"Added all vanilla moons with a rarity weight of {item.Rarity}");
					break;
				default:
					val2.planetNames.Add(item);
					mls.LogInfo((object)$"Added to moon '{item.Name}' with a rarity weight of {item.Rarity}");
					break;
				}
			}
			val.LevelMatchingProperties = val2;
			val.DungeonEvents.onApparatusTaken.AddListener((ParameterEvent<LungProp>)OnDungeonApparatusTaken);
			PatchedContent.RegisterExtendedDungeonFlow(val);
			if (configEnableCustomScrap.Value)
			{
				Item val3 = DungeonAssets.LoadAsset<Item>("Assets/PoolRooms/Scrap/LifeBuoy.asset");
				Utilities.FixMixerGroups(val3.spawnPrefab);
				NetworkPrefabs.RegisterNetworkPrefab(val3.spawnPrefab);
				PoolItems.Add(val3);
				PoolItemRarities.Add(configLifeBuoyWeighting.Value);
				Items.RegisterScrap(val3, configLifeBuoyWeighting.Value, (LevelTypes)((!configUseCustomScrapGlobally.Value) ? 1 : (-1)));
				Item val4 = DungeonAssets.LoadAsset<Item>("Assets/PoolRooms/Scrap/PoolNet.asset");
				Utilities.FixMixerGroups(val4.spawnPrefab);
				NetworkPrefabs.RegisterNetworkPrefab(val4.spawnPrefab);
				PoolItems.Add(val4);
				PoolItemRarities.Add(configPoolNetWeighting.Value);
				Items.RegisterScrap(val4, configPoolNetWeighting.Value, (LevelTypes)((!configUseCustomScrapGlobally.Value) ? 1 : (-1)));
				Item val5 = DungeonAssets.LoadAsset<Item>("Assets/PoolRooms/Scrap/PoolBall.asset");
				Utilities.FixMixerGroups(val5.spawnPrefab);
				NetworkPrefabs.RegisterNetworkPrefab(val5.spawnPrefab);
				PoolItems.Add(val5);
				PoolItemRarities.Add(configPoolBallWeighting.Value);
				Items.RegisterScrap(val5, configPoolBallWeighting.Value, (LevelTypes)((!configUseCustomScrapGlobally.Value) ? 1 : (-1)));
				Item val6 = DungeonAssets.LoadAsset<Item>("Assets/PoolRooms/Scrap/WetFloorSign.asset");
				Utilities.FixMixerGroups(val6.spawnPrefab);
				NetworkPrefabs.RegisterNetworkPrefab(val6.spawnPrefab);
				PoolItems.Add(val6);
				PoolItemRarities.Add(configWetFloorSignWeighting.Value);
				Items.RegisterScrap(val6, configWetFloorSignWeighting.Value, (LevelTypes)((!configUseCustomScrapGlobally.Value) ? 1 : (-1)));
			}
			GameObject obj = DungeonAssets.LoadAsset<GameObject>("Assets/PoolRooms/Prefabs/LockerDoor.prefab");
			Utilities.FixMixerGroups(obj);
			NetworkPrefabs.RegisterNetworkPrefab(obj);
			GameObject obj2 = DungeonAssets.LoadAsset<GameObject>("Assets/PoolRooms/Prefabs/PoolRoomsDoor.prefab");
			Utilities.FixMixerGroups(obj2);
			NetworkPrefabs.RegisterNetworkPrefab(obj2);
			Utilities.FixMixerGroups(DungeonAssets.LoadAsset<GameObject>("Assets/PoolRooms/Prefabs/RoomWater.prefab"));
			Utilities.FixMixerGroups(DungeonAssets.LoadAsset<GameObject>("Assets/PoolRooms/Prefabs/WaterBehavior.prefab"));
			mls.LogInfo((object)"Pool Rooms [Version 0.1.22] successfully loaded.");
		}

		private void OnDungeonApparatusTaken(LungProp lung)
		{
			PoolLightBehaviour[] array = Object.FindObjectsOfType<PoolLightBehaviour>();
			for (int i = 0; i < array.Length; i++)
			{
				array[i].OnApparatusPulled();
			}
		}

		private List<StringWithRarity> GetLevelStringsWithRarity(string delimitedList, int baseRarity, int fixedRarity)
		{
			List<StringWithRarity> listOut = new List<StringWithRarity>();
			Dictionary<string, int> lookup = new Dictionary<string, int>();
			string[] array = delimitedList.Split(',', StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(':');
				string text = array2[0].Trim();
				int rarity2 = baseRarity;
				if (fixedRarity > 0)
				{
					rarity2 = fixedRarity;
				}
				else if (array2.Length >= 2)
				{
					rarity2 = int.Parse(array2[1]);
				}
				string[] array3 = DictionaryExtensions.Get<string, string[]>((IDictionary<string, string[]>)MoonIDToMoonsMapping, text, (string[])null);
				if (array3 != null)
				{
					string[] array4 = array3;
					for (int j = 0; j < array4.Length; j++)
					{
						AddRarity(array4[j], rarity2);
					}
				}
				else
				{
					AddRarity(text, rarity2);
				}
			}
			return listOut;
			void AddRarity(string mapLevelID, int rarity)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Expected O, but got Unknown
				int num = DictionaryExtensions.Get<string, int>((IDictionary<string, int>)lookup, mapLevelID, -1);
				if (num == -1)
				{
					listOut.Add(new StringWithRarity(mapLevelID, rarity));
					lookup.Add(mapLevelID, listOut.Count - 1);
				}
				else
				{
					listOut[num].Rarity = rarity;
				}
			}
		}
	}
	public static class StringExtensions
	{
		public static string FirstCharToUpper(this string input)
		{
			if (input != null)
			{
				if (input == "")
				{
					throw new ArgumentException("input cannot be empty", "input");
				}
				return input[0].ToString().ToUpper() + input.Substring(1);
			}
			throw new ArgumentNullException("input");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "PoolRooms";

		public const string PLUGIN_NAME = "PoolRooms";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace PoolRooms.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}

plugins/PoolRooms/PoolRoomsBehaviours.dll

Decompiled 6 months ago
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 GameNetcodeStuff;
using Microsoft.CodeAnalysis;
using PoolRoomsBehaviours.NetcodePatcher;
using UnityEngine;

[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("PoolRoomsBehaviours")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Pool Rooms Behaviours")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PoolRoomsBehaviours")]
[assembly: AssemblyTitle("PoolRoomsBehaviours")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
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 PoolRooms
{
	public class PoolLightBehaviour : MonoBehaviour
	{
		public Light LightToUpdate;

		public Color RedAlertColor = Color.red;

		public void OnApparatusPulled()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			LightToUpdate.color = RedAlertColor;
		}
	}
	public class PoolRoomsWaterBehaviour : MonoBehaviour
	{
		public static string BehaviorsVer = "5";

		public AudioSource SplashSound;

		public AudioSource WaterMovementSound;

		public ParticleSystem SplashParticles;

		public Vector3 LastPosition = Vector3.zero;

		public float NextSplashTime;

		public List<AudioClip> SplashSounds = new List<AudioClip>();

		private void Awake()
		{
			NextSplashTime = Time.unscaledTime;
			SplashSound.volume = 0f;
		}

		public AudioClip GetRandomSplashSound()
		{
			return SplashSounds[Random.Range(0, SplashSounds.Count)];
		}
	}
	public class PoolRoomsWaterTrigger : MonoBehaviour
	{
		public bool isWater;

		public int audioClipIndex;

		[Space(5f)]
		public bool sinkingLocalPlayer;

		public float movementHinderance = 1.6f;

		public float sinkingSpeedMultiplier = 0.15f;

		public Transform WaterSurface;

		public GameObject WaterBehaviourPrefab;

		private List<Transform> EnteredThingTransforms = new List<Transform>();

		private List<GameObject> WaterMovementsWeCreated = new List<GameObject>();

		private static string PoolRoomsWaterMovementTag = "PoolRoomsWaterMovement";

		private void OnDestroy()
		{
			foreach (GameObject item in WaterMovementsWeCreated)
			{
				if ((Object)(object)item != (Object)null)
				{
					Object.Destroy((Object)(object)item);
				}
			}
			WaterMovementsWeCreated.Clear();
		}

		public static PoolRoomsWaterBehaviour FindGameObjectChildWaterBehaviour(GameObject parent)
		{
			Transform transform = parent.transform;
			for (int i = 0; i < transform.childCount; i++)
			{
				PoolRoomsWaterBehaviour component = ((Component)transform.GetChild(i)).gameObject.GetComponent<PoolRoomsWaterBehaviour>();
				if (Object.op_Implicit((Object)(object)component))
				{
					return component;
				}
			}
			return null;
		}

		private static float FInterpTo(float Current, float Target, float DeltaTime, float InterpSpeed)
		{
			if (InterpSpeed <= 0f)
			{
				return Target;
			}
			float num = Target - Current;
			if (num * num < 1E-08f)
			{
				return Target;
			}
			float num2 = num * Mathf.Clamp(DeltaTime * InterpSpeed, 0f, 1f);
			return Current + num2;
		}

		private void Update()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			List<Transform> list = new List<Transform>();
			foreach (Transform enteredThingTransform in EnteredThingTransforms)
			{
				PoolRoomsWaterBehaviour poolRoomsWaterBehaviour = FindGameObjectChildWaterBehaviour(((Component)enteredThingTransform).gameObject);
				if (!((Object)(object)poolRoomsWaterBehaviour != (Object)null))
				{
					continue;
				}
				((Component)poolRoomsWaterBehaviour).transform.position = new Vector3(enteredThingTransform.position.x, WaterSurface.position.y, enteredThingTransform.position.z);
				bool flag = Mathf.Abs(WaterSurface.position.y - enteredThingTransform.position.y) > 1.1f;
				Vector3 val = poolRoomsWaterBehaviour.LastPosition - enteredThingTransform.position;
				float magnitude = ((Vector3)(ref val)).magnitude;
				if (magnitude > 5f)
				{
					list.Add(enteredThingTransform);
					continue;
				}
				bool flag2 = magnitude > 0.04f * Time.deltaTime;
				poolRoomsWaterBehaviour.LastPosition = enteredThingTransform.position;
				float volume = poolRoomsWaterBehaviour.WaterMovementSound.volume;
				volume = FInterpTo(volume, (!flag2) ? 0f : (flag ? 0.3f : 1f), Time.deltaTime, 2f);
				poolRoomsWaterBehaviour.WaterMovementSound.volume = volume;
				if (!flag2)
				{
					poolRoomsWaterBehaviour.NextSplashTime = Time.unscaledTime + 0.5f;
				}
				else if (poolRoomsWaterBehaviour.NextSplashTime <= Time.unscaledTime)
				{
					poolRoomsWaterBehaviour.NextSplashTime = Time.unscaledTime + ((magnitude > 0.1f) ? 0.3f : 0.5f);
					poolRoomsWaterBehaviour.SplashParticles.Play();
					poolRoomsWaterBehaviour.SplashSound.clip = poolRoomsWaterBehaviour.GetRandomSplashSound();
					poolRoomsWaterBehaviour.SplashSound.volume = ((magnitude > 0.1f) ? 0.15f : 0.05f);
					poolRoomsWaterBehaviour.SplashSound.Play();
				}
			}
			foreach (Transform item in list)
			{
				EnteredThingTransforms.Remove(item);
				PoolRoomsWaterBehaviour poolRoomsWaterBehaviour2 = FindGameObjectChildWaterBehaviour(((Component)item).gameObject);
				if ((Object)(object)poolRoomsWaterBehaviour2 != (Object)null)
				{
					poolRoomsWaterBehaviour2.WaterMovementSound.Stop();
					OnExit(((Component)item).gameObject.GetComponent<Collider>());
				}
			}
		}

		private void OnTriggerEnter(Collider other)
		{
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if (!isWater || !((Component)other).gameObject.CompareTag("Player"))
			{
				return;
			}
			PlayerControllerB component = ((Component)other).gameObject.GetComponent<PlayerControllerB>();
			if ((Object)(object)component != (Object)null)
			{
				EnteredThingTransforms.Add(((Component)component).transform);
				PoolRoomsWaterBehaviour poolRoomsWaterBehaviour = FindGameObjectChildWaterBehaviour(((Component)component).gameObject);
				if ((Object)(object)poolRoomsWaterBehaviour == (Object)null)
				{
					MonoBehaviour.print((object)"Creating new WaterBehaviourPrefab");
					GameObject obj = Object.Instantiate<GameObject>(WaterBehaviourPrefab, new Vector3(0f, 0f, 0f), Quaternion.Euler(-90f, 0f, 0f));
					obj.transform.parent = ((Component)component).transform;
					obj.transform.localPosition = Vector3.zero;
					obj.transform.localRotation = Quaternion.Euler(-90f, 0f, 0f);
					poolRoomsWaterBehaviour = obj.GetComponent<PoolRoomsWaterBehaviour>();
				}
				poolRoomsWaterBehaviour.LastPosition = ((Component)component).transform.position;
				poolRoomsWaterBehaviour.WaterMovementSound.Play();
				poolRoomsWaterBehaviour.WaterMovementSound.volume = 0f;
			}
		}

		private void OnTriggerExit(Collider other)
		{
			OnExit(other);
			if (!isWater || !((Component)other).gameObject.CompareTag("Player"))
			{
				return;
			}
			PlayerControllerB component = ((Component)other).gameObject.GetComponent<PlayerControllerB>();
			if ((Object)(object)component != (Object)null)
			{
				EnteredThingTransforms.Remove(((Component)component).transform);
				PoolRoomsWaterBehaviour poolRoomsWaterBehaviour = FindGameObjectChildWaterBehaviour(((Component)component).gameObject);
				if ((Object)(object)poolRoomsWaterBehaviour != (Object)null)
				{
					poolRoomsWaterBehaviour.WaterMovementSound.Stop();
				}
			}
		}

		public void OnLocalPlayerTeleported(PlayerControllerB player)
		{
			if ((Object)(object)player != (Object)null)
			{
				EnteredThingTransforms.Remove(((Component)player).transform);
				PoolRoomsWaterBehaviour poolRoomsWaterBehaviour = FindGameObjectChildWaterBehaviour(((Component)player).gameObject);
				if ((Object)(object)poolRoomsWaterBehaviour != (Object)null)
				{
					poolRoomsWaterBehaviour.WaterMovementSound.Stop();
				}
				OnExit(((Component)player).gameObject.GetComponent<Collider>());
			}
		}

		private void OnTriggerStay(Collider other)
		{
			if (isWater)
			{
				if (!((Component)other).gameObject.CompareTag("Player"))
				{
					return;
				}
				PlayerControllerB component = ((Component)other).gameObject.GetComponent<PlayerControllerB>();
				if ((Object)(object)component != (Object)(object)GameNetworkManager.Instance.localPlayerController && (Object)(object)component != (Object)null && (Object)(object)component.underwaterCollider != (Object)(object)this)
				{
					component.underwaterCollider = ((Component)this).gameObject.GetComponent<Collider>();
					return;
				}
			}
			if (GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom || (!isWater && !((Component)other).gameObject.CompareTag("Player")))
			{
				return;
			}
			PlayerControllerB component2 = ((Component)other).gameObject.GetComponent<PlayerControllerB>();
			if ((Object)(object)component2 != (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				return;
			}
			if (isWater && !component2.isUnderwater)
			{
				component2.underwaterCollider = ((Component)this).gameObject.GetComponent<Collider>();
				component2.isUnderwater = true;
			}
			component2.statusEffectAudioIndex = audioClipIndex;
			if (component2.isUnderwater)
			{
				component2.statusEffectAudio.volume = component2.statusEffectAudio.volume * 0.25f;
			}
			if (component2.isSinking)
			{
				return;
			}
			if (sinkingLocalPlayer)
			{
				if (!component2.CheckConditionsForSinkingInQuicksand())
				{
					StopSinkingLocalPlayer(component2);
				}
			}
			else if (component2.CheckConditionsForSinkingInQuicksand())
			{
				sinkingLocalPlayer = true;
				component2.sourcesCausingSinking++;
				component2.isMovementHindered++;
				component2.hinderedMultiplier *= movementHinderance;
				if (isWater)
				{
					component2.sinkingSpeedMultiplier = 0f;
				}
				else
				{
					component2.sinkingSpeedMultiplier = sinkingSpeedMultiplier;
				}
			}
		}

		public void OnExit(Collider other)
		{
			if (!sinkingLocalPlayer)
			{
				if (isWater && ((Component)other).CompareTag("Player") && !((Object)(object)((Component)other).gameObject.GetComponent<PlayerControllerB>() == (Object)(object)GameNetworkManager.Instance.localPlayerController))
				{
					((Component)other).gameObject.GetComponent<PlayerControllerB>().isUnderwater = false;
				}
			}
			else if (((Component)other).CompareTag("Player"))
			{
				PlayerControllerB component = ((Component)other).gameObject.GetComponent<PlayerControllerB>();
				if (!((Object)(object)component != (Object)(object)GameNetworkManager.Instance.localPlayerController))
				{
					StopSinkingLocalPlayer(component);
				}
			}
		}

		public void StopSinkingLocalPlayer(PlayerControllerB playerScript)
		{
			if (sinkingLocalPlayer)
			{
				sinkingLocalPlayer = false;
				playerScript.sourcesCausingSinking = Mathf.Clamp(playerScript.sourcesCausingSinking - 1, 0, 100);
				playerScript.isMovementHindered = Mathf.Clamp(playerScript.isMovementHindered - 1, 0, 100);
				playerScript.hinderedMultiplier = Mathf.Clamp(playerScript.hinderedMultiplier / movementHinderance, 1f, 100f);
				if (playerScript.isMovementHindered == 0 && isWater)
				{
					playerScript.isUnderwater = false;
				}
			}
		}
	}
}
namespace PoolRoomsBehaviours.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}