Decompiled source of ShivrerCompany v1.1.2

ShivrerCompany.dll

Decompiled 9 months ago
using System;
using System.Collections;
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 HarmonyLib;
using Microsoft.CodeAnalysis;
using ShivrerCompany.patches;
using ShivrerCompany.util;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;

[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("ShivrerCompany")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("a Lethal Company mod for vtuber streamer Shivrer and her kitty cat posse")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+fac08c82534d497df098c461d70cb8f28d78744c")]
[assembly: AssemblyProduct("ShivrerCompany")]
[assembly: AssemblyTitle("ShivrerCompany")]
[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 ShivrerCompany
{
	[BepInPlugin("ShivrerCompany", "ShivrerCompany", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public static Plugin instance;

		private readonly Harmony harmony = new Harmony("ShivrerCompany");

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			Log("Shivrer is munching on the Lethal Company code...");
			TextureUtil.LoadTexturePaths();
			harmony.PatchAll(typeof(Plugin));
			harmony.PatchAll(typeof(RoundManagerPatch));
			harmony.PatchAll(typeof(TerminalPatch));
			harmony.PatchAll(typeof(WalkieTalkiePatch));
			harmony.PatchAll(typeof(FlashlightItemPatch));
			harmony.PatchAll(typeof(GrabbableObjectPatch));
			harmony.PatchAll(typeof(EnemyAIPatch));
			Log("Plugin ShivrerCompany is loaded! <3");
		}

		public void Log(string message)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)message);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "ShivrerCompany";

		public const string PLUGIN_NAME = "ShivrerCompany";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace ShivrerCompany.util
{
	internal class EnemyUtil
	{
		public static void SpawnEnemyFromVent(EnemyVent vent, string query)
		{
			RoundManager instance = RoundManager.Instance;
			for (int i = 0; i < instance.currentLevel.Enemies.Count; i++)
			{
				SpawnableEnemyWithRarity val = instance.currentLevel.Enemies[i];
				if (val.enemyType.enemyName.Contains(query, StringComparison.OrdinalIgnoreCase))
				{
					Plugin.instance.Log("Spawning enemy [" + val.enemyType.enemyName + "] from a vent!");
					SpawnEnemyFromVent(vent, i);
				}
			}
		}

		public static void SpawnEnemyFromVent(EnemyVent vent, int enemyType)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = vent.floorNode.position;
			float y = vent.floorNode.eulerAngles.y;
			RoundManager.Instance.SpawnEnemyOnServer(position, y, enemyType);
			vent.OpenVentClientRpc();
			vent.occupied = false;
		}
	}
	internal class ItemUtil
	{
		public static void ApplyCustomItemChanges(ref Terminal terminal, List<Item> itemsList)
		{
		}

		public static void UpdateItemIcon(Item item, string iconPath)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			Plugin.instance.Log("Updating Item Icon for [" + item.itemName + "]");
			Texture2D val = TextureUtil.LoadTexture(iconPath);
			Sprite itemIcon = Sprite.Create(new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 256f, val);
			item.itemIcon = itemIcon;
			Plugin.instance.Log("Applied Texture [" + ((object)val)?.ToString() + "]");
		}

		public static void TryAddBuyableItem(ref Terminal __instance, Item item)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			Plugin.instance.Log("Trying to add a new item to the Terminal!");
			if (!((Object)(object)item == (Object)null))
			{
				Item[] buyableItemsList = __instance.buyableItemsList;
				List<Item> list = new List<Item>(buyableItemsList.Length);
				Item[] array = buyableItemsList;
				foreach (Item item2 in array)
				{
					list.Add(item2);
				}
				List<Item> list2 = list;
				list2.Add(item);
				TerminalKeyword val = new TerminalKeyword();
				val.word = item.itemName;
				AddKeyword(ref __instance.terminalNodes, val);
				Plugin.instance.Log("Added [" + ((Object)item).name + "] to the buyable items list.");
				__instance.buyableItemsList = list2.ToArray();
			}
		}

		public static int GetBuyableIdByName(ref Terminal __instance, List<Item> allItems, string name)
		{
			Item val = TryGetItemByName(allItems, name);
			if ((Object)(object)val == (Object)null)
			{
				return -1;
			}
			for (int i = 0; i < __instance.buyableItemsList.Length; i++)
			{
				if (((object)__instance.buyableItemsList[i]).Equals((object?)val))
				{
					return i;
				}
			}
			return -1;
		}

		public static Item TryGetItemByName(List<Item> allItems, string query)
		{
			Plugin.instance.Log("Searching for item [" + query + "]...");
			foreach (Item allItem in allItems)
			{
				if (allItem.itemName.Contains(query, StringComparison.OrdinalIgnoreCase))
				{
					return allItem;
				}
			}
			Plugin.instance.Log("WARNING: Couldn't find item with name [" + query + "]!");
			return null;
		}

		public static void AddKeyword(ref TerminalNodesList nodes, TerminalKeyword keyword)
		{
			TerminalKeyword[] allKeywords = nodes.allKeywords;
			List<TerminalKeyword> list = new List<TerminalKeyword>(allKeywords.Length);
			TerminalKeyword[] array = allKeywords;
			foreach (TerminalKeyword item in array)
			{
				list.Add(item);
			}
			List<TerminalKeyword> list2 = list;
			list2.Add(keyword);
			nodes.allKeywords = list2.ToArray();
		}

		public static void AddTerminalItem(TerminalNodesList nodes, string name, int cost, int index)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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)
			new TerminalNode
			{
				displayText = "ShivBucks",
				itemCost = cost,
				buyItemIndex = index
			};
			Plugin.instance.Log("Terminal Item Added [" + name + "]");
		}
	}
	internal class TaskUtil
	{
		public static void RunTaskLater(MonoBehaviour taskOwner, UnityAction action, float delay)
		{
			taskOwner.StartCoroutine(RunTaskLater(action, delay));
		}

		private static IEnumerator RunTaskLater(UnityAction action, float delay)
		{
			float t = delay;
			while (t > 0f)
			{
				t -= Time.deltaTime;
				yield return null;
			}
			action.Invoke();
		}
	}
	internal class TextureUtil
	{
		public static string SANDSPIDER_TEX;

		public static string NUTCRACKER_TEX;

		public static string WALKIETALKIE_TEX;

		public static string WALKIETALKIE_SCREEN_TEX;

		public static string WALKIETALKIE_ICON;

		public static string FLASHLIGHT_TEX;

		public static string FLASHLIGHT_ICON;

		public static string TINY_FLASHLIGHT_TEX;

		public static string TINY_FLASHLIGHT_ICON;

		public static string GIFTBOX_TEX;

		public static string GIFTBOX_ICON;

		public static string AIRHORN_TEX;

		public static string SODACAN_TEX;

		public static string STOPSIGN_TEX;

		public static string YIELDSIGN_TEX;

		public static string FLOORVINYL_ALBEDO;

		public static string GALVANIZEDSTEEL_ALBEDO;

		public static string BUNKBEDS_TEX;

		public static string COMPUTER_TERMINAL_TEX;

		public static string CONTROL_PANEL_B_TEX;

		public static string KEYBOARD_TEX;

		public static string TIPSPOSTER_TEX;

		public static string POSTERS_TEX;

		private static Dictionary<string, Texture2D> LOADED_TEXTURES = new Dictionary<string, Texture2D>();

		public static void LoadTexturePaths()
		{
			List<string> list = new List<string>();
			AddFilePaths(list, Paths.PluginPath);
			AddFilePaths(list, Path.Combine(Paths.PluginPath, "SuperSuccubus-ShivrerCompany"));
			AddFilePaths(list, Path.Combine(Paths.PluginPath, "SuperSuccubus-ShivrerCompany", "ShivrerAssets"));
			SANDSPIDER_TEX = FindTextureInFiles(list, "SandSpiderTex");
			NUTCRACKER_TEX = FindTextureInFiles(list, "NutcrackerTex");
			WALKIETALKIE_TEX = FindTextureInFiles(list, "WalkieTalkieTex");
			WALKIETALKIE_SCREEN_TEX = FindTextureInFiles(list, "WalkieTalkieScreenEmission");
			WALKIETALKIE_ICON = FindTextureInFiles(list, "WalkieTalkieIcon");
			FLASHLIGHT_TEX = FindTextureInFiles(list, "FlashlightTexture");
			FLASHLIGHT_ICON = FindTextureInFiles(list, "FlashlightIcon");
			TINY_FLASHLIGHT_TEX = FindTextureInFiles(list, "TinyFlashlightTex");
			TINY_FLASHLIGHT_ICON = FindTextureInFiles(list, "TinyFlashlightIcon");
			GIFTBOX_TEX = FindTextureInFiles(list, "GiftBoxTex");
			GIFTBOX_ICON = FindTextureInFiles(list, "GiftBoxIcon");
			AIRHORN_TEX = FindTextureInFiles(list, "AirhornTex");
			SODACAN_TEX = FindTextureInFiles(list, "SodaCanTex1");
			STOPSIGN_TEX = FindTextureInFiles(list, "StopSignTex");
			YIELDSIGN_TEX = FindTextureInFiles(list, "YieldSignTex");
			FLOORVINYL_ALBEDO = FindTextureInFiles(list, "FloorVinylAlbedo");
			GALVANIZEDSTEEL_ALBEDO = FindTextureInFiles(list, "GalvanizedSteelAlbedo");
			BUNKBEDS_TEX = FindTextureInFiles(list, "BunkBedsTex");
			COMPUTER_TERMINAL_TEX = FindTextureInFiles(list, "ComputerTerminalTexture");
			CONTROL_PANEL_B_TEX = FindTextureInFiles(list, "ControlPanelB");
			KEYBOARD_TEX = FindTextureInFiles(list, "KeyboardTex");
			TIPSPOSTER_TEX = FindTextureInFiles(list, "TipsPoster2");
			POSTERS_TEX = FindTextureInFiles(list, "posters");
			Plugin.instance.Log("All required textures have been loaded! <3");
		}

		private static void AddFilePaths(List<string> files, string path)
		{
			try
			{
				Plugin.instance.Log("Searching for files in [" + path + "]");
				files.AddRange(Directory.GetFiles(path));
			}
			catch (DirectoryNotFoundException)
			{
			}
		}

		public static string FindTextureInFiles(List<string> allfiles, string query)
		{
			foreach (string allfile in allfiles)
			{
				if (allfile.Split('\\')[^1].Equals(query + ".png", StringComparison.OrdinalIgnoreCase))
				{
					Plugin.instance.Log("Found " + query + " at [" + allfile + "]");
					return allfile;
				}
			}
			Plugin.instance.Log("WARNING: Couldn't find file with name [" + query + "]");
			return "ERROR";
		}

		public static Texture2D LoadTexture(string path)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			Texture2D value = null;
			if (LOADED_TEXTURES.TryGetValue(path, out value))
			{
				return value;
			}
			value = new Texture2D(2, 2);
			ImageConversion.LoadImage(value, File.ReadAllBytes(path));
			LOADED_TEXTURES.Add(path, value);
			return value;
		}
	}
}
namespace ShivrerCompany.patches
{
	[HarmonyPatch(typeof(EnemyAI))]
	internal class EnemyAIPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void PatchEnemy(EnemyAI __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				SkinnedMeshRenderer[] skinnedMeshRenderers = __instance.skinnedMeshRenderers;
				foreach (SkinnedMeshRenderer r in skinnedMeshRenderers)
				{
					ReplaceTexturesInRenderer(__instance, r);
				}
			}
		}

		private static void ReplaceTexturesInRenderer(EnemyAI enemy, SkinnedMeshRenderer r)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			DebugTextures(enemy, ((Object)((Component)r).gameObject).name, ((Renderer)r).materials);
			if (!((Object)(object)((Renderer)r).sharedMaterial == (Object)null))
			{
				string text = (((Object)(object)((Renderer)r).sharedMaterial.mainTexture != (Object)null) ? ((Object)((Renderer)r).sharedMaterial.mainTexture).name : "NULL");
				Plugin.instance.Log("Seeking Replacement for Enemy Texture [" + text + "]...");
				Texture2D replacementTexture = GetReplacementTexture(text);
				if ((Object)(object)replacementTexture != (Object)null)
				{
					((Renderer)r).sharedMaterial.color = Color.white;
					((Renderer)r).sharedMaterial.mainTexture = (Texture)(object)replacementTexture;
					Plugin.instance.Log("Replaced Enemy Texture [" + ((Object)enemy).name + "] with [" + ((Object)replacementTexture).name + "]");
				}
			}
		}

		private static Texture2D GetReplacementTexture(string enemyTextureName)
		{
			if (enemyTextureName.Contains("spider", StringComparison.OrdinalIgnoreCase))
			{
				return TextureUtil.LoadTexture(TextureUtil.SANDSPIDER_TEX);
			}
			if (enemyTextureName.Contains("nutcracker", StringComparison.OrdinalIgnoreCase))
			{
				return TextureUtil.LoadTexture(TextureUtil.NUTCRACKER_TEX);
			}
			return null;
		}

		private static void DebugTextures(EnemyAI enemy, string part, Material[] materials)
		{
			for (int i = 0; i < materials.Length; i++)
			{
				string text = (((Object)(object)materials[i] == (Object)null) ? "NULL MAT" : (((Object)(object)materials[i].mainTexture != (Object)null) ? ((Object)materials[i].mainTexture).name : "NULL TEX"));
				string text2 = (((Object)(object)enemy.enemyType != (Object)null) ? enemy.enemyType.enemyName : "NULL");
				Plugin.instance.Log("Item [" + text2 + "] - GameObject:" + part + " has " + materials.Length + " slots. Slot " + i + " contains [" + text + "]");
			}
		}
	}
	[HarmonyPatch(typeof(FlashlightItem))]
	internal class FlashlightItemPatch
	{
		[HarmonyPatch("SwitchFlashlight")]
		[HarmonyPostfix]
		private static void SwitchFlashlightPatch(bool on, FlashlightItem __instance)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			Plugin.instance.Log("flashlight");
			if (on)
			{
				Plugin.instance.Log("its on");
				__instance.bulbLight.color = new Color(1f, 0.7058824f, 38f / 51f);
				__instance.flashlightBulbGlow.color = new Color(1f, 0.7058824f, 38f / 51f);
				((GrabbableObject)__instance).playerHeldBy.helmetLight.color = new Color(1f, 0.7058824f, 38f / 51f);
			}
		}
	}
	[HarmonyPatch(typeof(GrabbableObject))]
	internal class GrabbableObjectPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void PatchGrabbableObject(GrabbableObject __instance)
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.itemProperties == (Object)null)
			{
				return;
			}
			if ((Object)(object)__instance.mainObjectRenderer != (Object)null)
			{
				ReplaceTexturesInRenderer(__instance, __instance.mainObjectRenderer);
				return;
			}
			MeshRenderer[] componentsInChildren = ((Component)((Component)__instance).transform.parent).GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer r in componentsInChildren)
			{
				ReplaceTexturesInRenderer(__instance, r);
			}
		}

		private static void ReplaceTexturesInRenderer(GrabbableObject item, MeshRenderer r)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)((Renderer)r).sharedMaterial == (Object)null))
			{
				Texture2D replacementTexture = GetReplacementTexture(((Object)(object)((Renderer)r).sharedMaterial.mainTexture != (Object)null) ? ((Object)((Renderer)r).sharedMaterial.mainTexture).name : "NULL");
				if ((Object)(object)replacementTexture != (Object)null)
				{
					((Renderer)r).sharedMaterial.color = Color.white;
					((Renderer)r).sharedMaterial.mainTexture = (Texture)(object)replacementTexture;
					Plugin.instance.Log("Replaced Item Texture [" + ((Object)item.itemProperties).name + "] with [" + ((Object)replacementTexture).name + "]");
				}
			}
		}

		private static Texture2D GetReplacementTexture(string itemName)
		{
			if (itemName.Contains("yield", StringComparison.OrdinalIgnoreCase))
			{
				return TextureUtil.LoadTexture(TextureUtil.YIELDSIGN_TEX);
			}
			if (itemName.Contains("stop", StringComparison.OrdinalIgnoreCase))
			{
				return TextureUtil.LoadTexture(TextureUtil.STOPSIGN_TEX);
			}
			if (itemName.Contains("soda", StringComparison.OrdinalIgnoreCase))
			{
				return TextureUtil.LoadTexture(TextureUtil.SODACAN_TEX);
			}
			if (itemName.Contains("airhorn", StringComparison.OrdinalIgnoreCase))
			{
				return TextureUtil.LoadTexture(TextureUtil.AIRHORN_TEX);
			}
			if (itemName.Contains("gift", StringComparison.OrdinalIgnoreCase))
			{
				return TextureUtil.LoadTexture(TextureUtil.GIFTBOX_TEX);
			}
			if (itemName.Contains("tiny", StringComparison.OrdinalIgnoreCase))
			{
				return TextureUtil.LoadTexture(TextureUtil.TINY_FLASHLIGHT_TEX);
			}
			if (itemName.Contains("flashlight", StringComparison.OrdinalIgnoreCase))
			{
				return TextureUtil.LoadTexture(TextureUtil.FLASHLIGHT_TEX);
			}
			return null;
		}

		private static void DebugTextures(Item item, string part, Material[] materials)
		{
			for (int i = 0; i < materials.Length; i++)
			{
				string text = (((Object)(object)materials[i] == (Object)null) ? "NULL MAT" : (((Object)(object)materials[i].mainTexture != (Object)null) ? ((Object)materials[i].mainTexture).name : "NULL TEX"));
				string text2 = (((Object)(object)item != (Object)null) ? item.itemName : "NULL");
				Plugin.instance.Log("Item [" + text2 + "] - GameObject:" + part + " has " + materials.Length + " slots. Slot " + i + " contains [" + text + "]");
			}
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	internal class RoundManagerPatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void AwakePatch(RoundManager __instance)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			UpdateTextures(0);
			Light[] array = Object.FindObjectsOfType<Light>();
			foreach (Light val in array)
			{
				if (((Object)val).name.Contains("Area", StringComparison.OrdinalIgnoreCase))
				{
					Plugin.instance.Log("Updating Light Color for [" + ((Object)val).name + "]...");
					val.color = new Color(1f, 77f / 85f, 78f / 85f);
				}
			}
			MeshRenderer[] array2 = Object.FindObjectsOfType<MeshRenderer>();
			foreach (MeshRenderer renderer in array2)
			{
				if (!SearchAndReplaceTexture(renderer, "BunkBeds", TextureUtil.BUNKBEDS_TEX) && !SearchAndReplaceTexture(renderer, "ComputerTerminal", TextureUtil.COMPUTER_TERMINAL_TEX) && !SearchAndReplaceTexture(renderer, "ControlPanelB", TextureUtil.CONTROL_PANEL_B_TEX) && !SearchAndReplaceTexture(renderer, "Keyboard", TextureUtil.KEYBOARD_TEX) && !SearchAndReplaceTexture(renderer, "Treadplate", TextureUtil.FLOORVINYL_ALBEDO) && !SearchAndReplaceTexture(renderer, "GalvanizedSteel", TextureUtil.GALVANIZEDSTEEL_ALBEDO))
				{
					SearchAndReplaceTexture(renderer, "TipsPoster2", TextureUtil.TIPSPOSTER_TEX);
				}
			}
		}

		private static bool SearchAndReplaceTexture(MeshRenderer renderer, string query, string replacement)
		{
			Material[] materials = ((Renderer)renderer).materials;
			foreach (Material val in materials)
			{
				if (val.HasTexture("_MainTex") && !((Object)(object)val.mainTexture == (Object)null) && ((Object)val.mainTexture).name.Contains(query, StringComparison.OrdinalIgnoreCase))
				{
					string[] array = replacement.Split('\\');
					Plugin.instance.Log("Replacing [" + ((Object)val.mainTexture).name + "] with [" + array[^1] + "]...");
					val.mainTexture = (Texture)(object)TextureUtil.LoadTexture(replacement);
					return true;
				}
			}
			return false;
		}

		[HarmonyPatch("GenerateNewLevelClientRpc")]
		[HarmonyPostfix]
		private static void GenerateNewLevelClientRpcPatch(int randomSeed)
		{
			UpdateTextures(randomSeed);
		}

		private static void UpdateTextures(int seed)
		{
			Plugin.instance.Log("Updating Poster Textures...");
			new Random(seed);
			((Renderer)GameObject.Find("HangarShip/Plane.001").GetComponent<MeshRenderer>()).materials[0].mainTexture = (Texture)(object)TextureUtil.LoadTexture(TextureUtil.POSTERS_TEX);
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	internal class TerminalPatch
	{
		private static Random rand = new Random();

		private static Dictionary<TerminalNode, UnityAction<Terminal>> CUSTOM_EVENT_MAP = new Dictionary<TerminalNode, UnityAction<Terminal>>();

		private static string GIMME_GIMME_MESSAGE = "Fine, fine. I know all you want is to play with your little toys.\nI need you to hold on tight, while Daddy orders you some things online. <3\nGo wait outside for the mailman to arrive, okay?\n   - xoxo The Company\n\n\n";

		private static string SPIDER_PLS_MESSAGE = "Are you sure? Okidoki. I'll add a Spider for you bbgirl <3\n   - xoxo The Company\n\n\n";

		private static string DEEZ_NUTS_MESSAGE = "You're gonna like this one 0.0\nNUTCRACKERS GALORE!!!\n   - xoxo The Company\n\n\n";

		private static int MONEY_REQUESTED = 0;

		private static int[] MONEY_AMOUNTS = new int[5] { 500, 250, 100, 50, 0 };

		private static string[] MONEY_PLEASE_MESSAGES = new string[5] { "Alright then Shiv, but only because you hold a special place in my tentacly heart!\nHere you go kitten, have some money \\(*v*)/\n   - xoxo The Company\n\n\n", "Nahww, you know I have a weak spot for you <3 you little stinker.\nFor this once, I'll give you 250 extra credits\n   - xoxo The Company\n\n\n", "Don't get greedy now pookie! Daddy's money doesn't grow on his back...\nOr like, whatever you'd call my incomprehensibly horrifying phsyical manifestation.\n   - xoxo The Company\n\n\n", "I'll give you a just few more credits now, but is your last allowance Shivvy,\nPapa loves you very much, but you're going to have to make your own credits some day.\n   - The Company\n\n\n", "No more credits for you babygirl .\\_/. You've made me very upset now!\nGo outside and get some more trinkets for Daddy, then we can talk.\n   - The Company\n\n\n" };

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void AwakePatch(ref Terminal __instance)
		{
			Plugin.instance.Log("Patching Terminal...");
			StartOfRound val = Object.FindObjectOfType<StartOfRound>();
			List<Item> allItems = val.allItemsList.itemsList;
			ItemUtil.ApplyCustomItemChanges(ref __instance, allItems);
			TerminalNodesList nodes = __instance.terminalNodes;
			AddExactSentence(ref nodes, "moneyplease", MONEY_PLEASE_MESSAGES[0], delegate(Terminal terminal)
			{
				int num = MONEY_AMOUNTS[0];
				if (!((NetworkBehaviour)terminal).IsServer)
				{
					Plugin.instance.Log("Trying to add money on the Server");
					terminal.SyncGroupCreditsServerRpc(terminal.groupCredits + num, 1);
					Plugin.instance.Log("Added money on the Server");
				}
				else
				{
					Plugin.instance.Log("Trying to add money on the Client");
					terminal.SyncGroupCreditsClientRpc(terminal.groupCredits + num, 1);
					Plugin.instance.Log("Added money on the Client");
				}
				MONEY_REQUESTED++;
			});
			AddExactSentence(ref nodes, "spiderpls", SPIDER_PLS_MESSAGE, delegate
			{
				Plugin.instance.Log("spider command");
				RoundManager instance = RoundManager.Instance;
				EnemyUtil.SpawnEnemyFromVent(instance.allEnemyVents[rand.Next(0, instance.allEnemyVents.Length)], "spider");
			});
			AddExactSentence(ref nodes, "deeznuts", DEEZ_NUTS_MESSAGE, delegate
			{
				Plugin.instance.Log("nutcracker command");
				EnemyVent[] allEnemyVents = RoundManager.Instance.allEnemyVents;
				for (int i = 0; i < allEnemyVents.Length; i++)
				{
					EnemyUtil.SpawnEnemyFromVent(allEnemyVents[i], "nutcracker");
				}
			});
			AddExactSentence(ref nodes, "gimmegimme", GIMME_GIMME_MESSAGE, delegate(Terminal terminal)
			{
				terminal.orderedItemsFromTerminal.Add(ItemUtil.GetBuyableIdByName(ref terminal, allItems, "airhorn"));
				terminal.orderedItemsFromTerminal.Add(ItemUtil.GetBuyableIdByName(ref terminal, allItems, "yield"));
				terminal.orderedItemsFromTerminal.Add(ItemUtil.GetBuyableIdByName(ref terminal, allItems, "gift"));
				terminal.orderedItemsFromTerminal.Add(ItemUtil.GetBuyableIdByName(ref terminal, allItems, "soda"));
				terminal.orderedItemsFromTerminal.Add(ItemUtil.GetBuyableIdByName(ref terminal, allItems, "stop"));
				if (!((NetworkBehaviour)terminal).IsServer)
				{
					Plugin.instance.Log("Trying to buy toys on the Server");
					terminal.useCreditsCooldown = true;
					terminal.BuyItemsServerRpc(terminal.orderedItemsFromTerminal.ToArray(), terminal.groupCredits, 5);
					terminal.orderedItemsFromTerminal.Clear();
					Plugin.instance.Log("Bought toys on the Server");
				}
				else
				{
					Plugin.instance.Log("Trying to buy toys on the Client");
					terminal.SyncGroupCreditsClientRpc(terminal.groupCredits, 5);
					Plugin.instance.Log("Bought toys on the Client");
				}
			});
			ItemUtil.AddTerminalItem(nodes, "ShivBucks", 6, 12);
		}

		private static void AddExactSentence(ref TerminalNodesList nodes, string sentence, string description, UnityAction<Terminal> nodeEvent)
		{
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			val.terminalEvent = sentence;
			((Object)val).name = sentence;
			val.displayText = description;
			TerminalKeyword val2 = ScriptableObject.CreateInstance<TerminalKeyword>();
			val2.word = sentence;
			val2.specialKeywordResult = val;
			ItemUtil.AddKeyword(ref nodes, val2);
			nodes.specialNodes.Add(val);
			CUSTOM_EVENT_MAP.Add(val, nodeEvent);
			Plugin.instance.Log("Terminal Event Added [" + sentence + "]");
		}

		[HarmonyPatch("RunTerminalEvents")]
		[HarmonyPostfix]
		private static void RunTerminalEventsPatch(ref Terminal __instance, TerminalNode node)
		{
			string text = (((Object)(object)node == (Object)null) ? "null" : ((Object)node).name);
			Plugin.instance.Log("Looking for Custom Nodes called [" + text + "]...");
			CUSTOM_EVENT_MAP.TryGetValue(node, out var value);
			if (value != null)
			{
				Plugin.instance.Log("Invoking action for Custom Node [" + text + "]");
				value.Invoke(__instance);
			}
		}

		[HarmonyPatch("OnSubmit")]
		[HarmonyPrefix]
		private static void OnSubmitPatch(ref Terminal __instance)
		{
			string text = (((Object)(object)__instance.currentNode == (Object)null) ? "null" : ((Object)__instance.currentNode).name);
			Plugin.instance.Log("Player Submitted Keyword! Current Node is [" + text + "]");
		}

		[HarmonyPatch("ParseWord")]
		[HarmonyPostfix]
		private static void ParseWordPatch(ref TerminalKeyword __result)
		{
			string text = (((Object)(object)__result == (Object)null) ? "null" : __result.word);
			Plugin.instance.Log("Parsing found Keyword [" + text + "]");
		}

		[HarmonyPatch("ParsePlayerSentence")]
		[HarmonyPrefix]
		private static void ParsePlayerSentencePatch()
		{
			Plugin.instance.Log("Parsing Player Sentence");
		}

		[HarmonyPatch("LoadNewNode")]
		[HarmonyPrefix]
		private static void LoadNewNodePatch(TerminalNode node)
		{
			Plugin.instance.Log("Loading Node [" + ((Object)node).name + "]");
		}
	}
	[HarmonyPatch(typeof(WalkieTalkie))]
	internal class WalkieTalkiePatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void PatchGiftbox(WalkieTalkie __instance)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Plugin.instance.Log("Replacing WalkieTalkie Texture...");
			MeshRenderer mainObjectRenderer = ((GrabbableObject)__instance).mainObjectRenderer;
			((Renderer)mainObjectRenderer).sharedMaterial.color = Color.white;
			((Renderer)mainObjectRenderer).sharedMaterial.mainTexture = (Texture)(object)TextureUtil.LoadTexture(TextureUtil.WALKIETALKIE_TEX);
			__instance.onMaterial.mainTexture = (Texture)(object)TextureUtil.LoadTexture(TextureUtil.WALKIETALKIE_TEX);
			__instance.offMaterial.mainTexture = (Texture)(object)TextureUtil.LoadTexture(TextureUtil.WALKIETALKIE_TEX);
			Plugin.instance.Log("Replaced WalkieTalkie Texture!");
		}
	}
}