Decompiled source of Do We Need To Go Deeper v1.5.0

Index154.DoWeNeedToGoDeeper.dll

Decompiled 2 months 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.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalNetworkAPI;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[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("Index154.DoWeNeedToGoDeeper")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.5.0.0")]
[assembly: AssemblyInformationalVersion("1.5.0+a1231a968ad287e8bfafef6ec189385d136c0b05")]
[assembly: AssemblyProduct("DoWeNeedToGoDeeper")]
[assembly: AssemblyTitle("Index154.DoWeNeedToGoDeeper")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.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 DoWeNeedToGoDeeper
{
	public class ConfigManager
	{
		internal ConfigEntry<int> lockedChance = null;

		internal ConfigEntry<string> customLockedChances = null;

		internal Dictionary<string, int> customLockedChancesDict = null;

		internal ConfigEntry<int> dynamicChance = null;

		internal ConfigEntry<string> customDynamicChances = null;

		internal Dictionary<string, int> customDynamicChancesDict = null;

		internal ConfigEntry<int> reverseChance = null;

		internal ConfigEntry<string> customReverseChances = null;

		internal Dictionary<string, int> customReverseChancesDict = null;

		internal ConfigEntry<bool> allowExitIfLastOneAlive = null;

		internal ConfigEntry<int> earlyGameGracePeriod = null;

		internal ConfigEntry<bool> disableIfFlooded = null;

		internal ConfigEntry<bool> disableIfApparatusTaken = null;

		internal ConfigEntry<bool> disableIfBreakerBoxDisabled = null;

		internal ConfigEntry<bool> postChatAlert = null;

		internal ConfigEntry<bool> popupAlert = null;

		internal void Setup(ConfigFile configFile)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			lockedChance = configFile.Bind<int>("1. Entrance control activation", "Global activation chance", 20, new ConfigDescription("Default percentage chance for the entrance control systems to activate on any given day. Will make it so by default everyone can only enter through the main entrance and leave through the fire exits. The other modes will override this behavior", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			customLockedChances = configFile.Bind<string>("1. Entrance control activation", "Custom activation chances per moon", "", new ConfigDescription("Comma-separated list of moons with custom entrance control activation chances. Example: 'Titan:0,Vow:25,March:90,Dine:5,Gratar:100'. This will override the global chance for the selected moons. Modded moons should also work", (AcceptableValueBase)null, Array.Empty<object>()));
			dynamicChance = configFile.Bind<int>("2. Dynamic mode", "Global dynamic mode chance", 50, new ConfigDescription("Default percentage chance for dynamic mode to activate on any given day where the entrance control systems have already been activated. Will make it so everyone can enter using any door. Each player can then only exit through the type of door they did not enter through. If you teleport into the facility then you can use any door to leave. This mode will take priority over corruption mode", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			customDynamicChances = configFile.Bind<string>("2. Dynamic mode", "Custom dynamic mode chances per moon", "", new ConfigDescription("Comma-separated list of moons with custom dynamic mode chances. Example: 'Titan:0,Vow:25,March:90,Dine:5,Gratar:100'. Modded moons should also work", (AcceptableValueBase)null, Array.Empty<object>()));
			reverseChance = configFile.Bind<int>("3. Corruption mode", "Global corruption chance", 10, new ConfigDescription("Default percentage chance for corruption mode to activate on any given day where the entrance control systems have already been activated. Will make it so everyone can only enter through a fire exit and leave through the main entrance, basically reversing the default behavior", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			customReverseChances = configFile.Bind<string>("3. Corruption mode", "Custom corruption chances per moon", "", new ConfigDescription("Comma-separated list of moons with custom corruption chances. Example: 'Titan:0,Vow:25,March:90,Dine:5,Gratar:100'. This will override the global chance for the selected moons. Modded moons should also work", (AcceptableValueBase)null, Array.Empty<object>()));
			allowExitIfLastOneAlive = configFile.Bind<bool>("4. Other", "Allow exit if last one alive", false, "If true, the last player alive is always able to leave using any door");
			earlyGameGracePeriod = configFile.Bind<int>("4. Other", "Early game grace period", 0, "The amount of days, if any, on a fresh save file where the entrance controls should not be able to activate at all, no matter what their chances are. Useful for preventing early softlocks when you have no keys yet");
			disableIfFlooded = configFile.Bind<bool>("4. Other", "Disable entrance controls on flooded moons", false, "If true, prevents entrance controls from activating if the weather is flooded");
			disableIfApparatusTaken = configFile.Bind<bool>("4. Other", "Disable entrance controls after Apparatus is grabbed", false, "If true, everyone can exit and enter using any door after the Apparatus is taken by a player");
			disableIfBreakerBoxDisabled = configFile.Bind<bool>("4. Other", "Disable entrance controls while the breaker box is turned off", false, "If true, everyone can exit and enter using any door while power in the facility is turned off through the breaker box (or if the moon started with the power turned off)");
			postChatAlert = configFile.Bind<bool>("4. Other", "Send status alert in chat", false, "Whether a chat message should be sent when the entrance controls are active (in addition to the alert popup). Can be useful because it doesn't disappear unlike the alert box");
			popupAlert = configFile.Bind<bool>("4. Other", "Enable warning popups", true, "Whether a popup alert should appear when landing on a moon that has entrance controls enabled");
			customLockedChancesDict = StrToDict(customLockedChances.Value);
			customReverseChancesDict = StrToDict(customReverseChances.Value);
			customDynamicChancesDict = StrToDict(customDynamicChances.Value);
			static Dictionary<string, int> StrToDict(string list)
			{
				Dictionary<string, int> dictionary = new Dictionary<string, int>();
				string[] array = list.ToLowerInvariant().Split(",");
				foreach (string text in array)
				{
					string[] array2 = text.Split(":");
					if (array2.Length > 1)
					{
						int num = 0;
						try
						{
							num = int.Parse(array2[1]);
						}
						finally
						{
							if (num < 0)
							{
								num = 0;
							}
							if (num > 100)
							{
								num = 100;
							}
							if (!dictionary.ContainsKey(array2[0]))
							{
								dictionary.Add(array2[0], num);
							}
						}
					}
				}
				return dictionary;
			}
		}
	}
	internal class DoorString : MonoBehaviour
	{
		public string lastUsedDoor = "";
	}
	[BepInPlugin("Index154.DoWeNeedToGoDeeper", "DoWeNeedToGoDeeper", "1.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class DoWeNeedToGoDeeper : BaseUnityPlugin
	{
		internal static ConfigManager configManager = null;

		public static LethalNetworkVariable<bool> locked = new LethalNetworkVariable<bool>("DWNTGDlocked");

		public static LethalNetworkVariable<bool> dynamicMode = new LethalNetworkVariable<bool>("DWNTGDdynamicMode");

		public static LethalNetworkVariable<bool> reverseMode = new LethalNetworkVariable<bool>("DWNTGDreverseMode");

		public static LethalNetworkVariable<bool> breakerOff = new LethalNetworkVariable<bool>("DWNTGDbreakerOff");

		public static DoWeNeedToGoDeeper Instance { get; private set; } = null;


		internal static ManualLogSource Logger { get; private set; } = null;


		internal static Harmony? Harmony { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			configManager = new ConfigManager();
			configManager.Setup(((BaseUnityPlugin)this).Config);
			Patch();
			Logger.LogInfo((object)"DoWeNeedToGoDeeper v1.5.0 has loaded!");
		}

		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("Index154.DoWeNeedToGoDeeper");
			}
			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 ExitChecker
	{
		public static bool IsLastAlive()
		{
			int num = StartOfRound.Instance.allPlayerScripts.Count((PlayerControllerB playerScript) => !playerScript.isPlayerDead && playerScript.isPlayerControlled);
			if (num > 1)
			{
				return false;
			}
			return true;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Index154.DoWeNeedToGoDeeper";

		public const string PLUGIN_NAME = "DoWeNeedToGoDeeper";

		public const string PLUGIN_VERSION = "1.5.0";
	}
}
namespace DoWeNeedToGoDeeper.Patches
{
	[HarmonyPatch(typeof(LungProp))]
	public class ApparaticePatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("EquipItem")]
		internal static void turnOffLockedMode(LungProp __instance, ref bool ___isLungDocked)
		{
			if (((NetworkBehaviour)__instance).IsHost && ___isLungDocked && DoWeNeedToGoDeeper.configManager.disableIfApparatusTaken.Value)
			{
				DoWeNeedToGoDeeper.locked.Value = false;
			}
		}
	}
	[HarmonyPatch(typeof(HUDManager))]
	public class HUDManagerPatch
	{
		[HarmonyPatch("HoldInteractionFill")]
		[HarmonyPostfix]
		private static void DestroyEntranceExitAbility(ref bool __result)
		{
			if (!__result || !DoWeNeedToGoDeeper.locked.Value || (DoWeNeedToGoDeeper.configManager.disableIfBreakerBoxDisabled.Value && DoWeNeedToGoDeeper.breakerOff.Value))
			{
				return;
			}
			PlayerControllerB localPlayerController = HUDManager.Instance.playersManager.localPlayerController;
			DoorString component = ((Component)localPlayerController).gameObject.GetComponent<DoorString>();
			InteractTrigger hoveringOverTrigger = localPlayerController.hoveringOverTrigger;
			if ((Object)(object)hoveringOverTrigger == (Object)null)
			{
				return;
			}
			EntranceTeleport component2 = ((Component)hoveringOverTrigger).gameObject.GetComponent<EntranceTeleport>();
			if ((Object)(object)component2 == (Object)null)
			{
				return;
			}
			string text = "leave";
			string text2 = "fire exit";
			string text3 = "Passage restricted. ";
			bool flag = false;
			if (component2.entranceId == 0)
			{
				if (component2.isEntranceToBuilding)
				{
					text = "enter";
					if (DoWeNeedToGoDeeper.reverseMode.Value)
					{
						flag = true;
						text3 = "PAss<ge rrestrc?! .Ex%Enter--";
						text2 += "?.";
					}
				}
				else
				{
					flag = true;
					if (DoWeNeedToGoDeeper.reverseMode.Value)
					{
						return;
					}
				}
			}
			else
			{
				text2 = "main entrance";
				if (component2.isEntranceToBuilding)
				{
					text = "enter";
					flag = true;
					if (DoWeNeedToGoDeeper.reverseMode.Value)
					{
						return;
					}
				}
				else if (DoWeNeedToGoDeeper.reverseMode.Value)
				{
					flag = true;
					text3 = "PAssa ge rrestrc?! .Ex%Enter--";
					text2 += "?.";
				}
			}
			if (DoWeNeedToGoDeeper.dynamicMode.Value)
			{
				flag = false;
				if (text == "enter")
				{
					if (component2.entranceId == 0)
					{
						component.lastUsedDoor = "main";
					}
					else
					{
						component.lastUsedDoor = "exit";
					}
				}
				else if (component2.entranceId == 0)
				{
					if (component.lastUsedDoor == "main")
					{
						flag = true;
						text2 = "fire exit";
					}
					else
					{
						component.lastUsedDoor = "";
					}
				}
				else if (component.lastUsedDoor == "exit")
				{
					flag = true;
					text2 = "main entrance";
				}
				else
				{
					component.lastUsedDoor = "";
				}
			}
			if (!(text == "leave") || !ExitChecker.IsLastAlive() || !DoWeNeedToGoDeeper.configManager.allowExitIfLastOneAlive.Value)
			{
				string text4 = text3 + "Please " + text + " using a designated " + text2;
				if (flag)
				{
					__result = false;
					hoveringOverTrigger.currentCooldownValue = 1f;
					HUDManager.Instance.DisplayTip("Entrance control", text4, false, false, "LC_Tip1");
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	public class PlayerControllerBPatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void AddDoorValue(PlayerControllerB __instance)
		{
			DoorString doorString = ((Component)__instance).gameObject.AddComponent<DoorString>();
		}

		[HarmonyPatch("KillPlayer")]
		[HarmonyPostfix]
		private static void ResetDoorValueOnDeath(PlayerControllerB __instance)
		{
			if (__instance.isPlayerDead)
			{
				DoorString component = ((Component)__instance).gameObject.GetComponent<DoorString>();
				component.lastUsedDoor = "";
			}
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	internal class RoundManagerPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("LoadNewLevel")]
		public static void RollForLocking(int randomSeed, SelectableLevel newLevel, RoundManager __instance)
		{
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Invalid comparison between Unknown and I4
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Invalid comparison between Unknown and I4
			int value = DoWeNeedToGoDeeper.configManager.lockedChance.Value;
			int value2 = DoWeNeedToGoDeeper.configManager.reverseChance.Value;
			int value3 = DoWeNeedToGoDeeper.configManager.dynamicChance.Value;
			foreach (KeyValuePair<string, int> item in DoWeNeedToGoDeeper.configManager.customLockedChancesDict)
			{
				if (item.Key != "" && ((Object)StartOfRound.Instance.currentLevel).name.ToLowerInvariant().Contains(item.Key))
				{
					value = item.Value;
				}
			}
			foreach (KeyValuePair<string, int> item2 in DoWeNeedToGoDeeper.configManager.customDynamicChancesDict)
			{
				if (item2.Key != "" && ((Object)StartOfRound.Instance.currentLevel).name.ToLowerInvariant().Contains(item2.Key))
				{
					value3 = item2.Value;
				}
			}
			foreach (KeyValuePair<string, int> item3 in DoWeNeedToGoDeeper.configManager.customReverseChancesDict)
			{
				if (item3.Key != "" && ((Object)StartOfRound.Instance.currentLevel).name.ToLowerInvariant().Contains(item3.Key))
				{
					value2 = item3.Value;
				}
			}
			DoWeNeedToGoDeeper.Logger.LogDebug((object)("LevelName = " + ((Object)StartOfRound.Instance.currentLevel).name));
			DoWeNeedToGoDeeper.Logger.LogDebug((object)("LockChance = " + value));
			DoWeNeedToGoDeeper.Logger.LogDebug((object)("ReverseChance = " + value2));
			DoWeNeedToGoDeeper.Logger.LogDebug((object)("DynamicChance = " + value3));
			DoWeNeedToGoDeeper.Logger.LogDebug((object)("Flooded = " + ((int)StartOfRound.Instance.currentLevel.currentWeather == 4)));
			DoWeNeedToGoDeeper.Logger.LogDebug((object)("Days spent = " + StartOfRound.Instance.gameStats.daysSpent));
			int num = Random.Range(1, 101);
			if (DoWeNeedToGoDeeper.configManager.disableIfFlooded.Value && (int)StartOfRound.Instance.currentLevel.currentWeather == 4)
			{
				num = 200;
			}
			if (StartOfRound.Instance.gameStats.daysSpent < DoWeNeedToGoDeeper.configManager.earlyGameGracePeriod.Value)
			{
				num = 200;
			}
			if (((Object)StartOfRound.Instance.currentLevel).name.ToLowerInvariant().Contains("company"))
			{
				num = 200;
			}
			DoWeNeedToGoDeeper.Logger.LogDebug((object)("Locking roll = " + num));
			if (num <= value)
			{
				DoWeNeedToGoDeeper.locked.Value = true;
				DoWeNeedToGoDeeper.Logger.LogDebug((object)"Lock applied!");
				int num2 = Random.Range(1, 101);
				string text = "<color=green>Entrance control systems detected!</color>";
				if (num2 <= value3)
				{
					DoWeNeedToGoDeeper.reverseMode.Value = false;
					DoWeNeedToGoDeeper.dynamicMode.Value = true;
					text = "<color=yellow>Dynamic entrance control systems detected!</color>";
				}
				else if (num2 <= value3 + value2)
				{
					DoWeNeedToGoDeeper.reverseMode.Value = true;
					DoWeNeedToGoDeeper.dynamicMode.Value = false;
					text = "<color=red>Corrupted entrance control systems detected!</color>";
				}
				else
				{
					DoWeNeedToGoDeeper.reverseMode.Value = false;
					DoWeNeedToGoDeeper.dynamicMode.Value = false;
				}
				if (DoWeNeedToGoDeeper.configManager.postChatAlert.Value)
				{
					HUDManager.Instance.AddTextToChatOnServer(text, -1);
				}
			}
			else
			{
				DoWeNeedToGoDeeper.locked.Value = false;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("SwitchPower")]
		public static void TrackBreakerState(bool on)
		{
			if (DoWeNeedToGoDeeper.locked.Value && DoWeNeedToGoDeeper.configManager.disableIfBreakerBoxDisabled.Value)
			{
				if (on)
				{
					DoWeNeedToGoDeeper.breakerOff.Value = false;
				}
				else
				{
					DoWeNeedToGoDeeper.breakerOff.Value = true;
				}
			}
		}
	}
	[HarmonyPatch(typeof(ShipTeleporter))]
	public class ShipTeleporterPatch
	{
		[HarmonyPatch("SetPlayerTeleporterId")]
		[HarmonyPostfix]
		private static void ResetDoorValueOnBeamUp(PlayerControllerB playerScript, int teleporterId)
		{
			if (!playerScript.isInsideFactory && teleporterId == -1)
			{
				DoorString component = ((Component)playerScript).gameObject.GetComponent<DoorString>();
				component.lastUsedDoor = "";
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartOfRoundPatches
	{
		private static IEnumerator DelayedTip(float delay, string text)
		{
			yield return (object)new WaitForSeconds(delay);
			HUDManager.Instance.DisplayTip("Warning", text, true, false, "LC_Tip1");
		}

		[HarmonyPostfix]
		[HarmonyPatch("ResetStats")]
		public static void DisplayLockedAlert()
		{
			if (DoWeNeedToGoDeeper.locked.Value && DoWeNeedToGoDeeper.configManager.popupAlert.Value)
			{
				string text = "Entrance control systems detected!\n(Main -> Fire)";
				if (DoWeNeedToGoDeeper.dynamicMode.Value)
				{
					text = "Dynamic entrance control systems detected!\n(Any -> Opposite)";
				}
				else if (DoWeNeedToGoDeeper.reverseMode.Value)
				{
					text = "Corrupted entrance control systems detected!\n(Fire -> Main)";
				}
				HUDManager.Instance.DisplayTip("Warning", text, true, false, "LC_Tip1");
			}
		}
	}
}