Decompiled source of yangz pack v5.5.0

LGUCasinoSignDump.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
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("LGUCasinoSignDump")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8c5521e37f37e3d76518a16d04e5d1051842f105")]
[assembly: AssemblyProduct("LGUCasinoSignDump")]
[assembly: AssemblyTitle("LGUCasinoSignDump")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 LGUCasinoSignDump
{
	[BepInPlugin("com.y4ngz.lgucasinosigndump", "LGUCasinoSignDump", "1.0.3")]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <DelayedPatchAttempt>d__7 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Plugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedPatchAttempt>d__7(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				Plugin plugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					if (plugin._patchAttempted)
					{
						return false;
					}
					plugin._patchAttempted = true;
					Log.LogInfo((object)"Searching for CasinoBuilding type now.");
					plugin.TryApplyPatch();
					plugin.TryPatchMenuManagerFix();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string PLUGIN_GUID = "com.y4ngz.lgucasinosigndump";

		public const string PLUGIN_NAME = "LGUCasinoSignDump";

		public const string PLUGIN_VERSION = "1.0.3";

		public static ManualLogSource Log;

		private Harmony _harmony;

		private bool _patchAttempted;

		private void Awake()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"LGUCasinoSignDump v1.0.3 loaded.");
			Log.LogInfo((object)"Will attempt to patch CasinoBuilding.Awake on next frame (after all plugins finish loading).");
			_harmony = new Harmony("com.y4ngz.lgucasinosigndump");
			((MonoBehaviour)this).StartCoroutine(DelayedPatchAttempt());
		}

		[IteratorStateMachine(typeof(<DelayedPatchAttempt>d__7))]
		private IEnumerator DelayedPatchAttempt()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedPatchAttempt>d__7(0)
			{
				<>4__this = this
			};
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void TryApplyPatch()
		{
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Expected O, but got Unknown
			try
			{
				Type type = null;
				string text = null;
				Log.LogInfo((object)"Scanning all loaded assemblies...");
				int num = 0;
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					num++;
					Type[] array;
					try
					{
						array = assembly.GetTypes();
					}
					catch (ReflectionTypeLoadException ex)
					{
						array = ex.Types.Where((Type t) => t != null).ToArray();
					}
					catch
					{
						continue;
					}
					Type[] array2 = array;
					foreach (Type type2 in array2)
					{
						if (!(type2 == null) && (type2.FullName == "LethalCasino.Custom.CasinoBuilding" || type2.FullName == "LethalCasino.CasinoBuilding" || (type2.Name == "CasinoBuilding" && type2.Namespace != null && type2.Namespace.Contains("Casino"))))
						{
							type = type2;
							text = assembly.GetName().Name;
							break;
						}
					}
					if (type != null)
					{
						break;
					}
				}
				Log.LogInfo((object)$"Scanned {num} assemblies.");
				if (type == null)
				{
					Log.LogError((object)"CasinoBuilding type NOT found in any loaded assembly.");
					Log.LogError((object)"Listing assemblies that contain 'casino' in their name (case-insensitive):");
					assemblies = AppDomain.CurrentDomain.GetAssemblies();
					foreach (Assembly assembly2 in assemblies)
					{
						string name = assembly2.GetName().Name;
						if (name == null || !name.ToLowerInvariant().Contains("casino"))
						{
							continue;
						}
						Log.LogError((object)("  Found: " + assembly2.FullName));
						try
						{
							foreach (string item in (from t in assembly2.GetTypes()
								where t != null && t.IsClass
								select t.FullName).Take(50))
							{
								Log.LogError((object)("    type: " + item));
							}
						}
						catch (Exception ex2)
						{
							Log.LogError((object)("    (could not list types: " + ex2.Message + ")"));
						}
					}
					return;
				}
				Log.LogInfo((object)("Found CasinoBuilding: " + type.FullName + " in assembly '" + text + "'"));
				MethodInfo method = type.GetMethod("Awake", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method == null)
				{
					Log.LogError((object)"Could not find CasinoBuilding.Awake method.");
					Log.LogError((object)"Available instance methods:");
					MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (MethodInfo methodInfo in methods)
					{
						Log.LogError((object)("  " + methodInfo.Name));
					}
				}
				else
				{
					MethodInfo method2 = typeof(SignDumpPatch).GetMethod("AwakePostfix", BindingFlags.Static | BindingFlags.Public);
					_harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)"Harmony patch applied. Will dump CasinoBuilding hierarchy on Awake.");
				}
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"TryApplyPatch error: {arg}");
			}
		}

		private void TryPatchMenuManagerFix()
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			try
			{
				Type type = null;
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				for (int i = 0; i < assemblies.Length; i++)
				{
					type = assemblies[i].GetType("LethalCasino.Patches.MenuManagerPatch");
					if (type != null)
					{
						break;
					}
				}
				if (type != null)
				{
					MethodInfo methodInfo = AccessTools.Method(type, "StartPatch", (Type[])null, (Type[])null);
					if (methodInfo != null)
					{
						MethodInfo method = typeof(LethalCasinoMenuFix).GetMethod("Prefix", BindingFlags.Static | BindingFlags.Public);
						_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Log.LogInfo((object)"Patched LethalCasino MenuManagerPatch.StartPatch — skipping broken v69 DisplayMenuNotification call.");
					}
					else
					{
						Log.LogWarning((object)"Found MenuManagerPatch type but could not find StartPatch method.");
					}
				}
				else
				{
					Log.LogInfo((object)"LethalCasino.Patches.MenuManagerPatch not found — skipping menu fix (LethalCasino may not be installed).");
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Could not patch LethalCasino MenuManagerPatch: " + ex.Message));
			}
		}
	}
	internal static class LethalCasinoMenuFix
	{
		public static bool Prefix()
		{
			return false;
		}
	}
	public static class SignDumpPatch
	{
		private static int _dumpCount;

		public static void AwakePostfix(object __instance)
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				_dumpCount++;
				Component val = (Component)((__instance is Component) ? __instance : null);
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Log.LogError((object)"CasinoBuilding instance is not a Component?");
					return;
				}
				Transform transform = val.transform;
				string text = Path.Combine(Paths.BepInExRootPath, "Y4NGZ_Discovery");
				Directory.CreateDirectory(text);
				string arg = DateTime.Now.ToString("yyyyMMdd_HHmmss");
				string text2 = Path.Combine(text, $"casinobuilding_hierarchy_{arg}_dump{_dumpCount}.txt");
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("CasinoBuilding hierarchy dump");
				stringBuilder.AppendLine($"Generated: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
				stringBuilder.AppendLine($"Dump #{_dumpCount} this session");
				stringBuilder.AppendLine($"Root: {((Object)transform).name} (instance ID {((Object)transform).GetInstanceID()})");
				stringBuilder.AppendLine($"World pos: {transform.position}, rot: {transform.eulerAngles}, scale: {transform.lossyScale}");
				stringBuilder.AppendLine(new string('=', 80));
				stringBuilder.AppendLine();
				DumpRecursive(transform, stringBuilder, 0);
				File.WriteAllText(text2, stringBuilder.ToString());
				Plugin.Log.LogInfo((object)("[SignDump] CasinoBuilding hierarchy written to: " + text2));
			}
			catch (Exception arg2)
			{
				Plugin.Log.LogError((object)$"AwakePostfix error: {arg2}");
			}
		}

		private static void DumpRecursive(Transform t, StringBuilder sb, int depth)
		{
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)t == (Object)null)
			{
				return;
			}
			string text = new string(' ', depth * 2);
			GameObject gameObject = ((Component)t).gameObject;
			Component[] components = gameObject.GetComponents<Component>();
			string text2 = string.Join(", ", from c in components
				where (Object)(object)c != (Object)null
				select ((object)c).GetType().Name);
			sb.AppendLine(text + ((Object)gameObject).name);
			sb.AppendLine($"{text}  active={gameObject.activeInHierarchy}, layer={LayerMask.LayerToName(gameObject.layer)}, tag={gameObject.tag}");
			sb.AppendLine(text + "  localPos=" + V3(t.localPosition) + "  worldPos=" + V3(t.position));
			sb.AppendLine(text + "  localRot=" + V3(t.localEulerAngles) + "  worldRot=" + V3(t.eulerAngles));
			sb.AppendLine(text + "  localScale=" + V3(t.localScale) + "  lossyScale=" + V3(t.lossyScale));
			sb.AppendLine(text + "  components: [" + text2 + "]");
			Renderer component = gameObject.GetComponent<Renderer>();
			if ((Object)(object)component != (Object)null)
			{
				string[] obj = new string[7]
				{
					text,
					"  RENDERER: ",
					((object)component).GetType().Name,
					" bounds.center=",
					null,
					null,
					null
				};
				Bounds bounds = component.bounds;
				obj[4] = V3(((Bounds)(ref bounds)).center);
				obj[5] = " bounds.size=";
				bounds = component.bounds;
				obj[6] = V3(((Bounds)(ref bounds)).size);
				sb.AppendLine(string.Concat(obj));
				if (component.sharedMaterials != null)
				{
					for (int i = 0; i < component.sharedMaterials.Length; i++)
					{
						Material val = component.sharedMaterials[i];
						if ((Object)(object)val != (Object)null)
						{
							object[] obj2 = new object[4]
							{
								text,
								i,
								((Object)val).name,
								null
							};
							Shader shader = val.shader;
							obj2[3] = ((shader != null) ? ((Object)shader).name : null) ?? "null";
							sb.AppendLine(string.Format("{0}    MAT[{1}] name='{2}' shader='{3}'", obj2));
							if (val.HasProperty("_MainTex"))
							{
								Texture texture = val.GetTexture("_MainTex");
								sb.AppendLine(text + "      _MainTex=" + (((Object)(object)texture != (Object)null) ? ((Object)texture).name : "null"));
							}
							if (val.HasProperty("_EmissionMap"))
							{
								Texture texture2 = val.GetTexture("_EmissionMap");
								sb.AppendLine(text + "      _EmissionMap=" + (((Object)(object)texture2 != (Object)null) ? ((Object)texture2).name : "null"));
							}
						}
					}
				}
			}
			MeshFilter component2 = gameObject.GetComponent<MeshFilter>();
			if ((Object)(object)component2 != (Object)null && (Object)(object)component2.sharedMesh != (Object)null)
			{
				sb.AppendLine($"{text}  MESH: '{((Object)component2.sharedMesh).name}' verts={component2.sharedMesh.vertexCount} submeshes={component2.sharedMesh.subMeshCount}");
			}
			Light component3 = gameObject.GetComponent<Light>();
			if ((Object)(object)component3 != (Object)null)
			{
				sb.AppendLine($"{text}  LIGHT: type={component3.type} intensity={component3.intensity:F2} color={component3.color} range={component3.range:F2}");
			}
			sb.AppendLine();
			for (int j = 0; j < t.childCount; j++)
			{
				DumpRecursive(t.GetChild(j), sb, depth + 1);
			}
		}

		private static string V3(Vector3 v)
		{
			//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)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			return $"({v.x:F3}, {v.y:F3}, {v.z:F3})";
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LGUCasinoSignDump";

		public const string PLUGIN_NAME = "LGUCasinoSignDump";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}

LGUCompanyPosters.dll

Decompiled 4 days ago
using System;
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.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[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("LGUCompanyPosters")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Spawns Y4NGZ propaganda posters on the Company Building wall")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8c5521e37f37e3d76518a16d04e5d1051842f105")]
[assembly: AssemblyProduct("LGUCompanyPosters")]
[assembly: AssemblyTitle("LGUCompanyPosters")]
[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 LGUCompanyPosters
{
	[BepInPlugin("com.y4ngz.lgucompanyposters", "LGUCompanyPosters", "1.2.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "com.y4ngz.lgucompanyposters";

		public const string PLUGIN_NAME = "LGUCompanyPosters";

		public const string PLUGIN_VERSION = "1.2.0";

		internal static ManualLogSource Log;

		internal static Harmony harmony;

		internal static Texture2D posterTexture;

		internal static Material posterMaterial;

		internal static bool assetsReady = false;

		internal static bool spawnedThisLanding = false;

		internal static readonly Vector3 POSTER_LEFT_POS = new Vector3(-26f, 35f, -37f);

		internal static readonly Vector3 POSTER_LEFT_ROT = new Vector3(0f, 90f, 0f);

		internal static readonly Vector3 POSTER_RIGHT_POS = new Vector3(-26f, 35f, 0f);

		internal static readonly Vector3 POSTER_RIGHT_ROT = new Vector3(0f, 90f, 0f);

		internal static readonly Vector3 POSTER_SCALE = new Vector3(22.5f, 30f, 0.02f);

		private void Awake()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"LGUCompanyPosters v1.2.0 loaded!");
			LoadTextureFromFile();
			harmony = new Harmony("com.y4ngz.lgucompanyposters");
			harmony.PatchAll();
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		private void LoadTextureFromFile()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			try
			{
				string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "PropagandaPoster.png");
				if (!File.Exists(text))
				{
					Log.LogError((object)("Poster texture not found at: " + text));
					Log.LogError((object)"Place PropagandaPoster.png next to LGUCompanyPosters.dll");
					return;
				}
				byte[] array = File.ReadAllBytes(text);
				posterTexture = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!ImageConversion.LoadImage(posterTexture, array))
				{
					Log.LogError((object)"Failed to decode PNG data.");
					return;
				}
				((Object)posterTexture).name = "PropagandaPoster";
				((Texture)posterTexture).wrapMode = (TextureWrapMode)1;
				((Texture)posterTexture).filterMode = (FilterMode)1;
				Log.LogInfo((object)$"Poster texture loaded: {((Texture)posterTexture).width}x{((Texture)posterTexture).height}");
				assetsReady = true;
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to load poster texture: {arg}");
			}
		}

		internal static Shader FindWorkingShader()
		{
			string[] array = new string[3] { "Unlit/Texture", "HDRP/Unlit", "Universal Render Pipeline/Unlit" };
			foreach (string text in array)
			{
				Shader val = Shader.Find(text);
				if ((Object)(object)val != (Object)null)
				{
					Log.LogInfo((object)("Using preferred shader: " + text));
					return val;
				}
			}
			try
			{
				MeshRenderer[] array2 = Object.FindObjectsOfType<MeshRenderer>();
				foreach (MeshRenderer val2 in array2)
				{
					string name = ((Object)((Component)val2).gameObject).name;
					if (name.StartsWith("Poster") && (Object)(object)((Renderer)val2).sharedMaterial != (Object)null && (Object)(object)((Renderer)val2).sharedMaterial.shader != (Object)null)
					{
						Log.LogInfo((object)("Borrowed shader '" + ((Object)((Renderer)val2).sharedMaterial.shader).name + "' from '" + name + "'"));
						return ((Renderer)val2).sharedMaterial.shader;
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Error searching for poster shader: " + ex.Message));
			}
			array = new string[3] { "HDRP/Lit", "Universal Render Pipeline/Lit", "Standard" };
			foreach (string text2 in array)
			{
				Shader val3 = Shader.Find(text2);
				if ((Object)(object)val3 != (Object)null)
				{
					Log.LogInfo((object)("Using fallback shader: " + text2));
					return val3;
				}
			}
			Log.LogError((object)"Could not find any working shader!");
			return null;
		}

		internal static Material GetOrCreateMaterial()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)posterMaterial != (Object)null)
			{
				return posterMaterial;
			}
			Shader val = FindWorkingShader();
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			posterMaterial = new Material(val);
			((Object)posterMaterial).name = "PropagandaPoster_Mat";
			posterMaterial.mainTexture = (Texture)(object)posterTexture;
			posterMaterial.color = Color.white;
			if (posterMaterial.HasProperty("_Cull"))
			{
				posterMaterial.SetFloat("_Cull", 0f);
			}
			try
			{
				if (posterMaterial.HasProperty("_Metallic"))
				{
					posterMaterial.SetFloat("_Metallic", 0f);
				}
				if (posterMaterial.HasProperty("_Smoothness"))
				{
					posterMaterial.SetFloat("_Smoothness", 0f);
				}
				if (posterMaterial.HasProperty("_Glossiness"))
				{
					posterMaterial.SetFloat("_Glossiness", 0f);
				}
				if (posterMaterial.HasProperty("_SpecColor"))
				{
					posterMaterial.SetColor("_SpecColor", Color.black);
				}
				if (posterMaterial.HasProperty("_EmissiveColor"))
				{
					posterMaterial.SetColor("_EmissiveColor", new Color(0.5f, 0.5f, 0.5f));
					posterMaterial.EnableKeyword("_EMISSION");
				}
				else if (posterMaterial.HasProperty("_EmissionColor"))
				{
					posterMaterial.SetColor("_EmissionColor", new Color(0.5f, 0.5f, 0.5f));
					posterMaterial.EnableKeyword("_EMISSION");
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Could not set all material properties: " + ex.Message));
			}
			Log.LogInfo((object)("Material created with shader: " + ((Object)val).name));
			return posterMaterial;
		}

		internal static Mesh CreateQuadMesh()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			Mesh val = new Mesh();
			((Object)val).name = "PosterQuad";
			val.vertices = (Vector3[])(object)new Vector3[8]
			{
				new Vector3(-0.5f, -0.5f, 0f),
				new Vector3(0.5f, -0.5f, 0f),
				new Vector3(0.5f, 0.5f, 0f),
				new Vector3(-0.5f, 0.5f, 0f),
				new Vector3(-0.5f, -0.5f, 0f),
				new Vector3(0.5f, -0.5f, 0f),
				new Vector3(0.5f, 0.5f, 0f),
				new Vector3(-0.5f, 0.5f, 0f)
			};
			val.uv = (Vector2[])(object)new Vector2[8]
			{
				new Vector2(1f, 0f),
				new Vector2(0f, 0f),
				new Vector2(0f, 1f),
				new Vector2(1f, 1f),
				new Vector2(0f, 0f),
				new Vector2(1f, 0f),
				new Vector2(1f, 1f),
				new Vector2(0f, 1f)
			};
			val.triangles = new int[12]
			{
				0, 1, 2, 0, 2, 3, 4, 6, 5, 4,
				7, 6
			};
			val.normals = (Vector3[])(object)new Vector3[8]
			{
				-Vector3.forward,
				-Vector3.forward,
				-Vector3.forward,
				-Vector3.forward,
				Vector3.forward,
				Vector3.forward,
				Vector3.forward,
				Vector3.forward
			};
			val.RecalculateBounds();
			return val;
		}

		internal static void TrySpawnPosters()
		{
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			if (!assetsReady || (Object)(object)posterTexture == (Object)null)
			{
				Log.LogWarning((object)"Cannot spawn posters — texture not loaded.");
				return;
			}
			if (spawnedThisLanding)
			{
				Log.LogDebug((object)"Posters already spawned this landing, skipping.");
				return;
			}
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.currentLevel == (Object)null)
			{
				Log.LogDebug((object)"[TrySpawn] StartOfRound or currentLevel is null.");
				return;
			}
			string text = instance.currentLevel.PlanetName ?? "";
			string text2 = instance.currentLevel.sceneName ?? "";
			Log.LogInfo((object)("[TrySpawn] Planet: \"" + text + "\" Scene: \"" + text2 + "\""));
			if (!text.Contains("Gordion") && !text.Contains("Company") && text2 != "CompanyBuilding")
			{
				Log.LogInfo((object)"[TrySpawn] Not Company moon — posters will not spawn.");
				return;
			}
			Material orCreateMaterial = GetOrCreateMaterial();
			if ((Object)(object)orCreateMaterial == (Object)null)
			{
				Log.LogError((object)"Failed to create material. Posters not spawned.");
				return;
			}
			Mesh mesh = CreateQuadMesh();
			SpawnPoster("PropagandaPoster_Left", POSTER_LEFT_POS, POSTER_LEFT_ROT, POSTER_SCALE, orCreateMaterial, mesh);
			SpawnPoster("PropagandaPoster_Right", POSTER_RIGHT_POS, POSTER_RIGHT_ROT, POSTER_SCALE, orCreateMaterial, mesh);
			spawnedThisLanding = true;
			Log.LogInfo((object)"Propaganda posters spawned on Company Building wall.");
		}

		private static void SpawnPoster(string instanceName, Vector3 position, Vector3 rotation, Vector3 scale, Material mat, Mesh mesh)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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: 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)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject val = new GameObject(instanceName);
				val.transform.position = position;
				val.transform.localRotation = Quaternion.Euler(rotation);
				val.transform.localScale = scale;
				val.AddComponent<MeshFilter>().sharedMesh = mesh;
				MeshRenderer obj = val.AddComponent<MeshRenderer>();
				((Renderer)obj).sharedMaterial = mat;
				((Renderer)obj).shadowCastingMode = (ShadowCastingMode)2;
				((Renderer)obj).receiveShadows = true;
				AddPosterLight(val, scale);
				Log.LogInfo((object)$"[{instanceName}] Poster spawned at {position}, shader: {((Object)mat.shader).name}");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to spawn poster '{instanceName}': {arg}");
			}
		}

		private static void AddPosterLight(GameObject poster, Vector3 posterScale)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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)
			GameObject val = new GameObject("PosterSpotLight");
			val.transform.SetParent(poster.transform);
			float y = posterScale.y;
			val.transform.localPosition = new Vector3(0f, y * 0.6f, -0.5f);
			val.transform.localRotation = Quaternion.Euler(45f, 0f, 0f);
			Light obj = val.AddComponent<Light>();
			obj.type = (LightType)0;
			obj.color = new Color(1f, 0.95f, 0.85f);
			obj.intensity = 15f;
			obj.range = 8f;
			obj.spotAngle = 60f;
			obj.shadows = (LightShadows)2;
		}

		internal static void DespawnPosters()
		{
			GameObject val = GameObject.Find("PropagandaPoster_Left");
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)val);
			}
			GameObject val2 = GameObject.Find("PropagandaPoster_Right");
			if ((Object)(object)val2 != (Object)null)
			{
				Object.Destroy((Object)(object)val2);
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "openingDoorsSequence")]
	internal class PosterSpawnOnLandingPatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			try
			{
				Plugin.Log.LogInfo((object)"[PosterSpawn] openingDoorsSequence fired.");
				Plugin.TrySpawnPosters();
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"PosterSpawnOnLandingPatch error: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "ShipLeave")]
	internal class PosterResetOnLeavePatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			Plugin.DespawnPosters();
			Plugin.spawnedThisLanding = false;
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "ShipLeaveAutomatically")]
	internal class PosterResetOnAutoLeavePatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			Plugin.DespawnPosters();
			Plugin.spawnedThisLanding = false;
		}
	}
}

LGUConstellationsBridge.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("DunGen")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")]
[assembly: IgnoresAccessChecksTo("Unity.XR.Management")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LGUConstellationsBridge")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("4.4.1.0")]
[assembly: AssemblyInformationalVersion("4.4.1+8c5521e37f37e3d76518a16d04e5d1051842f105")]
[assembly: AssemblyProduct("LGUConstellationsBridge")]
[assembly: AssemblyTitle("LGUConstellationsBridge")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.4.1.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 LGUConstellationsBridge
{
	public static class ConstellationNotification
	{
		[CompilerGenerated]
		private sealed class <RunNotification>d__21 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Canvas canvas;

			public string constellationName;

			private GameObject <root>5__2;

			private RawImage <flash>5__3;

			private GameObject <banner>5__4;

			private CanvasGroup <bannerGroup>5__5;

			private float <t>5__6;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <RunNotification>d__21(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<root>5__2 = null;
				<flash>5__3 = null;
				<banner>5__4 = null;
				<bannerGroup>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Expected O, but got Unknown
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: 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_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Expected O, but got Unknown
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_012b: Unknown result type (might be due to invalid IL or missing references)
				//IL_013b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0145: Expected O, but got Unknown
				//IL_0177: Unknown result type (might be due to invalid IL or missing references)
				//IL_018c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0197: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0202: Unknown result type (might be due to invalid IL or missing references)
				//IL_0219: Unknown result type (might be due to invalid IL or missing references)
				//IL_022a: Unknown result type (might be due to invalid IL or missing references)
				//IL_023f: Unknown result type (might be due to invalid IL or missing references)
				//IL_024a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0254: Unknown result type (might be due to invalid IL or missing references)
				//IL_0285: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0303: Unknown result type (might be due to invalid IL or missing references)
				//IL_0341: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_042a: Unknown result type (might be due to invalid IL or missing references)
				//IL_046f: Unknown result type (might be due to invalid IL or missing references)
				//IL_04e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_051b: Unknown result type (might be due to invalid IL or missing references)
				//IL_05e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_05fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_05c9: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<root>5__2 = new GameObject("LGU_ConstellationNotification");
					<root>5__2.transform.SetParent(((Component)canvas).transform, false);
					_activeRoot = <root>5__2;
					RectTransform obj = <root>5__2.AddComponent<RectTransform>();
					obj.anchorMin = Vector2.zero;
					obj.anchorMax = Vector2.one;
					obj.offsetMin = Vector2.zero;
					obj.offsetMax = Vector2.zero;
					<root>5__2.transform.SetAsLastSibling();
					GameObject val = new GameObject("Flash");
					val.transform.SetParent(<root>5__2.transform, false);
					<flash>5__3 = val.AddComponent<RawImage>();
					((Graphic)<flash>5__3).raycastTarget = false;
					RectTransform component = val.GetComponent<RectTransform>();
					component.anchorMin = Vector2.zero;
					component.anchorMax = Vector2.one;
					component.offsetMin = Vector2.zero;
					component.offsetMax = Vector2.zero;
					((Graphic)<flash>5__3).color = new Color(FlashBaseColor.r, FlashBaseColor.g, FlashBaseColor.b, 0f);
					<banner>5__4 = new GameObject("Banner");
					<banner>5__4.transform.SetParent(<root>5__2.transform, false);
					RectTransform obj2 = <banner>5__4.AddComponent<RectTransform>();
					obj2.anchorMin = new Vector2(0.2f, 0.44f);
					obj2.anchorMax = new Vector2(0.8f, 0.56f);
					obj2.offsetMin = Vector2.zero;
					obj2.offsetMax = Vector2.zero;
					Image obj3 = <banner>5__4.AddComponent<Image>();
					((Graphic)obj3).color = BannerBgColor;
					((Graphic)obj3).raycastTarget = false;
					Outline obj4 = <banner>5__4.AddComponent<Outline>();
					((Shadow)obj4).effectColor = BorderColor;
					((Shadow)obj4).effectDistance = new Vector2(1f, -1f);
					((Shadow)obj4).useGraphicAlpha = false;
					GameObject val2 = new GameObject("Line1");
					val2.transform.SetParent(<banner>5__4.transform, false);
					RectTransform obj5 = val2.AddComponent<RectTransform>();
					obj5.anchorMin = new Vector2(0f, 0.52f);
					obj5.anchorMax = new Vector2(1f, 0.92f);
					obj5.offsetMin = Vector2.zero;
					obj5.offsetMax = Vector2.zero;
					TextMeshProUGUI obj6 = val2.AddComponent<TextMeshProUGUI>();
					((TMP_Text)obj6).text = "CONSTELLATION UNLOCKED";
					((TMP_Text)obj6).fontSize = 16f;
					((TMP_Text)obj6).alignment = (TextAlignmentOptions)514;
					((Graphic)obj6).color = Line1Color;
					((TMP_Text)obj6).characterSpacing = 3f;
					((Graphic)obj6).raycastTarget = false;
					((TMP_Text)obj6).enableWordWrapping = false;
					GameObject val3 = new GameObject("Line2");
					val3.transform.SetParent(<banner>5__4.transform, false);
					RectTransform obj7 = val3.AddComponent<RectTransform>();
					obj7.anchorMin = new Vector2(0f, 0.08f);
					obj7.anchorMax = new Vector2(1f, 0.5f);
					obj7.offsetMin = Vector2.zero;
					obj7.offsetMax = Vector2.zero;
					TextMeshProUGUI obj8 = val3.AddComponent<TextMeshProUGUI>();
					((TMP_Text)obj8).text = constellationName.ToUpper();
					((TMP_Text)obj8).fontSize = 28f;
					((TMP_Text)obj8).fontStyle = (FontStyles)1;
					((TMP_Text)obj8).alignment = (TextAlignmentOptions)514;
					((Graphic)obj8).color = Line2Color;
					((Graphic)obj8).raycastTarget = false;
					((TMP_Text)obj8).enableWordWrapping = false;
					<bannerGroup>5__5 = <banner>5__4.AddComponent<CanvasGroup>();
					<bannerGroup>5__5.interactable = false;
					<bannerGroup>5__5.blocksRaycasts = false;
					<bannerGroup>5__5.alpha = 0f;
					<banner>5__4.transform.localScale = new Vector3(0.8f, 0.8f, 1f);
					<t>5__6 = 0f;
					break;
				}
				case 1:
					<>1__state = -1;
					break;
				}
				if (<t>5__6 < 3.4f)
				{
					if ((Object)(object)<root>5__2 == (Object)null)
					{
						return false;
					}
					<t>5__6 += Time.deltaTime;
					if (<t>5__6 < 0.05f)
					{
						((Graphic)<flash>5__3).color = new Color(FlashBaseColor.r, FlashBaseColor.g, FlashBaseColor.b, <t>5__6 / 0.05f * 0.4f);
					}
					else if (<t>5__6 < 0.2f)
					{
						((Graphic)<flash>5__3).color = new Color(FlashBaseColor.r, FlashBaseColor.g, FlashBaseColor.b, 0.4f);
					}
					else if (<t>5__6 < 0.8f)
					{
						float num = (<t>5__6 - 0.2f) / 0.6f;
						((Graphic)<flash>5__3).color = new Color(FlashBaseColor.r, FlashBaseColor.g, FlashBaseColor.b, 0.4f * (1f - num));
					}
					else if (((Graphic)<flash>5__3).color.a > 0f)
					{
						((Graphic)<flash>5__3).color = new Color(FlashBaseColor.r, FlashBaseColor.g, FlashBaseColor.b, 0f);
					}
					if (<t>5__6 >= 0.1f)
					{
						if (<bannerGroup>5__5.alpha < 1f)
						{
							<bannerGroup>5__5.alpha = 1f;
						}
						if (<t>5__6 < 0.3f)
						{
							float num2 = (<t>5__6 - 0.1f) / 0.20000002f;
							float num3 = ((num2 < 0.7f) ? Mathf.Lerp(0.8f, 1.05f, num2 / 0.7f) : Mathf.Lerp(1.05f, 1f, (num2 - 0.7f) / 0.3f));
							<banner>5__4.transform.localScale = new Vector3(num3, num3, 1f);
						}
						else if (<banner>5__4.transform.localScale.x != 1f)
						{
							<banner>5__4.transform.localScale = Vector3.one;
						}
						if (<t>5__6 >= 2.6f)
						{
							float num4 = (<t>5__6 - 2.6f) / 0.8000002f;
							<bannerGroup>5__5.alpha = 1f - num4;
						}
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if ((Object)(object)_activeRoot == (Object)(object)<root>5__2)
				{
					_activeRoot = null;
					_activeCoroutine = null;
				}
				if ((Object)(object)<root>5__2 != (Object)null)
				{
					Object.Destroy((Object)(object)<root>5__2);
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <ShowNotificationsSequentially>d__19 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public List<string> names;

			private int <i>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ShowNotificationsSequentially>d__19(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Expected O, but got Unknown
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_0093;
				}
				<>1__state = -1;
				<i>5__2 = 0;
				goto IL_00a3;
				IL_0093:
				<i>5__2++;
				goto IL_00a3;
				IL_00a3:
				if (<i>5__2 < names.Count)
				{
					Plugin.Log.LogInfo((object)("[Notification] Showing notification for: " + names[<i>5__2]));
					ShowNotificationImmediate(names[<i>5__2]);
					if (<i>5__2 < names.Count - 1)
					{
						<>2__current = (object)new WaitForSeconds(4.5f);
						<>1__state = 1;
						return true;
					}
					goto IL_0093;
				}
				_sequenceCoroutine = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static int _cachedQuotaSeen = -1;

		private static HashSet<string> _knownConstellations = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static Dictionary<string, int> _quotaThresholds;

		private static bool _rulesInitialized;

		private static readonly Regex SectionPattern = new Regex("^\\[Constellation:\\s*(.+?)\\]\\s*$", RegexOptions.Compiled);

		private static AudioClip _cachedChime;

		private static Coroutine _activeCoroutine;

		private static Coroutine _sequenceCoroutine;

		private static GameObject _activeRoot;

		private static readonly Color FlashBaseColor = new Color(0f, 40f / 51f, 0f, 0f);

		private static readonly Color BannerBgColor = new Color(1f / 51f, 1f / 51f, 1f / 51f, 0.9f);

		private static readonly Color BorderColor = new Color(0f, 40f / 51f, 0f, 1f);

		private static readonly Color Line1Color = new Color(0f, 40f / 51f, 0f, 1f);

		private static readonly Color Line2Color = new Color(0f, 1f, 0f, 1f);

		public static void CheckAndNotify()
		{
			if (Plugin.EnableUnlockNotification == null || !Plugin.EnableUnlockNotification.Value)
			{
				return;
			}
			try
			{
				EnsureRulesLoaded();
				int num = (((Object)(object)TimeOfDay.Instance != (Object)null) ? TimeOfDay.Instance.timesFulfilledQuota : 0);
				HashSet<string> hashSet = ComputeUnlockedAtQuota(num);
				Plugin.Log.LogInfo((object)($"[Notification] Current constellations (quota={num}): " + ((hashSet.Count > 0) ? string.Join(", ", hashSet) : "(none gated)")));
				if (_cachedQuotaSeen < 0)
				{
					int num2 = Math.Max(0, num - 1);
					_knownConstellations = ComputeUnlockedAtQuota(num2);
					_cachedQuotaSeen = num2;
					Plugin.Log.LogInfo((object)($"[Notification] Seeded cache for quota={num2}: " + ((_knownConstellations.Count > 0) ? string.Join(", ", _knownConstellations) : "(empty)")));
				}
				List<string> list = new List<string>();
				foreach (string item in hashSet)
				{
					if (!_knownConstellations.Contains(item))
					{
						list.Add(item);
					}
				}
				_knownConstellations = hashSet;
				_cachedQuotaSeen = num;
				if (list.Count == 0)
				{
					Plugin.Log.LogInfo((object)"[Notification] No new constellations unlocked this quota.");
					return;
				}
				foreach (string item2 in list)
				{
					Plugin.Log.LogInfo((object)("[Notification] Newly unlocked: " + item2));
				}
				if (!((Object)(object)Plugin.Instance == (Object)null))
				{
					CancelActive();
					_sequenceCoroutine = ((MonoBehaviour)Plugin.Instance).StartCoroutine(ShowNotificationsSequentially(list));
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"[Notification] CheckAndNotify failed: {arg}");
			}
		}

		public static void ResetCache()
		{
			_knownConstellations.Clear();
			_cachedQuotaSeen = -1;
			Plugin.Log.LogInfo((object)"[Notification] Cache reset.");
		}

		private static void EnsureRulesLoaded()
		{
			if (_rulesInitialized)
			{
				return;
			}
			_rulesInitialized = true;
			_quotaThresholds = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
			try
			{
				string text = Path.Combine(Paths.ConfigPath, "LethalMoonUnlocks - Constellations.cfg");
				if (!File.Exists(text))
				{
					Plugin.Log.LogWarning((object)("[Notification] Config not found: " + text + " — quota-based unlock detection disabled."));
					return;
				}
				string[] array = File.ReadAllLines(text);
				string text2 = null;
				bool result = false;
				int result2 = 0;
				for (int i = 0; i < array.Length; i++)
				{
					string text3 = array[i].Trim();
					Match match = SectionPattern.Match(text3);
					if (match.Success)
					{
						FlushSection(text2, result, result2);
						text2 = match.Groups[1].Value.Trim();
						result = false;
						result2 = 0;
					}
					else
					{
						if (text2 == null || text3.StartsWith("#") || string.IsNullOrEmpty(text3))
						{
							continue;
						}
						if (text3.StartsWith("Enabled", StringComparison.OrdinalIgnoreCase))
						{
							int num = text3.IndexOf('=');
							if (num >= 0)
							{
								bool.TryParse(text3.Substring(num + 1).Trim(), out result);
							}
						}
						else if (text3.StartsWith("RequiredQuotaCount", StringComparison.OrdinalIgnoreCase))
						{
							int num2 = text3.IndexOf('=');
							if (num2 >= 0)
							{
								int.TryParse(text3.Substring(num2 + 1).Trim(), out result2);
							}
						}
					}
				}
				FlushSection(text2, result, result2);
				Plugin.Log.LogInfo((object)$"[Notification] Parsed {_quotaThresholds.Count} gated constellation(s) from config:");
				foreach (KeyValuePair<string, int> quotaThreshold in _quotaThresholds)
				{
					Plugin.Log.LogInfo((object)$"[Notification]   {quotaThreshold.Key} -> quota {quotaThreshold.Value}");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[Notification] Failed to parse unlock rules: " + ex.Message));
			}
		}

		private static void FlushSection(string name, bool enabled, int quota)
		{
			if (name != null && enabled && quota > 0)
			{
				_quotaThresholds[name] = quota;
			}
		}

		private static HashSet<string> ComputeUnlockedAtQuota(int quota)
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			if (_quotaThresholds == null)
			{
				return hashSet;
			}
			foreach (KeyValuePair<string, int> quotaThreshold in _quotaThresholds)
			{
				if (quotaThreshold.Value <= quota)
				{
					hashSet.Add(quotaThreshold.Key);
				}
			}
			return hashSet;
		}

		[IteratorStateMachine(typeof(<ShowNotificationsSequentially>d__19))]
		private static IEnumerator ShowNotificationsSequentially(List<string> names)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ShowNotificationsSequentially>d__19(0)
			{
				names = names
			};
		}

		private static void ShowNotificationImmediate(string constellationName)
		{
			if ((Object)(object)HUDManager.Instance == (Object)null || (Object)(object)HUDManager.Instance.playerScreenTexture == (Object)null)
			{
				Plugin.Log.LogDebug((object)"[Notification] Skipping — HUD not available");
				return;
			}
			Canvas canvas = ((Graphic)HUDManager.Instance.playerScreenTexture).canvas;
			if ((Object)(object)canvas == (Object)null)
			{
				Plugin.Log.LogDebug((object)"[Notification] Skipping — HUD canvas not available");
				return;
			}
			if (_activeCoroutine != null)
			{
				((MonoBehaviour)Plugin.Instance).StopCoroutine(_activeCoroutine);
				_activeCoroutine = null;
			}
			if ((Object)(object)_activeRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_activeRoot);
				_activeRoot = null;
			}
			AudioClip orCreateChime = GetOrCreateChime();
			if ((Object)(object)orCreateChime != (Object)null && (Object)(object)HUDManager.Instance.UIAudio != (Object)null)
			{
				HUDManager.Instance.UIAudio.PlayOneShot(orCreateChime, Plugin.NotificationVolume.Value);
			}
			_activeCoroutine = ((MonoBehaviour)Plugin.Instance).StartCoroutine(RunNotification(constellationName, canvas));
		}

		[IteratorStateMachine(typeof(<RunNotification>d__21))]
		private static IEnumerator RunNotification(string constellationName, Canvas canvas)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RunNotification>d__21(0)
			{
				constellationName = constellationName,
				canvas = canvas
			};
		}

		private static void CancelActive()
		{
			if (!((Object)(object)Plugin.Instance == (Object)null))
			{
				if (_sequenceCoroutine != null)
				{
					((MonoBehaviour)Plugin.Instance).StopCoroutine(_sequenceCoroutine);
					_sequenceCoroutine = null;
				}
				if (_activeCoroutine != null)
				{
					((MonoBehaviour)Plugin.Instance).StopCoroutine(_activeCoroutine);
					_activeCoroutine = null;
				}
				if ((Object)(object)_activeRoot != (Object)null)
				{
					Object.Destroy((Object)(object)_activeRoot);
					_activeRoot = null;
				}
			}
		}

		private static AudioClip GetOrCreateChime()
		{
			if ((Object)(object)_cachedChime != (Object)null)
			{
				return _cachedChime;
			}
			int num = 22050;
			float[] array = new float[num];
			AddSineTone(array, 44100, 600f, 0f, 0.12f, 0.01f, 8f, 0.5f);
			AddSineTone(array, 44100, 900f, 0.08f, 0.18f, 0.01f, 6f, 0.5f);
			int num2 = 8820;
			for (int i = num2; i < num; i++)
			{
				float num3 = (float)(i - num2) / 44100f;
				array[i] += (Random.value * 2f - 1f) * 0.05f * Mathf.Exp((0f - num3) * 15f);
			}
			float num4 = 0f;
			for (int j = 0; j < num; j++)
			{
				if (Mathf.Abs(array[j]) > num4)
				{
					num4 = Mathf.Abs(array[j]);
				}
			}
			if (num4 > 0.9f)
			{
				float num5 = 0.9f / num4;
				for (int k = 0; k < num; k++)
				{
					array[k] *= num5;
				}
			}
			_cachedChime = AudioClip.Create("LGU_ConstellationUnlock_Chime", num, 1, 44100, false);
			_cachedChime.SetData(array, 0);
			Plugin.Log.LogInfo((object)$"[Notification] Generated procedural unlock chime ({num} samples)");
			return _cachedChime;
		}

		private static void AddSineTone(float[] data, int sampleRate, float freqHz, float startSec, float durationSec, float attackSec, float decayRate, float amplitude)
		{
			int num = (int)((float)sampleRate * startSec);
			int num2 = (int)((float)sampleRate * durationSec);
			float num3 = 0f;
			for (int i = 0; i < num2; i++)
			{
				int num4 = num + i;
				if (num4 < data.Length)
				{
					float num5 = (float)i / (float)sampleRate;
					num3 += freqHz / (float)sampleRate;
					float num6 = Mathf.Sin(num3 * 2f * MathF.PI);
					float num7 = Mathf.Clamp01(num5 / attackSec);
					float num8 = Mathf.Exp((0f - num5) * decayRate);
					data[num4] += num6 * (num7 * num8) * amplitude;
					continue;
				}
				break;
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "Start")]
	internal static class HelpPagePatch
	{
		[CompilerGenerated]
		private sealed class <DeferredRewrite>d__8 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Terminal terminal;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DeferredRewrite>d__8(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					DoRewrite(terminal);
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static readonly Regex MoonsBlockPattern = new Regex(">MOONS\\r?\\n[^\\r\\n]*(\\r?\\n){1,2}", RegexOptions.IgnoreCase | RegexOptions.Compiled);

		private static readonly Regex ConstellationsBlockPattern = new Regex(">CONSTELLATIONS\\r?\\n[^\\r\\n]*(\\r?\\n){1,2}", RegexOptions.IgnoreCase | RegexOptions.Compiled);

		private static readonly Regex FirstHeadingPattern = new Regex("^[ \\t]*>[A-Z][A-Z_ ]*\\r?\\n", RegexOptions.Multiline | RegexOptions.Compiled);

		private const string MoonsRestoredBlock = ">MOONS\nTo see the list of moons the autopilot can route to.\n\n";

		private static bool _alreadyProcessed;

		private static ManualLogSource Log => Plugin.Log;

		[HarmonyPostfix]
		private static void Postfix(Terminal __instance)
		{
			try
			{
				if (!((Object)(object)__instance == (Object)null) && !_alreadyProcessed)
				{
					((MonoBehaviour)__instance).StartCoroutine(DeferredRewrite(__instance));
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogError((object)$"[Bridge.Help] Postfix exception: {arg}");
				}
			}
		}

		[IteratorStateMachine(typeof(<DeferredRewrite>d__8))]
		private static IEnumerator DeferredRewrite(Terminal terminal)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DeferredRewrite>d__8(0)
			{
				terminal = terminal
			};
		}

		private static void DoRewrite(Terminal terminal)
		{
			try
			{
				if ((Object)(object)terminal == (Object)null || (Object)(object)terminal.terminalNodes == (Object)null)
				{
					return;
				}
				if (terminal.terminalNodes.specialNodes == null || terminal.terminalNodes.specialNodes.Count <= 13)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)"[Bridge.Help] specialNodes shape unexpected - skipping rewrite.");
					}
					return;
				}
				TerminalNode val = terminal.terminalNodes.specialNodes[13];
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				string text = val.displayText ?? string.Empty;
				if (string.IsNullOrEmpty(text))
				{
					return;
				}
				bool flag = false;
				if (MoonsBlockPattern.IsMatch(text))
				{
					text = MoonsBlockPattern.Replace(text, string.Empty, 1);
					flag = true;
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogInfo((object)"[Bridge.Help] Stripped >MOONS block from help page.");
					}
				}
				else
				{
					ManualLogSource log3 = Log;
					if (log3 != null)
					{
						log3.LogInfo((object)"[Bridge.Help] No >MOONS block found - skipping strip.");
					}
				}
				Match match = ConstellationsBlockPattern.Match(text);
				if (match.Success)
				{
					Match match2 = FirstHeadingPattern.Match(text);
					if (match2.Success && match2.Index != match.Index)
					{
						string value = match.Value;
						string text2 = text.Remove(match.Index, match.Length);
						Match match3 = FirstHeadingPattern.Match(text2);
						int startIndex = (match3.Success ? match3.Index : 0);
						text = text2.Insert(startIndex, value);
						flag = true;
						ManualLogSource log4 = Log;
						if (log4 != null)
						{
							log4.LogInfo((object)"[Bridge.Help] Moved >CONSTELLATIONS block to top of help page.");
						}
					}
					else if (match2.Success)
					{
						ManualLogSource log5 = Log;
						if (log5 != null)
						{
							log5.LogInfo((object)"[Bridge.Help] >CONSTELLATIONS already at top - no reorder needed.");
						}
					}
				}
				else
				{
					ManualLogSource log6 = Log;
					if (log6 != null)
					{
						log6.LogInfo((object)"[Bridge.Help] No >CONSTELLATIONS block found - skipping reorder.");
					}
				}
				if (Plugin.ReaddMoonsBelowConstellations != null && Plugin.ReaddMoonsBelowConstellations.Value)
				{
					Match match4 = ConstellationsBlockPattern.Match(text);
					if (match4.Success && !MoonsBlockPattern.IsMatch(text))
					{
						int startIndex2 = match4.Index + match4.Length;
						text = text.Insert(startIndex2, ">MOONS\nTo see the list of moons the autopilot can route to.\n\n");
						flag = true;
						ManualLogSource log7 = Log;
						if (log7 != null)
						{
							log7.LogInfo((object)"[Bridge.Help] Re-added >MOONS block below >CONSTELLATIONS (config opt-in).");
						}
					}
				}
				if (flag)
				{
					val.displayText = text;
				}
				_alreadyProcessed = true;
			}
			catch (Exception arg)
			{
				ManualLogSource log8 = Log;
				if (log8 != null)
				{
					log8.LogError((object)$"[Bridge.Help] DoRewrite exception: {arg}");
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class MoonSelectionClosePatch
	{
		[CompilerGenerated]
		private sealed class <TargetMethods>d__4 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private MethodBase <>2__current;

			private int <>l__initialThreadId;

			MethodBase IEnumerator<MethodBase>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TargetMethods>d__4(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "darmuhsTerminalStuff");
					if (assembly == null)
					{
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogInfo((object)"[Bridge.MoonClose] TerminalStuff not loaded - skipping moon-close patch.");
						}
						return false;
					}
					Type type = assembly.GetType("TerminalStuff.MoonsTweaks.MoonInfo");
					if (type == null)
					{
						ManualLogSource log2 = Log;
						if (log2 != null)
						{
							log2.LogWarning((object)"[Bridge.MoonClose] MoonInfo type not found - skipping.");
						}
						return false;
					}
					MethodInfo method = type.GetMethod("SelectThisMoon", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (method == null)
					{
						ManualLogSource log3 = Log;
						if (log3 != null)
						{
							log3.LogWarning((object)"[Bridge.MoonClose] SelectThisMoon method not found on MoonInfo - skipping.");
						}
						return false;
					}
					_moonsPlusMenuField = assembly.GetType("TerminalStuff.MoonsTweaks.MoonsPlus")?.GetField("MoonsPlusMenu", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					if (_moonsPlusMenuField == null)
					{
						ManualLogSource log4 = Log;
						if (log4 != null)
						{
							log4.LogWarning((object)"[Bridge.MoonClose] MoonsPlusMenu field not found - skipping.");
						}
						return false;
					}
					Type type2 = _moonsPlusMenuField.FieldType;
					while (type2 != null && type2 != typeof(object))
					{
						_exitMenuMethod = type2.GetMethod("ExitMenu", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(bool) }, null);
						if (_exitMenuMethod != null)
						{
							break;
						}
						type2 = type2.BaseType;
					}
					if (_exitMenuMethod == null)
					{
						ManualLogSource log5 = Log;
						if (log5 != null)
						{
							log5.LogWarning((object)"[Bridge.MoonClose] ExitMenu(bool) not found on MoonsPlusMenu hierarchy - skipping.");
						}
						return false;
					}
					ManualLogSource log6 = Log;
					if (log6 != null)
					{
						log6.LogInfo((object)"[Bridge.MoonClose] Patching MoonInfo.SelectThisMoon.");
					}
					<>2__current = method;
					<>1__state = 1;
					return true;
				}
				case 1:
					<>1__state = -1;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <TargetMethods>d__4(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<MethodBase>)this).GetEnumerator();
			}
		}

		private static MethodInfo _exitMenuMethod;

		private static FieldInfo _moonsPlusMenuField;

		private static ManualLogSource Log => Plugin.Log;

		[IteratorStateMachine(typeof(<TargetMethods>d__4))]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TargetMethods>d__4(-2);
		}

		[HarmonyPostfix]
		private static void Postfix()
		{
			try
			{
				if ((Object)(object)StartOfRound.Instance == (Object)null || !StartOfRound.Instance.travellingToNewLevel)
				{
					return;
				}
				object value = _moonsPlusMenuField.GetValue(null);
				if (value != null)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogInfo((object)"[Bridge.MoonClose] Moon route succeeded - closing MoonsPlus menu.");
					}
					_exitMenuMethod.Invoke(value, new object[1] { true });
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogError((object)$"[Bridge.MoonClose] Postfix exception: {arg}");
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class MoonsPlusHeaderPatch
	{
		[CompilerGenerated]
		private sealed class <TargetMethods>d__3 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private MethodBase <>2__current;

			private int <>l__initialThreadId;

			MethodBase IEnumerator<MethodBase>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TargetMethods>d__3(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "darmuhsTerminalStuff");
					if (assembly == null)
					{
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogInfo((object)"[Bridge.Header] TerminalStuff not loaded - skipping MoonsPlus header patch.");
						}
						return false;
					}
					Type type = assembly.GetType("TerminalStuff.MoonsTweaks.MoonsPlus");
					if (type == null)
					{
						ManualLogSource log2 = Log;
						if (log2 != null)
						{
							log2.LogWarning((object)"[Bridge.Header] MoonsPlus type not found - skipping header patch.");
						}
						return false;
					}
					MethodInfo method = type.GetMethod("SetupBetterMenu", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					if (method == null)
					{
						ManualLogSource log3 = Log;
						if (log3 != null)
						{
							log3.LogWarning((object)"[Bridge.Header] SetupBetterMenu not found - skipping header patch.");
						}
						return false;
					}
					BuildConsNameGetter();
					ManualLogSource log4 = Log;
					if (log4 != null)
					{
						log4.LogInfo((object)"[Bridge.Header] Patching MoonsPlus.SetupBetterMenu.");
					}
					<>2__current = method;
					<>1__state = 1;
					return true;
				}
				case 1:
					<>1__state = -1;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <TargetMethods>d__3(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<MethodBase>)this).GetEnumerator();
			}
		}

		private static Func<string> _consNameGetter;

		private static ManualLogSource Log => Plugin.Log;

		[IteratorStateMachine(typeof(<TargetMethods>d__3))]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TargetMethods>d__3(-2);
		}

		private static void BuildConsNameGetter()
		{
			try
			{
				Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "LethalConstellations");
				if (assembly == null)
				{
					return;
				}
				Type type = assembly.GetType("LethalConstellations.PluginCore.Collections");
				if (type == null)
				{
					return;
				}
				FieldInfo currentField = type.GetField("CurrentConstellationCM", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (currentField == null)
				{
					return;
				}
				FieldInfo consNameField = currentField.FieldType.GetField("consName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(consNameField == null))
				{
					_consNameGetter = delegate
					{
						object value = currentField.GetValue(null);
						return (value == null) ? string.Empty : (((string)consNameField.GetValue(value)) ?? string.Empty);
					};
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("[Bridge.Header] Could not build consName getter: " + ex.Message));
				}
			}
		}

		private static PropertyInfo FindHeaderProperty(object instance)
		{
			if (instance == null)
			{
				return null;
			}
			Type type = instance.GetType();
			while (type != null && type != typeof(object))
			{
				PropertyInfo property = type.GetProperty("Header", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.PropertyType == typeof(Func<string>) && property.CanWrite)
				{
					return property;
				}
				type = type.BaseType;
			}
			return null;
		}

		[HarmonyPostfix]
		private static void Postfix()
		{
			try
			{
				Type type = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "darmuhsTerminalStuff")?.GetType("TerminalStuff.MoonsTweaks.MoonsPlus");
				if (type == null)
				{
					return;
				}
				string[] obj = new string[3] { "AllMoons", "GoodWeatherMoons", "AffordableMoons" };
				int num = 0;
				string[] array = obj;
				foreach (string text in array)
				{
					object obj2 = type.GetField(text, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null);
					if (obj2 == null)
					{
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogDebug((object)("[Bridge.Header] Field " + text + " not found or null - skipping."));
						}
						continue;
					}
					PropertyInfo propertyInfo = FindHeaderProperty(obj2);
					if (propertyInfo == null)
					{
						ManualLogSource log2 = Log;
						if (log2 != null)
						{
							log2.LogWarning((object)("[Bridge.Header] Could not find Header property on " + obj2.GetType().FullName + "."));
						}
						continue;
					}
					Func<string> value = delegate
					{
						string text2 = _consNameGetter?.Invoke() ?? string.Empty;
						return string.IsNullOrEmpty(text2) ? "===== Select a Moon =====\n\n" : ("===== " + text2.ToUpperInvariant() + " =====\n\n");
					};
					propertyInfo.SetValue(obj2, value);
					num++;
					ManualLogSource log3 = Log;
					if (log3 != null)
					{
						log3.LogDebug((object)("[Bridge.Header] Replaced header on " + text + "."));
					}
				}
				if (num > 0)
				{
					ManualLogSource log4 = Log;
					if (log4 != null)
					{
						log4.LogInfo((object)$"[Bridge.Header] MoonsPlus headers now show current constellation ({num} pages).");
					}
				}
				else
				{
					ManualLogSource log5 = Log;
					if (log5 != null)
					{
						log5.LogWarning((object)"[Bridge.Header] No headers were rewritten - constellation name will not appear.");
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log6 = Log;
				if (log6 != null)
				{
					log6.LogError((object)$"[Bridge.Header] Postfix exception: {arg}");
				}
			}
		}
	}
	[BepInPlugin("com.lawson.lguconstellationsbridge", "LGUConstellationsBridge", "4.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.lawson.lguconstellationsbridge";

		public const string PluginName = "LGUConstellationsBridge";

		public const string PluginVersion = "4.5.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> ReaddMoonsBelowConstellations;

		internal static ConfigEntry<bool> EnableUnlockNotification;

		internal static ConfigEntry<float> NotificationVolume;

		private Harmony _harmony;

		public static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"LGUConstellationsBridge v4.5.0 loading...");
			ReaddMoonsBelowConstellations = ((BaseUnityPlugin)this).Config.Bind<bool>("Help", "ReaddMoonsBelowConstellations", false, "If true, the help page will show >MOONS again as a second entry directly under >CONSTELLATIONS. Default off so players are funneled through constellations.");
			EnableUnlockNotification = ((BaseUnityPlugin)this).Config.Bind<bool>("Notifications", "EnableUnlockNotification", true, "Show a green flash + chime when a constellation is unlocked.");
			NotificationVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Notifications", "NotificationVolume", 1f, new ConfigDescription("Volume multiplier for the constellation unlock chime (0.0 – 1.0).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			_harmony = new Harmony("com.lawson.lguconstellationsbridge");
			SafePatchAll(typeof(TravelToNewConstellationPatch));
			SafePatchAll(typeof(ChangeLevelBlockPatch));
			SafePatchAll(typeof(MoonsPlusHeaderPatch));
			SafePatchAll(typeof(MoonSelectionClosePatch));
			SafePatchAll(typeof(HelpPagePatch));
			Log.LogInfo((object)"LGUConstellationsBridge ready.");
		}

		private void SafePatchAll(Type type)
		{
			try
			{
				_harmony.PatchAll(type);
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("PatchAll(" + type.Name + ") failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch]
	internal static class TravelToNewConstellationPatch
	{
		[CompilerGenerated]
		private sealed class <TargetMethods>d__8 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private MethodBase <>2__current;

			private int <>l__initialThreadId;

			MethodBase IEnumerator<MethodBase>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TargetMethods>d__8(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "LethalConstellations");
					if (assembly == null)
					{
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogWarning((object)"[Bridge] LethalConstellations assembly not loaded - bridge will not patch.");
						}
						return false;
					}
					Type type = assembly.GetType("LethalConstellations.PluginCore.MenuStuff");
					if (type == null)
					{
						ManualLogSource log2 = Log;
						if (log2 != null)
						{
							log2.LogWarning((object)"[Bridge] Could not find LethalConstellations.PluginCore.MenuStuff.");
						}
						return false;
					}
					MethodInfo method = type.GetMethod("TravelToNewConstellation", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
					{
						typeof(int),
						typeof(int)
					}, null);
					if (method == null)
					{
						ManualLogSource log3 = Log;
						if (log3 != null)
						{
							log3.LogWarning((object)"[Bridge] Could not find MenuStuff.TravelToNewConstellation(int, int).");
						}
						return false;
					}
					_inMenuField = type.GetField("ConstellationsMenu", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.FieldType.GetField("inMenu", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					_confirmationCheckField = type.GetField("ConfirmationCheck", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					Assembly assembly2 = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "darmuhsTerminalStuff");
					_enterMoonsMenuMethod = (assembly2?.GetType("TerminalStuff.MoonsTweaks.MoonsPlus"))?.GetMethod("EnterMoonsMenu", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					if (_enterMoonsMenuMethod != null)
					{
						_moonsPlusAvailable = true;
						ManualLogSource log4 = Log;
						if (log4 != null)
						{
							log4.LogInfo((object)"[Bridge] MoonsPlus.EnterMoonsMenu found - constellation picks will route to MoonsPlus.");
						}
					}
					else if (assembly2 == null)
					{
						ManualLogSource log5 = Log;
						if (log5 != null)
						{
							log5.LogInfo((object)"[Bridge] TerminalStuff not loaded - constellation picks will land on vanilla moons.");
						}
					}
					else
					{
						ManualLogSource log6 = Log;
						if (log6 != null)
						{
							log6.LogWarning((object)"[Bridge] TerminalStuff loaded but MoonsPlus not found - falling back to vanilla moons.");
						}
					}
					BuildConsNameGetter(assembly);
					ManualLogSource log7 = Log;
					if (log7 != null)
					{
						log7.LogInfo((object)"[Bridge] Patching MenuStuff.TravelToNewConstellation.");
					}
					<>2__current = method;
					<>1__state = 1;
					return true;
				}
				case 1:
					<>1__state = -1;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <TargetMethods>d__8(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<MethodBase>)this).GetEnumerator();
			}
		}

		private static FieldInfo _confirmationCheckField;

		private static FieldInfo _inMenuField;

		private static MethodInfo _enterMoonsMenuMethod;

		private static bool _moonsPlusAvailable;

		private static Func<string> _currentConsNameGetter;

		internal static bool BlockNextChangeLevel;

		private static ManualLogSource Log => Plugin.Log;

		[IteratorStateMachine(typeof(<TargetMethods>d__8))]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TargetMethods>d__8(-2);
		}

		[HarmonyPrefix]
		private static void Prefix()
		{
			BlockNextChangeLevel = true;
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogDebug((object)"[Bridge] Block flag set - next ChangeLevelServerRpc will be skipped.");
			}
		}

		[HarmonyPostfix]
		private static void Postfix(int getPrice, int indexNum)
		{
			try
			{
				BlockNextChangeLevel = false;
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)$"[Bridge] TravelToNewConstellation completed (price={getPrice}, index={indexNum}).");
				}
				ClearLcMenuState();
				if (_moonsPlusAvailable && _enterMoonsMenuMethod != null)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogInfo((object)"[Bridge] Routing to MoonsPlus.EnterMoonsMenu.");
					}
					_enterMoonsMenuMethod.Invoke(null, null);
				}
				else
				{
					ManualLogSource log3 = Log;
					if (log3 != null)
					{
						log3.LogInfo((object)"[Bridge] No MoonsPlus available - menu will close to default ExitPage.");
					}
				}
			}
			catch (Exception arg)
			{
				BlockNextChangeLevel = false;
				ManualLogSource log4 = Log;
				if (log4 != null)
				{
					log4.LogError((object)$"[Bridge] Postfix exception: {arg}");
				}
			}
		}

		private static void BuildConsNameGetter(Assembly lcAsm)
		{
			try
			{
				Type type = lcAsm?.GetType("LethalConstellations.PluginCore.Collections");
				if (type == null)
				{
					return;
				}
				FieldInfo currentField = type.GetField("CurrentConstellationCM", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (currentField == null)
				{
					return;
				}
				FieldInfo consNameField = currentField.FieldType.GetField("consName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(consNameField == null))
				{
					_currentConsNameGetter = delegate
					{
						object value = currentField.GetValue(null);
						return (value == null) ? null : (consNameField.GetValue(value) as string);
					};
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogInfo((object)"[Bridge] Collections.CurrentConstellationCM.consName getter built.");
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("[Bridge] Could not build constellation name getter: " + ex.Message));
				}
			}
		}

		private static void ClearLcMenuState()
		{
			try
			{
				object obj = (AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "LethalConstellations")?.GetType("LethalConstellations.PluginCore.MenuStuff"))?.GetField("ConstellationsMenu", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null);
				if (obj != null && _inMenuField != null)
				{
					_inMenuField.SetValue(obj, false);
				}
				if (_confirmationCheckField != null)
				{
					_confirmationCheckField.SetValue(null, false);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("[Bridge] ClearLcMenuState failed (non-fatal): " + ex.Message));
				}
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "ChangeLevelServerRpc", new Type[]
	{
		typeof(int),
		typeof(int)
	})]
	internal static class ChangeLevelBlockPatch
	{
		private static ManualLogSource Log => Plugin.Log;

		[HarmonyPrefix]
		private static bool Prefix(int levelID, int newGroupCreditsAmount)
		{
			if (TravelToNewConstellationPatch.BlockNextChangeLevel)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)($"[Bridge] Blocking ChangeLevelServerRpc(levelID={levelID}, credits={newGroupCreditsAmount}) " + "during constellation pick - keeping ship in place."));
				}
				return false;
			}
			return true;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

LGUContractHUD.dll

Decompiled 4 days ago
using System;
using System.Collections;
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 BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MoreShipUpgrades.Managers;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("MoreShipUpgrades")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LGUContractHUD")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Contract HUD display for LateGameUpgrades")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8c5521e37f37e3d76518a16d04e5d1051842f105")]
[assembly: AssemblyProduct("LGUContractHUD")]
[assembly: AssemblyTitle("LGUContractHUD")]
[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 LGUContractHUD
{
	internal class ContractHUDManager : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <AnimateSequence>d__31 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ContractHUDManager <>4__this;

			public string title;

			public string objective;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <AnimateSequence>d__31(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: 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_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_011f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0129: Expected O, but got Unknown
				//IL_016d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0177: Expected O, but got Unknown
				int num = <>1__state;
				ContractHUDManager contractHUDManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					contractHUDManager._isShowing = true;
					contractHUDManager._cardRect.anchorMin = new Vector2(0.5f, 0.5f);
					contractHUDManager._cardRect.anchorMax = new Vector2(0.5f, 0.5f);
					contractHUDManager._cardRect.pivot = new Vector2(0.5f, 0.5f);
					contractHUDManager._cardRect.anchoredPosition = Vector2.zero;
					((Transform)contractHUDManager._cardRect).localScale = Vector3.one * 1f;
					contractHUDManager._canvasGroup.alpha = 1f;
					contractHUDManager.SetBorderVisible(visible: true);
					((TMP_Text)contractHUDManager._titleText).text = "";
					((TMP_Text)contractHUDManager._objectiveText).text = "";
					<>2__current = ((MonoBehaviour)contractHUDManager).StartCoroutine(contractHUDManager.TypewriterText(contractHUDManager._titleText, title));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.15f);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)contractHUDManager).StartCoroutine(contractHUDManager.TypewriterText(contractHUDManager._objectiveText, objective));
					<>1__state = 3;
					return true;
				case 3:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.6f);
					<>1__state = 4;
					return true;
				case 4:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)contractHUDManager).StartCoroutine(contractHUDManager.ShrinkAndMove());
					<>1__state = 5;
					return true;
				case 5:
					<>1__state = -1;
					contractHUDManager.SetBorderVisible(visible: false);
					contractHUDManager._isShowing = true;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <FadeOut>d__34 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ContractHUDManager <>4__this;

			private float <duration>5__2;

			private float <start>5__3;

			private float <elapsed>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <FadeOut>d__34(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				ContractHUDManager contractHUDManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<duration>5__2 = 0.5f;
					<start>5__3 = contractHUDManager._canvasGroup.alpha;
					<elapsed>5__4 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<elapsed>5__4 < <duration>5__2)
				{
					<elapsed>5__4 += Time.deltaTime;
					contractHUDManager._canvasGroup.alpha = Mathf.Lerp(<start>5__3, 0f, <elapsed>5__4 / <duration>5__2);
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				contractHUDManager._canvasGroup.alpha = 0f;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <ShrinkAndMove>d__33 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ContractHUDManager <>4__this;

			private Vector2 <startPos>5__2;

			private Vector3 <startScale>5__3;

			private Vector2 <targetPos>5__4;

			private Vector3 <targetScale>5__5;

			private float <elapsed>5__6;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ShrinkAndMove>d__33(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//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_0053: 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_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_011b: Unknown result type (might be due to invalid IL or missing references)
				//IL_012c: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				ContractHUDManager contractHUDManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<startPos>5__2 = contractHUDManager._cardRect.anchoredPosition;
					<startScale>5__3 = ((Transform)contractHUDManager._cardRect).localScale;
					<targetPos>5__4 = new Vector2(688f, 440f);
					<targetScale>5__5 = Vector3.one * 0.75f;
					<elapsed>5__6 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<elapsed>5__6 < 1.2f)
				{
					<elapsed>5__6 += Time.deltaTime;
					float num2 = Mathf.Clamp01(<elapsed>5__6 / 1.2f);
					float num3 = num2 * num2 * (3f - 2f * num2);
					contractHUDManager._cardRect.anchoredPosition = Vector2.Lerp(<startPos>5__2, <targetPos>5__4, num3);
					((Transform)contractHUDManager._cardRect).localScale = Vector3.Lerp(<startScale>5__3, <targetScale>5__5, num3);
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				contractHUDManager._cardRect.anchoredPosition = <targetPos>5__4;
				((Transform)contractHUDManager._cardRect).localScale = <targetScale>5__5;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <TypewriterText>d__32 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TextMeshProUGUI tmp;

			public string fullText;

			private int <i>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TypewriterText>d__32(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0077: Expected O, but got Unknown
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_0087;
				}
				<>1__state = -1;
				((TMP_Text)tmp).text = "";
				<i>5__2 = 0;
				goto IL_0097;
				IL_0087:
				<i>5__2++;
				goto IL_0097;
				IL_0097:
				if (<i>5__2 < fullText.Length)
				{
					((TMP_Text)tmp).text = fullText.Substring(0, <i>5__2 + 1);
					if (!char.IsWhiteSpace(fullText[<i>5__2]))
					{
						<>2__current = (object)new WaitForSeconds(0.035f);
						<>1__state = 1;
						return true;
					}
					goto IL_0087;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private Canvas _canvas;

		private CanvasGroup _canvasGroup;

		private RectTransform _cardRect;

		private Image _borderImage;

		private TextMeshProUGUI _titleText;

		private TextMeshProUGUI _objectiveText;

		private Coroutine _animCoroutine;

		private bool _isShowing;

		private static readonly Color LCTeal = new Color(0f, 1f, 0.87f, 1f);

		private static readonly Color BorderColor = new Color(0f, 1f, 0.87f, 0.6f);

		private const float CenteredScale = 1f;

		private const float SettledScale = 0.75f;

		private const float CardWidth = 620f;

		private const float CardHeight = 180f;

		private const float TypewriterCharDelay = 0.035f;

		private const float ShrinkMoveDuration = 1.2f;

		private const float PauseAfterTypewriter = 0.6f;

		private static readonly Dictionary<string, (string DisplayName, string Objective)> ContractInfo = new Dictionary<string, (string, string)>
		{
			{
				"Data",
				("DATA RETRIEVAL", "Locate the laptop, bruteforce its IP,\nlogin and extract the .db file")
			},
			{
				"Defusal",
				("BOMB DEFUSAL", "Find the bomb, lookup its serial number,\ncut the correct wires before time runs out")
			},
			{
				"Exorcism",
				("EXORCISM", "Find the ritual site, identify the demon,\ngather ritual items and complete the banishment")
			},
			{
				"Exterminator",
				("EXTERMINATOR", "Locate the bug nest\nand destroy it to clear the infestation")
			},
			{
				"Extraction",
				("EXTRACTION", "Find the lost operative,\nheal them with a medkit and bring them to the ship")
			}
		};

		internal static ContractHUDManager Instance { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			BuildUI();
			Hide(immediate: true);
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (((Scene)(ref scene)).name != "SampleSceneRelay")
			{
				Hide(immediate: true);
			}
		}

		internal void ShowContract()
		{
			string activeContractType = GetActiveContractType();
			if (string.IsNullOrEmpty(activeContractType) || activeContractType == "None")
			{
				Plugin.Log.LogDebug((object)"No active contract - skipping HUD.");
				return;
			}
			if (!ContractInfo.TryGetValue(activeContractType, out (string, string) value))
			{
				Plugin.Log.LogWarning((object)("Unknown contract type '" + activeContractType + "' - skipping HUD."));
				return;
			}
			if (_animCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_animCoroutine);
			}
			_animCoroutine = ((MonoBehaviour)this).StartCoroutine(AnimateSequence(value.Item1, value.Item2));
		}

		internal void Hide(bool immediate = false)
		{
			if (_animCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_animCoroutine);
				_animCoroutine = null;
			}
			_isShowing = false;
			if (immediate)
			{
				_canvasGroup.alpha = 0f;
			}
			else
			{
				((MonoBehaviour)this).StartCoroutine(FadeOut());
			}
		}

		private void BuildUI()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Expected O, but got Unknown
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			_canvas = ((Component)this).gameObject.AddComponent<Canvas>();
			_canvas.renderMode = (RenderMode)0;
			_canvas.sortingOrder = 100;
			CanvasScaler obj = ((Component)this).gameObject.AddComponent<CanvasScaler>();
			obj.uiScaleMode = (ScaleMode)1;
			obj.referenceResolution = new Vector2(1920f, 1080f);
			obj.matchWidthOrHeight = 1f;
			((Component)this).gameObject.AddComponent<GraphicRaycaster>();
			_canvasGroup = ((Component)this).gameObject.AddComponent<CanvasGroup>();
			_canvasGroup.interactable = false;
			_canvasGroup.blocksRaycasts = false;
			GameObject val = new GameObject("ContractCard");
			val.transform.SetParent(((Component)_canvas).transform, false);
			_cardRect = val.AddComponent<RectTransform>();
			_cardRect.sizeDelta = new Vector2(620f, 180f);
			_cardRect.anchorMin = new Vector2(0.5f, 0.5f);
			_cardRect.anchorMax = new Vector2(0.5f, 0.5f);
			_cardRect.pivot = new Vector2(0.5f, 0.5f);
			_cardRect.anchoredPosition = Vector2.zero;
			CreateBorder(val.transform);
			GameObject val2 = new GameObject("TitleText");
			val2.transform.SetParent(val.transform, false);
			_titleText = val2.AddComponent<TextMeshProUGUI>();
			((TMP_Text)_titleText).fontSize = 32f;
			((TMP_Text)_titleText).fontStyle = (FontStyles)1;
			((Graphic)_titleText).color = LCTeal;
			((TMP_Text)_titleText).alignment = (TextAlignmentOptions)257;
			((TMP_Text)_titleText).enableWordWrapping = false;
			((TMP_Text)_titleText).overflowMode = (TextOverflowModes)0;
			RectTransform rectTransform = ((TMP_Text)_titleText).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 0.5f);
			rectTransform.anchorMax = new Vector2(1f, 1f);
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.offsetMin = new Vector2(20f, 5f);
			rectTransform.offsetMax = new Vector2(-20f, -15f);
			AssignVanillaFont(_titleText);
			GameObject val3 = new GameObject("ObjectiveText");
			val3.transform.SetParent(val.transform, false);
			_objectiveText = val3.AddComponent<TextMeshProUGUI>();
			((TMP_Text)_objectiveText).fontSize = 22f;
			((TMP_Text)_objectiveText).fontStyle = (FontStyles)0;
			((Graphic)_objectiveText).color = LCTeal;
			((TMP_Text)_objectiveText).alignment = (TextAlignmentOptions)257;
			((TMP_Text)_objectiveText).enableWordWrapping = true;
			((TMP_Text)_objectiveText).overflowMode = (TextOverflowModes)0;
			RectTransform rectTransform2 = ((TMP_Text)_objectiveText).rectTransform;
			rectTransform2.anchorMin = new Vector2(0f, 0f);
			rectTransform2.anchorMax = new Vector2(1f, 0.5f);
			rectTransform2.pivot = new Vector2(0.5f, 0.5f);
			rectTransform2.offsetMin = new Vector2(20f, 10f);
			rectTransform2.offsetMax = new Vector2(-20f, -5f);
			AssignVanillaFont(_objectiveText);
		}

		private void AssignVanillaFont(TextMeshProUGUI tmp)
		{
			if ((Object)(object)HUDManager.Instance != (Object)null && (Object)(object)HUDManager.Instance.clockNumber != (Object)null)
			{
				TMP_FontAsset font = ((TMP_Text)HUDManager.Instance.clockNumber).font;
				if ((Object)(object)font != (Object)null)
				{
					((TMP_Text)tmp).font = font;
					return;
				}
			}
			TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
			foreach (TMP_FontAsset val in array)
			{
				if (((Object)val).name.Contains("3270") || ((Object)val).name.Contains("edunline") || ((Object)val).name.Contains("EdgeOf"))
				{
					((TMP_Text)tmp).font = val;
					break;
				}
			}
		}

		private void CreateBorder(Transform parent)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_008f: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			float num = 2f;
			_borderImage = CreateBorderEdge(parent, "BorderTop", new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, 0f - num), new Vector2(0f, 0f));
			CreateBorderEdge(parent, "BorderBottom", new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 0f), new Vector2(0f, num));
			CreateBorderEdge(parent, "BorderLeft", new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 0.5f), new Vector2(0f, 0f), new Vector2(num, 0f));
			CreateBorderEdge(parent, "BorderRight", new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(1f, 0.5f), new Vector2(0f - num, 0f), new Vector2(0f, 0f));
		}

		private Image CreateBorderEdge(Transform parent, string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 offsetMin, Vector2 offsetMax)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMin = anchorMin;
			obj.anchorMax = anchorMax;
			obj.pivot = pivot;
			obj.offsetMin = offsetMin;
			obj.offsetMax = offsetMax;
			Image obj2 = val.AddComponent<Image>();
			((Graphic)obj2).color = BorderColor;
			return obj2;
		}

		[IteratorStateMachine(typeof(<AnimateSequence>d__31))]
		private IEnumerator AnimateSequence(string title, string objective)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AnimateSequence>d__31(0)
			{
				<>4__this = this,
				title = title,
				objective = objective
			};
		}

		[IteratorStateMachine(typeof(<TypewriterText>d__32))]
		private IEnumerator TypewriterText(TextMeshProUGUI tmp, string fullText)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TypewriterText>d__32(0)
			{
				tmp = tmp,
				fullText = fullText
			};
		}

		[IteratorStateMachine(typeof(<ShrinkAndMove>d__33))]
		private IEnumerator ShrinkAndMove()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ShrinkAndMove>d__33(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<FadeOut>d__34))]
		private IEnumerator FadeOut()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FadeOut>d__34(0)
			{
				<>4__this = this
			};
		}

		private void SetBorderVisible(bool visible)
		{
			Transform transform = ((Component)_cardRect).transform;
			for (int i = 0; i < transform.childCount; i++)
			{
				Transform child = transform.GetChild(i);
				if (((Object)child).name.StartsWith("Border"))
				{
					((Component)child).gameObject.SetActive(visible);
				}
			}
		}

		private string GetActiveContractType()
		{
			if ((Object)(object)ContractManager.Instance == (Object)null)
			{
				return null;
			}
			return ContractManager.Instance.contractType;
		}

		internal static void EnsureInstance()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Instance != (Object)null))
			{
				new GameObject("LGUContractHUD_Canvas").AddComponent<ContractHUDManager>();
			}
		}
	}
	[BepInPlugin("com.lguhud.contracthud", "LGUContractHUD", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "com.lguhud.contracthud";

		public const string PLUGIN_NAME = "LGUContractHUD";

		public const string PLUGIN_VERSION = "1.0.0";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			_harmony = new Harmony("com.lguhud.contracthud");
			_harmony.PatchAll(typeof(StartOfRoundPatches));
			Log.LogInfo((object)"LGUContractHUD v1.0.0 loaded.");
		}
	}
	internal static class StartOfRoundPatches
	{
		[CompilerGenerated]
		private sealed class <WrapWithContractHUD>d__1 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public IEnumerator original;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WrapWithContractHUD>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					goto IL_0045;
				case 1:
					<>1__state = -1;
					goto IL_0045;
				case 2:
					{
						<>1__state = -1;
						ContractHUDManager.EnsureInstance();
						if ((Object)(object)ContractHUDManager.Instance != (Object)null)
						{
							ContractHUDManager.Instance.ShowContract();
						}
						return false;
					}
					IL_0045:
					if (original.MoveNext())
					{
						<>2__current = original.Current;
						<>1__state = 1;
						return true;
					}
					<>2__current = (object)new WaitForSeconds(1.5f);
					<>1__state = 2;
					return true;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "openingDoorsSequence")]
		[HarmonyPostfix]
		private static void AfterOpeningDoorsSequence(ref IEnumerator __result)
		{
			__result = WrapWithContractHUD(__result);
		}

		[IteratorStateMachine(typeof(<WrapWithContractHUD>d__1))]
		private static IEnumerator WrapWithContractHUD(IEnumerator original)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WrapWithContractHUD>d__1(0)
			{
				original = original
			};
		}

		[HarmonyPatch(typeof(StartOfRound), "ShipLeave")]
		[HarmonyPostfix]
		private static void OnShipLeave()
		{
			if ((Object)(object)ContractHUDManager.Instance != (Object)null)
			{
				ContractHUDManager.Instance.Hide();
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "ShipLeaveAutomatically")]
		[HarmonyPostfix]
		private static void OnShipLeaveAutomatically()
		{
			if ((Object)(object)ContractHUDManager.Instance != (Object)null)
			{
				ContractHUDManager.Instance.Hide();
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "SetShipReadyToLand")]
		[HarmonyPostfix]
		private static void OnSetShipReadyToLand()
		{
			if ((Object)(object)ContractHUDManager.Instance != (Object)null)
			{
				ContractHUDManager.Instance.Hide(immediate: true);
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "Disconnect")]
		[HarmonyPostfix]
		private static void OnDisconnect()
		{
			if ((Object)(object)ContractHUDManager.Instance != (Object)null)
			{
				ContractHUDManager.Instance.Hide(immediate: true);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LGUContractHUD";

		public const string PLUGIN_NAME = "LGUContractHUD";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

LGUCustomUpgrades.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using HotbarPlus.Config;
using HotbarPlus.Input;
using HotbarPlus.Networking;
using HotbarPlus.Patches;
using LGUCustomUpgrades.HUD;
using LGUCustomUpgrades.Patches;
using LGUCustomUpgrades.Upgrades;
using LethalHands;
using Microsoft.CodeAnalysis;
using MoreShipUpgrades.Managers;
using MoreShipUpgrades.Misc.Upgrades;
using MoreShipUpgrades.UI.TerminalNodes;
using MoreShipUpgrades.UpgradeComponents.TierUpgrades;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("HotbarPlus")]
[assembly: IgnoresAccessChecksTo("LethalHands")]
[assembly: IgnoresAccessChecksTo("MoreShipUpgrades")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LGUCustomUpgrades")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Custom upgrades for LateGameUpgrades")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+3423ac2532854e1dd50557f43abe79469809b434")]
[assembly: AssemblyProduct("LGUCustomUpgrades")]
[assembly: AssemblyTitle("LGUCustomUpgrades")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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 LGUCustomUpgrades
{
	internal class PipeBombProjectile : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <LureLoop>d__29 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public PipeBombProjectile <>4__this;

			private float <startTime>5__2;

			private float <nextBeep>5__3;

			private float <nextBlink>5__4;

			private float <nextLurePoll>5__5;

			private bool <host>5__6;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LureLoop>d__29(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Expected O, but got Unknown
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				PipeBombProjectile pipeBombProjectile = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					GameObject val = new GameObject("LGU_PipeBomb_BlinkLight");
					val.transform.SetParent(((Component)pipeBombProjectile).transform, false);
					pipeBombProjectile._blinkLight = val.AddComponent<Light>();
					pipeBombProjectile._blinkLight.type = (LightType)2;
					pipeBombProjectile._blinkLight.color = Color.red;
					pipeBombProjectile._blinkLight.intensity = 2f;
					pipeBombProjectile._blinkLight.range = 5f;
					pipeBombProjectile._blinkLight.shadows = (LightShadows)0;
					pipeBombProjectile._beepSource = ((Component)pipeBombProjectile).gameObject.AddComponent<AudioSource>();
					pipeBombProjectile._beepSource.spatialBlend = 1f;
					pipeBombProjectile._beepSource.minDistance = 1f;
					pipeBombProjectile._beepSource.maxDistance = 30f;
					pipeBombProjectile._beepSource.playOnAwake = false;
					<startTime>5__2 = Time.time;
					pipeBombProjectile._detonationTime = <startTime>5__2 + pipeBombProjectile._lureDuration;
					<nextBeep>5__3 = 0f;
					<nextBlink>5__4 = 0f;
					<nextLurePoll>5__5 = 0f;
					<host>5__6 = (Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsHost;
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogInfo((object)$"[PipeBomb] Lure started, duration={pipeBombProjectile._lureDuration}s, lure radius={pipeBombProjectile._lureRadius}");
					}
					break;
				}
				case 1:
					<>1__state = -1;
					break;
				}
				if (Time.time < pipeBombProjectile._detonationTime)
				{
					float num2 = Mathf.Clamp01((Time.time - <startTime>5__2) / pipeBombProjectile._lureDuration);
					if (Time.time >= <nextBlink>5__4)
					{
						if ((Object)(object)pipeBombProjectile._blinkLight != (Object)null)
						{
							((Behaviour)pipeBombProjectile._blinkLight).enabled = !((Behaviour)pipeBombProjectile._blinkLight).enabled;
						}
						<nextBlink>5__4 = Time.time + 0.3f;
					}
					if (Time.time >= <nextBeep>5__3)
					{
						if ((Object)(object)pipeBombProjectile._beepSource != (Object)null && (Object)(object)BeepClip != (Object)null)
						{
							pipeBombProjectile._beepSource.PlayOneShot(BeepClip);
						}
						float num3 = Mathf.Lerp(0.6f, 0.2f, num2);
						ManualLogSource log2 = Plugin.Log;
						if (log2 != null)
						{
							log2.LogInfo((object)$"[PipeBomb] Beep played at interval {num3:F2}s");
						}
						<nextBeep>5__3 = Time.time + num3;
					}
					if (<host>5__6 && Time.time >= <nextLurePoll>5__5)
					{
						pipeBombProjectile.LureNearbyEnemies();
						<nextLurePoll>5__5 = Time.time + 0.2f;
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				pipeBombProjectile.Detonate();
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private const float MAX_AIRBORNE_TIME = 5f;

		private const float LURE_POLL_INTERVAL = 0.2f;

		private const float BLINK_INTERVAL = 0.3f;

		private const float BEEP_START_INTERVAL = 0.6f;

		private const float BEEP_END_INTERVAL = 0.2f;

		internal static readonly List<PipeBombProjectile> ActiveBombs = new List<PipeBombProjectile>();

		internal static AudioClip BeepClip;

		private static Mesh _cachedMesh;

		private static Material _cachedMaterial;

		private static bool _meshScanned;

		private Rigidbody _rb;

		private Light _blinkLight;

		private AudioSource _beepSource;

		private bool _hasLanded;

		private bool _detonated;

		private float _spawnTime;

		private Vector3 _bombPosition;

		internal float _detonationTime;

		private float _lureRadius;

		private float _lureDuration;

		private float _blastRadius;

		private int _enemyDamage;

		private int _playerDamage;

		public static GameObject Spawn(Vector3 position, Vector3 direction, float throwForce)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("LGU_PipeBomb");
			val.transform.position = position;
			SphereCollider obj = val.AddComponent<SphereCollider>();
			obj.radius = 0.15f;
			((Collider)obj).isTrigger = false;
			Rigidbody val2 = val.AddComponent<Rigidbody>();
			val2.useGravity = true;
			val2.mass = 0.3f;
			val2.drag = 0.1f;
			val2.collisionDetectionMode = (CollisionDetectionMode)2;
			AttachVisual(val.transform);
			PipeBombProjectile pipeBombProjectile = val.AddComponent<PipeBombProjectile>();
			pipeBombProjectile._rb = val2;
			pipeBombProjectile._spawnTime = Time.time;
			pipeBombProjectile._lureRadius = Plugin.PipeBombLureRadius.Value;
			pipeBombProjectile._lureDuration = Plugin.PipeBombLureDuration.Value;
			pipeBombProjectile._blastRadius = Plugin.PipeBombBlastRadius.Value;
			pipeBombProjectile._enemyDamage = Plugin.PipeBombEnemyDamage.Value;
			pipeBombProjectile._playerDamage = Plugin.PipeBombPlayerDamage.Value;
			val2.AddForce(((Vector3)(ref direction)).normalized * throwForce, (ForceMode)2);
			ActiveBombs.Add(pipeBombProjectile);
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"[PipeBomb] Projectile spawned at ({position.x:F2},{position.y:F2},{position.z:F2}) with force ({((Vector3)(ref direction)).normalized.x * throwForce:F2},{((Vector3)(ref direction)).normalized.y * throwForce:F2},{((Vector3)(ref direction)).normalized.z * throwForce:F2})");
			}
			return val;
		}

		private static void AttachVisual(Transform parent)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			EnsureMeshCached();
			GameObject val = new GameObject("Visual");
			val.transform.SetParent(parent, false);
			val.transform.localScale = Vector3.one * 0.6f;
			if ((Object)(object)_cachedMesh != (Object)null && (Object)(object)_cachedMaterial != (Object)null)
			{
				val.AddComponent<MeshFilter>().sharedMesh = _cachedMesh;
				((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterial = _cachedMaterial;
			}
		}

		private static void EnsureMeshCached()
		{
			if (_meshScanned)
			{
				return;
			}
			_meshScanned = true;
			StunGrenadeItem[] array = Resources.FindObjectsOfTypeAll<StunGrenadeItem>();
			foreach (StunGrenadeItem val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				MeshFilter componentInChildren = ((Component)val).GetComponentInChildren<MeshFilter>(true);
				MeshRenderer componentInChildren2 = ((Component)val).GetComponentInChildren<MeshRenderer>(true);
				if (!((Object)(object)componentInChildren == (Object)null) && !((Object)(object)componentInChildren2 == (Object)null) && !((Object)(object)componentInChildren.sharedMesh == (Object)null) && !((Object)(object)((Renderer)componentInChildren2).sharedMaterial == (Object)null))
				{
					_cachedMesh = componentInChildren.sharedMesh;
					_cachedMaterial = ((Renderer)componentInChildren2).sharedMaterial;
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogInfo((object)("[PipeBomb] Borrowed mesh '" + ((Object)_cachedMesh).name + "' from StunGrenadeItem."));
					}
					return;
				}
			}
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				log2.LogWarning((object)"[PipeBomb] Could not borrow stun grenade mesh — projectile will be invisible mid-flight.");
			}
		}

		private void Update()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (!_hasLanded && Time.time - _spawnTime >= 5f)
			{
				Land(((Component)this).transform.position);
			}
		}

		private void OnCollisionEnter(Collision collision)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (!_hasLanded && (!((Object)(object)collision.collider != (Object)null) || !((Object)(object)((Component)collision.collider).GetComponentInParent<PlayerControllerB>() != (Object)null)))
			{
				ContactPoint contact = collision.GetContact(0);
				Land(((ContactPoint)(ref contact)).point);
			}
		}

		private void Land(Vector3 position)
		{
			//IL_0011: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if (!_hasLanded)
			{
				_hasLanded = true;
				_bombPosition = position;
				((Component)this).transform.position = position;
				if ((Object)(object)_rb != (Object)null)
				{
					_rb.velocity = Vector3.zero;
					_rb.angularVelocity = Vector3.zero;
					_rb.isKinematic = true;
				}
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"[PipeBomb] Projectile landed at ({position.x:F2},{position.y:F2},{position.z:F2})");
				}
				((MonoBehaviour)this).StartCoroutine(LureLoop());
			}
		}

		[IteratorStateMachine(typeof(<LureLoop>d__29))]
		private IEnumerator LureLoop()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LureLoop>d__29(0)
			{
				<>4__this = this
			};
		}

		private void LureNearbyEnemies()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapSphere(_bombPosition, _lureRadius);
			HashSet<EnemyAI> hashSet = new HashSet<EnemyAI>();
			foreach (Collider val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				EnemyAI componentInParent = ((Component)val).GetComponentInParent<EnemyAI>();
				if ((Object)(object)componentInParent == (Object)null || componentInParent.isEnemyDead || !hashSet.Add(componentInParent))
				{
					continue;
				}
				try
				{
					componentInParent.targetPlayer = null;
					componentInParent.movingTowardsTargetPlayer = false;
					componentInParent.SetDestinationToPosition(_bombPosition, false);
					if ((Object)(object)componentInParent.agent != (Object)null && componentInParent.agent.isOnNavMesh)
					{
						componentInParent.agent.SetDestination(_bombPosition);
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogDebug((object)("[PipeBomb] Lure call failed on " + ((object)componentInParent).GetType().Name + ": " + ex.Message));
					}
				}
			}
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)$"[PipeBomb] Lure pulse: found {hashSet.Count} enemies in radius");
			}
		}

		private void Detonate()
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if (_detonated)
			{
				return;
			}
			_detonated = true;
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"[PipeBomb] Detonation at ({_bombPosition.x:F2},{_bombPosition.y:F2},{_bombPosition.z:F2})");
			}
			try
			{
				float num = _blastRadius * 0.5f;
				float blastRadius = _blastRadius;
				Landmine.SpawnExplosion(_bombPosition, true, num, blastRadius, _playerDamage, 80f, (GameObject)null, false);
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)$"[PipeBomb] Landmine.SpawnExplosion called (killRange={num}, damageRange={blastRadius}, nonLethalDamage={_playerDamage})");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogError((object)$"[PipeBomb] Landmine.SpawnExplosion threw: {arg}");
				}
			}
			ActiveBombs.Remove(this);
			Object.Destroy((Object)(object)((Component)this).gameObject);
			ManualLogSource log4 = Plugin.Log;
			if (log4 != null)
			{
				log4.LogInfo((object)"[PipeBomb] Cleanup complete");
			}
		}

		private void OnDestroy()
		{
			ActiveBombs.Remove(this);
		}

		public static void DestroyAllActive()
		{
			PipeBombProjectile[] array = ActiveBombs.ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				if ((Object)(object)array[i] != (Object)null && (Object)(object)((Component)array[i]).gameObject != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)array[i]).gameObject);
				}
			}
			ActiveBombs.Clear();
		}
	}
	[BepInPlugin("LGUCustomUpgrades", "LGU Custom Upgrades", "1.4.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private const string MOD_GUID = "LGUCustomUpgrades";

		private const string MOD_NAME = "LGU Custom Upgrades";

		private const string MOD_VERSION = "1.4.0";

		public static ManualLogSource Log;

		internal static List<GameObject> NetworkPrefabs = new List<GameObject>();

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

		public static ConfigEntry<string> FlareBurstKeybind;

		public static ConfigEntry<string> ShadowStepKeybind;

		public static ConfigEntry<string> EscapeProtocolKeybind;

		public static ConfigEntry<string> PipeBombKeybind;

		public static ConfigEntry<bool> PipeBombEnabled;

		public static ConfigEntry<int> PipeBombPriceT1;

		public static ConfigEntry<int> PipeBombPriceT2;

		public static ConfigEntry<int> PipeBombPriceT3;

		public static ConfigEntry<int> PipeBombChargesT1;

		public static ConfigEntry<int> PipeBombChargesT2;

		public static ConfigEntry<int> PipeBombChargesT3;

		public static ConfigEntry<float> PipeBombLureRadius;

		public static ConfigEntry<float> PipeBombLureDuration;

		public static ConfigEntry<float> PipeBombBlastRadius;

		public static ConfigEntry<int> PipeBombEnemyDamage;

		public static ConfigEntry<int> PipeBombPlayerDamage;

		public static ConfigEntry<float> PipeBombCooldown;

		public static ConfigEntry<float> PipeBombThrowForce;

		private static Key? _flareBurstKey;

		private static Key? _shadowStepKey;

		private static Key? _escapeProtocolKey;

		private static Key? _pipeBombKey;

		private static bool _keysResolved = false;

		private static readonly HashSet<uint> ReservedHashes = new HashSet<uint> { 0u, 581939109u };

		private static readonly HashSet<uint> AssignedHashes = new HashSet<uint>();

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"LGU Custom Upgrades loading...");
			FlareBurstKeybind = ((BaseUnityPlugin)this).Config.Bind<string>("Keybinds", "Flare Burst Key", "v", "Key to activate Flare Burst. Use Unity InputSystem Key names: v, g, b, f, t, r, x, c, z, q, capslock, tab, etc.");
			ShadowStepKeybind = ((BaseUnityPlugin)this).Config.Bind<string>("Keybinds", "Shadow Step Key", "g", "Key to activate Shadow Step invisibility. Use Unity InputSystem Key names: v, g, b, f, t, r, x, c, z, q, capslock, tab, etc.");
			EscapeProtocolKeybind = ((BaseUnityPlugin)this).Config.Bind<string>("Keybinds", "Escape Protocol Key", "h", "Key to toggle Escape Protocol exit markers. Use Unity InputSystem Key names: v, g, b, f, t, r, x, c, z, q, capslock, tab, etc.");
			PipeBombKeybind = ((BaseUnityPlugin)this).Config.Bind<string>("Keybinds", "Pipe Bomb Key", "g", "Key to throw a Pipe Bomb. Use Unity InputSystem Key names: v, g, b, f, t, r, x, c, z, q, capslock, tab, etc.");
			PipeBombEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Pipe Bomb", "Enabled", true, "Enable the Pipe Bomb upgrade.");
			PipeBombPriceT1 = ((BaseUnityPlugin)this).Config.Bind<int>("Pipe Bomb", "Price Tier 1", 80, "BXP cost for Tier 1.");
			PipeBombPriceT2 = ((BaseUnityPlugin)this).Config.Bind<int>("Pipe Bomb", "Price Tier 2", 120, "BXP cost for Tier 2.");
			PipeBombPriceT3 = ((BaseUnityPlugin)this).Config.Bind<int>("Pipe Bomb", "Price Tier 3", 160, "BXP cost for Tier 3.");
			PipeBombChargesT1 = ((BaseUnityPlugin)this).Config.Bind<int>("Pipe Bomb", "Charges Tier 1", 1, "Charges per round at Tier 1.");
			PipeBombChargesT2 = ((BaseUnityPlugin)this).Config.Bind<int>("Pipe Bomb", "Charges Tier 2", 2, "Charges per round at Tier 2.");
			PipeBombChargesT3 = ((BaseUnityPlugin)this).Config.Bind<int>("Pipe Bomb", "Charges Tier 3", 3, "Charges per round at Tier 3.");
			PipeBombLureRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Pipe Bomb", "Lure Radius", 25f, "Radius in units for attracting enemies.");
			PipeBombLureDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Pipe Bomb", "Lure Duration", 4.5f, "Seconds before detonation.");
			PipeBombBlastRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Pipe Bomb", "Blast Radius", 8f, "Radius in units for detonation damage.");
			PipeBombEnemyDamage = ((BaseUnityPlugin)this).Config.Bind<int>("Pipe Bomb", "Enemy Damage", 3, "Damage dealt to enemies (HitEnemy hit count).");
			PipeBombPlayerDamage = ((BaseUnityPlugin)this).Config.Bind<int>("Pipe Bomb", "Player Damage", 60, "Damage dealt to players (HP, 0-100).");
			PipeBombCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Pipe Bomb", "Cooldown", 10f, "Seconds between throws.");
			PipeBombThrowForce = ((BaseUnityPlugin)this).Config.Bind<float>("Pipe Bomb", "Throw Force", 18f, "Projectile launch force.");
			_flareBurstKey = ParseKey(FlareBurstKeybind.Value);
			_shadowStepKey = ParseKey(ShadowStepKeybind.Value);
			_escapeProtocolKey = ParseKey(EscapeProtocolKeybind.Value);
			_pipeBombKey = ParseKey(PipeBombKeybind.Value);
			_keysResolved = true;
			Log.LogInfo((object)("Keybinds: Flare Burst=[" + FlareBurstKeybind.Value + "] ShadowStep=[" + ShadowStepKeybind.Value + "] EscapeProtocol=[" + EscapeProtocolKeybind.Value + "] PipeBomb=[" + PipeBombKeybind.Value + "]"));
			Plugin.CreateUpgradePrefab<SpatialAwarenessUpgrade>("Spatial Awareness");
			Plugin.CreateUpgradePrefab<LoneWolfUpgrade>("Lone Wolf");
			Plugin.CreateUpgradePrefab<SalvagerUpgrade>("Salvager");
			Plugin.CreateUpgradePrefab<LethalHandsUpgrade>("Lethal Hands Training");
			Plugin.CreateUpgradePrefab<RetaliationUpgrade>("Retaliation");
			Plugin.CreateUpgradePrefab<FlareBurstUpgrade>("Flare Burst");
			Plugin.CreateUpgradePrefab<PredatorInstinctUpgrade>("Predator Instinct");
			Plugin.CreateUpgradePrefab<ShadowStepUpgrade>("Shadow Step");
			Plugin.CreateUpgradePrefab<AdrenalineRushUpgrade>("Adrenaline Rush");
			Plugin.CreateUpgradePrefab<SquadSightUpgrade>("Squad Sight");
			Plugin.CreateUpgradePrefab<GlowInTheDarkUpgrade>("Glow in the Dark");
			Plugin.CreateUpgradePrefab<EscapeProtocolUpgrade>("Escape Protocol");
			Plugin.CreateUpgradePrefab<ExtraSlotUpgrade>("Extra Inventory Slot");
			if (PipeBombEnabled.Value)
			{
				Plugin.CreateUpgradePrefab<PipeBombUpgrade>("Pipe Bomb");
			}
			UpgradeBus.Instance.upgradeTypes.Add(typeof(SpatialAwarenessUpgrade));
			UpgradeBus.Instance.upgradeTypes.Add(typeof(LoneWolfUpgrade));
			UpgradeBus.Instance.upgradeTypes.Add(typeof(SalvagerUpgrade));
			UpgradeBus.Instance.upgradeTypes.Add(typeof(LethalHandsUpgrade));
			UpgradeBus.Instance.upgradeTypes.Add(typeof(RetaliationUpgrade));
			UpgradeBus.Instance.upgradeTypes.Add(typeof(FlareBurstUpgrade));
			UpgradeBus.Instance.upgradeTypes.Add(typeof(PredatorInstinctUpgrade));
			UpgradeBus.Instance.upgradeTypes.Add(typeof(ShadowStepUpgrade));
			UpgradeBus.Instance.upgradeTypes.Add(typeof(AdrenalineRushUpgrade));
			UpgradeBus.Instance.upgradeTypes.Add(typeof(SquadSightUpgrade));
			UpgradeBus.Instance.upgradeTypes.Add(typeof(GlowInTheDarkUpgrade));
			UpgradeBus.Instance.upgradeTypes.Add(typeof(EscapeProtocolUpgrade));
			UpgradeBus.Instance.upgradeTypes.Add(typeof(ExtraSlotUpgrade));
			if (PipeBombEnabled.Value)
			{
				UpgradeBus.Instance.upgradeTypes.Add(typeof(PipeBombUpgrade));
			}
			harmony.PatchAll();
			Log.LogInfo((object)"LGU Custom Upgrades loaded successfully!");
		}

		public static Key? GetFlareBurstKey()
		{
			return _flareBurstKey;
		}

		public static Key? GetShadowStepKey()
		{
			return _shadowStepKey;
		}

		public static Key? GetEscapeProtocolKey()
		{
			return _escapeProtocolKey;
		}

		public static Key? GetPipeBombKey()
		{
			return _pipeBombKey;
		}

		private static Key? ParseKey(string keyName)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrWhiteSpace(keyName))
			{
				return null;
			}
			if (Enum.TryParse<Key>(keyName, ignoreCase: true, out Key result))
			{
				return result;
			}
			switch (keyName.ToLower().Trim())
			{
			case "a":
				return (Key)15;
			case "b":
				return (Key)16;
			case "c":
				return (Key)17;
			case "d":
				return (Key)18;
			case "e":
				return (Key)19;
			case "f":
				return (Key)20;
			case "g":
				return (Key)21;
			case "h":
				return (Key)22;
			case "i":
				return (Key)23;
			case "j":
				return (Key)24;
			case "k":
				return (Key)25;
			case "l":
				return (Key)26;
			case "m":
				return (Key)27;
			case "n":
				return (Key)28;
			case "p":
				return (Key)30;
			case "q":
				return (Key)31;
			case "r":
				return (Key)32;
			case "s":
				return (Key)33;
			case "t":
				return (Key)34;
			case "u":
				return (Key)35;
			case "v":
				return (Key)36;
			case "w":
				return (Key)37;
			case "x":
				return (Key)38;
			case "y":
				return (Key)39;
			case "z":
				return (Key)40;
			case "capslock":
			case "caps":
				return (Key)72;
			case "tab":
				return (Key)3;
			case "space":
				return (Key)1;
			case "f1":
				return (Key)94;
			case "f2":
				return (Key)95;
			case "f3":
				return (Key)96;
			case "f4":
				return (Key)97;
			case "f5":
				return (Key)98;
			case "f6":
				return (Key)99;
			case "f7":
				return (Key)100;
			case "f8":
				return (Key)101;
			default:
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("ParseKey: unrecognised key name '" + keyName + "'. Ability will use its default key."));
				}
				return null;
			}
			}
		}

		internal static void CreateUpgradePrefab<T>(string name) where T : BaseUpgrade
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			NetworkObject netObj = val.AddComponent<NetworkObject>();
			val.AddComponent<T>();
			((Object)val).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)val);
			uint num = GenerateUniqueHash(name);
			AssignGlobalObjectIdHash(netObj, num);
			NetworkPrefabs.Add(val);
			if (!UpgradeBus.Instance.UpgradeObjects.ContainsKey(name))
			{
				UpgradeBus.Instance.UpgradeObjects.Add(name, val);
			}
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)$"Registered upgrade prefab '{name}' with GlobalObjectIdHash={num}");
			}
		}

		private static uint GenerateUniqueHash(string prefabName)
		{
			string name = Assembly.GetExecutingAssembly().GetName().Name;
			uint num = ComputeHash(name + ":" + prefabName);
			int num2 = 0;
			while (ReservedHashes.Contains(num) || AssignedHashes.Contains(num))
			{
				num2++;
				num = ComputeHash($"{name}:{prefabName}:{num2}");
				if (num2 > 1000)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("GenerateUniqueHash: could not find unique hash for '" + prefabName + "' after 1000 salts."));
					}
					break;
				}
			}
			AssignedHashes.Add(num);
			return num;
		}

		private static uint ComputeHash(string input)
		{
			using MD5 mD = MD5.Create();
			return BitConverter.ToUInt32(mD.ComputeHash(Encoding.UTF8.GetBytes(input)), 0);
		}

		private static void AssignGlobalObjectIdHash(NetworkObject netObj, uint hash)
		{
			Type typeFromHandle = typeof(NetworkObject);
			PropertyInfo property = typeFromHandle.GetProperty("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null && property.CanWrite)
			{
				property.SetValue(netObj, hash);
				return;
			}
			FieldInfo field = typeFromHandle.GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				field.SetValue(netObj, hash);
				return;
			}
			FieldInfo field2 = typeFromHandle.GetField("<GlobalObjectIdHash>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field2 != null)
			{
				field2.SetValue(netObj, hash);
				return;
			}
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)"Could not find NetworkObject.GlobalObjectIdHash via reflection. Multiplayer spawn will fail.");
			}
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "Start")]
	internal static class GameNetworkManagerStartPatch
	{
		[HarmonyPostfix]
		private static void RegisterNetworkPrefabs()
		{
			foreach (GameObject networkPrefab in Plugin.NetworkPrefabs)
			{
				if (!NetworkManager.Singleton.NetworkConfig.Prefabs.Contains(networkPrefab))
				{
					NetworkManager.Singleton.AddNetworkPrefab(networkPrefab);
				}
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LGUCustomUpgrades";

		public const string PLUGIN_NAME = "LGUCustomUpgrades";

		public const string PLUGIN_VERSION = "1.1.0";
	}
}
namespace LGUCustomUpgrades.Upgrades
{
	internal class AdrenalineRushUpgrade : TierUpgrade
	{
		public const string UPGRADE_NAME = "Adrenaline Rush";

		public const int INITIAL_PRICE = 20;

		public static readonly int[] TIER_PRICES = new int[1] { 30 };

		public const int LOW_HP_THRESHOLD = 20;

		public const float SPEED_MULTIPLIER = 1.3f;

		public const float INVINCIBILITY_SECONDS = 2f;

		public static bool IsAdrenalineActive = false;

		public static bool InsuranceUsedThisRound = false;

		public static bool IsInvincible = false;

		public static float InvincibilityEndTime = 0f;

		public static float OriginalSpeed = 0f;

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Adrenaline Rush";
			((BaseUpgrade)this).overridenUpgradeName = "Adrenaline Rush";
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			string text = "";
			text += $"${initialPrice} - Level 1: Below 20 HP, gain +30% movement speed and a danger vignette.\n";
			if (incrementalPrices != null && incrementalPrices.Length != 0)
			{
				text += $"${incrementalPrices[0]} - Level 2: Survive one lethal hit per round at 1HP + 2s invincibility (enemy/trap only).\n";
			}
			return text;
		}

		public static void RegisterUpgrade()
		{
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Adrenaline Rush", Array.Empty<string>());
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!UpgradeBus.Instance.UpgradeObjects.ContainsKey("Adrenaline Rush"))
			{
				return null;
			}
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Adrenaline Rush", false, true, 20, TIER_PRICES, "", UpgradeBus.Instance.UpgradeObjects["Adrenaline Rush"], true, (PurchaseMode)0, false, 1f);
		}

		public static bool IsUnlocked()
		{
			return BaseUpgrade.GetActiveUpgrade("Adrenaline Rush");
		}

		public static int GetTier()
		{
			if (!IsUnlocked())
			{
				return 0;
			}
			return BaseUpgrade.GetUpgradeLevel("Adrenaline Rush") + 1;
		}

		public static bool HasInsurance()
		{
			return GetTier() >= 2;
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "AdrenalineRushUpgrade";
		}
	}
	internal class EscapeProtocolUpgrade : OneTimeUpgrade
	{
		public const string UPGRADE_NAME = "Escape Protocol";

		public const int PRICE = 25;

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Escape Protocol";
			((BaseUpgrade)this).overridenUpgradeName = "Escape Protocol";
		}

		public override string GetDisplayInfo(int price = -1)
		{
			return $"${price} - Toggle to reveal all exits through walls with real-time distance readouts.";
		}

		public static void RegisterUpgrade()
		{
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Escape Protocol", Array.Empty<string>());
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!UpgradeBus.Instance.UpgradeObjects.ContainsKey("Escape Protocol"))
			{
				return null;
			}
			return UpgradeBus.Instance.SetupOneTimeTerminalNode("Escape Protocol", false, true, 25, "", UpgradeBus.Instance.UpgradeObjects["Escape Protocol"], true, (PurchaseMode)0, false, 1f);
		}

		public static bool IsUnlocked()
		{
			return BaseUpgrade.GetActiveUpgrade("Escape Protocol");
		}

		public override void __initializeVariables()
		{
			((OneTimeUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((OneTimeUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "EscapeProtocolUpgrade";
		}
	}
	internal class ExtraSlotUpgrade : TierUpgrade
	{
		public const string UPGRADE_NAME = "Extra Inventory Slot";

		public const int INITIAL_PRICE = 25;

		public static readonly int[] TIER_PRICES = new int[2] { 25, 25 };

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Extra Inventory Slot";
			((BaseUpgrade)this).overridenUpgradeName = "Extra Inventory Slot";
		}

		public override void Load()
		{
			((BaseUpgrade)this).Load();
			try
			{
				int num = BaseUpgrade.GetUpgradeLevel("Extra Inventory Slot") + 1;
				PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
				if ((Object)(object)val != (Object)null)
				{
					ExtraSlotManager.BroadcastBonusSlots(val.actualClientId, num);
					Plugin.Log.LogInfo((object)$"ExtraSlot: Load() — broadcasting tier {num} for local player");
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"ExtraSlot: Load() failed: {arg}");
			}
		}

		public override void Increment()
		{
			((TierUpgrade)this).Increment();
			try
			{
				int num = BaseUpgrade.GetUpgradeLevel("Extra Inventory Slot") + 1;
				PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
				if ((Object)(object)val != (Object)null)
				{
					ExtraSlotManager.BroadcastBonusSlots(val.actualClientId, num);
					Plugin.Log.LogInfo((object)$"ExtraSlot: Increment() — broadcasting tier {num} for local player");
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"ExtraSlot: Increment() failed: {arg}");
			}
		}

		public override void Unwind()
		{
			((TierUpgrade)this).Unwind();
			try
			{
				PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
				if ((Object)(object)val != (Object)null)
				{
					ExtraSlotManager.BroadcastBonusSlots(val.actualClientId, 0);
					Plugin.Log.LogInfo((object)"ExtraSlot: Unwind() — clearing bonus for local player");
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"ExtraSlot: Unwind() failed: {arg}");
			}
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			string text = "EXTRA INVENTORY SLOT\nExpands your suit's carrying capacity with modular storage compartments.\n\n";
			text += $"${initialPrice} - Tier 1: +1 inventory slot.\n";
			if (incrementalPrices != null && incrementalPrices.Length != 0)
			{
				text += $"${incrementalPrices[0]} - Tier 2: +1 inventory slot (total +2).\n";
			}
			if (incrementalPrices != null && incrementalPrices.Length > 1)
			{
				text += $"${incrementalPrices[1]} - Tier 3: +1 inventory slot (total +3).\n";
			}
			return text + "\n\"More pockets, more problems -- but mostly more pockets.\"\n";
		}

		public static void RegisterUpgrade()
		{
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Extra Inventory Slot", Array.Empty<string>());
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!UpgradeBus.Instance.UpgradeObjects.ContainsKey("Extra Inventory Slot"))
			{
				return null;
			}
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Extra Inventory Slot", false, true, 25, TIER_PRICES, "", UpgradeBus.Instance.UpgradeObjects["Extra Inventory Slot"], true, (PurchaseMode)0, false, 1f);
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "ExtraSlotUpgrade";
		}
	}
	internal class FlareBurstUpgrade : TierUpgrade
	{
		public const string UPGRADE_NAME = "Flare Burst";

		public const int INITIAL_PRICE = 15;

		public static readonly int[] TIER_PRICES = new int[2] { 22, 30 };

		public static readonly float[] RADIUS_BY_LEVEL = new float[3] { 15f, 25f, 25f };

		public static readonly float[] STUN_BY_LEVEL = new float[3] { 3f, 5f, 5f };

		public const float TIER3_FLEE_SECONDS = 4f;

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Flare Burst";
			((BaseUpgrade)this).overridenUpgradeName = "Flare Burst";
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			string text = "";
			text += $"${initialPrice} - Level 1: Press [V] to flash a 15m AOE that stuns enemies for 3s. One use per round.\n";
			if (incrementalPrices != null && incrementalPrices.Length != 0)
			{
				text += $"${incrementalPrices[0]} - Level 2: Radius increases to 25m, stun to 5s.\n";
			}
			if (incrementalPrices != null && incrementalPrices.Length > 1)
			{
				text += $"${incrementalPrices[1]} - Level 3: After the stun, hit enemies flee for 4s.\n";
			}
			return text;
		}

		public static void RegisterUpgrade()
		{
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Flare Burst", Array.Empty<string>());
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!UpgradeBus.Instance.UpgradeObjects.ContainsKey("Flare Burst"))
			{
				return null;
			}
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Flare Burst", false, true, 15, TIER_PRICES, "", UpgradeBus.Instance.UpgradeObjects["Flare Burst"], true, (PurchaseMode)0, false, 1f);
		}

		public static bool IsUnlocked()
		{
			return BaseUpgrade.GetActiveUpgrade("Flare Burst");
		}

		public static int GetTier()
		{
			if (!IsUnlocked())
			{
				return 0;
			}
			return BaseUpgrade.GetUpgradeLevel("Flare Burst") + 1;
		}

		public static float GetRadius()
		{
			int tier = GetTier();
			if (tier <= 0)
			{
				return 0f;
			}
			return RADIUS_BY_LEVEL[tier - 1];
		}

		public static float GetStunSeconds()
		{
			int tier = GetTier();
			if (tier <= 0)
			{
				return 0f;
			}
			return STUN_BY_LEVEL[tier - 1];
		}

		public static bool ShouldFlee()
		{
			return GetTier() >= 3;
		}

		public static bool IsMaxTier()
		{
			return GetTier() >= 3;
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "FlareBurstUpgrade";
		}
	}
	internal class GlowInTheDarkUpgrade : OneTimeUpgrade
	{
		public const string UPGRADE_NAME = "Glow in the Dark";

		public const int PRICE = 25;

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Glow in the Dark";
			((BaseUpgrade)this).overridenUpgradeName = "Glow in the Dark";
		}

		public override string GetDisplayInfo(int price = -1)
		{
			return $"${price} - A soft ambient glow radiates from your body, illuminating the area around you.";
		}

		public static void RegisterUpgrade()
		{
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Glow in the Dark", Array.Empty<string>());
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!UpgradeBus.Instance.UpgradeObjects.ContainsKey("Glow in the Dark"))
			{
				return null;
			}
			return UpgradeBus.Instance.SetupOneTimeTerminalNode("Glow in the Dark", false, true, 25, "", UpgradeBus.Instance.UpgradeObjects["Glow in the Dark"], true, (PurchaseMode)0, false, 1f);
		}

		public static bool IsUnlocked()
		{
			return BaseUpgrade.GetActiveUpgrade("Glow in the Dark");
		}

		public override void __initializeVariables()
		{
			((OneTimeUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((OneTimeUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "GlowInTheDarkUpgrade";
		}
	}
	internal class LethalHandsUpgrade : TierUpgrade
	{
		public const string UPGRADE_NAME = "Lethal Hands Training";

		public const int INITIAL_PRICE = 15;

		public static readonly int[] TIER_PRICES = new int[2] { 22, 30 };

		private const float TIER_1_DAMAGE = 0.5f;

		private const float TIER_2_DAMAGE = 1f;

		private const float TIER_3_DAMAGE = 1.5f;

		public const float TIER_3_STUN_SECONDS = 1f;

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Lethal Hands Training";
			((BaseUpgrade)this).overridenUpgradeName = "Lethal Hands Training";
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			string text = "";
			text += $"${initialPrice} - Tier 1: Unlocks empty-handed punching (LMB / RMB). 50% shovel damage.\n";
			if (incrementalPrices != null && incrementalPrices.Length != 0)
			{
				text += $"${incrementalPrices[0]} - Tier 2: Punch damage increased to 100% shovel damage.\n";
			}
			if (incrementalPrices != null && incrementalPrices.Length > 1)
			{
				text += $"${incrementalPrices[1]} - Tier 3: 150% shovel damage and stuns enemies on hit.\n";
			}
			return text;
		}

		public static void RegisterUpgrade()
		{
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Lethal Hands Training", Array.Empty<string>());
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!UpgradeBus.Instance.UpgradeObjects.ContainsKey("Lethal Hands Training"))
			{
				return null;
			}
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Lethal Hands Training", false, true, 15, TIER_PRICES, "", UpgradeBus.Instance.UpgradeObjects["Lethal Hands Training"], true, (PurchaseMode)0, false, 1f);
		}

		public static float GetCurrentDamageMultiplier()
		{
			if (!BaseUpgrade.GetActiveUpgrade("Lethal Hands Training"))
			{
				return 0f;
			}
			return BaseUpgrade.GetUpgradeLevel("Lethal Hands Training") switch
			{
				0 => 0.5f, 
				1 => 1f, 
				2 => 1.5f, 
				_ => 1.5f, 
			};
		}

		public static bool ShouldStun()
		{
			if (!BaseUpgrade.GetActiveUpgrade("Lethal Hands Training"))
			{
				return false;
			}
			return BaseUpgrade.GetUpgradeLevel("Lethal Hands Training") >= 2;
		}

		public static bool IsUnlocked()
		{
			return BaseUpgrade.GetActiveUpgrade("Lethal Hands Training");
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "LethalHandsUpgrade";
		}
	}
	internal class LoneWolfUpgrade : TierUpgrade
	{
		[CompilerGenerated]
		private sealed class <RevealNearbyEnemies>d__21 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public PlayerControllerB player;

			private List<Light> <revealLights>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <RevealNearbyEnemies>d__21(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<revealLights>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_010b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0115: Expected O, but got Unknown
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					EnemyAI[] array = Object.FindObjectsOfType<EnemyAI>();
					<revealLights>5__2 = new List<Light>();
					EnemyAI[] array2 = array;
					foreach (EnemyAI val in array2)
					{
						if (!((Object)(object)val == (Object)null) && !val.isEnemyDead && !(Vector3.Distance(((Component)val).transform.position, ((Component)player).transform.position) > 30f))
						{
							Light val2 = ((Component)val).gameObject.AddComponent<Light>();
							val2.type = (LightType)2;
							val2.color = new Color(1f, 0.2f, 0.2f);
							val2.intensity = 4f;
							val2.range = 10f;
							<revealLights>5__2.Add(val2);
						}
					}
					if (<revealLights>5__2.Count > 0)
					{
						Plugin.Log.LogDebug((object)$"Lone Wolf Level 3: Revealed {<revealLights>5__2.Count} nearby enemies.");
					}
					<>2__current = (object)new WaitForSeconds(5f);
					<>1__state = 1;
					return true;
				}
				case 1:
					<>1__state = -1;
					foreach (Light item in <revealLights>5__2)
					{
						if ((Object)(object)item != (Object)null)
						{
							Object.Destroy((Object)(object)item);
						}
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string UPGRADE_NAME = "Lone Wolf";

		public const int INITIAL_PRICE = 15;

		public static readonly int[] TIER_PRICES = new int[2] { 22, 30 };

		private const float SPEED_MULTIPLIER = 0.3f;

		private const float STAMINA_RECOVERY_RATE = 0.015f;

		private const float ENEMY_REVEAL_RANGE = 30f;

		private const float ENEMY_REVEAL_DURATION = 5f;

		internal static bool LoneWolfActive = false;

		internal static int ActiveLevel = 0;

		private static float speedBonus = 0f;

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Lone Wolf";
			((BaseUpgrade)this).overridenUpgradeName = "Lone Wolf";
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			string text = "";
			text += $"${initialPrice} - Level 1: When last surviving player on moon, +30% movement speed.\n";
			if (incrementalPrices != null && incrementalPrices.Length != 0)
			{
				text += $"${incrementalPrices[0]} - Level 2: Also reduces stamina drain significantly.\n";
			}
			if (incrementalPrices != null && incrementalPrices.Length > 1)
			{
				text += $"${incrementalPrices[1]} - Level 3: Also briefly reveals nearby enemy positions.\n";
			}
			return text;
		}

		public static void RegisterUpgrade()
		{
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Lone Wolf", Array.Empty<string>());
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!UpgradeBus.Instance.UpgradeObjects.ContainsKey("Lone Wolf"))
			{
				return null;
			}
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Lone Wolf", false, true, 15, TIER_PRICES, "", UpgradeBus.Instance.UpgradeObjects["Lone Wolf"], true, (PurchaseMode)0, false, 1f);
		}

		internal static void CheckAndActivate()
		{
			if (!BaseUpgrade.GetActiveUpgrade("Lone Wolf") || LoneWolfActive)
			{
				return;
			}
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if ((Object)(object)localPlayerController == (Object)null || localPlayerController.isPlayerDead || localPlayerController.isInHangarShipRoom)
			{
				return;
			}
			int num = 0;
			for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
			{
				PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[i];
				if (val.isPlayerControlled && !val.isPlayerDead && !val.isInHangarShipRoom)
				{
					num++;
				}
			}
			if (num == 1)
			{
				int level = BaseUpgrade.GetUpgradeLevel("Lone Wolf") + 1;
				ActivateLoneWolf(localPlayerController, level);
			}
		}

		private static void ActivateLoneWolf(PlayerControllerB player, int level)
		{
			speedBonus = player.movementSpeed * 0.3f;
			player.movementSpeed += speedBonus;
			LoneWolfActive = true;
			ActiveLevel = level;
			Plugin.Log.LogInfo((object)$"Lone Wolf activated! Level {level}, speed bonus: {speedBonus:F2}");
			HUDManager.Instance.DisplayTip("LONE WOLF", GetActivationMessage(level), false, false, "LC_Tip1");
			if (level >= 3)
			{
				((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(RevealNearbyEnemies(player));
			}
		}

		private static string GetActivationMessage(int level)
		{
			return level switch
			{
				1 => "You're the last one standing. Movement speed increased.", 
				2 => "You're the last one standing. Speed and stamina enhanced.", 
				3 => "You're the last one standing. Full survival mode activated.", 
				_ => "Lone Wolf activated.", 
			};
		}

		internal static void Deactivate()
		{
			if (!LoneWolfActive)
			{
				return;
			}
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if ((Object)(object)localPlayerController != (Object)null)
			{
				localPlayerController.movementSpeed -= speedBonus;
				if (localPlayerController.movementSpeed < 4f)
				{
					localPlayerController.movementSpeed = 4.6f;
				}
			}
			speedBonus = 0f;
			LoneWolfActive = false;
			ActiveLevel = 0;
			Plugin.Log.LogDebug((object)"Lone Wolf deactivated.");
		}

		[IteratorStateMachine(typeof(<RevealNearbyEnemies>d__21))]
		private static IEnumerator RevealNearbyEnemies(PlayerControllerB player)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RevealNearbyEnemies>d__21(0)
			{
				player = player
			};
		}

		internal static void ApplyStaminaBonus(PlayerControllerB player)
		{
			if (LoneWolfActive && ActiveLevel >= 2 && !((Object)(object)player == (Object)null) && !player.isPlayerDead)
			{
				player.sprintMeter = Mathf.Clamp01(player.sprintMeter + Time.deltaTime * 0.015f);
			}
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "LoneWolfUpgrade";
		}
	}
	internal class PipeBombUpgrade : TierUpgrade
	{
		public const string UPGRADE_NAME = "Pipe Bomb";

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Pipe Bomb";
			((BaseUpgrade)this).overridenUpgradeName = "Pipe Bomb";
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			string arg = Plugin.PipeBombKeybind?.Value?.ToUpperInvariant() ?? "G";
			string text = "";
			text += $"${initialPrice} - Level 1: Press [{arg}] to throw a pipe bomb that lures enemies, then detonates. 1 charge per round.\n";
			if (incrementalPrices != null && incrementalPrices.Length != 0)
			{
				text += $"${incrementalPrices[0]} - Level 2: 2 charges per round.\n";
			}
			if (incrementalPrices != null && incrementalPrices.Length > 1)
			{
				text += $"${incrementalPrices[1]} - Level 3: 3 charges per round.\n";
			}
			return text;
		}

		public static void RegisterUpgrade()
		{
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Pipe Bomb", Array.Empty<string>());
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!UpgradeBus.Instance.UpgradeObjects.ContainsKey("Pipe Bomb"))
			{
				return null;
			}
			int value = Plugin.PipeBombPriceT1.Value;
			int[] array = new int[2]
			{
				Plugin.PipeBombPriceT2.Value,
				Plugin.PipeBombPriceT3.Value
			};
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Pipe Bomb", false, true, value, array, "", UpgradeBus.Instance.UpgradeObjects["Pipe Bomb"], true, (PurchaseMode)0, false, 1f);
		}

		public static bool IsUnlocked()
		{
			return BaseUpgrade.GetActiveUpgrade("Pipe Bomb");
		}

		public static int GetTier()
		{
			if (!IsUnlocked())
			{
				return 0;
			}
			return BaseUpgrade.GetUpgradeLevel("Pipe Bomb") + 1;
		}

		public static int GetMaxCharges()
		{
			return GetTier() switch
			{
				1 => Plugin.PipeBombChargesT1.Value, 
				2 => Plugin.PipeBombChargesT2.Value, 
				3 => Plugin.PipeBombChargesT3.Value, 
				_ => 0, 
			};
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "PipeBombUpgrade";
		}
	}
	internal class PredatorInstinctUpgrade : TierUpgrade
	{
		public const string UPGRADE_NAME = "Predator Instinct";

		public const int INITIAL_PRICE = 15;

		public static readonly int[] TIER_PRICES = new int[2] { 22, 30 };

		public static readonly float[] RANGE_BY_LEVEL = new float[3] { 10f, 20f, 30f };

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Predator Instinct";
			((BaseUpgrade)this).overridenUpgradeName = "Predator Instinct";
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			string text = "";
			text += $"${initialPrice} - Level 1: Reveals enemies within 10m as red point lights.\n";
			if (incrementalPrices != null && incrementalPrices.Length != 0)
			{
				text += $"${incrementalPrices[0]} - Level 2: Sense range expands to 20m.\n";
			}
			if (incrementalPrices != null && incrementalPrices.Length > 1)
			{
				text += $"${incrementalPrices[1]} - Level 3: Range becomes 30m and a heartbeat speeds up as enemies close.\n";
			}
			return text;
		}

		public static void RegisterUpgrade()
		{
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Predator Instinct", Array.Empty<string>());
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!UpgradeBus.Instance.UpgradeObjects.ContainsKey("Predator Instinct"))
			{
				return null;
			}
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Predator Instinct", false, true, 15, TIER_PRICES, "", UpgradeBus.Instance.UpgradeObjects["Predator Instinct"], true, (PurchaseMode)0, false, 1f);
		}

		public static bool IsUnlocked()
		{
			return BaseUpgrade.GetActiveUpgrade("Predator Instinct");
		}

		public static int GetTier()
		{
			if (!IsUnlocked())
			{
				return 0;
			}
			return BaseUpgrade.GetUpgradeLevel("Predator Instinct") + 1;
		}

		public static float GetRange()
		{
			int tier = GetTier();
			if (tier <= 0)
			{
				return 0f;
			}
			return RANGE_BY_LEVEL[tier - 1];
		}

		public static bool ShouldHeartbeat()
		{
			return GetTier() >= 3;
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "PredatorInstinctUpgrade";
		}
	}
	internal class RetaliationUpgrade : TierUpgrade
	{
		public const string UPGRADE_NAME = "Retaliation";

		public const int INITIAL_PRICE = 20;

		public static readonly int[] TIER_PRICES = new int[1] { 30 };

		public const float TIER1_REFLECT_CHANCE = 0.5f;

		public const float TIER2_STUN_SECONDS = 1f;

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Retaliation";
			((BaseUpgrade)this).overridenUpgradeName = "Retaliation";
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			string text = "";
			text += $"${initialPrice} - Level 1: When an enemy damages you, 50% chance to reflect a shovel hit back.\n";
			if (incrementalPrices != null && incrementalPrices.Length != 0)
			{
				text += $"${incrementalPrices[0]} - Level 2: Always reflects, plus a 1s stagger on the attacker.\n";
			}
			return text;
		}

		public static void RegisterUpgrade()
		{
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Retaliation", Array.Empty<string>());
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!UpgradeBus.Instance.UpgradeObjects.ContainsKey("Retaliation"))
			{
				return null;
			}
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Retaliation", false, true, 20, TIER_PRICES, "", UpgradeBus.Instance.UpgradeObjects["Retaliation"], true, (PurchaseMode)0, false, 1f);
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "RetaliationUpgrade";
		}
	}
	internal class SalvagerUpgrade : TierUpgrade
	{
		public const string UPGRADE_NAME = "Salvager";

		public const int INITIAL_PRICE = 25;

		public static readonly int[] TIER_PRICES = new int[2] { 25, 25 };

		public const int TIER_GLOW = 1;

		public const int TIER_BEACON = 2;

		public const int TIER_TRAIL = 3;

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Salvager";
			((BaseUpgrade)this).overridenUpgradeName = "Salvager";
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			string text = "Recovery and death-handling implants for the unlucky and the unlucky-adjacent.\n";
			text += $"${initialPrice} - Tier 1: Items dropped by dead players glow with a soft light.\n";
			if (incrementalPrices != null && incrementalPrices.Length != 0)
			{
				text += $"${incrementalPrices[0]} - Tier 2: On death, drops a pulsing beacon and a HUD skull marker.\n";
			}
			if (incrementalPrices != null && incrementalPrices.Length > 1)
			{
				text += $"${incrementalPrices[1]} - Tier 3: Also paints a ghost trail from the entrance to your body.\n";
			}
			return text;
		}

		public static void RegisterUpgrade()
		{
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Salvager", Array.Empty<string>());
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!UpgradeBus.Instance.UpgradeObjects.ContainsKey("Salvager"))
			{
				return null;
			}
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Salvager", false, true, 25, TIER_PRICES, "", UpgradeBus.Instance.UpgradeObjects["Salvager"], true, (PurchaseMode)0, false, 1f);
		}

		public static bool IsUnlocked()
		{
			return BaseUpgrade.GetActiveUpgrade("Salvager");
		}

		public static int GetTier()
		{
			if (!IsUnlocked())
			{
				return 0;
			}
			return BaseUpgrade.GetUpgradeLevel("Salvager") + 1;
		}

		public static bool HasTier(int requiredTier)
		{
			return GetTier() >= requiredTier;
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "SalvagerUpgrade";
		}
	}
	internal class ShadowStepUpgrade : TierUpgrade
	{
		public const string UPGRADE_NAME = "Shadow Step";

		public const int INITIAL_PRICE = 15;

		public static readonly int[] TIER_PRICES = new int[2] { 22, 30 };

		public const float INVISIBILITY_DURATION = 6f;

		public const float COOLDOWN_DURATION = 120f;

		public const float REDUCED_DETECTION_MULTIPLIER = 0.75f;

		public static bool IsInvisible = false;

		public static float InvisibilityEndTime = 0f;

		public static float CooldownEndTime = 0f;

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Shadow Step";
			((BaseUpgrade)this).overridenUpgradeName = "Shadow Step";
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			string text = "";
			text += $"${initialPrice} - Level 1: -25% enemy detection range while crouching.\n";
			if (incrementalPrices != null && incrementalPrices.Length != 0)
			{
				text += $"${incrementalPrices[0]} - Level 2: -25% detection range while crouching OR walking (not sprinting).\n";
			}
			if (incrementalPrices != null && incrementalPrices.Length > 1)
			{
				text += $"${incrementalPrices[1]} - Level 3: Press [G] for 6s of full invisibility (120s cooldown).\n";
			}
			return text;
		}

		public static void RegisterUpgrade()
		{
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Shadow Step", Array.Empty<string>());
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!UpgradeBus.Instance.UpgradeObjects.ContainsKey("Shadow Step"))
			{
				return null;
			}
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Shadow Step", false, true, 15, TIER_PRICES, "", UpgradeBus.Instance.UpgradeObjects["Shadow Step"], true, (PurchaseMode)0, false, 1f);
		}

		public static bool IsUnlocked()
		{
			return BaseUpgrade.GetActiveUpgrade("Shadow Step");
		}

		public static int GetTier()
		{
			if (!IsUnlocked())
			{
				return 0;
			}
			return BaseUpgrade.GetUpgradeLevel("Shadow Step") + 1;
		}

		public static bool HasActiveAbility()
		{
			return GetTier() >= 3;
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "ShadowStepUpgrade";
		}
	}
	internal class SpatialAwarenessUpgrade : TierUpgrade
	{
		public const string UPGRADE_NAME = "Spatial Awareness";

		public const int INITIAL_PRICE = 25;

		public static readonly int[] TIER_PRICES = new int[3] { 25, 25, 25 };

		public const int TIER_LIGHT_FEET = 1;

		public const int TIER_DONT_SHOOT = 2;

		public const int TIER_GROUNDED = 3;

		public const int TIER_NPC = 4;

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Spatial Awareness";
			((BaseUpgrade)this).overridenUpgradeName = "Spatial Awareness";
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			string text = "Heightened environmental awareness implants that let you sense and avoid hazards.\n";
			text += $"${initialPrice} - Tier 1: Landmines no longer trigger when you walk over them.\n";
			if (incrementalPrices != null && incrementalPrices.Length != 0)
			{
				text += $"${incrementalPrices[0]} - Tier 2: Turrets can no longer detect you.\n";
			}
			if (incrementalPrices != null && incrementalPrices.Length > 1)
			{
				text += $"${incrementalPrices[1]} - Tier 3: Lightning can no longer strike you.\n";
			}
			if (incrementalPrices != null && incrementalPrices.Length > 2)
			{
				text += $"${incrementalPrices[2]} - Tier 4: Masked enemies ignore your presence.\n";
			}
			return text + "\n\"See everything. Touch nothing.\"";
		}

		public static void RegisterUpgrade()
		{
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Spatial Awareness", Array.Empty<string>());
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!UpgradeBus.Instance.UpgradeObjects.ContainsKey("Spatial Awareness"))
			{
				return null;
			}
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Spatial Awareness", false, true, 25, TIER_PRICES, "", UpgradeBus.Instance.UpgradeObjects["Spatial Awareness"], true, (PurchaseMode)0, false, 1f);
		}

		public static bool IsUnlocked()
		{
			return BaseUpgrade.GetActiveUpgrade("Spatial Awareness");
		}

		public static int GetTier()
		{
			if (!IsUnlocked())
			{
				return 0;
			}
			return BaseUpgrade.GetUpgradeLevel("Spatial Awareness") + 1;
		}

		public static bool HasTier(int requiredTier)
		{
			return GetTier() >= requiredTier;
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "SpatialAwarenessUpgrade";
		}
	}
	internal class SquadSightUpgrade : TierUpgrade
	{
		public const string UPGRADE_NAME = "Squad Sight";

		public const int INITIAL_PRICE = 15;

		public static readonly int[] TIER_PRICES = new int[2] { 22, 30 };

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Squad Sight";
			((BaseUpgrade)this).overridenUpgradeName = "Squad Sight";
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			string text = "";
			text += $"${initialPrice} - Level 1: See teammates within 30m through walls and in darkness.\n";
			if (incrementalPrices != null && incrementalPrices.Length != 0)
			{
				text += $"${incrementalPrices[0]} - Level 2: Range increased to 60m, indicators are brighter.\n";
			}
			if (incrementalPrices != null && incrementalPrices.Length > 1)
			{
				text += $"${incrementalPrices[1]} - Level 3: Unlimited range, all teammates always visible.\n";
			}
			return text;
		}

		public static void RegisterUpgrade()
		{
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Squad Sight", Array.Empty<string>());
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!UpgradeBus.Instance.UpgradeObjects.ContainsKey("Squad Sight"))
			{
				return null;
			}
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Squad Sight", false, true, 15, TIER_PRICES, "", UpgradeBus.Instance.UpgradeObjects["Squad Sight"], true, (PurchaseMode)0, false, 1f);
		}

		public static bool IsUnlocked()
		{
			return BaseUpgrade.GetActiveUpgrade("Squad Sight");
		}

		public static int GetTier()
		{
			if (!IsUnlocked())
			{
				return 0;
			}
			return BaseUpgrade.GetUpgradeLevel("Squad Sight") + 1;
		}

		public static float GetRange()
		{
			return GetTier() switch
			{
				1 => 30f, 
				2 => 60f, 
				3 => -1f, 
				_ => 0f, 
			};
		}

		public static float GetVisibilityMultiplier()
		{
			return GetTier() switch
			{
				1 => 0.6f, 
				2 => 0.85f, 
				3 => 1f, 
				_ => 0f, 
			};
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "SquadSightUpgrade";
		}
	}
}
namespace LGUCustomUpgrades.Patches
{
	[HarmonyPatch]
	internal static class AdrenalineRushPatch
	{
		private const float VIGNETTE_ALPHA_BASE = 0.1f;

		private const float VIGNETTE_ALPHA_AMP = 0.06f;

		private const float VIGNETTE_PULSE_HZ = 3f;

		private static readonly Color VIGNETTE_TINT_NORMAL = new Color(0.8f, 0.15f, 0.05f, 0f);

		private static readonly Color VIGNETTE_TINT_INVULN = new Color(1f, 0.95f, 0.95f, 0f);

		private static RawImage _vignette;

		private static float _pulseTime;

		[HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")]
		[HarmonyPrefix]
		private static bool PreDamagePlayer(PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return true;
			}
			if ((Object)(object)__instance != (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				return true;
			}
			if (!AdrenalineRushUpgrade.IsInvincible)
			{
				return true;
			}
			return false;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")]
		[HarmonyPostfix]
		private static void PostDamagePlayer(PlayerControllerB __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance == (Object)null) && !((Object)(object)__instance != (Object)(object)GameNetworkManager.Instance.localPlayerController) && AdrenalineRushUpgrade.IsUnlocked() && !__instance.isPlayerDead && __instance.health > 0 && __instance.health <= 20 && !AdrenalineRushUpgrade.IsAdrenalineActive)
			{
				ActivateAdrenaline(__instance);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")]
		[HarmonyPrefix]
		private static bool PreKillPlayer(PlayerControllerB __instance, Vector3 bodyVelocity, bool spawnBody, CauseOfDeath causeOfDeath, int deathAnimation)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return true;
			}
			if ((Object)(object)__instance != (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				return true;
			}
			if (!AdrenalineRushUpgrade.HasInsurance())
			{
				return true;
			}
			if (AdrenalineRushUpgrade.InsuranceUsedThisRound)
			{
				return true;
			}
			if (!IsEnemyOrTrapDeath(causeOfDeath))
			{
				return true;
			}
			__instance.health = 1;
			AdrenalineRushUpgrade.InsuranceUsedThisRound = true;
			__instance.isPlayerDead = false;
			if (!AdrenalineRushUpgrade.IsAdrenalineActive)
			{
				ActivateAdrenaline(__instance);
			}
			StartInvincibility(__instance, 2f);
			HUDManager instance = HUDManager.Instance;
			if (instance != null)
			{
				instance.DisplayTip("ADRENALINE SURGE", "Survival insurance triggered — 2s of invincibility.", true, false, "LC_Tip1");
			}
			return false;
		}

		private static bool IsEnemyOrTrapDeath(CauseOfDeath cause)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected I4, but got Unknown
			switch ((int)cause)
			{
			case 0:
			case 1:
			case 3:
			case 4:
			case 6:
			case 7:
			case 8:
			case 11:
			case 12:
			case 13:
			case 14:
			case 15:
			case 17:
				return true;
			default:
				return false;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
		[HarmonyPostfix]
		private static void PostLateUpdate(PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)__instance != (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				return;
			}
			if (AdrenalineRushUpgrade.IsInvincible && Time.time >= AdrenalineRushUpgrade.InvincibilityEndTime)
			{
				AdrenalineRushUpgrade.IsInvincible = false;
			}
			if (AdrenalineRushUpgrade.IsAdrenalineActive)
			{
				if (__instance.isPlayerDead || __instance.health > 20)
				{
					DeactivateAdrenaline(__instance);
				}
				else
				{
					UpdateVignette();
				}
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "StartGame")]
		[HarmonyPostfix]
		private static void PostStartGame()
		{
			AdrenalineRushUpgrade.InsuranceUsedThisRound = false;
			AdrenalineRushUpgrade.IsInvincible = false;
			AdrenalineRushUpgrade.InvincibilityEndTime = 0f;
			AdrenalineRushUpgrade.IsAdrenalineActive = false;
			HideVignette();
		}

		private static void ActivateAdrenaline(PlayerControllerB player)
		{
			if (!((Object)(object)player == (Object)null) && !AdrenalineRushUpgrade.IsAdrenalineActive)
			{
				AdrenalineRushUpgrade.OriginalSpeed = player.movementSpeed;
				player.movementSpeed = AdrenalineRushUpgrade.OriginalSpeed * 1.3f;
				AdrenalineRushUpgrade.IsAdrenalineActive = true;
				HUDManager instance = HUDManager.Instance;
				if (instance != null)
				{
					instance.DisplayTip("ADRENALINE", "Heart pounding — speed surge engaged.", true, false, "LC_Tip1");
				}
			}
		}

		private static void DeactivateAdrenaline(PlayerControllerB player)
		{
			if (AdrenalineRushUpgrade.IsAdrenalineActive)
			{
				if ((Object)(object)player != (Object)null && AdrenalineRushUpgrade.OriginalSpeed > 0f)
				{
					player.movementSpeed = AdrenalineRushUpgrade.OriginalSpeed;
				}
				AdrenalineRushUpgrade.IsAdrenalineActive = false;
				HideVignette();
			}
		}

		private static void StartInvincibility(PlayerControllerB player, float seconds)
		{
			AdrenalineRushUpgrade.IsInvincible = true;
			AdrenalineRushUpgrade.InvincibilityEndTime = Time.time + seconds;
		}

		private static void UpdateVignette()
		{
			//IL_0093: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			EnsureVignette();
			if (!((Object)(object)_vignette == (Object)null))
			{
				((Component)_vignette).gameObject.SetActive(true);
				_pulseTime += Time.deltaTime * 3f;
				if (AdrenalineRushUpgrade.IsInvincible)
				{
					float a = 0.18f + 0.1f * Mathf.Abs(Mathf.Sin(Time.time * 8f));
					Color vIGNETTE_TINT_INVULN = VIGNETTE_TINT_INVULN;
					vIGNETTE_TINT_INVULN.a = a;
					((Graphic)_vignette).color = vIGNETTE_TINT_INVULN;
				}
				else
				{
					float a2 = 0.1f + 0.06f * Mathf.Sin(_pulseTime);
					Color vIGNETTE_TINT_NORMAL = VIGNETTE_TINT_NORMAL;
					vIGNETTE_TINT_NORMAL.a = a2;
					((Graphic)_vignette).color = vIGNETTE_TINT_NORMAL;
				}
			}
		}

		private static void EnsureVignette()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_vignette != (Object)null) && !((Object)(object)HUDManager.Instance == (Object)null) && !((Object)(object)HUDManager.Instance.playerScreenTexture == (Object)null))
			{
				Canvas canvas = ((Graphic)HUDManager.Instance.playerScreenTexture).canvas;
				if (!((Object)(object)canvas == (Object)null))
				{
					GameObject val = new GameObject("AdrenalineVignette");
					val.transform.SetParent(((Component)canvas).transform, false);
					RectTransform obj = val.AddComponent<RectTransform>();
					obj.anchorMin = Vector2.zero;
					obj.anchorMax = Vector2.one;
					obj.offsetMin = Vector2.zero;
					obj.offsetMax = Vector2.zero;
					_vignette = val.AddComponent<RawImage>();
					((Graphic)_vignette).raycastTarget = false;
					((Graphic)_vignette).color = new Color(0f, 0f, 0f, 0f);
				}
			}
		}

		private static void HideVignette()
		{
			if ((Object)(object)_vignette != (Object)null)
			{
				((Component)_vignette).gameObject.SetActive(false);
			}
			_pulseTime = 0f;
		}
	}
	[HarmonyPatch(typeof(ItemProgressionManager), "AssignConfiguredScrap")]
	internal static class AssignConfiguredScrapPatch
	{
		[HarmonyPrefix]
		private static bool SafeAssignConfiguredScrap()
		{
			try
			{
				UpgradeBus instance = UpgradeBus.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogWarning((object)"[LGUCustomUpgrades] AssignConfiguredScrap skipped: UpgradeBus.Instance is null.");
					}
					return false;
				}
				if (instance.scrapToCollectionUpgrade == null)
				{
					ManualLogSource log2 = Plugin.Log;
					if (log2 != null)
					{
						log2.LogWarning((object)"[LGUCustomUpgrades] AssignConfiguredScrap: scrapToCollectionUpgrade dict was null; skipping Clear().");
					}
				}
				else
				{
					instance.scrapToCollectionUpgrade.Clear();
				}
				if (instance.upgradeTypes == null)
				{
					ManualLogSource log3 = Plugin.Log;
					if (log3 != null)
					{
						log3.LogWarning((object)"[LGUCustomUpgrades] AssignConfiguredScrap: upgradeTypes list is null; nothing to assign.");
					}
					return false;
				}
				foreach (Type upgradeType in instance.upgradeTypes)
				{
					if (upgradeType == null)
					{
						ManualLogSource log4 = Plugin.Log;
						if (log4 != null)
						{
							log4.LogWarning((object)"[LGUCustomUpgrades] AssignConfiguredScrap: encountered null upgrade type, skipping.");
						}
						continue;
					}
					MethodInfo method;
					try
					{
						method = upgradeType.GetMethod("RegisterScrapToUpgrade", BindingFlags.Static | BindingFlags.Public);
					}
					catch (AmbiguousMatchException ex)
					{
						ManualLogSource log5 = Plugin.Log;
						if (log5 != null)
						{
							log5.LogWarning((object)("[LGUCustomUpgrades] AssignConfiguredScrap: ambiguous RegisterScrapToUpgrade on '" + upgradeType.FullName + "', skipping. " + ex.Message));
						}
						continue;
					}
					if (method == null)
					{
						ManualLogSource log6 = Plugin.Log;
						if (log6 != null)
						{
							log6.LogWarning((object)("[LGUCustomUpgrades] Upgrade type '" + upgradeType.FullName + "' has no static RegisterScrapToUpgrade() method; skipping it in AssignConfiguredScrap."));
						}
						continue;
					}
					object obj;
					try
					{
						obj = method.Invoke(null, null);
					}
					catch (Exception ex2)
					{
						ManualLogSource log7 = Plugin.Log;
						if (log7 != null)
						{
							log7.LogWarning((object)("[LGUCustomUpgrades] RegisterScrapToUpgrade on '" + upgradeType.FullName + "' threw " + ex2.GetType().Name + ": " + ex2.Message + "; skipping."));
						}
						continue;
					}
					if (obj == null)
					{
						ManualLogSource log8 = Plugin.Log;
						if (log8 != null)
						{
							log8.LogInfo((object)("[LGUCustomUpgrades] RegisterScrapToUpgrade on '" + upgradeType.FullName + "' returned null; skipping."));
						}
						continue;
					}
					if (!(obj is (string, string[]) tuple))
					{
						ManualLogSource log9 = Plugin.Log;
						if (log9 != null)
						{
							log9.LogWarning((object)("[LGUCustomUpgrades] RegisterScrapToUpgrade on '" + upgradeType.FullName + "' returned unexpected type '" + obj.GetType().FullName + "'; skipping."));
						}
						continue;
					}
					var (text, array) = tuple;
					if (string.IsNullOrWhiteSpace(text))
					{
						ManualLogSource log10 = Plugin.Log;
						if (log10 != null)
						{
							log10.LogWarning((object)("[LGUCustomUpgrades] RegisterScrapToUpgrade on '" + upgradeType.FullName + "' returned null/empty upgrade name; skipping."));
						}
					}
					else
					{
						if (array == null || array.Length == 0)
						{
							continue;
						}
						string[] array2 = array;
						foreach (string text2 in array2)
						{
							if (string.IsNullOrWhiteSpace(text2))
							{
								ManualLogSource log11 = Plugin.Log;
								if (log11 != null)
								{
									log11.LogWarning((object)("[LGUCustomUpgrades] Skipping null/empty scrap name for upgrade '" + text + "'."));
								}
								continue;
							}
							try
							{
								ItemProgressionManager.AddScrapToUpgrade(text, text2);
							}
							catch (Exception ex3)
							{
								ManualLogSource log12 = Plugin.Log;
								if (log12 != null)
								{
									log12.LogWarning((object)("[LGUCustomUpgrades] AddScrapToUpgrade('" + text + "', '" + text2 + "') threw " + ex3.GetType().Name + ": " + ex3.Message + "; skipping."));
								}
							}
						}
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log13 = Plugin.Log;
				if (log13 != null)
				{
					log13.LogError((object)$"[LGUCustomUpgrades] Unhandled exception in SafeAssignConfiguredScrap: {arg}");
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(DepositItemsDesk))]
	internal class DepositItemsDeskPatch
	{
		[HarmonyPatch("UpdateEffects")]
		[HarmonyPrefix]
		private static bool UpdateEffectsPrefix(DepositItemsDesk __instance)
		{
			if ((Object)(object)__instance.deskAudio == (Object)null || (Object)(object)__instance.deskObjectsContainer == (Object)null || (Object)(object)__instance.speakerAudio == (Object)null)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal static class EscapeProtocolPatch
	{
		private struct ExitMarker
		{
			public EntranceTeleport Exit;

			public GameObject Root;

			public TMP_Text Label;

			public Image Background;

			public Image Border;

			public bool IsMainEntrance;
		}

		private const float ACTIVE_DURATION = 5f;

		private const float COOLDOWN_DURATION = 60f;

		private static bool _isActive = false;

		private static float _activeUntil = 0f;

		private static float _cooldownUntil = 0f;

		private static bool _keyWasDown = false;

		private static bool _wasInsideAtActivation = false;

		private static EntranceTeleport[] _cachedExits;

		private static GameObject _overlayCanvas;

		private static readonly List<ExitMarker> _markers = new List<ExitMarker>();

		private const string HUD_SPRITE = "escape_hud";

		private const int HUD_STACK_POSITION = 0;

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPostfix]
		private static void PostPlayerUpdate(PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)null || !((NetworkBehaviour)__instance).IsOwner || !__instance.isPlayerControlled || (Object)(object)__instance != (Object)(object)GameNetworkManager.Instance?.localPlayerController)
			{
				return;
			}
			UpdateStatusHUD(__instance);
			if (!EscapeProtocolUpgrade.IsUnlocked())
			{
				return;
			}
			if (__instance.isPlayerDead)
			{
				if (_isActive)
				{
					Deactivate();
				}
				return;
			}
			if (_isActive && Time.time >= _activeUntil)
			{
				Deactivate();
				_cooldownUntil = Time.time + 60f;
				HUDManager instance = HUDManager.Instance;
				if (instance != null)
				{
					instance.DisplayTip("ESCAPE PROTOCOL", "Signal lost. Recharging...", false, false, "LC_Tip1");
				}
			}
			if (!__instance.isTypingChat && !__instance.inTerminalMenu && ((Object)(object)__instance.quickMenuManager == (Object)null || !__instance.quickMenuManager.isMenuOpen) && !__instance.inSpecialInteractAnimation)
			{
				PollKeybind(__instance);
			}
			if (_isActive)
			{
				UpdateMarkers(__instance);
			}
		}

		private static void PollKeybind(PlayerControllerB player)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				return;
			}
			Key? escapeProtocolKey = Plugin.GetEscapeProtocolKey();
			bool flag = (escapeProtocolKey.HasValue ? ((ButtonControl)current[escapeProtocolKey.Value]).isPressed : ((ButtonControl)current.hKey).isPressed);
			bool num = flag && !_keyWasDown;
			_keyWasDown = flag;
			if (!num || _isActive)
			{
				return;
			}
			if (Time.time < _cooldownUntil)
			{
				float num2 = _cooldownUntil - Time.time;
				HUDManager instance = HUDManager.Instance;
				if (instance != null)
				{
					instance.DisplayTip("ESCAPE PROTOCOL", $"Cooldown: {num2:F0}s", true, false, "LC_Tip1");
				}
			}
			else
			{
				Activate(player);
			}
		}

		private static void Activate(PlayerControllerB player)
		{
			_wasInsideAtActivation = player.isInsideFactory;
			CacheExits(_wasInsideAtActivation);
			if (_cachedExits == null || _cachedExits.Length == 0)
			{
				HUDManager instance = HUDManager.Instance;
				if (instance != null)
				{
					instance.DisplayTip("ESCAPE PROTOCOL", "No exits detected.", true, false, "LC_Tip1");
				}
			}
			else
			{
				_isActive = true;
				_activeUntil = Time.time + 5f;
				EnsureOverlayCanvas();
				BuildMarkers();
			}
		}

		private static void Deactivate()
		{
			_isActive = false;
			DestroyMarkers();
		}

		private static void CacheExits(bool playerIsInside)
		{
			EntranceTeleport[] array = Object.FindObjectsOfType<EntranceTeleport>();
			List<EntranceTeleport> list = new List<EntranceTeleport>();
			bool flag = !playerIsInside;
			for (int i = 0; i < array.Length; i++)
			{
				if (!((Object)(object)array[i] == (Object)null) && array[i].isEntranceToBuilding == flag)
				{
					list.Add(array[i]);
				}
			}
			_cachedExits = list.ToArray();
		}

		private static void EnsureOverlayCanvas()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_overlayCanvas != (Object)null))
			{
				_overlayCanvas = new GameObject("LGU_EscapeProtocol_Canvas");
				Canvas obj = _overlayCanvas.AddComponent<Canvas>();
				obj.renderMode = (RenderMode)0;
				obj.sortingOrder = 60;
				CanvasScaler obj2 = _overlayCanvas.AddComponent<CanvasScaler>();
				obj2.uiScaleMode = (ScaleMode)1;
				obj2.referenceResolution = new Vector2(1920f, 1080f);
				_overlayCanvas.AddComponent<GraphicRaycaster>();
				Object.DontDestroyOnLoad((Object)(object)_overlayCanvas);
			}
		}

		private static void BuildMarkers()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			DestroyMarkers();
			if (_cachedExits == null || (Object)(object)_overlayCanvas == (Object)null)
			{
				return;
			}
			Color color = HexColor("00C800");
			Color color2 = default(Color);
			((Color)(ref color2))..ctor(0.02f, 0.02f, 0.02f, 0.9f);
			for (int i = 0; i < _cachedExits.Length; i++)
			{
				EntranceTeleport val = _cachedExits[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				bool flag = IsMainEntrance(val, i);
				GameObject val2 = new GameObject($"ExitMarker_{i}");
				val2.transform.SetParent(_overlayCanvas.transform, false);
				val2.AddComponent<RectTransform>().sizeDelta = new Vector2(220f, 36f);
				Image val3 = val2.AddComponent<Image>();
				((Graphic)val3).color = color;
				((Graphic)val3).raycastTarget = false;
				GameObject val4 = new GameObject("Inner");
				val4.transform.SetParent(val2.transform, false);
				RectTransform obj = val4.AddComponent<RectTransform>();
				obj.anchorMin = Vector2.zero;
				obj.anchorMax = Vector2.one;
				obj.offsetMin = new Vector2(1f, 1f);
				obj.offsetMax = new Vector2(-1f, -1f);
				Image val5 = val4.AddComponent<Image>();
				((Graphic)val5).color = color2;
				((Graphic)val5).raycastTarget = false;
				GameObject val6 = new GameObject("Text");
				val6.transform.SetParent(val4.transform, false);
				RectTransform obj2 = val6.AddComponent<RectTransform>();
				obj2.anchorMin = Vector2.zero;
				obj2.anchorMax = Vector2.one;
				obj2.offsetMin = new Vector2(6f, 0f);
				obj2.offsetMax = new Vector2(-6f, 0f);
				TMP_Text val7 = (TMP_Text)(object)val6.AddComponent<TextMeshProUGUI>();
				val7.fontSize = 13f;
				val7.alignment = (TextAlignmentOptions)514;
				((Graphic)val7).color = color;
				((Graphic)val7).raycastTarget = false;
				val7.enableWordWrapping = false;
				val7.overflowMode = (TextOverflowModes)0;
				val7.text = (flag ? "ENTRANCE" : "EXIT");
				Terminal val8 = Object.FindObjectOfType<Terminal>();
				if ((Object)(object)val8 != (Object)null)
				{
					TMP_Text componentInChildren = ((Component)val8).GetComponentInChildren<TMP_Text>();
					if ((Object)(object)((componentInChildren != null) ? componentInChildren.font : null) != (Object)null)
					{
						val7.font = componentInChildren.font;
					}
				}
				_markers.Add(new ExitMarker
				{
					Exit = val,
					Root = val2,
					Label = val7,
					Background = val5,
					Border = val3,
					IsMainEntrance = flag
				});
			}
		}

		private static bool IsMainEntrance(EntranceTeleport exit, int index)
		{
			if (index == 0)
			{
				return true;
			}
			string text = ((Object)((Component)exit).gameObject).name.ToLowerInvariant();
			if ((text.Contains("main") || text.Contains("entrance")) && !text.Contains("fire") && !text.Contains("exit"))
			{
				return true;
			}
			return false;
		}

		private static void UpdateMarkers(PlayerControllerB player)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			if (player.isInsideFactory != _wasInsideAtActivation)
			{
				_wasInsideAtActivation = player.isInsideFactory;
				CacheExits(_wasInsideAtActivation);
				BuildMarkers();
			}
			if (_cachedExits == null || _cachedExits.Length == 0)
			{
				return;
			}
			Camera gameplayCamera = player.gameplayCamera;
			if ((Object)(object)gameplayCamera == (Object)null)
			{
				return;
			}
			for (int i = 0; i < _markers.Count; i++)
			{
				ExitMarker exitMarker = _markers[i];
				if ((Object)(object)exitMarker.Exit == (Object)null || (Object)(object)exitMarker.Root == (Object)null)
				{
					if ((Object)(object)exitMarker.Root != (Object)null)
					{
						exitMarker.Root.SetActive(false);
					}
					continue;
				}
				Vector3 val = ((Component)exitMarker.Exit).transform.position + Vector3.up * 2f;
				Vector3 val2 = gameplayCamera.WorldToViewportPoint(val);
				if (val2.z < 0f)
				{
					exitMarker.Root.SetActive(false);
					continue;
				}
				exitMarker.Root.SetActive(true);
				float num = val2.x * (float)Screen.width;
				float num2 = val2.y * (float)Screen.height;
				num = Mathf.Clamp(num, 30f, (float)Screen.width - 30f);
				num2 = Mathf.Clamp(num2, 30f, (float)Screen.height - 30f);
				((Transform)exitMarker.Root.GetComponent<RectTransform>()).position = new Vector3(num, num2, 0f);
				float num3 = Vector3.Distance(((Component)player).transform.position, ((Component)exitMarker.Exit).transform.position);
				string arg = (exitMarker.IsMainEntrance ? "ENTRANCE" : "EXIT");
				exitMarker.Label.text = $"{arg} — {num3:F0}m";
			}
		}

		private static void DestroyMarkers()
		{
			for (int i = 0; i < _markers.Count; i++)
			{
				if ((Object)(object)_markers[i].Root != (Object)null)
				{
					Object.Destroy((Object)(object)_markers[i].Root);
				}
			}
			_markers.Clear();
		}

		private static void EnsureSpriteHUD()
		{
			if (!((Object)(object)UpgradeHUDManager.GetHUDElement("escape_hud") != (Object)null) && !((Object)(object)HUDManager.Instance == (Object)null) && !((Object)(object)HUDManager.Instance.playerScreenTexture == (Object)null))
			{
				Canvas canvas = ((Graphic)HUDManager.Instance.playerScreenTexture).canvas;
				if (!((Object)(object)canvas == (Object)null))
				{
					UpgradeHUDManager.CreateHUDElement("escape_hud", 0, ((Component)canvas).transform);
				}
			}
		}

		private static void UpdateStatusHUD(PlayerControllerB localPlayer)
		{
			if (!EscapeProtocolUpgrade.IsUnlocked())
			{
				GameObject hUDElement = UpgradeHUDManager.GetHUDElement("escape_hud");
				if ((Object)(object)hUDElement != (Object)null)
				{
					hUDElement.SetActive(false);
				}
				return;
			}
			if ((Object)(object)localPlayer == (Object)null || localPlayer.inTerminalMenu || localPlayer.isTypingChat || ((Object)(object)localPlayer.quickMenuManager != (Object)null && localPlayer.quickMenuManager.isMenuOpen))
			{
				GameObject hUDElement2 = UpgradeHUDManager.GetHUDElement("escape_hud");
				if ((Object)(object)hUDElement2 != (Object)null)
				{
					hUDElement2.SetActive(false);
				}
				return;
			}
			EnsureSpriteHUD();
			GameObject hUDElement3 = UpgradeHUDManager.GetHUDElement("escape_hud");
			if (!((Object)(object)hUDElement3 == (Object)null))
			{
				hUDElement3.SetActive(true);
				if (_isActive)
				{
					UpgradeHUDManager.SetCooldownActive("escape_hud", active: false);
				}
				else if (Time.time < _cooldownUntil)
				{
					UpgradeHUDManager.SetCooldownActive("escape_hud", active: true);
					float num = _cooldownUntil - Time.time;
					UpgradeHUDManager.UpdateFillBar("escape_hud", num / 60f);
				}
				else
				{
					UpgradeHUDManager.SetCooldownActive("escape_hud", active: false);
				}
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "StartGame")]
		[HarmonyPostfix]
		private static void PostStartGame()
		{
			Deactivate();
			_cachedExits = null;
			_keyWasDown = false;
			_activeUntil = 0f;
			_cooldownUntil = 0f;
		}

		[HarmonyPatch(typeof(StartOfRound), "EndOfGame")]
		[HarmonyPostfix]
		private static void PostEndOfGame()
		{
			Deactivate();
			_cachedExits = null;
			_activeUntil = 0f;
			_cooldownUntil = 0f;
			UpgradeHUDManager.DestroyHUDElement("escape_hud");
			if ((Object)(object)_overlayCanvas != (Object)null)
			{
				Object.Destroy((Object)(object)_overlayCanvas);
			}
			_overlayCanvas = null;
		}

		private static Color HexColor(string hex)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			Color result = default(Color);
			ColorUtility.TryParseHtmlString("#" + hex, ref result);
			return result;
		}
	}
	internal static class ExtraSlotManager
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnSetBonusSlotsServerRpc;

			public static HandleNamedMessageDelegate <1>__OnRequestAllBonusSlotsServerRpc;

			public static HandleNamedMessageDelegate <2>__OnSetBonusSlotsClientRpc;

			public static HandleNamedMessageDelegate <3>__OnSyncAllBonusSlotsClientRpc;
		}

		private static readonly Dictionary<ulong, int> playerBonusSlots = new Dictionary<ulong, int>();

		private static bool handlersRegistered = false;

		private const string MSG_SET_SERVER = "LGUExtraSlot.SetBonusSlotsServerRpc";

		private const string MSG_SET_CLIENT = "LGUExtraSlot.SetBonusSlotsClientRpc";

		private const string MSG_REQUEST_ALL_SERVER = "LGUExtraSlot.RequestAllServerRpc";

		private const string MSG_SYNC_ALL_CLIENT = "LGUExtraSlot.SyncAllClientRpc";

		public static int GetPlayerBonusSlots(ulong clientId)
		{
			if (!playerBonusSlots.TryGetValue(clientId, out var value))
			{
				return 0;
			}
			return value;
		}

		public static int GetLocalPlayerBonusSlots()
		{
			PlayerControllerB val = StartOfRound.Instance?.localPlayerController;
			if (!((Object)(object)val != (Object)null))
			{
				return 0;
			}
			return GetPlayerBonusSlots(val.actualClientId);
		}

		public static short GetEffectiveHotbarSize()
		{
			return (short)(SyncManager.currentHotbarSize + GetLocalPlayerBonusSlots());
		}

		public static void BroadcastBonusSlots(ulong clientId, int bonusSlots)
		{
			if (!SyncManager.isSynced)
			{
				playerBonusSlots[clientId] = bonusSlots;
				Plugin.Log.LogInfo((object)$"ExtraSlot: Stored bonus {bonusSlots} for client {clientId} (pre-sync, will apply on sync)");
			}
			else if (NetworkManager.Singleton.IsServer)
			{
				SetPlayerBonusSlotsLocal(clientId, bonusSlots);
				SendSetBonusSlotsToAllClients(clientId, bonusSlots);
			}
			else
			{
				SendSetBonusSlotsToServer(clientId, bonusSlots);
			}
		}

		public static void ApplyBonusInventorySlots()
		{
			try
			{
				if ((Object)(object)StartOfRound.Instance == (Object)null)
				{
					return;
				}
				PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				foreach (PlayerControllerB val in allPlayerScripts)
				{
					if (val.isPlayerControlled || !((Object)(object)val != (Object)(object)StartOfRound.Instance.localPlayerController))
					{
						int num = GetPlayerBonusSlots(val.actualClientId);
						if (num > 0)
						{
							int targetSize = SyncManager.currentHotbarSize + num;
							ResizePlayerInventory(val, targetSize);
						}
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"ExtraSlot: ApplyBonusInventorySlots failed: {arg}");
			}
		}

		public static void ApplyBonusHUDSlots()
		{
			try
			{
				PlayerControllerB val = StartOfRound.Instance?.localPlayerController;
				if (!((Object)(object)val == (Object)null))
				{
					int num = GetPlayerBonusSlots(val.actualClientId);
					if (num > 0)
					{
						ResizeLocalHUD(SyncManager.currentHotbarSize + num);
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"ExtraSlot: ApplyBonusHUDSlots failed: {arg}");
			}
		}

		public static void RegisterNetworkHandlers()
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_00ad: 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)
			//IL_00b8: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			if (handlersRegistered)
			{
				return;
			}
			handlersRegistered = true;
			CustomMessagingManager customMessagingManager = NetworkManag

LGUDebugTools.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

[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("LGUDebugTools")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Debug terminal commands for Lethal Company")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0+8c5521e37f37e3d76518a16d04e5d1051842f105")]
[assembly: AssemblyProduct("LGUDebugTools")]
[assembly: AssemblyTitle("LGUDebugTools")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.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 LGUDebugTools
{
	public class DebugGUI : MonoBehaviour
	{
		private bool _visible;

		private int _tab;

		private Rect _winRect;

		private bool _winInitialized;

		private CursorLockMode _savedLock;

		private bool _savedVisible;

		private string _itemFilter = "";

		private Vector2 _itemScroll;

		private string _spawnQty = "1";

		private string _enemyFilter = "";

		private Vector2 _enemyScroll;

		private List<EnemyType> _enemies;

		private float _enemyCacheTime;

		internal static bool GodMode;

		internal static bool MobIgnore;

		private bool _nightVision;

		private float _nvOrigIntensity;

		private float _nvOrigRange;

		private string _creditsInput = "";

		private string _bxpInput = "";

		private bool _stylesOk;

		private GUIStyle _sWin;

		private GUIStyle _sLabel;

		private GUIStyle _sHeader;

		private GUIStyle _sBtn;

		private GUIStyle _sTab;

		private GUIStyle _sTabOn;

		private GUIStyle _sField;

		private GUIStyle _sListBtn;

		private GUIStyle _sCloseBtn;

		private Texture2D _texBg;

		private Texture2D _texBtn;

		private Texture2D _texHover;

		private Texture2D _texTabOn;

		private Texture2D _texField;

		private Texture2D _texBorder;

		private static readonly Color CG = new Color(0f, 0.784f, 0f);

		private static readonly Color CBg = new Color(0.02f, 0.02f, 0.02f, 0.97f);

		private void Update()
		{
			if (Keyboard.current != null && ((ButtonControl)Keyboard.current.f9Key).wasPressedThisFrame)
			{
				_visible = !_visible;
				if (_visible)
				{
					Open();
				}
				else
				{
					Close();
				}
			}
			if (_nightVision)
			{
				PlayerControllerB val = LP();
				if ((Object)(object)val?.nightVision != (Object)null)
				{
					val.nightVision.intensity = 5000f;
					val.nightVision.range = 10000f;
				}
			}
		}

		private void OnGUI()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			if (_visible)
			{
				if (!_winInitialized)
				{
					_winRect = new Rect((float)(Screen.width - 500) / 2f, (float)(Screen.height - 600) / 2f, 500f, 600f);
					_winInitialized = true;
				}
				if (!_stylesOk || (Object)(object)_texBg == (Object)null)
				{
					BuildStyles();
				}
				GUI.depth = -1000;
				GUI.DrawTexture(new Rect(((Rect)(ref _winRect)).x - 1f, ((Rect)(ref _winRect)).y - 1f, ((Rect)(ref _winRect)).width + 2f, ((Rect)(ref _winRect)).height + 2f), (Texture)(object)_texBorder);
				_winRect = GUI.Window(86753, _winRect, new WindowFunction(DrawWin), "", _sWin);
			}
		}

		private void DrawWin(int id)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: 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)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			GUI.Label(new Rect(10f, 5f, 400f, 25f), "LGUDebugTools v2.0", _sHeader);
			if (GUI.Button(new Rect(((Rect)(ref _winRect)).width - 30f, 5f, 25f, 25f), "X", _sCloseBtn))
			{
				_visible = false;
				Close();
				return;
			}
			float num = ((Rect)(ref _winRect)).width / 3f;
			string[] array = new string[3] { "Items", "Enemies", "Cheats" };
			for (int i = 0; i < 3; i++)
			{
				if (GUI.Button(new Rect((float)i * num, 32f, num, 26f), array[i], (i == _tab) ? _sTabOn : _sTab))
				{
					_tab = i;
				}
			}
			GUILayout.BeginArea(new Rect(8f, 62f, ((Rect)(ref _winRect)).width - 16f, ((Rect)(ref _winRect)).height - 70f));
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				GUILayout.Label("Not in game.", _sLabel, Array.Empty<GUILayoutOption>());
			}
			else
			{
				try
				{
					switch (_tab)
					{
					case 0:
						TabItems();
						break;
					case 1:
						TabEnemies();
						break;
					case 2:
						TabCheats();
						break;
					}
				}
				catch (Exception ex)
				{
					GUILayout.Label("Error: " + ex.Message, _sLabel, Array.Empty<GUILayoutOption>());
				}
			}
			GUILayout.EndArea();
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _winRect)).width - 35f, 32f));
		}

		private void TabItems()
		{
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			List<Item> itemsList = StartOfRound.Instance.allItemsList.itemsList;
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Search:", _sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(52f) });
			_itemFilter = GUILayout.TextField(_itemFilter, _sField, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Qty:", _sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(28f) });
			_spawnQty = GUILayout.TextField(_spawnQty, 3, _sField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) });
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			IList<Item> list = (string.IsNullOrEmpty(_itemFilter) ? itemsList : itemsList.Where((Item i) => i.itemName.IndexOf(_itemFilter, StringComparison.OrdinalIgnoreCase) >= 0).ToList());
			GUILayout.Label($"Items ({list.Count}):", _sLabel, Array.Empty<GUILayoutOption>());
			_itemScroll = GUILayout.BeginScrollView(_itemScroll, Array.Empty<GUILayoutOption>());
			foreach (Item item in list)
			{
				if (GUILayout.Button(item.itemName, _sListBtn, Array.Empty<GUILayoutOption>()))
				{
					int result = 1;
					int.TryParse(_spawnQty, out result);
					result = Mathf.Clamp(result, 1, 50);
					DoSpawnItem(item, result);
				}
			}
			GUILayout.EndScrollView();
		}

		private void TabEnemies()
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			bool flag = IsHost();
			if (!flag)
			{
				GUILayout.Label("Host only — enemy spawning requires host authority.", _sLabel, Array.Empty<GUILayoutOption>());
				GUILayout.Space(4f);
			}
			CacheEnemies();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Search:", _sLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(52f) });
			_enemyFilter = GUILayout.TextField(_enemyFilter, _sField, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			List<EnemyType> list = (string.IsNullOrEmpty(_enemyFilter) ? _enemies : _enemies.Where((EnemyType e) => e.enemyName.IndexOf(_enemyFilter, StringComparison.OrdinalIgnoreCase) >= 0).ToList());
			GUILayout.Label($"Enemies ({list.Count}):", _sLabel, Array.Empty<GUILayoutOption>());
			_enemyScroll = GUILayout.BeginScrollView(_enemyScroll, Array.Empty<GUILayoutOption>());
			GUI.enabled = flag;
			foreach (EnemyType item in list)
			{
				if (GUILayout.Button(item.enemyName, _sListBtn, Array.Empty<GUILayoutOption>()))
				{
					DoSpawnEnemy(item);
				}
			}
			GUI.enabled = true;
			GUILayout.EndScrollView();
		}

		private void TabCheats()
		{
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Space(4f);
			if (GUILayout.Button("God Mode: " + (GodMode ? "ON" : "OFF"), GodMode ? _sTabOn : _sBtn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				GodMode = !GodMode;
			}
			GUILayout.Space(2f);
			if (GUILayout.Button("Mob Ignore: " + (MobIgnore ? "ON" : "OFF"), MobIgnore ? _sTabOn : _sBtn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				MobIgnore = !MobIgnore;
			}
			GUILayout.Space(2f);
			if (GUILayout.Button("Night Vision: " + (_nightVision ? "ON" : "OFF"), _nightVision ? _sTabOn : _sBtn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				_nightVision = !_nightVision;
				PlayerControllerB val = LP();
				if ((Object)(object)val?.nightVision != (Object)null)
				{
					if (_nightVision)
					{
						_nvOrigIntensity = val.nightVision.intensity;
						_nvOrigRange = val.nightVision.range;
					}
					else
					{
						val.nightVision.intensity = _nvOrigIntensity;
						val.nightVision.range = _nvOrigRange;
					}
				}
			}
			GUILayout.Space(10f);
			GUILayout.Label("Set Credits:", _sLabel, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			_creditsInput = GUILayout.TextField(_creditsInput, _sField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) });
			if (GUILayout.Button("Set", _sBtn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }) && int.TryParse(_creditsInput, out var result))
			{
				result = Mathf.Clamp(result, 0, 999999);
				Terminal val2 = Object.FindObjectOfType<Terminal>();
				if ((Object)(object)val2 != (Object)null)
				{
					val2.groupCredits = result;
					val2.SyncGroupCreditsServerRpc(result, val2.numberOfItemsInDropship);
				}
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			GUILayout.Label("Set BXP:", _sLabel, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			_bxpInput = GUILayout.TextField(_bxpInput, _sField, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) });
			if (GUILayout.Button("Set", _sBtn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }) && int.TryParse(_bxpInput, out var result2))
			{
				result2 = Mathf.Clamp(result2, 0, 999999);
				TerminalPatch.ResolveBxpReflection();
				if (!TerminalPatch.BxpFailed)
				{
					TerminalPatch.SetBxp(result2);
				}
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(8f);
			if (GUILayout.Button("Fulfill Quota", _sBtn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				TimeOfDay instance = TimeOfDay.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					int num = instance.profitQuota - instance.quotaFulfilled;
					instance.quotaFulfilled += Mathf.Max(0, num);
					instance.SyncNewProfitQuotaClientRpc(instance.profitQuota, instance.quotaFulfilled, instance.timesFulfilledQuota);
				}
			}
			GUILayout.Space(2f);
			if (GUILayout.Button("Teleport to Entrance", _sBtn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				try
				{
					PlayerControllerB val3 = LP();
					if ((Object)(object)val3 != (Object)null)
					{
						EntranceTeleport val4 = ((IEnumerable<EntranceTeleport>)Object.FindObjectsOfType<EntranceTeleport>()).FirstOrDefault((Func<EntranceTeleport, bool>)((EntranceTeleport e) => e.entranceId == 0));
						if ((Object)(object)val4?.entrancePoint != (Object)null)
						{
							val3.TeleportPlayer(val4.entrancePoint.position, false, 0f, false, true);
						}
					}
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Teleport: {arg}");
				}
			}
			GUILayout.Space(2f);
			if (!GUILayout.Button("Teleport to Ship", _sBtn, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				return;
			}
			try
			{
				PlayerControllerB val5 = LP();
				StartOfRound instance2 = StartOfRound.Instance;
				if ((Object)(object)val5 != (Object)null && (Object)(object)instance2 != (Object)null)
				{
					Vector3 val6 = (((Object)(object)instance2.middleOfShipNode != (Object)null) ? instance2.middleOfShipNode.position : ((instance2.playerSpawnPositions != null && instance2.playerSpawnPositions.Length != 0) ? instance2.playerSpawnPositions[0].position : (((Object)(object)instance2.shipDoorNode != (Object)null) ? ((Component)instance2.shipDoorNode).transform.position : Vector3.zero)));
					val5.TeleportPlayer(val6, false, 0f, false, true);
					val5.isInElevator = true;
					val5.isInHangarShipRoom = true;
					val5.isInsideFactory = false;
				}
			}
			catch (Exception arg2)
			{
				Plugin.Log.LogError((object)$"Teleport ship: {arg2}");
			}
		}

		private void DoSpawnItem(Item item, int qty)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB val = LP();
			if ((Object)(object)val == (Object)null || (Object)(object)item?.spawnPrefab == (Object)null)
			{
				return;
			}
			Vector3 val2 = ((Component)val).transform.position + ((Component)val).transform.forward * 2f + Vector3.up * 0.5f;
			Vector3 val3 = default(Vector3);
			for (int i = 0; i < qty; i++)
			{
				((Vector3)(ref val3))..ctor(Random.Range(-1f, 1f), 0f, Random.Range(-1f, 1f));
				GameObject obj = Object.Instantiate<GameObject>(item.spawnPrefab, val2 + val3, Quaternion.identity);
				GrabbableObject component = obj.GetComponent<GrabbableObject>();
				if ((Object)(object)component != (Object)null)
				{
					if (item.isScrap && (Object)(object)RoundManager.Instance != (Object)null)
					{
						component.SetScrapValue((int)Random.Range((float)item.minValue * RoundManager.Instance.scrapValueMultiplier, (float)item.maxValue * RoundManager.Instance.scrapValueMultiplier));
					}
					component.fallTime = 0f;
				}
				NetworkObject component2 = obj.GetComponent<NetworkObject>();
				if (component2 != null)
				{
					component2.Spawn(false);
				}
			}
		}

		private void DoSpawnEnemy(EnemyType enemy)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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)
			//IL_0052: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			if (!IsHost() || (Object)(object)enemy?.enemyPrefab == (Object)null)
			{
				return;
			}
			PlayerControllerB val = LP();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			try
			{
				Vector3 val2 = ((Component)val).transform.position + ((Component)val).transform.forward * 3f;
				GameObject obj = Object.Instantiate<GameObject>(enemy.enemyPrefab, val2, Quaternion.identity);
				NetworkObject componentInChildren = obj.GetComponentInChildren<NetworkObject>();
				if (componentInChildren != null)
				{
					componentInChildren.Spawn(true);
				}
				EnemyAI component = obj.GetComponent<EnemyAI>();
				if ((Object)(object)component != (Object)null && (Object)(object)RoundManager.Instance != (Object)null)
				{
					RoundManager.Instance.SpawnedEnemies.Add(component);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Enemy spawn: {arg}");
			}
		}

		private void CacheEnemies()
		{
			if (_enemies != null && Time.time - _enemyCacheTime < 10f)
			{
				return;
			}
			_enemyCacheTime = Time.time;
			HashSet<string> hashSet = new HashSet<string>();
			_enemies = new List<EnemyType>();
			if (StartOfRound.Instance?.levels != null)
			{
				SelectableLevel[] levels = StartOfRound.Instance.levels;
				foreach (SelectableLevel val in levels)
				{
					Collect(val.Enemies, hashSet);
					Collect(val.OutsideEnemies, hashSet);
					Collect(val.DaytimeEnemies, hashSet);
				}
			}
			EnemyType[] array = Resources.FindObjectsOfTypeAll<EnemyType>();
			foreach (EnemyType val2 in array)
			{
				if ((Object)(object)val2 != (Object)null && !string.IsNullOrEmpty(val2.enemyName) && hashSet.Add(val2.enemyName))
				{
					_enemies.Add(val2);
				}
			}
			_enemies.Sort((EnemyType a, EnemyType b) => string.Compare(a.enemyName, b.enemyName, StringComparison.OrdinalIgnoreCase));
		}

		private void Collect(List<SpawnableEnemyWithRarity> list, HashSet<string> seen)
		{
			if (list == null)
			{
				return;
			}
			foreach (SpawnableEnemyWithRarity item in list)
			{
				if ((Object)(object)item?.enemyType != (Object)null && !string.IsNullOrEmpty(item.enemyType.enemyName) && seen.Add(item.enemyType.enemyName))
				{
					_enemies.Add(item.enemyType);
				}
			}
		}

		private void Open()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			_savedLock = Cursor.lockState;
			_savedVisible = Cursor.visible;
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			PlayerControllerB val = LP();
			if ((Object)(object)val != (Object)null)
			{
				val.disableLookInput = true;
			}
		}

		private void Close()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			Cursor.lockState = _savedLock;
			Cursor.visible = _savedVisible;
			PlayerControllerB val = LP();
			if ((Object)(object)val != (Object)null)
			{
				val.disableLookInput = false;
			}
		}

		private void OnDestroy()
		{
			if (_visible)
			{
				Close();
			}
			if ((Object)(object)_texBg != (Object)null)
			{
				Object.Destroy((Object)(object)_texBg);
			}
			if ((Object)(object)_texBtn != (Object)null)
			{
				Object.Destroy((Object)(object)_texBtn);
			}
			if ((Object)(object)_texHover != (Object)null)
			{
				Object.Destroy((Object)(object)_texHover);
			}
			if ((Object)(object)_texTabOn != (Object)null)
			{
				Object.Destroy((Object)(object)_texTabOn);
			}
			if ((Object)(object)_texField != (Object)null)
			{
				Object.Destroy((Object)(object)_texField);
			}
			if ((Object)(object)_texBorder != (Object)null)
			{
				Object.Destroy((Object)(object)_texBorder);
			}
		}

		private static PlayerControllerB LP()
		{
			return GameNetworkManager.Instance?.localPlayerController;
		}

		private static bool IsHost()
		{
			if ((Object)(object)NetworkManager.Singleton != (Object)null)
			{
				if (!NetworkManager.Singleton.IsHost)
				{
					return NetworkManager.Singleton.IsServer;
				}
				return true;
			}
			return false;
		}

		private void BuildStyles()
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			//IL_0198: Expected O, but got Unknown
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Expected O, but got Unknown
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Expected O, but got Unknown
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Expected O, but got Unknown
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Expected O, but got Unknown
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Expected O, but got Unknown
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Expected O, but got Unknown
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Expected O, but got Unknown
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Expected O, but got Unknown
			//IL_03ae: Expected O, but got Unknown
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Expected O, but got Unknown
			if ((Object)(object)_texBg != (Object)null)
			{
				Object.Destroy((Object)(object)_texBg);
			}
			if ((Object)(object)_texBtn != (Object)null)
			{
				Object.Destroy((Object)(object)_texBtn);
			}
			if ((Object)(object)_texHover != (Object)null)
			{
				Object.Destroy((Object)(object)_texHover);
			}
			if ((Object)(object)_texTabOn != (Object)null)
			{
				Object.Destroy((Object)(object)_texTabOn);
			}
			if ((Object)(object)_texField != (Object)null)
			{
				Object.Destroy((Object)(object)_texField);
			}
			if ((Object)(object)_texBorder != (Object)null)
			{
				Object.Destroy((Object)(object)_texBorder);
			}
			_texBg = Tex(CBg);
			_texBtn = Tex(new Color(0.08f, 0.08f, 0.08f));
			_texHover = Tex(new Color(0f, 0.15f, 0f));
			_texTabOn = Tex(new Color(0f, 0.12f, 0f));
			_texField = Tex(new Color(0.05f, 0.05f, 0.05f));
			_texBorder = Tex(CG);
			GUIStyle val = new GUIStyle(GUI.skin.window);
			val.normal.background = _texBg;
			val.normal.textColor = CG;
			val.onNormal.background = _texBg;
			val.onNormal.textColor = CG;
			val.padding = new RectOffset(0, 0, 0, 4);
			_sWin = val;
			GUIStyle val2 = new GUIStyle(GUI.skin.label);
			val2.normal.textColor = CG;
			val2.fontSize = 14;
			_sLabel = val2;
			_sHeader = new GUIStyle(_sLabel)
			{
				fontSize = 16,
				fontStyle = (FontStyle)1
			};
			GUIStyle val3 = new GUIStyle(GUI.skin.button);
			val3.normal.background = _texBtn;
			val3.normal.textColor = CG;
			val3.hover.background = _texHover;
			val3.hover.textColor = CG;
			val3.active.background = _texHover;
			val3.active.textColor = Color.white;
			val3.focused.background = _texBtn;
			val3.focused.textColor = CG;
			val3.fontSize = 14;
			val3.alignment = (TextAnchor)4;
			_sBtn = val3;
			_sTab = new GUIStyle(_sBtn)
			{
				fontStyle = (FontStyle)1
			};
			GUIStyle val4 = new GUIStyle(_sTab);
			val4.normal.background = _texTabOn;
			val4.normal.textColor = CG;
			val4.hover.background = _texTabOn;
			val4.hover.textColor = CG;
			_sTabOn = val4;
			GUIStyle val5 = new GUIStyle(GUI.skin.textField);
			val5.normal.background = _texField;
			val5.normal.textColor = CG;
			val5.focused.background = _texField;
			val5.focused.textColor = CG;
			val5.hover.background = _texField;
			val5.hover.textColor = CG;
			val5.fontSize = 14;
			_sField = val5;
			_sListBtn = new GUIStyle(_sBtn)
			{
				alignment = (TextAnchor)3,
				padding = new RectOffset(8, 8, 3, 3),
				margin = new RectOffset(0, 0, 1, 1)
			};
			_sCloseBtn = new GUIStyle(_sBtn)
			{
				fontStyle = (FontStyle)1
			};
			_stylesOk = true;
		}

		private static Texture2D Tex(Color c)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_0019: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
			val.SetPixel(0, 0, c);
			val.Apply();
			return val;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class GodModePatch
	{
		[HarmonyPatch("DamagePlayer")]
		[HarmonyPrefix]
		private static bool DamagePrefix(PlayerControllerB __instance)
		{
			try
			{
				if (DebugGUI.GodMode && (Object)(object)__instance == (Object)(object)GameNetworkManager.Instance.localPlayerController)
				{
					return false;
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"GodMode DamagePlayer: {arg}");
			}
			return true;
		}

		[HarmonyPatch("KillPlayer")]
		[HarmonyPrefix]
		private static bool KillPrefix(PlayerControllerB __instance)
		{
			try
			{
				if (DebugGUI.GodMode && (Object)(object)__instance == (Object)(object)GameNetworkManager.Instance.localPlayerController)
				{
					return false;
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"GodMode KillPlayer: {arg}");
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(EnemyAI))]
	internal class MobIgnorePatch
	{
		[HarmonyPatch("PlayerIsTargetable")]
		[HarmonyPrefix]
		private static bool TargetablePrefix(PlayerControllerB playerScript, ref bool __result)
		{
			try
			{
				if (DebugGUI.MobIgnore && (Object)(object)playerScript == (Object)(object)GameNetworkManager.Instance.localPlayerController)
				{
					__result = false;
					return false;
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"MobIgnore: {arg}");
			}
			return true;
		}
	}
	[BepInPlugin("com.y4ngz.lgudebugtools", "LGUDebugTools", "2.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "com.y4ngz.lgudebugtools";

		public const string NAME = "LGUDebugTools";

		public const string VERSION = "2.0.0";

		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			new Harmony("com.y4ngz.lgudebugtools").PatchAll();
			GameObject val = new GameObject("LGUDebugTools_GUI");
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)61;
			val.AddComponent<DebugGUI>();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"LGUDebugTools v2.0.0 loaded. Terminal debug commands + F9 GUI active.");
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	internal class TerminalPatch
	{
		private static Type _currencyManagerType;

		private static FieldInfo _altCurrencyField;

		private static PropertyInfo _altCurrencyProp;

		private static bool _bxpReflResolved;

		private static bool _bxpReflFailed;

		internal static bool BxpFailed => _bxpReflFailed;

		internal static void ResolveBxpReflection()
		{
			if (_bxpReflResolved || _bxpReflFailed)
			{
				return;
			}
			try
			{
				BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				for (int i = 0; i < assemblies.Length; i++)
				{
					_currencyManagerType = assemblies[i].GetType("MoreShipUpgrades.Managers.CurrencyManager");
					if (_currencyManagerType != null)
					{
						break;
					}
				}
				if (_currencyManagerType == null)
				{
					Plugin.Log.LogWarning((object)"[BXP] Could not find CurrencyManager type.");
					_bxpReflFailed = true;
					return;
				}
				Plugin.Log.LogInfo((object)"[BXP] Found CurrencyManager. Dumping members...");
				FieldInfo[] fields = _currencyManagerType.GetFields(bindingAttr);
				foreach (FieldInfo fieldInfo in fields)
				{
					Plugin.Log.LogInfo((object)("[BXP]   Field: " + fieldInfo.FieldType.Name + " " + fieldInfo.Name));
				}
				PropertyInfo[] properties = _currencyManagerType.GetProperties(bindingAttr);
				foreach (PropertyInfo propertyInfo in properties)
				{
					Plugin.Log.LogInfo((object)("[BXP]   Property: " + propertyInfo.PropertyType.Name + " " + propertyInfo.Name));
				}
				MethodInfo[] methods = _currencyManagerType.GetMethods(bindingAttr);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.Name.ToLower().Contains("currency") || methodInfo.Name.ToLower().Contains("alternate"))
					{
						Plugin.Log.LogInfo((object)("[BXP]   Method: " + methodInfo.ReturnType.Name + " " + methodInfo.Name));
					}
				}
				_altCurrencyProp = _currencyManagerType.GetProperty("AlternateCurrency", bindingAttr);
				if (_altCurrencyProp == null)
				{
					_altCurrencyProp = _currencyManagerType.GetProperty("CurrencyAmount", bindingAttr);
				}
				if (_altCurrencyProp == null)
				{
					_altCurrencyField = _currencyManagerType.GetField("AlternateCurrency", bindingAttr) ?? _currencyManagerType.GetField("CurrencyAmount", bindingAttr) ?? _currencyManagerType.GetField("<AlternateCurrency>k__BackingField", bindingAttr) ?? _currencyManagerType.GetField("<CurrencyAmount>k__BackingField", bindingAttr);
				}
				if (_altCurrencyProp == null && _altCurrencyField == null)
				{
					Plugin.Log.LogWarning((object)"[BXP] Could not find currency property/field on CurrencyManager.");
					_bxpReflFailed = true;
				}
				else
				{
					string text = ((_altCurrencyProp != null) ? ("property '" + _altCurrencyProp.Name + "'") : ("field '" + _altCurrencyField.Name + "'"));
					Plugin.Log.LogInfo((object)("[BXP] Reflection resolved via " + text + "."));
					_bxpReflResolved = true;
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"[BXP] Reflection failed: {arg}");
				_bxpReflFailed = true;
			}
		}

		private static object GetCurrencyManagerInstance()
		{
			if (_currencyManagerType == null)
			{
				return null;
			}
			BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;
			PropertyInfo property = _currencyManagerType.GetProperty("Instance", bindingAttr);
			if (property != null)
			{
				return property.GetValue(null);
			}
			FieldInfo field = _currencyManagerType.GetField("Instance", bindingAttr);
			if (field != null)
			{
				return field?.GetValue(null);
			}
			return null;
		}

		private static int GetBxp()
		{
			object currencyManagerInstance = GetCurrencyManagerInstance();
			if (_altCurrencyProp != null)
			{
				return (int)_altCurrencyProp.GetValue(_altCurrencyProp.GetMethod.IsStatic ? null : currencyManagerInstance);
			}
			if (_altCurrencyField != null)
			{
				return (int)_altCurrencyField.GetValue(_altCurrencyField.IsStatic ? null : currencyManagerInstance);
			}
			return -1;
		}

		internal static void SetBxp(int value)
		{
			object currencyManagerInstance = GetCurrencyManagerInstance();
			if (_altCurrencyProp != null)
			{
				_altCurrencyProp.SetValue(_altCurrencyProp.SetMethod.IsStatic ? null : currencyManagerInstance, value);
			}
			else if (_altCurrencyField != null)
			{
				_altCurrencyField.SetValue(_altCurrencyField.IsStatic ? null : currencyManagerInstance, value);
			}
		}

		[HarmonyPatch("ParsePlayerSentence")]
		[HarmonyPrefix]
		private static bool ParsePrefix(Terminal __instance, ref TerminalNode __result)
		{
			string text = __instance.screenText.text;
			int num = text.LastIndexOf('\n');
			string text2 = ((num >= 0) ? text.Substring(num + 1).Trim().ToLower() : text.Trim().ToLower());
			if (text2.StartsWith("spawn "))
			{
				string text3 = text2.Substring(6).Trim();
				int quantity = 1;
				string[] array = text3.Split(' ');
				string itemName;
				if (array.Length >= 2 && int.TryParse(array[^1], out var result))
				{
					quantity = Mathf.Clamp(result, 1, 50);
					itemName = string.Join(" ", array.Take(array.Length - 1));
				}
				else
				{
					itemName = text3;
				}
				__result = SpawnItem(__instance, itemName, quantity);
				return false;
			}
			if (text2.StartsWith("setcredits "))
			{
				if (int.TryParse(text2.Substring(11).Trim(), out var result2))
				{
					result2 = (__instance.groupCredits = Mathf.Clamp(result2, 0, 999999));
					__instance.SyncGroupCreditsServerRpc(result2, __instance.numberOfItemsInDropship);
					__result = CreateNode($"Credits set to ${result2}.");
				}
				else
				{
					__result = CreateNode("Usage: setcredits <amount>\nExample: setcredits 5000");
				}
				return false;
			}
			if (text2.StartsWith("setbxp "))
			{
				ResolveBxpReflection();
				if (_bxpReflFailed)
				{
					__result = CreateNode("Error: Could not access BXP currency.\nMoreShipUpgrades / LGU may not be loaded.");
					return false;
				}
				if (int.TryParse(text2.Substring(7).Trim(), out var result3))
				{
					result3 = Mathf.Clamp(result3, 0, 999999);
					SetBxp(result3);
					__result = CreateNode($"BXP set to {result3}.");
				}
				else
				{
					__result = CreateNode("Usage: setbxp <amount>\nExample: setbxp 500");
				}
				return false;
			}
			if (text2.StartsWith("addbxp "))
			{
				ResolveBxpReflection();
				if (_bxpReflFailed)
				{
					__result = CreateNode("Error: Could not access BXP currency.\nMoreShipUpgrades / LGU may not be loaded.");
					return false;
				}
				if (int.TryParse(text2.Substring(7).Trim(), out var result4))
				{
					result4 = Mathf.Max(0, result4);
					int num2 = Mathf.Clamp(GetBxp() + result4, 0, 999999);
					SetBxp(num2);
					__result = CreateNode($"Added {result4} BXP.\nNew balance: {num2} BXP.");
				}
				else
				{
					__result = CreateNode("Usage: addbxp <amount>\nExample: addbxp 200");
				}
				return false;
			}
			if (text2 == "getbxp")
			{
				ResolveBxpReflection();
				if (_bxpReflFailed)
				{
					__result = CreateNode("Error: Could not access BXP currency.\nMoreShipUpgrades / LGU may not be loaded.");
					return false;
				}
				int bxp = GetBxp();
				__result = CreateNode($"Current BXP: {bxp}");
				return false;
			}
			if (text2.StartsWith("setquota "))
			{
				if (int.TryParse(text2.Substring(9).Trim(), out var result5))
				{
					result5 = Mathf.Clamp(result5, 0, 999999);
					TimeOfDay.Instance.profitQuota = result5;
					TimeOfDay.Instance.SyncNewProfitQuotaClientRpc(TimeOfDay.Instance.profitQuota, TimeOfDay.Instance.quotaFulfilled, TimeOfDay.Instance.timesFulfilledQuota);
					__result = CreateNode($"Profit quota set to ${result5}.\nCurrently fulfilled: ${TimeOfDay.Instance.quotaFulfilled}");
				}
				else
				{
					__result = CreateNode("Usage: setquota <amount>\nExample: setquota 200");
				}
				return false;
			}
			if (text2.StartsWith("fulfillquota"))
			{
				string text4 = text2.Substring(12).Trim();
				if (string.IsNullOrEmpty(text4) || !int.TryParse(text4, out var result6))
				{
					result6 = TimeOfDay.Instance.profitQuota - TimeOfDay.Instance.quotaFulfilled;
				}
				result6 = Mathf.Max(0, result6);
				TimeOfDay instance = TimeOfDay.Instance;
				instance.quotaFulfilled += result6;
				TimeOfDay.Instance.SyncNewProfitQuotaClientRpc(TimeOfDay.Instance.profitQuota, TimeOfDay.Instance.quotaFulfilled, TimeOfDay.Instance.timesFulfilledQuota);
				__result = CreateNode($"Added ${result6} to quota fulfillment.\nQuota: ${TimeOfDay.Instance.quotaFulfilled} / ${TimeOfDay.Instance.profitQuota}");
				return false;
			}
			if (text2 == "listitems")
			{
				List<Item> itemsList = StartOfRound.Instance.allItemsList.itemsList;
				string text5 = "All spawnable items:\n\n";
				for (int i = 0; i < itemsList.Count; i++)
				{
					text5 = text5 + "  " + itemsList[i].itemName + "\n";
				}
				text5 += $"\nTotal: {itemsList.Count} items";
				__result = CreateNode(text5);
				return false;
			}
			if (text2 == "debughelp")
			{
				__result = CreateNode("=== DEBUG COMMANDS ===\n\nspawn <item> [qty]\n  Spawn items at your feet.\n  Example: spawn gold bar 5\n\nsetcredits <amount>\n  Set group credits.\n  Example: setcredits 5000\n\nsetbxp <amount>\n  Set BXP currency to exact amount.\n  Example: setbxp 500\n\naddbxp <amount>\n  Add BXP to current balance.\n  Example: addbxp 200\n\ngetbxp\n  Show current BXP balance.\n\nsetquota <amount>\n  Set the profit quota.\n  Example: setquota 500\n\nfulfillquota [amount]\n  Add to quota fulfillment.\n  No amount = fulfill entirely.\n\nlistitems\n  List all spawnable item names.\n\ndebughelp\n  Show this help text.\n");
				return false;
			}
			return true;
		}

		private static TerminalNode SpawnItem(Terminal terminal, string itemName, int quantity)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			List<Item> itemsList = StartOfRound.Instance.allItemsList.itemsList;
			Item val = null;
			val = ((IEnumerable<Item>)itemsList).FirstOrDefault((Func<Item, bool>)((Item i) => i.itemName.ToLower() == itemName));
			if ((Object)(object)val == (Object)null)
			{
				val = ((IEnumerable<Item>)itemsList).FirstOrDefault((Func<Item, bool>)((Item i) => i.itemName.ToLower().Contains(itemName)));
			}
			if ((Object)(object)val == (Object)null)
			{
				return CreateNode("Item '" + itemName + "' not found.\nType 'listitems' to see all available items.");
			}
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if ((Object)(object)localPlayerController == (Object)null)
			{
				return CreateNode("Error: Local player not found.");
			}
			Vector3 val2 = ((Component)localPlayerController).transform.position + ((Component)localPlayerController).transform.forward * 2f + Vector3.up * 0.5f;
			int num = 0;
			Vector3 val3 = default(Vector3);
			for (int j = 0; j < quantity; j++)
			{
				((Vector3)(ref val3))..ctor(Random.Range(-1f, 1f), 0f, Random.Range(-1f, 1f));
				GameObject obj = Object.Instantiate<GameObject>(val.spawnPrefab, val2 + val3, Quaternion.identity);
				GrabbableObject component = obj.GetComponent<GrabbableObject>();
				if ((Object)(object)component != (Object)null)
				{
					if (val.isScrap)
					{
						component.SetScrapValue((int)Random.Range((float)val.minValue * RoundManager.Instance.scrapValueMultiplier, (float)val.maxValue * RoundManager.Instance.scrapValueMultiplier));
					}
					component.fallTime = 0f;
				}
				NetworkObject component2 = obj.GetComponent<NetworkObject>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.Spawn(false);
				}
				num++;
			}
			string arg = (val.isScrap ? " (with random scrap values)" : "");
			return CreateNode($"Spawned {num}x {val.itemName}{arg}.");
		}

		private static TerminalNode CreateNode(string text)
		{
			TerminalNode obj = ScriptableObject.CreateInstance<TerminalNode>();
			obj.displayText = text + "\n\n";
			obj.clearPreviousText = true;
			return obj;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LGUDebugTools";

		public const string PLUGIN_NAME = "LGUDebugTools";

		public const string PLUGIN_VERSION = "2.0.0";
	}
}

LGUEmotes.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using LethalEmotesAPI.ImportV2;
using Microsoft.CodeAnalysis;
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("LGUEmotes")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8c5521e37f37e3d76518a16d04e5d1051842f105")]
[assembly: AssemblyProduct("LGUEmotes")]
[assembly: AssemblyTitle("LGUEmotes")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 LGUEmotes
{
	[BepInPlugin("com.y4ngz.lguemotes", "LGUEmotes", "0.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private struct Registered
		{
			public string slug;

			public string displayName;

			public AnimationClip clip;

			public AudioClip audio;

			public int rarity;

			public bool looping;
		}

		[Serializable]
		public class EmoteRegistry
		{
			public string bundle_name;

			public string source_humanoid_avatar_fbx;

			public float fbx_animation_sample_rate;

			public List<EmoteEntry> emotes;
		}

		[Serializable]
		public class EmoteEntry
		{
			public string slug;

			public string display_name;

			public string bucket;

			public string source_fbx;

			public string animation_asset_name;

			public string audio_asset_name;

			public string audio_path;

			public int rarity;

			public float speed_multiplier;

			public float snippet_length_sec;

			public float snippet_bpm;

			public bool loop_time;

			public float trim_start_sec;

			public float trim_end_sec;

			public string shares_motion_with;

			public bool disabled;

			public bool loop_audio = true;

			public EmoteSegments segments;
		}

		[Serializable]
		public class EmoteSegments
		{
			public EmoteSegment begin;

			public EmoteSegment loop;

			public EmoteSegment stop;
		}

		[Serializable]
		public class EmoteSegment
		{
			public string source_fbx;

			public string animation_asset_name;

			public bool loop_time;
		}

		public const string GUID = "com.y4ngz.lguemotes";

		public const string NAME = "LGUEmotes";

		public const string VERSION = "0.2.0";

		private const string BUNDLE_FILENAME = "y4ngz_emotes.lethalbundle";

		private const string REGISTRY_ASSET = "y4ngz_emotes_registry";

		internal static ManualLogSource Log;

		private AssetBundle _bundle;

		private Dictionary<string, AnimationClip> _clipsByName;

		private Dictionary<string, AudioClip> _audioByName;

		private readonly HashSet<string> _seededAudioKeys = new HashSet<string>();

		private readonly HashSet<int> _clipsAlreadyRegistered = new HashSet<int>();

		private readonly List<Registered> _registered = new List<Registered>();

		private static Harmony _harmony;

		private static Type _tEmoteAudioPlayer;

		private static Type _tEmoteAudioSource;

		private static FieldInfo _fShipSpeaker;

		private static PropertyInfo _pShipSpeaker;

		private static bool _ueDumpDone;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "y4ngz_emotes.lethalbundle");
			if (!File.Exists(text))
			{
				Log.LogError((object)("emote bundle not found at " + text + " — emotes will not be registered"));
				return;
			}
			_bundle = AssetBundle.LoadFromFile(text);
			if ((Object)(object)_bundle == (Object)null)
			{
				Log.LogError((object)("AssetBundle.LoadFromFile returned null for " + text));
				return;
			}
			_clipsByName = new Dictionary<string, AnimationClip>();
			AnimationClip[] array = _bundle.LoadAllAssets<AnimationClip>();
			foreach (AnimationClip val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)val).name.StartsWith("__preview__"))
				{
					_clipsByName[((Object)val).name] = val;
				}
			}
			Log.LogInfo((object)$"loaded {_clipsByName.Count} animation clips from bundle");
			AudioClip[] array2 = _bundle.LoadAllAssets<AudioClip>();
			Log.LogInfo((object)$"[AUDIO-DIAG] bundle.LoadAllAssets<AudioClip>() returned {array2.Length} clips:");
			_audioByName = new Dictionary<string, AudioClip>();
			AudioClip[] array3 = array2;
			foreach (AudioClip val2 in array3)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					_audioByName[((Object)val2).name] = val2;
					Log.LogInfo((object)$"[AUDIO-DIAG]   '{((Object)val2).name}' length={val2.length:F2}s channels={val2.channels} freq={val2.frequency}Hz");
				}
			}
			EmoteRegistry emoteRegistry = LoadRegistry(_bundle);
			if (emoteRegistry == null || emoteRegistry.emotes == null)
			{
				Log.LogError((object)"failed to parse registry asset 'y4ngz_emotes_registry' from bundle");
				return;
			}
			Log.LogInfo((object)$"registry loaded with {emoteRegistry.emotes.Count} emotes");
			int num = 0;
			foreach (EmoteEntry emote in emoteRegistry.emotes)
			{
				if (TryRegister(emote))
				{
					num++;
				}
			}
			Log.LogInfo((object)$"registered {num}/{emoteRegistry.emotes.Count} emotes with LethalEmotesAPI");
			TryIntegrateWithTooManyEmotes();
		}

		private EmoteRegistry LoadRegistry(AssetBundle bundle)
		{
			TextAsset val = bundle.LoadAsset<TextAsset>("y4ngz_emotes_registry");
			if ((Object)(object)val == (Object)null)
			{
				Log.LogWarning((object)"registry TextAsset 'y4ngz_emotes_registry' not in bundle");
				return null;
			}
			try
			{
				return JsonUtility.FromJson<EmoteRegistry>(val.text);
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"JsonUtility.FromJson failed: {arg}");
				return null;
			}
		}

		private bool TryRegister(EmoteEntry e)
		{
			try
			{
				if (e.disabled)
				{
					Log.LogInfo((object)("emote '" + e.slug + "': disabled in registry — skipped (no in-game registration)"));
					return false;
				}
				switch (e.bucket)
				{
				case "showpiece":
					return RegisterShowpieceOrLoopable(e, looping: false);
				case "loopable":
					return RegisterShowpieceOrLoopable(e, looping: true);
				case "pose":
					return RegisterPose(e);
				default:
					Log.LogWarning((object)("emote '" + e.slug + "': unknown bucket '" + e.bucket + "' — skipped"));
					return false;
				}
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"emote '{e.slug}': registration threw — {arg}");
				return false;
			}
		}

		private AnimationClip CloneClipIfShared(AnimationClip clip, string slug)
		{
			if ((Object)(object)clip == (Object)null)
			{
				return null;
			}
			if (_clipsAlreadyRegistered.Add(((Object)clip).GetInstanceID()))
			{
				return clip;
			}
			AnimationClip val = Object.Instantiate<AnimationClip>(clip);
			((Object)val).name = ((Object)clip).name + "__" + slug;
			Log.LogInfo((object)("emote '" + slug + "': clip '" + ((Object)clip).name + "' shared with prior emote — registering clone '" + ((Object)val).name + "' to avoid LethalEmotesAPI dedup"));
			return val;
		}

		private bool RegisterShowpieceOrLoopable(EmoteEntry e, bool looping)
		{
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Expected O, but got Unknown
			_clipsByName.TryGetValue(e.animation_asset_name, out var value);
			if ((Object)(object)value == (Object)null)
			{
				Log.LogWarning((object)("emote '" + e.slug + "': clip '" + e.animation_asset_name + "' not in bundle"));
				return false;
			}
			if (!((Motion)value).isHumanMotion)
			{
				Log.LogWarning((object)("emote '" + e.slug + "': clip '" + ((Object)value).name + "' is not humanoid — skipped"));
				return false;
			}
			value = CloneClipIfShared(value, e.slug);
			AudioClip val = ((e.audio_asset_name != null) ? _bundle.LoadAsset<AudioClip>(e.audio_asset_name) : null);
			Log.LogInfo((object)($"[AUDIO-DIAG] emote '{e.slug}' audio_asset_name='{e.audio_asset_name}' resolved={(Object)(object)val != (Object)null}" + (((Object)(object)val != (Object)null) ? $" -> name='{((Object)val).name}' length={val.length:F2}s" : "")));
			if ((Object)(object)val == (Object)null)
			{
				Log.LogWarning((object)("emote '" + e.slug + "': audio '" + e.audio_asset_name + "' not in bundle (registering without audio)"));
			}
			CustomEmoteParams val2 = new CustomEmoteParams();
			val2.displayName = e.display_name;
			val2.internalName = e.slug;
			val2.primaryAnimationClips = (AnimationClip[])(object)new AnimationClip[1] { value };
			val2.primaryAudioClips = (AudioClip[])(object)((!((Object)(object)val != (Object)null)) ? null : new AudioClip[1] { val });
			val2.audioLoops = e.loop_audio;
			val2.visible = true;
			val2.willGetClaimedByDMCA = false;
			EmoteImporter.ImportEmote(val2);
			_registered.Add(new Registered
			{
				slug = e.slug,
				displayName = e.display_name,
				clip = value,
				audio = val,
				rarity = ClampRarity(e.rarity),
				looping = looping
			});
			Log.LogInfo((object)string.Format("registered {0} '{1}' (rarity={2})", looping ? "loopable" : "showpiece", e.slug, e.rarity));
			return true;
		}

		private bool RegisterPose(EmoteEntry e)
		{
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Expected O, but got Unknown
			if (e.segments == null || e.segments.loop == null)
			{
				Log.LogWarning((object)("emote '" + e.slug + "': pose has no loop segment — skipped"));
				return false;
			}
			_clipsByName.TryGetValue(e.segments.loop.animation_asset_name, out var value);
			if ((Object)(object)value == (Object)null)
			{
				Log.LogWarning((object)("emote '" + e.slug + "': loop clip '" + e.segments.loop.animation_asset_name + "' not in bundle"));
				return false;
			}
			if (!((Motion)value).isHumanMotion)
			{
				Log.LogWarning((object)("emote '" + e.slug + "': loop clip is not humanoid — skipped"));
				return false;
			}
			value = CloneClipIfShared(value, e.slug);
			AudioClip val = ((e.audio_asset_name != null) ? _bundle.LoadAsset<AudioClip>(e.audio_asset_name) : null);
			Log.LogInfo((object)($"[AUDIO-DIAG] emote '{e.slug}' (pose) audio_asset_name='{e.audio_asset_name}' resolved={(Object)(object)val != (Object)null}" + (((Object)(object)val != (Object)null) ? $" -> name='{((Object)val).name}' length={val.length:F2}s" : "")));
			if ((Object)(object)val == (Object)null)
			{
				Log.LogWarning((object)("emote '" + e.slug + "': audio '" + e.audio_asset_name + "' not in bundle"));
			}
			CustomEmoteParams val2 = new CustomEmoteParams();
			val2.displayName = e.display_name;
			val2.internalName = e.slug;
			val2.primaryAnimationClips = (AnimationClip[])(object)new AnimationClip[1] { value };
			val2.primaryAudioClips = (AudioClip[])(object)((!((Object)(object)val != (Object)null)) ? null : new AudioClip[1] { val });
			val2.audioLoops = e.loop_audio;
			val2.visible = true;
			val2.willGetClaimedByDMCA = false;
			EmoteImporter.ImportEmote(val2);
			_registered.Add(new Registered
			{
				slug = e.slug,
				displayName = e.display_name,
				clip = value,
				audio = val,
				rarity = ClampRarity(e.rarity),
				looping = true
			});
			Log.LogInfo((object)("registered pose '" + e.slug + "' (loop segment only — begin/stop dropped)"));
			return true;
		}

		private static int ClampRarity(int r)
		{
			if (r >= 0)
			{
				if (r <= 3)
				{
					return r;
				}
				return 3;
			}
			return 0;
		}

		private void TryIntegrateWithTooManyEmotes()
		{
			if (_registered.Count == 0)
			{
				return;
			}
			Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "TooManyEmotes");
			if (assembly == null)
			{
				Log.LogInfo((object)"TooManyEmotes not loaded — skipping LGUGui category injection");
				return;
			}
			DumpTmeAssembly(assembly);
			try
			{
				Type type = assembly.GetType("TooManyEmotes.EmotesManager");
				Type type2 = assembly.GetType("TooManyEmotes.UnlockableEmote");
				Type type3 = assembly.GetType("TooManyEmotes.Audio.AudioManager") ?? assembly.GetType("TooManyEmotes.AudioManager");
				Log.LogInfo((object)("[AUDIO-DIAG] AudioManager type resolved: " + (type3?.FullName ?? "null")));
				if (type == null || type2 == null)
				{
					Log.LogWarning((object)"TooManyEmotes types not found — skipping LGUGui injection");
					return;
				}
				DumpUnlockableEmote(type2);
				FieldInfo field = type.GetField("allUnlockableEmotes", BindingFlags.Static | BindingFlags.Public);
				FieldInfo field2 = type.GetField("allUnlockableEmotesDict", BindingFlags.Static | BindingFlags.Public);
				FieldInfo[] array = new FieldInfo[4]
				{
					type.GetField("allEmotesTier0", BindingFlags.Static | BindingFlags.Public),
					type.GetField("allEmotesTier1", BindingFlags.Static | BindingFlags.Public),
					type.GetField("allEmotesTier2", BindingFlags.Static | BindingFlags.Public),
					type.GetField("allEmotesTier3", BindingFlags.Static | BindingFlags.Public)
				};
				if (field == null || field2 == null || array.Any((FieldInfo f) => f == null))
				{
					Log.LogWarning((object)"TooManyEmotes EmotesManager fields not found — TME version mismatch?");
					return;
				}
				IList list = (IList)field.GetValue(null);
				IDictionary dictionary = (IDictionary)field2.GetValue(null);
				if (list == null || dictionary == null)
				{
					Log.LogWarning((object)"TooManyEmotes EmotesManager lists are null — BuildEmotesList hasn't run yet (load order issue?)");
					return;
				}
				IDictionary dictionary2 = null;
				if (type3 != null)
				{
					FieldInfo field3 = type3.GetField("audioClipsDictDmcaFree", BindingFlags.Static | BindingFlags.NonPublic);
					dictionary2 = field3?.GetValue(null) as IDictionary;
					Log.LogInfo((object)("[AUDIO-DIAG] audioClipsDictDmcaFree field=" + ((field3 != null) ? "found" : "NOT FOUND") + " dict=" + ((dictionary2 != null) ? "non-null" : "null")));
				}
				int num = dictionary2?.Count ?? (-1);
				Log.LogInfo((object)$"[AUDIO-DIAG] audioClipsDictDmcaFree count before injection: {num}");
				int count = list.Count;
				int num2 = 0;
				object obj = null;
				foreach (Registered item in _registered)
				{
					string slug = item.slug;
					if (dictionary.Contains(slug))
					{
						continue;
					}
					object obj2 = Activator.CreateInstance(type2);
					SetField(obj2, "emoteId", count++);
					SetField(obj2, "emoteName", slug);
					SetField(obj2, "displayName", item.displayName);
					SetField(obj2, "animationClip", item.clip);
					SetField(obj2, "rarity", item.rarity);
					SetField(obj2, "purchasable", true);
					SetField(obj2, "canSyncEmote", true);
					list.Add(obj2);
					dictionary.Add(slug, obj2);
					(array[item.rarity].GetValue(null) as IList)?.Add(obj2);
					num2++;
					if ((Object)(object)item.audio != (Object)null)
					{
						try
						{
							bool num3 = TrySetMember(obj2, "overrideAudioClipName", item.slug);
							bool flag = TrySetMember(obj2, "overrideAudioLoopClipName", item.slug);
							if (!num3)
							{
								Log.LogWarning((object)("[AUDIO-DIAG] '" + item.slug + "': could not set overrideAudioClipName"));
							}
							if (!flag)
							{
								Log.LogWarning((object)("[AUDIO-DIAG] '" + item.slug + "': could not set overrideAudioLoopClipName"));
							}
							if (!TrySetProperty(obj2, "isBoomboxAudio", true))
							{
								Log.LogWarning((object)("[AUDIO-DIAG] '" + item.slug + "': could not set isBoomboxAudio=true"));
							}
							if (dictionary2 != null)
							{
								string text = (((Object)(object)item.clip != (Object)null) ? ((Object)item.clip).name : null);
								SeedAudio(dictionary2, item.slug, item.audio);
								SeedAudio(dictionary2, text, item.audio);
								if (item.looping)
								{
									SeedAudio(dictionary2, item.slug + "_loop", item.audio);
									SeedAudio(dictionary2, text + "_loop", item.audio);
								}
							}
							if (!TrySetProperty(obj2, "isBoomboxAudio", false))
							{
								Log.LogWarning((object)("[AUDIO-DIAG] '" + item.slug + "': could not set isBoomboxAudio=false"));
							}
						}
						catch (Exception ex)
						{
							Log.LogWarning((object)("[AUDIO-DIAG] '" + item.slug + "': audio wiring threw — " + ex.Message));
						}
					}
					LogEmoteAudioState(obj2, item.slug, "post-wire");
					if (obj == null && item.slug == "bundy_lost_it")
					{
						obj = obj2;
					}
				}
				if (obj == null && dictionary.Contains("bundy_lost_it"))
				{
					LogEmoteAudioState(dictionary["bundy_lost_it"], "bundy_lost_it (preexisting)");
				}
				Log.LogInfo((object)$"injected {num2} emotes into TooManyEmotes EmotesManager (visible in LGUGui)");
				Log.LogInfo((object)$"[AUDIO-DIAG] audioClipsDictDmcaFree count after injection: {dictionary2?.Count ?? (-1)} (was {num}, delta={(dictionary2?.Count ?? 0) - ((num >= 0) ? num : 0)})");
				Log.LogInfo((object)string.Format("[AUDIO-DIAG] seeded {0} keys: {1}", _seededAudioKeys.Count, string.Join(", ", _seededAudioKeys.OrderBy((string s) => s))));
				LogAudioClipImportSettings(dictionary2);
				HookTmeAudioPath(type3);
				HookTmeRoutingPath(assembly);
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"TooManyEmotes integration threw — {arg}");
			}
		}

		private void DumpTmeAssembly(Assembly tmeAsm)
		{
			StringBuilder sb = new StringBuilder();
			Out("[TME-DUMP] assembly: " + tmeAsm.FullName);
			Out("[TME-DUMP] location: " + tmeAsm.Location);
			Type[] array;
			try
			{
				array = tmeAsm.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				Out($"[TME-DUMP] ReflectionTypeLoadException — using LoaderExceptions-filtered types ({ex.Types.Length} entries, {ex.LoaderExceptions.Length} load errors)");
				array = ex.Types.Where((Type t) => t != null).ToArray();
			}
			Out($"[TME-DUMP] total types: {array.Length}");
			Out("");
			Out("[TME-DUMP] === Step 1: types with 'audio' in name ===");
			List<Type> list = array.Where((Type t) => t.Name.IndexOf("audio", StringComparison.OrdinalIgnoreCase) >= 0).ToList();
			if (list.Count == 0)
			{
				Out("[TME-DUMP]   (none)");
			}
			foreach (Type item in list)
			{
				Out($"[TME-DUMP] type: {item.FullName}  (sealed={item.IsSealed} static={item.IsAbstract && item.IsSealed})");
				foreach (FieldInfo item2 in from f in item.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
					where f.IsStatic
					select f)
				{
					string text = item2.FieldType.FullName ?? item2.FieldType.Name;
					string text2 = ((item2.FieldType.IsGenericType && item2.FieldType.GetGenericTypeDefinition() == typeof(Dictionary<, >)) ? "  [DICT]" : "");
					string text3 = (item2.IsPublic ? "public" : (item2.IsPrivate ? "private" : (item2.IsAssembly ? "internal" : "protected")));
					Out("[TME-DUMP]   static field: " + text3 + " " + text + " " + item2.Name + text2);
				}
				foreach (PropertyInfo item3 in item.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Where(delegate(PropertyInfo p)
				{
					MethodInfo? getMethod = p.GetGetMethod(nonPublic: true);
					return ((object)getMethod != null && getMethod.IsStatic) || (p.GetSetMethod(nonPublic: true)?.IsStatic ?? false);
				}))
				{
					Out("[TME-DUMP]   static property: " + (item3.PropertyType.FullName ?? item3.PropertyType.Name) + " " + item3.Name);
				}
			}
			Out("");
			Out("[TME-DUMP] === Step 2: methods with 'play'/'audio'/'sound' in name ===");
			int num = 0;
			Type[] array2 = array;
			foreach (Type type in array2)
			{
				MethodInfo[] methods;
				try
				{
					methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				}
				catch
				{
					continue;
				}
				MethodInfo[] array3 = methods;
				foreach (MethodInfo methodInfo in array3)
				{
					if (methodInfo.DeclaringType != type)
					{
						continue;
					}
					string name = methodInfo.Name;
					if (name.IndexOf("play", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("audio", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("sound", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						string text4 = string.Join(", ", from p in methodInfo.GetParameters()
							select (p.ParameterType.FullName ?? p.ParameterType.Name) + " " + p.Name);
						string text5 = methodInfo.ReturnType.FullName ?? methodInfo.ReturnType.Name;
						string text6 = (methodInfo.IsStatic ? "static " : "") + (methodInfo.IsPublic ? "public " : (methodInfo.IsPrivate ? "private " : "internal "));
						Out("[TME-DUMP]   " + text6 + text5 + " " + type.FullName + "." + name + "(" + text4 + ")");
						num++;
					}
				}
			}
			Out($"[TME-DUMP] === total method matches: {num} ===");
			Out("");
			Out("[TME-DUMP] === Step 3: every static Dictionary<,> field in TME ===");
			int num2 = 0;
			array2 = array;
			foreach (Type type2 in array2)
			{
				FieldInfo[] fields;
				try
				{
					fields = type2.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				}
				catch
				{
					continue;
				}
				FieldInfo[] array4 = fields;
				foreach (FieldInfo fieldInfo in array4)
				{
					if (fieldInfo.IsStatic && fieldInfo.FieldType.IsGenericType && !(fieldInfo.FieldType.GetGenericTypeDefinition() != typeof(Dictionary<, >)))
					{
						Type[] genericArguments = fieldInfo.FieldType.GetGenericArguments();
						string text7 = genericArguments[0].FullName ?? genericArguments[0].Name;
						string text8 = genericArguments[1].FullName ?? genericArguments[1].Name;
						string text9 = (fieldInfo.IsPublic ? "public" : (fieldInfo.IsPrivate ? "private" : "internal"));
						int? num3 = null;
						try
						{
							num3 = (fieldInfo.GetValue(null) as IDictionary)?.Count;
						}
						catch
						{
						}
						Out($"[TME-DUMP]   {text9} static Dictionary<{text7}, {text8}> {type2.FullName}.{fieldInfo.Name}  count={num3}");
						num2++;
					}
				}
			}
			Out($"[TME-DUMP] === total static dicts: {num2} ===");
			try
			{
				string text10 = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "tme_dump.txt");
				File.WriteAllText(text10, sb.ToString());
				Log.LogInfo((object)("[TME-DUMP] written to " + text10));
			}
			catch (Exception ex2)
			{
				Log.LogWarning((object)("[TME-DUMP] failed to write tme_dump.txt: " + ex2.Message));
			}
			void Out(string s)
			{
				Log.LogInfo((object)s);
				sb.AppendLine(s);
			}
		}

		private void HookTmeAudioPath(Type tAudioManager)
		{
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			if (tAudioManager == null)
			{
				Log.LogWarning((object)"[AUDIO-DIAG] AudioManager type null — cannot hook");
				return;
			}
			Log.LogInfo((object)"[AUDIO-DIAG] enumerating TooManyEmotes.AudioManager methods:");
			MethodInfo[] methods = tAudioManager.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			MethodInfo[] array = methods;
			foreach (MethodInfo methodInfo in array)
			{
				if (!(methodInfo.DeclaringType != tAudioManager))
				{
					string text = string.Join(", ", from p in methodInfo.GetParameters()
						select p.ParameterType.Name + " " + p.Name);
					Log.LogInfo((object)("[AUDIO-DIAG]   " + (methodInfo.IsStatic ? "static " : "") + methodInfo.ReturnType.Name + " " + methodInfo.Name + "(" + text + ")"));
				}
			}
			_harmony = new Harmony("com.y4ngz.lguemotes.audiohook");
			HarmonyMethod val = new HarmonyMethod(typeof(Plugin).GetMethod("TmeAudioPostfix", BindingFlags.Static | BindingFlags.NonPublic));
			int num = 0;
			array = methods;
			foreach (MethodInfo methodInfo2 in array)
			{
				if (methodInfo2.DeclaringType != tAudioManager)
				{
					continue;
				}
				string name = methodInfo2.Name;
				switch (name)
				{
				default:
					if (!(name == "AddAudioClip"))
					{
						continue;
					}
					break;
				case "LoadAudioClip":
				case "GetAudioClip":
				case "AudioExists":
				case "TryGetAudioClip":
				case "PlayAudio":
				case "PlayEmoteAudio":
				case "BuildAudioClipList":
					break;
				}
				if (methodInfo2.IsAbstract || methodInfo2.ContainsGenericParameters)
				{
					continue;
				}
				try
				{
					_harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)("[AUDIO-DIAG] patched postfix on AudioManager." + name + "(" + string.Join(",", from p in methodInfo2.GetParameters()
						select p.ParameterType.Name) + ")"));
					num++;
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("[AUDIO-DIAG] failed to patch AudioManager." + name + ": " + ex.Message));
				}
			}
			Log.LogInfo((object)$"[AUDIO-DIAG] patched {num} TME AudioManager methods");
		}

		private static void TmeAudioPostfix(MethodBase __originalMethod, object[] __args, object __result)
		{
			try
			{
				string text = ((__args == null) ? "" : string.Join(", ", __args.Select(delegate(object a)
				{
					if (a != null)
					{
						Object val2 = (Object)((a is Object) ? a : null);
						if (val2 == null)
						{
							return a.ToString();
						}
						return ((object)val2).GetType().Name + "('" + val2.name + "')";
					}
					return "null";
				})));
				object obj;
				if (__result != null)
				{
					Object val = (Object)((__result is Object) ? __result : null);
					obj = ((val != null) ? (((object)val).GetType().Name + "('" + val.name + "')") : __result.ToString());
				}
				else
				{
					obj = "null";
				}
				string text2 = (string)obj;
				Log.LogInfo((object)("[AUDIO-DIAG-RT] AudioManager." + __originalMethod.Name + "(" + text + ") -> " + text2));
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[AUDIO-DIAG-RT] postfix log threw: " + ex.Message));
			}
		}

		private void HookTmeRoutingPath(Assembly tmeAsm)
		{
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Expected O, but got Unknown
			try
			{
				_tEmoteAudioPlayer = tmeAsm.GetType("TooManyEmotes.EmoteAudioPlayer") ?? tmeAsm.GetType("TooManyEmotes.Audio.EmoteAudioPlayer");
				_tEmoteAudioSource = tmeAsm.GetType("TooManyEmotes.EmoteAudioSource") ?? tmeAsm.GetType("TooManyEmotes.Audio.EmoteAudioSource");
				Type type = tmeAsm.GetType("TooManyEmotes.EmoteAudioPlayerManager") ?? tmeAsm.GetType("TooManyEmotes.Audio.EmoteAudioPlayerManager");
				Log.LogInfo((object)("[ROUTING-DIAG] EmoteAudioPlayer=" + (_tEmoteAudioPlayer?.FullName ?? "null") + " EmoteAudioSource=" + (_tEmoteAudioSource?.FullName ?? "null") + " EmoteAudioPlayerManager=" + (type?.FullName ?? "null")));
				if (type != null)
				{
					_fShipSpeaker = type.GetField("shipSpeakerAudioPlayer", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					_pShipSpeaker = type.GetProperty("shipSpeakerAudioPlayer", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					Log.LogInfo((object)("[ROUTING-DIAG] shipSpeakerAudioPlayer field=" + ((_fShipSpeaker != null) ? "found" : "no") + " property=" + ((_pShipSpeaker != null) ? "found" : "no")));
				}
				if (_harmony == null)
				{
					_harmony = new Harmony("com.y4ngz.lguemotes.routinghook");
				}
				HarmonyMethod postfix = new HarmonyMethod(typeof(Plugin).GetMethod("TmeRoutingPostfix", BindingFlags.Static | BindingFlags.NonPublic));
				int num = 0;
				num += PatchSetAudioFromEmote(_tEmoteAudioPlayer, postfix);
				num += PatchSetAudioFromEmote(_tEmoteAudioSource, postfix);
				Log.LogInfo((object)$"[ROUTING-DIAG] patched {num} SetAudioFromEmote method(s)");
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[ROUTING-DIAG] HookTmeRoutingPath threw: " + ex.Message));
			}
		}

		private static int PatchSetAudioFromEmote(Type t, HarmonyMethod postfix)
		{
			if (t == null)
			{
				return 0;
			}
			int num = 0;
			MethodInfo[] methods = t.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.DeclaringType != t || methodInfo.Name != "SetAudioFromEmote" || methodInfo.IsAbstract || methodInfo.ContainsGenericParameters)
				{
					continue;
				}
				try
				{
					_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, postfix, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)("[ROUTING-DIAG] patched " + t.Name + ".SetAudioFromEmote(" + string.Join(",", from p in methodInfo.GetParameters()
						select p.ParameterType.Name) + ")"));
					num++;
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("[ROUTING-DIAG] failed to patch " + t.Name + ".SetAudioFromEmote: " + ex.Message));
				}
			}
			return num;
		}

		private static void TmeRoutingPostfix(object __instance, object[] __args)
		{
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (__instance == null)
				{
					Log.LogInfo((object)"[ROUTING-DIAG-RT] SetAudioFromEmote __instance=null");
					return;
				}
				Type type = __instance.GetType();
				string text = "<no emote arg>";
				bool flag = false;
				bool flag2 = false;
				if (__args != null)
				{
					foreach (object obj in __args)
					{
						if (obj == null)
						{
							continue;
						}
						Type type2 = obj.GetType();
						FieldInfo field = type2.GetField("emoteName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (field != null)
						{
							text = field.GetValue(obj)?.ToString() ?? "null";
							MemberInfo memberInfo = (MemberInfo)(((object)type2.GetField("isBoomboxAudio", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) ?? ((object)type2.GetProperty("isBoomboxAudio", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)));
							if (memberInfo is FieldInfo fieldInfo)
							{
								flag = (bool)fieldInfo.GetValue(obj);
								flag2 = true;
							}
							else if (memberInfo is PropertyInfo propertyInfo && propertyInfo.CanRead)
							{
								flag = (bool)propertyInfo.GetValue(obj);
								flag2 = true;
							}
							break;
						}
					}
				}
				object obj2 = null;
				if (_fShipSpeaker != null)
				{
					obj2 = _fShipSpeaker.GetValue(null);
				}
				else if (_pShipSpeaker != null)
				{
					obj2 = _pShipSpeaker.GetValue(null);
				}
				bool flag3 = obj2 != null && __instance == obj2;
				AudioSource val = null;
				Component val2 = (Component)((__instance is Component) ? __instance : null);
				if (val2 != null)
				{
					FieldInfo field2 = type.GetField("audioSource", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field2 != null)
					{
						object? value = field2.GetValue(__instance);
						val = (AudioSource)((value is AudioSource) ? value : null);
					}
					if ((Object)(object)val == (Object)null)
					{
						PropertyInfo property = type.GetProperty("audioSource", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (property != null && property.CanRead)
						{
							object? value2 = property.GetValue(__instance);
							val = (AudioSource)((value2 is AudioSource) ? value2 : null);
						}
					}
					if ((Object)(object)val == (Object)null)
					{
						val = val2.GetComponent<AudioSource>();
					}
				}
				string text2 = "<no AudioSource>";
				string text3 = "<no parent info>";
				Component val3 = (Component)((__instance is Component) ? __instance : null);
				if (val3 != null && (Object)(object)val3 != (Object)null)
				{
					Transform val4 = (((Object)(object)val3.transform != (Object)null) ? val3.transform.parent : null);
					text3 = (((Object)(object)val4 != (Object)null) ? ("parent='" + ((Object)val4).name + "'") : "parent=null");
					Vector3 val5 = (((Object)(object)val3.transform != (Object)null) ? val3.transform.position : Vector3.zero);
					text3 += $" pos=({val5.x:F2},{val5.y:F2},{val5.z:F2})";
				}
				if ((Object)(object)val != (Object)null)
				{
					text2 = string.Format("spatialBlend={0:F2} clip={1} loop={2} volume={3:F2} outputMixerGroup={4}", val.spatialBlend, ((Object)(object)val.clip != (Object)null) ? ("'" + ((Object)val.clip).name + "'") : "null", val.loop, val.volume, ((Object)(object)val.outputAudioMixerGroup != (Object)null) ? ((Object)val.outputAudioMixerGroup).name : "null");
				}
				Log.LogInfo((object)string.Format("[ROUTING-DIAG-RT] {0}.SetAudioFromEmote(emoteName='{1}') instance={2} isShipSpeaker={3} {4} AudioSource[{5}] isBoomboxAudio={6}", type.Name, text, type.Name, flag3, text3, text2, flag2 ? flag.ToString() : "<unknown>"));
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[ROUTING-DIAG-RT] postfix threw: " + ex.Message));
			}
		}

		private static bool TrySetProperty(object obj, string name, object value)
		{
			PropertyInfo property = obj.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property == null || !property.CanWrite)
			{
				return false;
			}
			property.SetValue(obj, value);
			return true;
		}

		private void SeedAudio(IDictionary dict, string key, AudioClip clip)
		{
			if (dict != null && !string.IsNullOrEmpty(key) && !((Object)(object)clip == (Object)null))
			{
				if (dict.Contains(key))
				{
					_seededAudioKeys.Add(key + " (preexisting)");
					return;
				}
				dict.Add(key, clip);
				_seededAudioKeys.Add(key);
			}
		}

		private static bool TrySetMember(object obj, string name, object value)
		{
			Type type = obj.GetType();
			PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null && property.CanWrite)
			{
				property.SetValue(obj, value);
				return true;
			}
			string[] array = new string[4]
			{
				name,
				"<" + name + ">k__BackingField",
				"_" + name,
				"m_" + name
			};
			foreach (string name2 in array)
			{
				FieldInfo field = type.GetField(name2, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					field.SetValue(obj, value);
					return true;
				}
			}
			return false;
		}

		private void DumpUnlockableEmote(Type t)
		{
			if (_ueDumpDone || t == null)
			{
				return;
			}
			_ueDumpDone = true;
			StringBuilder sb = new StringBuilder();
			Out($"[UE-DUMP] type: {t.FullName}  (sealed={t.IsSealed})");
			Out("[UE-DUMP] === fields ===");
			FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (!(fieldInfo.DeclaringType != t))
				{
					string text = (fieldInfo.IsPublic ? "public" : (fieldInfo.IsPrivate ? "private" : (fieldInfo.IsAssembly ? "internal" : "protected")));
					string text2 = (fieldInfo.IsStatic ? "static " : "") + (fieldInfo.IsInitOnly ? "readonly " : "");
					string text3 = fieldInfo.FieldType.FullName ?? fieldInfo.FieldType.Name;
					Out("[UE-DUMP]   " + text + " " + text2 + text3 + " " + fieldInfo.Name);
				}
			}
			Out("[UE-DUMP] === constructors ===");
			ConstructorInfo[] constructors = t.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (ConstructorInfo constructorInfo in constructors)
			{
				if (!(constructorInfo.DeclaringType != t))
				{
					string text4 = (constructorInfo.IsPublic ? "public" : (constructorInfo.IsPrivate ? "private" : (constructorInfo.IsAssembly ? "internal" : "protected")));
					string text5 = string.Join(", ", from p in constructorInfo.GetParameters()
						select (p.ParameterType.FullName ?? p.ParameterType.Name) + " " + p.Name);
					Out("[UE-DUMP]   " + text4 + " .ctor(" + text5 + ")");
				}
			}
			Out("[UE-DUMP] === properties ===");
			PropertyInfo[] properties = t.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (PropertyInfo propertyInfo in properties)
			{
				if (!(propertyInfo.DeclaringType != t))
				{
					string text6 = propertyInfo.PropertyType.FullName ?? propertyInfo.PropertyType.Name;
					Out($"[UE-DUMP]   {text6} {propertyInfo.Name}  CanRead={propertyInfo.CanRead} CanWrite={propertyInfo.CanWrite}");
				}
			}
			Out("[UE-DUMP] === methods ===");
			MethodInfo[] methods = t.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (!(methodInfo.DeclaringType != t))
				{
					string text7 = (methodInfo.IsPublic ? "public" : (methodInfo.IsPrivate ? "private" : (methodInfo.IsAssembly ? "internal" : "protected")));
					string text8 = (methodInfo.IsStatic ? "static " : "");
					string text9 = string.Join(", ", from p in methodInfo.GetParameters()
						select (p.ParameterType.FullName ?? p.ParameterType.Name) + " " + p.Name);
					string text10 = methodInfo.ReturnType.FullName ?? methodInfo.ReturnType.Name;
					Out("[UE-DUMP]   " + text7 + " " + text8 + text10 + " " + methodInfo.Name + "(" + text9 + ")");
				}
			}
			try
			{
				string text11 = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "unlockable_emote_dump.txt");
				File.WriteAllText(text11, sb.ToString());
				Log.LogInfo((object)("[UE-DUMP] written to " + text11));
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[UE-DUMP] failed to write file: " + ex.Message));
			}
			void Out(string s)
			{
				Log.LogInfo((object)s);
				sb.AppendLine(s);
			}
		}

		private static void LogEmoteAudioState(object ue, string slug)
		{
			LogEmoteAudioState(ue, slug, "");
		}

		private static void LogEmoteAudioState(object ue, string slug, string phase)
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Type t = ue.GetType();
				string text = Read("overrideAudioClipName");
				string text2 = Read("overrideAudioLoopClipName");
				string text3 = Read("audioClipName");
				string text4 = Read("audioLoopClipName");
				string text5 = Read("hasAudio");
				string text6 = Read("isBoomboxAudio");
				string text7 = Read("loopable");
				string text8 = "<no animationClip>";
				FieldInfo field = t.GetField("animationClip", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					object? value = field.GetValue(ue);
					AnimationClip val = (AnimationClip)((value is AnimationClip) ? value : null);
					text8 = ((!((Object)(object)val != (Object)null)) ? "null" : $"name='{((Object)val).name}' isLooping={((Motion)val).isLooping} wrapMode={val.wrapMode}");
				}
				string text9 = "<no LoadAudioClip method>";
				MethodInfo method = t.GetMethod("LoadAudioClip", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
				if (method != null)
				{
					try
					{
						object obj = method.Invoke(ue, null);
						if (obj == null)
						{
							text9 = "null";
						}
						else
						{
							Object val2 = (Object)((obj is Object) ? obj : null);
							text9 = ((val2 == null) ? obj.ToString() : (((object)val2).GetType().Name + "('" + val2.name + "')"));
						}
					}
					catch (Exception ex)
					{
						text9 = "<threw: " + ex.GetType().Name + ": " + (ex.InnerException?.Message ?? ex.Message) + ">";
					}
				}
				string text10 = (string.IsNullOrEmpty(phase) ? "" : ("[" + phase + "] "));
				Log.LogInfo((object)("[AUDIO-DIAG] " + text10 + "'" + slug + "' overrideAudioClipName='" + text + "' overrideAudioLoopClipName='" + text2 + "' audioClipName='" + text3 + "' audioLoopClipName='" + text4 + "' hasAudio=" + text5 + " isBoomboxAudio=" + text6 + " loopable=" + text7 + " animClip[" + text8 + "] LoadAudioClip()=" + text9));
				string Read(string name)
				{
					FieldInfo field2 = t.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field2 != null)
					{
						return field2.GetValue(ue)?.ToString() ?? "null";
					}
					PropertyInfo property = t.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (property != null && property.CanRead)
					{
						try
						{
							return property.GetValue(ue)?.ToString() ?? "null";
						}
						catch (Exception ex3)
						{
							return "<getter threw: " + ex3.GetType().Name + ": " + (ex3.InnerException?.Message ?? ex3.Message) + ">";
						}
					}
					return "<no member>";
				}
			}
			catch (Exception ex2)
			{
				Log.LogWarning((object)("[AUDIO-DIAG] LogEmoteAudioState('" + slug + "') threw: " + ex2.Message));
			}
		}

		private static void SetField(object obj, string name, object value)
		{
			FieldInfo? field = obj.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				throw new MissingFieldException(obj.GetType().FullName, name);
			}
			field.SetValue(obj, value);
		}

		private void LogAudioClipImportSettings(IDictionary tmeAudioDict)
		{
			try
			{
				Log.LogInfo((object)"[SPATIAL-DIAG] === per-clip AudioClip settings (ours, then TME baseline) ===");
				foreach (Registered item in _registered)
				{
					LogOneClip("ours", item.slug, item.audio);
				}
				if (tmeAudioDict != null)
				{
					string[] obj = new string[4] { "controller_crew_start", "controller_crew_loop", "twerk_start", "twerk_loop" };
					bool flag = false;
					string[] array = obj;
					foreach (string text in array)
					{
						if (tmeAudioDict.Contains(text))
						{
							object? obj2 = tmeAudioDict[text];
							AudioClip val = (AudioClip)((obj2 is AudioClip) ? obj2 : null);
							if (val != null)
							{
								LogOneClip("tme", text, val);
								flag = true;
							}
						}
					}
					if (!flag)
					{
						foreach (object key in tmeAudioDict.Keys)
						{
							if (key is string text2 && !_seededAudioKeys.Contains(text2))
							{
								object? obj3 = tmeAudioDict[text2];
								AudioClip val2 = (AudioClip)((obj3 is AudioClip) ? obj3 : null);
								if (val2 != null)
								{
									LogOneClip("tme-fallback", text2, val2);
									break;
								}
							}
						}
					}
				}
				Log.LogInfo((object)"[SPATIAL-DIAG] === end ===");
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[SPATIAL-DIAG] LogAudioClipImportSettings threw: " + ex.Message));
			}
		}

		private static void LogOneClip(string source, string label, AudioClip c)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)c == (Object)null)
			{
				Log.LogInfo((object)("[SPATIAL-DIAG] " + source + " '" + label + "' clip=null"));
				return;
			}
			string text = "";
			try
			{
				PropertyInfo property = typeof(AudioClip).GetProperty("loadInBackground", BindingFlags.Instance | BindingFlags.Public);
				if (property != null)
				{
					text += $" loadInBackground={property.GetValue(c)}";
				}
			}
			catch
			{
			}
			Log.LogInfo((object)$"[SPATIAL-DIAG] {source} '{label}' name='{((Object)c).name}' loadType={c.loadType} preloadAudioData={c.preloadAudioData} ambisonic={c.ambisonic} channels={c.channels} frequency={c.frequency}Hz length={c.length:F2}s samples={c.samples} loadState={c.loadState}{text}");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LGUEmotes";

		public const string PLUGIN_NAME = "LGUEmotes";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}

LGUExpBridge.dll

Decompiled 4 days 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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MoreShipUpgrades.Managers;
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("LGUExpBridge")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Converts Lethal Company XP gains into LateGameUpgrades alternate currency")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8c5521e37f37e3d76518a16d04e5d1051842f105")]
[assembly: AssemblyProduct("LGUExpBridge")]
[assembly: AssemblyTitle("LGUExpBridge")]
[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 LGUExpBridge
{
	internal static class BXPSaveManager
	{
		private static readonly string SaveDir = Path.Combine(Application.persistentDataPath, "LGUExpBridge");

		private static readonly string SavePath = Path.Combine(SaveDir, "bxp_saves.json");

		private static Dictionary<string, int> _saves;

		private static bool _reflResolved;

		private static FieldInfo _betterXpField;

		private static FieldInfo _levelField;

		private static MethodInfo _setBetterXP;

		private static MethodInfo _saveMethod;

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void OnSaveLoaded()
		{
			if (!Plugin.BetterEXPLoaded)
			{
				return;
			}
			try
			{
				string currentSaveFile = GetCurrentSaveFile();
				if (string.IsNullOrEmpty(currentSaveFile))
				{
					Plugin.Log.LogWarning((object)"[BXPSaveManager] Could not determine current save file.");
					return;
				}
				LoadFromDisk();
				int num = 0;
				if (_saves.ContainsKey(currentSaveFile))
				{
					num = _saves[currentSaveFile];
					Plugin.Log.LogInfo((object)$"[BXPSaveManager] Restored {num} BXP for save '{currentSaveFile}'.");
				}
				else
				{
					Plugin.Log.LogInfo((object)("[BXPSaveManager] New save '" + currentSaveFile + "' — starting at 0 BXP."));
				}
				SetBXP(num);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[BXPSaveManager] Error loading save BXP: " + ex.Message));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void PersistCurrentBXP()
		{
			if (!Plugin.BetterEXPLoaded)
			{
				return;
			}
			try
			{
				string currentSaveFile = GetCurrentSaveFile();
				if (!string.IsNullOrEmpty(currentSaveFile))
				{
					int currentBXP = GetCurrentBXP();
					LoadFromDisk();
					_saves[currentSaveFile] = currentBXP;
					SaveToDisk();
					Plugin.Log.LogInfo((object)$"[BXPSaveManager] Saved {currentBXP} BXP for save '{currentSaveFile}'.");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[BXPSaveManager] Error persisting BXP: " + ex.Message));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void OnSaveReset()
		{
			if (!Plugin.BetterEXPLoaded)
			{
				return;
			}
			try
			{
				string currentSaveFile = GetCurrentSaveFile();
				if (!string.IsNullOrEmpty(currentSaveFile))
				{
					LoadFromDisk();
					if (_saves.Remove(currentSaveFile))
					{
						SaveToDisk();
						Plugin.Log.LogInfo((object)("[BXPSaveManager] Cleared BXP data for reset save '" + currentSaveFile + "'."));
					}
					SetBXP(0);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[BXPSaveManager] Error on save reset: " + ex.Message));
			}
		}

		private static string GetCurrentSaveFile()
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return null;
			}
			return GameNetworkManager.Instance.currentSaveFileName;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static int GetCurrentBXP()
		{
			ResolveReflection();
			if (_betterXpField == null)
			{
				return 0;
			}
			return (int)_betterXpField.GetValue(null);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void SetBXP(int value)
		{
			ResolveReflection();
			if (_setBetterXP != null)
			{
				_setBetterXP.Invoke(null, new object[1] { value });
			}
			else
			{
				_betterXpField?.SetValue(null, value);
				_levelField?.SetValue(null, 0);
			}
			_saveMethod?.Invoke(null, null);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void ResolveReflection()
		{
			if (_reflResolved)
			{
				return;
			}
			Assembly assembly = null;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly2 in assemblies)
			{
				if (assembly2.GetName().Name == "LCBetterEXP")
				{
					assembly = assembly2;
					break;
				}
			}
			if (assembly == null)
			{
				_reflResolved = true;
				return;
			}
			Type type = assembly.GetType("LCBetterEXP.patches.XPPatch");
			if (type != null)
			{
				_betterXpField = type.GetField("betterXp", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				_levelField = type.GetField("level", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				_setBetterXP = type.GetMethod("SetBetterXP", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			}
			Type type2 = assembly.GetType("LCBetterEXP.patches.Saving");
			if (type2 != null)
			{
				_saveMethod = type2.GetMethod("Save", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			}
			_reflResolved = true;
		}

		private static void LoadFromDisk()
		{
			if (_saves != null)
			{
				return;
			}
			_saves = new Dictionary<string, int>();
			if (!File.Exists(SavePath))
			{
				return;
			}
			try
			{
				string[] array = File.ReadAllLines(SavePath);
				for (int i = 0; i < array.Length; i++)
				{
					string[] array2 = array[i].Split('=');
					if (array2.Length == 2 && int.TryParse(array2[1].Trim(), out var result))
					{
						_saves[array2[0].Trim()] = result;
					}
				}
			}
			catch
			{
				_saves = new Dictionary<string, int>();
			}
		}

		private static void SaveToDisk()
		{
			if (_saves == null)
			{
				return;
			}
			if (!Directory.Exists(SaveDir))
			{
				Directory.CreateDirectory(SaveDir);
			}
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, int> safe in _saves)
			{
				list.Add($"{safe.Key}={safe.Value}");
			}
			File.WriteAllLines(SavePath, list);
		}
	}
	internal static class InsideCompletionPatch
	{
		private static FieldInfo _allNodesField;

		private static bool _resolved;

		private static bool _loggedSanitize;

		private static bool _loggedMissing;

		internal static void Apply(Harmony harmony)
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			try
			{
				Assembly assembly = null;
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly2 in assemblies)
				{
					if (assembly2.GetName().Name == "LCBetterEXP")
					{
						assembly = assembly2;
						break;
					}
				}
				if (assembly == null)
				{
					return;
				}
				Type type = assembly.GetType("LCBetterEXP.patches.InsideCompletion");
				if (type == null)
				{
					Plugin.Log.LogWarning((object)"[InsideCompletionPatch] InsideCompletion type not found.");
					return;
				}
				_allNodesField = type.GetField("AllPlayerUnexploredNodes", BindingFlags.Static | BindingFlags.Public);
				if (_allNodesField == null)
				{
					Plugin.Log.LogWarning((object)"[InsideCompletionPatch] AllPlayerUnexploredNodes field not found.");
					return;
				}
				MethodInfo methodInfo = AccessTools.Method(type, "UpdatePlayer", (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					Plugin.Log.LogWarning((object)"[InsideCompletionPatch] UpdatePlayer method not found.");
					return;
				}
				_resolved = true;
				HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(InsideCompletionPatch), "Prefix", (Type[])null, (Type[])null));
				harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Plugin.Log.LogInfo((object)"[InsideCompletionPatch] Patched InsideCompletion.UpdatePlayer.");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[InsideCompletionPatch] Failed to patch: " + ex.Message));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool Prefix(PlayerControllerB player)
		{
			if (!_resolved)
			{
				return true;
			}
			if (!(_allNodesField.GetValue(null) is Dictionary<PlayerControllerB, List<GameObject>> dictionary))
			{
				return true;
			}
			if (!dictionary.ContainsKey(player))
			{
				if (!_loggedMissing)
				{
					Plugin.Log.LogWarning((object)"[InsideCompletionPatch] Player not in BetterEXP tracking dictionary — skipping UpdatePlayer.");
					_loggedMissing = true;
				}
				return false;
			}
			List<GameObject> list = dictionary[player];
			if (list == null)
			{
				return true;
			}
			for (int num = list.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)list[num] == (Object)null)
				{
					list.RemoveAt(num);
					if (!_loggedSanitize)
					{
						Plugin.Log.LogWarning((object)"[InsideCompletionPatch] Removed destroyed AI node(s) from BetterEXP tracking — suppressing NRE storm.");
						_loggedSanitize = true;
					}
				}
			}
			return true;
		}
	}
	[BepInPlugin("Slayer6409.LGUExpBridge", "LGUExpBridge", "3.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private const string ModGUID = "Slayer6409.LGUExpBridge";

		private const string ModName = "LGUExpBridge";

		private const string ModVersion = "3.1.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<float> CurrencyMultiplier;

		internal static bool BetterEXPLoaded;

		private readonly Harmony _harmony = new Harmony("Slayer6409.LGUExpBridge");

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			CurrencyMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CurrencyMultiplier", 1f, "Multiplier applied to BXP before granting as LGU currency.\n1.0 = exact 1:1 with BXP shown on screen. 2.0 = double.");
			BetterEXPLoaded = Chainloader.PluginInfos.ContainsKey("Swaggies.BetterEXP");
			_harmony.PatchAll();
			if (BetterEXPLoaded)
			{
				SaveLoadPatch.Apply(_harmony);
				ResetPatch.Apply(_harmony);
				InsideCompletionPatch.Apply(_harmony);
			}
			Log.LogInfo((object)("LGUExpBridge v3.1.0 loaded! " + $"BetterEXP detected={BetterEXPLoaded}, " + $"CurrencyMultiplier={CurrencyMultiplier.Value}"));
		}
	}
	internal static class ResetPatch
	{
		internal static void Apply(Harmony harmony)
		{
			TryPatch(harmony, typeof(GameNetworkManager), "ResetSavedGameValues");
			TryPatch(harmony, typeof(StartOfRound), "ResetShipFurniture");
			Plugin.Log.LogInfo((object)"[ResetPatch] Patch registration complete.");
		}

		private static void TryPatch(Harmony harmony, Type targetType, string methodName)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = AccessTools.Method(targetType, methodName, (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					Plugin.Log.LogWarning((object)("[ResetPatch] " + targetType.Name + "." + methodName + " not found."));
				}
				else
				{
					HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(ResetPatch), "OnReset", (Type[])null, (Type[])null));
					harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Plugin.Log.LogInfo((object)("[ResetPatch] Patched " + targetType.Name + "." + methodName + " successfully."));
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[ResetPatch] Failed to patch " + targetType.Name + "." + methodName + ": " + ex.Message));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void OnReset()
		{
			if (Plugin.BetterEXPLoaded)
			{
				Plugin.Log.LogInfo((object)"[ResetPatch] Save reset detected — clearing per-save BXP.");
				BXPSaveManager.OnSaveReset();
			}
		}
	}
	internal static class SaveLoadPatch
	{
		internal static void Apply(Harmony harmony)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(StartOfRound), "Start", (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					Plugin.Log.LogWarning((object)"[SaveLoadPatch] StartOfRound.Start not found.");
					return;
				}
				HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(SaveLoadPatch), "OnStartOfRoundStart", (Type[])null, (Type[])null));
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Plugin.Log.LogInfo((object)"[SaveLoadPatch] Patched StartOfRound.Start successfully.");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[SaveLoadPatch] Failed to patch: " + ex.Message));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void OnStartOfRoundStart()
		{
			Plugin.Log.LogInfo((object)"[SaveLoadPatch] StartOfRound.Start fired — restoring per-save BXP.");
			BXPSaveManager.OnSaveLoaded();
		}
	}
	[HarmonyPatch(typeof(HUDManager), "SetPlayerLevel")]
	internal static class XPPatch
	{
		private static bool _reflectionResolved;

		private static FieldInfo _gainedDataField;

		private static FieldInfo _totalGainField;

		[HarmonyPrefix]
		internal static void Prefix(bool isDead, bool mostProfitable, bool allPlayersDead)
		{
			int num = 0;
			if (Plugin.BetterEXPLoaded)
			{
				num = ReadBetterEXPGain();
				Plugin.Log.LogInfo((object)$"[XPPatch] BetterEXP totalGain={num}");
			}
			else
			{
				if (isDead || (Object)(object)RoundManager.Instance == (Object)null)
				{
					return;
				}
				int scrapCollectedInLevel = RoundManager.Instance.scrapCollectedInLevel;
				num = Mathf.RoundToInt((float)scrapCollectedInLevel / 50f);
				if (mostProfitable)
				{
					num *= 2;
				}
				Plugin.Log.LogInfo((object)$"[XPPatch] Fallback: scrap={scrapCollectedInLevel}, bxpGain={num}");
			}
			if (num <= 0)
			{
				Plugin.Log.LogInfo((object)$"[XPPatch] BXP gain is {num} — no currency granted.");
			}
			else if ((Object)(object)CurrencyManager.Instance == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[XPPatch] CurrencyManager.Instance is null — skipping.");
			}
			else if (!((Object)(object)StartOfRound.Instance?.localPlayerController == (Object)null))
			{
				float value = Plugin.CurrencyMultiplier.Value;
				int num2 = Mathf.RoundToInt((float)num * value);
				if (num2 > 0)
				{
					CurrencyManager.Instance.AddCurrencyAmount(num2, false);
					BXPSaveManager.PersistCurrentBXP();
					Plugin.Log.LogInfo((object)($"[XPPatch] Granted {num2} LGU currency " + $"(BXP={num}, multiplier={value})"));
				}
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static int ReadBetterEXPGain()
		{
			try
			{
				if (!_reflectionResolved)
				{
					Assembly assembly = null;
					Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
					foreach (Assembly assembly2 in assemblies)
					{
						if (assembly2.GetName().Name == "LCBetterEXP")
						{
							assembly = assembly2;
							break;
						}
					}
					if (assembly == null)
					{
						Plugin.Log.LogWarning((object)"[XPPatch] Could not find LCBetterEXP assembly.");
						return 0;
					}
					Type type = assembly.GetType("LCBetterEXP.patches.VisualEXPPatch");
					if (type == null)
					{
						Plugin.Log.LogWarning((object)"[XPPatch] Could not find VisualEXPPatch type.");
						return 0;
					}
					_gainedDataField = type.GetField("gainedBetterEXPData", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					if (_gainedDataField == null)
					{
						Plugin.Log.LogWarning((object)"[XPPatch] Could not find gainedBetterEXPData field.");
						return 0;
					}
					_totalGainField = _gainedDataField.FieldType.GetField("totalGain", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (_totalGainField == null)
					{
						Plugin.Log.LogWarning((object)"[XPPatch] Could not find totalGain field.");
						return 0;
					}
					_reflectionResolved = true;
					Plugin.Log.LogInfo((object)"[XPPatch] BetterEXP reflection resolved successfully.");
				}
				if (_gainedDataField == null || _totalGainField == null)
				{
					return 0;
				}
				object value = _gainedDataField.GetValue(null);
				if (value == null)
				{
					return 0;
				}
				return (int)_totalGainField.GetValue(value);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[XPPatch] Reflection error reading BetterEXP data: " + ex.Message));
				return 0;
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LGUExpBridge";

		public const string PLUGIN_NAME = "LGUExpBridge";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}

LGUGui.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using Microsoft.CodeAnalysis;
using MoreShipUpgrades.API;
using MoreShipUpgrades.Managers;
using MoreShipUpgrades.UI.TerminalNodes;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[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("LGUGui")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Example Dice Addon")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8c5521e37f37e3d76518a16d04e5d1051842f105")]
[assembly: AssemblyProduct("LGUGui")]
[assembly: AssemblyTitle("LGUGui")]
[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 LGUGui
{
	public class IngameKeybinds : LcInputActions
	{
		[InputAction("<Keyboard>/p", Name = "PurchaseMenu")]
		public InputAction PurchaseMenu { get; set; } = null;

	}
	public class MenuController : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <AnimateClose>d__12 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public MenuController <>4__this;

			private float <startAlpha>5__1;

			private Vector3 <startScale>5__2;

			private float <t>5__3;

			private float <n>5__4;

			private float <ease>5__5;

			private float <s>5__6;

			private PlayerControllerB <player>5__7;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <AnimateClose>d__12(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<player>5__7 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: 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_0166: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<startAlpha>5__1 = (((Object)(object)<>4__this._canvasGroup != (Object)null) ? <>4__this._canvasGroup.alpha : 1f);
					<startScale>5__2 = (((Object)(object)<>4__this._panelRt != (Object)null) ? ((Transform)<>4__this._panelRt).localScale : Vector3.one);
					<t>5__3 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<t>5__3 < 0.12f)
				{
					<t>5__3 += Time.unscaledDeltaTime;
					<n>5__4 = Mathf.Clamp01(<t>5__3 / 0.12f);
					<ease>5__5 = <n>5__4 * <n>5__4 * <n>5__4;
					if ((Object)(object)<>4__this._canvasGroup != (Object)null)
					{
						<>4__this._canvasGroup.alpha = Mathf.Lerp(<startAlpha>5__1, 0f, <ease>5__5);
					}
					if ((Object)(object)<>4__this._panelRt != (Object)null)
					{
						<s>5__6 = Mathf.Lerp(<startScale>5__2.x, 0.92f, <ease>5__5);
						((Transform)<>4__this._panelRt).localScale = new Vector3(<s>5__6, <s>5__6, 1f);
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				try
				{
					<player>5__7 = StartOfRound.Instance?.localPlayerController;
					if ((Object)(object)<player>5__7 != (Object)null)
					{
						<player>5__7.quickMenuManager.isMenuOpen = false;
					}
					Cursor.visible = false;
					Cursor.lockState = (CursorLockMode)1;
					<player>5__7 = null;
				}
				catch
				{
				}
				IsOpen = false;
				try
				{
					typeof(PurchaseMenu).GetMethod("StopEmotePreview", BindingFlags.Static | BindingFlags.NonPublic)?.Invoke(null, null);
				}
				catch
				{
				}
				ClearPurchaseMenuStatics();
				if ((Object)(object)<>4__this._root != (Object)null)
				{
					Object.Destroy((Object)(object)<>4__this._root);
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <AnimateOpen>d__10 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public MenuController <>4__this;

			private float <t>5__1;

			private float <n>5__2;

			private float <ease>5__3;

			private float <s>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <AnimateOpen>d__10(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_0133: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>4__this._canvasGroup.alpha = 0f;
					if ((Object)(object)<>4__this._panelRt != (Object)null)
					{
						((Transform)<>4__this._panelRt).localScale = new Vector3(0.92f, 0.92f, 1f);
					}
					<t>5__1 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<t>5__1 < 0.18f)
				{
					<t>5__1 += Time.unscaledDeltaTime;
					<n>5__2 = Mathf.Clamp01(<t>5__1 / 0.18f);
					<ease>5__3 = 1f - Mathf.Pow(1f - <n>5__2, 3f);
					<>4__this._canvasGroup.alpha = <ease>5__3;
					if ((Object)(object)<>4__this._panelRt != (Object)null)
					{
						<s>5__4 = Mathf.Lerp(0.92f, 1f, <ease>5__3);
						((Transform)<>4__this._panelRt).localScale = new Vector3(<s>5__4, <s>5__4, 1f);
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				<>4__this._canvasGroup.alpha = 1f;
				if ((Object)(object)<>4__this._panelRt != (Object)null)
				{
					((Transform)<>4__this._panelRt).localScale = Vector3.one;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private GameObject _root;

		private CanvasGroup _canvasGroup;

		private RectTransform _panelRt;

		private bool _closing;

		private int _frameOpenedOn = -1;

		public static bool IsOpen;

		private const float OpenDuration = 0.18f;

		private const float CloseDuration = 0.12f;

		private static readonly string[] _objectFieldsToClear = new string[2] { "_selectedEmoteForPurchase", "_previewingEmote" };

		public void Init(GameObject root)
		{
			_root = root;
			_canvasGroup = _root.GetComponent<CanvasGroup>();
			if ((Object)(object)_canvasGroup == (Object)null)
			{
				_canvasGroup = _root.AddComponent<CanvasGroup>();
			}
			Transform val = _root.transform.Find("Panel");
			if ((Object)(object)val != (Object)null)
			{
				_panelRt = ((Component)val).GetComponent<RectTransform>();
			}
			IsOpen = true;
			_frameOpenedOn = Time.frameCount;
			((MonoBehaviour)this).StartCoroutine(AnimateOpen());
		}

		private void Update()
		{
			if (!_closing && Time.frameCount != _frameOpenedOn)
			{
				Keyboard current = Keyboard.current;
				if (current != null && (((ButtonControl)current.escapeKey).wasPressedThisFrame || ((ButtonControl)current.pKey).wasPressedThisFrame))
				{
					CloseMenu();
				}
			}
		}

		[IteratorStateMachine(typeof(<AnimateOpen>d__10))]
		private IEnumerator AnimateOpen()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AnimateOpen>d__10(0)
			{
				<>4__this = this
			};
		}

		public void CloseMenu()
		{
			if (!_closing)
			{
				_closing = true;
				((MonoBehaviour)this).StartCoroutine(AnimateClose());
			}
		}

		[IteratorStateMachine(typeof(<AnimateClose>d__12))]
		private IEnumerator AnimateClose()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AnimateClose>d__12(0)
			{
				<>4__this = this
			};
		}

		private static void ClearPurchaseMenuStatics()
		{
			FieldInfo[] fields = typeof(PurchaseMenu).GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				if (fieldInfo.IsLiteral || fieldInfo.IsInitOnly)
				{
					continue;
				}
				if (typeof(Object).IsAssignableFrom(fieldInfo.FieldType))
				{
					fieldInfo.SetValue(null, null);
					continue;
				}
				for (int j = 0; j < _objectFieldsToClear.Length; j++)
				{
					if (fieldInfo.Name == _objectFieldsToClear[j])
					{
						fieldInfo.SetValue(null, null);
						break;
					}
				}
			}
		}
	}
	public class MoreShipUpgradesPatch
	{
		[HarmonyPatch(typeof(LguStore), "HandleUpgradeClientRpc")]
		private class Patch_LGU_HandleUpgrade
		{
			private static void Postfix(string name, bool increment)
			{
				new PurchaseMenu().refresh();
			}
		}

		[HarmonyPatch(typeof(CurrencyManager), "TradePlayerCreditsClientRpc")]
		private class Patch_LGU_HandleTrade
		{
			private static void Postfix(ulong traderClientId, int playerCreditAmount, ClientRpcParams clientRpcParams)
			{
				new PurchaseMenu().refresh(fromTrade: true);
			}
		}
	}
	[Serializable]
	internal class PlayerLevelData
	{
		public List<string> suits = new List<string>();

		public List<string> cosmetics = new List<string>();
	}
	internal static class PlayerLevelStore
	{
		private static PlayerLevelData _data;

		private static string _key;

		private static string SaveDir => Path.Combine(Paths.ConfigPath, "LGUPlayerLevel");

		private static string CurrentKey()
		{
			string text = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.currentSaveFileName : null);
			return string.IsNullOrEmpty(text) ? "NoSave" : text;
		}

		private static string GetPath(string key)
		{
			return Path.Combine(SaveDir, SanitizeFileName(key) + ".json");
		}

		private static string SanitizeFileName(string raw)
		{
			char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
			char[] array = raw.ToCharArray();
			for (int i = 0; i < array.Length; i++)
			{
				if (Array.IndexOf(invalidFileNameChars, array[i]) >= 0)
				{
					array[i] = '_';
				}
			}
			return new string(array);
		}

		public static PlayerLevelData Get()
		{
			string text = CurrentKey();
			if (_data != null && _key == text)
			{
				return _data;
			}
			_key = text;
			string path = GetPath(text);
			if (File.Exists(path))
			{
				try
				{
					_data = JsonUtility.FromJson<PlayerLevelData>(File.ReadAllText(path)) ?? new PlayerLevelData();
				}
				catch
				{
					_data = new PlayerLevelData();
				}
			}
			else
			{
				_data = new PlayerLevelData();
			}
			PlayerLevelData data = _data;
			if (data.suits == null)
			{
				data.suits = new List<string>();
			}
			data = _data;
			if (data.cosmetics == null)
			{
				data.cosmetics = new List<string>();
			}
			return _data;
		}

		public static void Save()
		{
			if (_data == null)
			{
				return;
			}
			try
			{
				if (!Directory.Exists(SaveDir))
				{
					Directory.CreateDirectory(SaveDir);
				}
				File.WriteAllText(GetPath(_key), JsonUtility.ToJson((object)_data, true));
			}
			catch (Exception ex)
			{
				ManualLogSource customLogger = Plugin.CustomLogger;
				if (customLogger != null)
				{
					customLogger.LogWarning((object)("[PlayerLevelStore] save failed: " + ex.Message));
				}
			}
		}

		public static void Reload()
		{
			_data = null;
			_key = null;
		}
	}
	public class PlayerMenuHint : MonoBehaviour
	{
		private GameObject _canvasGo;

		private TMP_Text _label;

		private void Update()
		{
			if (EnsureCanvas())
			{
				_canvasGo.SetActive(ShouldShow());
			}
		}

		private bool ShouldShow()
		{
			if (MenuController.IsOpen)
			{
				return false;
			}
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return false;
			}
			PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController;
			if ((Object)(object)localPlayerController == (Object)null)
			{
				return false;
			}
			if (localPlayerController.inTerminalMenu)
			{
				return false;
			}
			if (localPlayerController.isTypingChat)
			{
				return false;
			}
			if ((Object)(object)localPlayerController.quickMenuManager != (Object)null && localPlayerController.quickMenuManager.isMenuOpen)
			{
				return false;
			}
			if (Plugin.onlyInOrbit != null && Plugin.onlyInOrbit.Value && !StartOfRound.Instance.inShipPhase)
			{
				return false;
			}
			if (Plugin.onlyOnShip != null && Plugin.onlyOnShip.Value && !localPlayerController.isInHangarShipRoom)
			{
				return false;
			}
			return true;
		}

		private bool EnsureCanvas()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_canvasGo != (Object)null)
			{
				return true;
			}
			if ((Object)(object)HUDManager.Instance == (Object)null || (Object)(object)HUDManager.Instance.playerScreenTexture == (Object)null)
			{
				return false;
			}
			Canvas canvas = ((Graphic)HUDManager.Instance.playerScreenTexture).canvas;
			if ((Object)(object)canvas == (Object)null)
			{
				return false;
			}
			_canvasGo = new GameObject("LGU_PlayerMenuHint");
			_canvasGo.transform.SetParent(((Component)canvas).transform, false);
			RectTransform val = _canvasGo.AddComponent<RectTransform>();
			val.anchorMin = new Vector2(0.5f, 0f);
			val.anchorMax = new Vector2(0.5f, 0f);
			val.pivot = new Vector2(0.5f, 0f);
			val.anchoredPosition = new Vector2(0f, 120f);
			val.sizeDelta = new Vector2(420f, 30f);
			_label = (TMP_Text)(object)_canvasGo.AddComponent<TextMeshProUGUI>();
			_label.text = "Press [P] for player menu";
			_label.fontSize = 14f;
			_label.alignment = (TextAlignmentOptions)514;
			((Graphic)_label).color = new Color(1f, 1f, 1f, 0.55f);
			((Graphic)_label).raycastTarget = false;
			_label.enableWordWrapping = false;
			TMP_FontAsset terminalFont = UI.GetTerminalFont();
			if ((Object)(object)terminalFont != (Object)null)
			{
				_label.font = terminalFont;
			}
			return true;
		}

		private void OnDestroy()
		{
			if ((Object)(object)_canvasGo != (Object)null)
			{
				Object.Destroy((Object)(object)_canvasGo);
			}
			_canvasGo = null;
			_label = null;
		}
	}
	[BepInPlugin("Slayer6409.LGU_GUI", "LGU_GUI", "0.0.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private const string modGUID = "Slayer6409.LGU_GUI";

		private const string modName = "LGU_GUI";

		private const string modVersion = "0.0.4";

		public static ManualLogSource CustomLogger;

		public static ConfigFile BepInExConfig;

		internal static IngameKeybinds Keybinds;

		private readonly Harmony harmony = new Harmony("Slayer6409.LGU_GUI");

		public static ConfigEntry<bool> onlyInOrbit;

		public static ConfigEntry<bool> onlyOnShip;

		public static ConfigEntry<bool> extendedLog;

		public static ConfigEntry<int> SuitPrice;

		public static ConfigEntry<int> CosmeticPrice;

		public static ConfigEntry<int> EmotePrice;

		private void Awake()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			CustomLogger = Logger.CreateLogSource("LateGameUpgrades GUI");
			BepInExConfig = new ConfigFile(Path.Combine(Paths.ConfigPath, "LGU_GUI.cfg"), true);
			configSetup();
			harmony.PatchAll();
			Keybinds = new IngameKeybinds();
			Keybinds.PurchaseMenu.performed += delegate
			{
				tryShowMenu();
			};
			GameObject val = new GameObject("LGU_PlayerMenuHintHost");
			Object.DontDestroyOnLoad((Object)(object)val);
			val.AddComponent<PlayerMenuHint>();
			CustomLogger.LogInfo((object)"Plugin LGUGui is loaded! (no-bundle build)");
		}

		public static void ExtendedLogging(string msg, LogLevel level = 16)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (extendedLog.Value)
			{
				CustomLogger.Log(level, (object)msg);
			}
		}

		public void configSetup()
		{
			onlyInOrbit = BepInExConfig.Bind<bool>("Main", "Only In Orbit", false, "Makes it so you are only able to upgrade in orbit.");
			onlyOnShip = BepInExConfig.Bind<bool>("Main", "Only On Ship", true, "Makes it so you are only able to upgrade on the ship.");
			extendedLog = BepInExConfig.Bind<bool>("Main", "Extended Logging", false, "Log extra debug information.");
			SuitPrice = BepInExConfig.Bind<int>("Player Level - Prices", "SuitPrice", 50, "BXP cost to unlock any suit.");
			CosmeticPrice = BepInExConfig.Bind<int>("Player Level - Prices", "CosmeticPrice", 25, "BXP cost to unlock any cosmetic.");
			EmotePrice = BepInExConfig.Bind<int>("Player Level - Prices", "EmotePrice", 30, "BXP cost to unlock any emote.");
		}

		public void tryShowMenu()
		{
			if (!((Object)(object)StartOfRound.Instance == (Object)null) && !StartOfRound.Instance.localPlayerController.quickMenuManager.isMenuOpen && (!onlyInOrbit.Value || StartOfRound.Instance.inShipPhase) && (!onlyOnShip.Value || StartOfRound.Instance.localPlayerController.isInHangarShipRoom) && !StartOfRound.Instance.localPlayerController.inTerminalMenu && !StartOfRound.Instance.localPlayerController.isTypingChat)
			{
				PurchaseMenu.initMenu();
			}
		}
	}
	internal static class Palette
	{
		public static readonly Color BgOverlay = new Color(0f, 0f, 0f, 0.5f);

		public static readonly Color BgPanel = new Color(0.08f, 0.04f, 0.04f, 0.97f);

		public static readonly Color BgHeader = new Color(0.18f, 0.04f, 0.04f, 1f);

		public static readonly Color BgRow = new Color(0.1f, 0.05f, 0.05f, 1f);

		public static readonly Color BgRowHover = new Color(0.2f, 0.08f, 0.06f, 1f);

		public static readonly Color BgInput = new Color(0.06f, 0.03f, 0.03f, 1f);

		public static readonly Color Separator = new Color(0.8f, 0.3f, 0.05f, 0.35f);

		public static readonly Color Green = new Color(0.9f, 0.35f, 0.05f, 1f);

		public static readonly Color Red = new Color(0.55f, 0.15f, 0.1f, 1f);

		public static readonly Color Cyan = new Color(1f, 0.65f, 0.1f, 1f);

		public static readonly Color Gold = new Color(1f, 0.8f, 0.2f, 1f);

		public static readonly Color CurrencyGold = new Color(1f, 0.55f, 0.1f, 1f);

		public static readonly Color LowCurrency = new Color(0.85f, 0.2f, 0.1f, 1f);

		public static readonly Color Dim = new Color(0.5f, 0.3f, 0.25f, 1f);

		public static readonly Color White = new Color(1f, 0.92f, 0.85f, 1f);

		public static readonly Color TypeSpeed = new Color(1f, 0.85f, 0.15f, 1f);

		public static readonly Color TypeDefense = new Color(0.3f, 0.6f, 1f, 1f);

		public static readonly Color TypeOffense = new Color(1f, 0.25f, 0.2f, 1f);

		public static readonly Color TypeStealth = new Color(0.2f, 0.9f, 0.35f, 1f);

		public static readonly Color TypeLoot = new Color(1f, 0.6f, 0.1f, 1f);

		public static readonly Color TypeTeam = new Color(0.7f, 0.4f, 1f, 1f);

		public static readonly Color BtnNormal = new Color(0.2f, 0.06f, 0.04f, 1f);

		public static readonly Color BtnHighlight = new Color(0.35f, 0.1f, 0.06f, 1f);

		public static readonly Color BtnActive = new Color(0.8f, 0.3f, 0.05f, 1f);

		public static readonly Color BtnDisabled = new Color(0.12f, 0.08f, 0.08f, 1f);

		public static readonly Color BtnRed = new Color(0.3f, 0.06f, 0.06f, 1f);

		public static readonly Color BtnRedHl = new Color(0.5f, 0.1f, 0.08f, 1f);

		public static readonly Color BtnBlue = new Color(0.22f, 0.08f, 0.04f, 1f);

		public static readonly Color BtnBlueHl = new Color(0.4f, 0.15f, 0.06f, 1f);

		public static Color UpgradeRow(bool hasEnough, bool maxed, bool onSale)
		{
			//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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (maxed)
			{
				return Gold;
			}
			if (onSale)
			{
				return Cyan;
			}
			return hasEnough ? Green : Red;
		}
	}
	internal static class UI
	{
		[CompilerGenerated]
		private sealed class <ResetScrollNextFrame>d__10 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ScrollRect sr;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ResetScrollNextFrame>d__10(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					if ((Object)(object)sr != (Object)null)
					{
						sr.verticalNormalizedPosition = 1f;
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static GameObject _cachedLevelUpBox;

		private static TMP_FontAsset _terminalFont;

		private static AudioClip _hoverClip;

		private static AudioClip _confirmClip;

		private static AudioClip _cancelClip;

		private static bool _soundResolved;

		public static AudioSource PurchaseSource;

		private static AudioClip _purchaseClip;

		public static GameObject MakeCanvas(string name)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			Canvas val2 = val.AddComponent<Canvas>();
			val2.renderMode = (RenderMode)0;
			val2.sortingOrder = 200;
			val2.pixelPerfect = true;
			CanvasScaler val3 = val.AddComponent<CanvasScaler>();
			val3.uiScaleMode = (ScaleMode)1;
			val3.referenceResolution = new Vector2(1536f, 864f);
			val3.matchWidthOrHeight = 0.5f;
			val3.referencePixelsPerUnit = 100f;
			val3.dynamicPixelsPerUnit = 100f;
			val.AddComponent<GraphicRaycaster>();
			return val;
		}

		public static GameObject MakePanel(string name, Transform parent, Color color, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin = default(Vector2), Vector2 offsetMax = default(Vector2))
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).color = color;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = anchorMin;
			component.anchorMax = anchorMax;
			component.offsetMin = offsetMin;
			component.offsetMax = offsetMax;
			return val;
		}

		public static GameObject CloneBorderedPanel(string name, Transform parent, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin = default(Vector2), Vector2 offsetMax = default(Vector2))
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_cachedLevelUpBox == (Object)null)
			{
				_cachedLevelUpBox = GameObject.Find("/Systems/UI/Canvas/EndgameStats/LevelUp/LevelUpBox");
				if ((Object)(object)_cachedLevelUpBox == (Object)null)
				{
					_cachedLevelUpBox = GameObject.Find("/Systems/UI/Canvas/EndgameStats/Grade") ?? GameObject.Find("/Systems/UI/Canvas/EndgameStats/DaysInCompany") ?? GameObject.Find("/Systems/UI/Canvas/EndgameStats/Collected");
				}
			}
			if ((Object)(object)_cachedLevelUpBox == (Object)null)
			{
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(_cachedLevelUpBox, parent);
			((Object)val).name = name;
			val.SetActive(true);
			foreach (Transform item in val.transform)
			{
				Transform val2 = item;
				Object.Destroy((Object)(object)((Component)val2).gameObject);
			}
			Animator[] components = val.GetComponents<Animator>();
			foreach (Animator val3 in components)
			{
				Object.Destroy((Object)(object)val3);
			}
			LayoutGroup[] components2 = val.GetComponents<LayoutGroup>();
			foreach (LayoutGroup val4 in components2)
			{
				Object.Destroy((Object)(object)val4);
			}
			ContentSizeFitter[] components3 = val.GetComponents<ContentSizeFitter>();
			foreach (ContentSizeFitter val5 in components3)
			{
				Object.Destroy((Object)(object)val5);
			}
			RectTransform val6 = val.GetComponent<RectTransform>();
			if ((Object)(object)val6 == (Object)null)
			{
				val6 = val.AddComponent<RectTransform>();
			}
			val6.anchorMin = anchorMin;
			val6.anchorMax = anchorMax;
			val6.offsetMin = offsetMin;
			val6.offsetMax = offsetMax;
			((Transform)val6).localScale = Vector3.one;
			((Transform)val6).localRotation = Quaternion.identity;
			return val;
		}

		public static bool VanillaPanelsAvailable()
		{
			if ((Object)(object)_cachedLevelUpBox != (Object)null)
			{
				return true;
			}
			_cachedLevelUpBox = GameObject.Find("/Systems/UI/Canvas/EndgameStats/LevelUp/LevelUpBox");
			if ((Object)(object)_cachedLevelUpBox == (Object)null)
			{
				_cachedLevelUpBox = GameObject.Find("/Systems/UI/Canvas/EndgameStats/Grade");
			}
			return (Object)(object)_cachedLevelUpBox != (Object)null;
		}

		public static TMP_Text MakeText(string name, Transform parent, string text, float fontSize, Color color, TextAlignmentOptions align = 513)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			TMP_FontAsset terminalFont = GetTerminalFont();
			if ((Object)(object)terminalFont != (Object)null)
			{
				((TMP_Text)val2).font = terminalFont;
			}
			((TMP_Text)val2).text = text;
			((TMP_Text)val2).fontSize = fontSize;
			((Graphic)val2).color = color;
			((TMP_Text)val2).alignment = align;
			((Component)val2).GetComponent<RectTransform>().anchorMin = Vector2.zero;
			((Component)val2).GetComponent<RectTransform>().anchorMax = Vector2.one;
			((Component)val2).GetComponent<RectTransform>().offsetMin = new Vector2(6f, 2f);
			((Component)val2).GetComponent<RectTransform>().offsetMax = new Vector2(-6f, -2f);
			return (TMP_Text)(object)val2;
		}

		public static (Button btn, TMP_Text label) MakeButton(string name, Transform parent, string text, float fontSize, Color bgColor, Color hlColor, Color textColor, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin = default(Vector2), Vector2 offsetMax = default(Vector2))
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).color = bgColor;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = anchorMin;
			component.anchorMax = anchorMax;
			component.offsetMin = offsetMin;
			component.offsetMax = offsetMax;
			Button val3 = val.AddComponent<Button>();
			ColorBlock colors = ((Selectable)val3).colors;
			((ColorBlock)(ref colors)).normalColor = bgColor;
			((ColorBlock)(ref colors)).highlightedColor = hlColor;
			((ColorBlock)(ref colors)).pressedColor = hlColor * 0.8f;
			((ColorBlock)(ref colors)).disabledColor = Palette.BtnDisabled;
			((ColorBlock)(ref colors)).fadeDuration = 0.08f;
			((Selectable)val3).colors = colors;
			GameObject val4 = new GameObject("Label");
			val4.transform.SetParent(val.transform, false);
			RectTransform val5 = val4.AddComponent<RectTransform>();
			val5.anchorMin = Vector2.zero;
			val5.anchorMax = Vector2.one;
			val5.offsetMin = new Vector2(4f, 2f);
			val5.offsetMax = new Vector2(-4f, -2f);
			TextMeshProUGUI val6 = val4.AddComponent<TextMeshProUGUI>();
			TMP_FontAsset terminalFont = GetTerminalFont();
			if ((Object)(object)terminalFont != (Object)null)
			{
				((TMP_Text)val6).font = terminalFont;
			}
			((TMP_Text)val6).text = text;
			((TMP_Text)val6).fontSize = fontSize;
			((Graphic)val6).color = textColor;
			((TMP_Text)val6).alignment = (TextAlignmentOptions)514;
			((TMP_Text)val6).enableWordWrapping = false;
			((TMP_Text)val6).overflowMode = (TextOverflowModes)1;
			return (val3, (TMP_Text)(object)val6);
		}

		public static (GameObject scrollGo, Transform content) MakeScrollView(string name, Transform parent, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin, Vector2 offsetMax, bool addScrollbar = false)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = anchorMin;
			val2.anchorMax = anchorMax;
			val2.offsetMin = offsetMin;
			val2.offsetMax = offsetMax;
			ScrollRect val3 = val.AddComponent<ScrollRect>();
			val3.horizontal = false;
			GameObject val4 = new GameObject("Viewport");
			val4.transform.SetParent(val.transform, false);
			RectTransform val5 = val4.AddComponent<RectTransform>();
			val5.anchorMin = Vector2.zero;
			val5.anchorMax = Vector2.one;
			val5.offsetMin = Vector2.zero;
			val5.offsetMax = (Vector2)(addScrollbar ? new Vector2(-14f, 0f) : Vector2.zero);
			val4.AddComponent<RectMask2D>();
			GameObject val6 = new GameObject("Content");
			val6.transform.SetParent(val4.transform, false);
			RectTransform val7 = val6.AddComponent<RectTransform>();
			val7.anchorMin = new Vector2(0f, 1f);
			val7.anchorMax = new Vector2(1f, 1f);
			val7.pivot = new Vector2(0.5f, 1f);
			val7.offsetMin = Vector2.zero;
			val7.offsetMax = Vector2.zero;
			val3.viewport = val5;
			val3.content = val7;
			val3.movementType = (MovementType)2;
			val3.scrollSensitivity = 25f;
			val3.verticalNormalizedPosition = 1f;
			Scrollbar val8 = null;
			if (addScrollbar)
			{
				val8 = BuildScrollbar(val.transform);
				val3.verticalScrollbar = val8;
				val3.verticalScrollbarVisibility = (ScrollbarVisibility)0;
			}
			return (val, val6.transform);
		}

		private static Scrollbar BuildScrollbar(Transform parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Expected O, but got Unknown
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("VScrollbar");
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = new Vector2(1f, 0f);
			val2.anchorMax = new Vector2(1f, 1f);
			val2.pivot = new Vector2(1f, 0.5f);
			val2.sizeDelta = new Vector2(12f, 0f);
			val2.anchoredPosition = Vector2.zero;
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = new Color(0.1f, 0.05f, 0.05f, 0.85f);
			Scrollbar val4 = val.AddComponent<Scrollbar>();
			val4.direction = (Direction)2;
			GameObject val5 = new GameObject("SlidingArea");
			val5.transform.SetParent(val.transform, false);
			RectTransform val6 = val5.AddComponent<RectTransform>();
			val6.anchorMin = Vector2.zero;
			val6.anchorMax = Vector2.one;
			val6.offsetMin = new Vector2(2f, 2f);
			val6.offsetMax = new Vector2(-2f, -2f);
			GameObject val7 = new GameObject("Handle");
			val7.transform.SetParent(val5.transform, false);
			RectTransform val8 = val7.AddComponent<RectTransform>();
			val8.anchorMin = Vector2.zero;
			val8.anchorMax = Vector2.one;
			val8.offsetMin = Vector2.zero;
			val8.offsetMax = Vector2.zero;
			Image val9 = val7.AddComponent<Image>();
			((Graphic)val9).color = new Color(0.9f, 0.4f, 0.1f, 1f);
			((Selectable)val4).targetGraphic = (Graphic)(object)val9;
			val4.handleRect = val8;
			return val4;
		}

		public static void ResetScrollToTop(ScrollRect sr, RectTransform contentRt)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)sr == (Object)null) && !((Object)(object)contentRt == (Object)null))
			{
				contentRt.anchoredPosition = Vector2.zero;
				sr.verticalNormalizedPosition = 1f;
				MenuController componentInParent = ((Component)sr).GetComponentInParent<MenuController>();
				if ((Object)(object)componentInParent != (Object)null && ((Behaviour)componentInParent).isActiveAndEnabled)
				{
					((MonoBehaviour)componentInParent).StartCoroutine(ResetScrollNextFrame(sr));
				}
			}
		}

		[IteratorStateMachine(typeof(<ResetScrollNextFrame>d__10))]
		private static IEnumerator ResetScrollNextFrame(ScrollRect sr)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ResetScrollNextFrame>d__10(0)
			{
				sr = sr
			};
		}

		public static TMP_InputField MakeInputField(string name, Transform parent, string placeholder, float fontSize, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin, Vector2 offsetMax)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_005f: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).color = Palette.BgInput;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = anchorMin;
			component.anchorMax = anchorMax;
			component.offsetMin = offsetMin;
			component.offsetMax = offsetMax;
			GameObject val3 = new GameObject("TextArea");
			val3.transform.SetParent(val.transform, false);
			RectTransform val4 = val3.AddComponent<RectTransform>();
			val4.anchorMin = Vector2.zero;
			val4.anchorMax = Vector2.one;
			val4.offsetMin = new Vector2(6f, 2f);
			val4.offsetMax = new Vector2(-6f, -2f);
			val3.AddComponent<RectMask2D>();
			GameObject val5 = new GameObject("Text");
			val5.transform.SetParent(val3.transform, false);
			RectTransform val6 = val5.AddComponent<RectTransform>();
			val6.anchorMin = Vector2.zero;
			val6.anchorMax = Vector2.one;
			val6.offsetMin = Vector2.zero;
			val6.offsetMax = Vector2.zero;
			TextMeshProUGUI val7 = val5.AddComponent<TextMeshProUGUI>();
			TMP_FontAsset terminalFont = GetTerminalFont();
			if ((Object)(object)terminalFont != (Object)null)
			{
				((TMP_Text)val7).font = terminalFont;
			}
			((TMP_Text)val7).fontSize = fontSize;
			((Graphic)val7).color = Palette.Green;
			((TMP_Text)val7).alignment = (TextAlignmentOptions)4097;
			GameObject val8 = new GameObject("Placeholder");
			val8.transform.SetParent(val3.transform, false);
			RectTransform val9 = val8.AddComponent<RectTransform>();
			val9.anchorMin = Vector2.zero;
			val9.anchorMax = Vector2.one;
			val9.offsetMin = Vector2.zero;
			val9.offsetMax = Vector2.zero;
			TextMeshProUGUI val10 = val8.AddComponent<TextMeshProUGUI>();
			TMP_FontAsset terminalFont2 = GetTerminalFont();
			if ((Object)(object)terminalFont2 != (Object)null)
			{
				((TMP_Text)val10).font = terminalFont2;
			}
			((TMP_Text)val10).text = placeholder;
			((TMP_Text)val10).fontSize = fontSize;
			((Graphic)val10).color = Palette.Dim;
			((TMP_Text)val10).alignment = (TextAlignmentOptions)4097;
			((TMP_Text)val10).fontStyle = (FontStyles)2;
			TMP_InputField val11 = val.AddComponent<TMP_InputField>();
			val11.textViewport = val4;
			val11.textComponent = (TMP_Text)(object)val7;
			val11.placeholder = (Graphic)(object)val10;
			val11.contentType = (ContentType)2;
			val11.text = "0";
			return val11;
		}

		public static TMP_FontAsset GetTerminalFont()
		{
			if ((Object)(object)_terminalFont != (Object)null)
			{
				return _terminalFont;
			}
			TMP_FontAsset val = null;
			Terminal val2 = Object.FindObjectOfType<Terminal>();
			if ((Object)(object)val2 != (Object)null)
			{
				TMP_Text componentInChildren = ((Component)val2).GetComponentInChildren<TMP_Text>();
				if ((Object)(object)((componentInChildren != null) ? componentInChildren.font : null) != (Object)null)
				{
					val = componentInChildren.font;
				}
			}
			if ((Object)(object)val == (Object)null && (Object)(object)HUDManager.Instance != (Object)null)
			{
				TMP_Text componentInChildren2 = ((Component)HUDManager.Instance).GetComponentInChildren<TMP_Text>();
				if ((Object)(object)((componentInChildren2 != null) ? componentInChildren2.font : null) != (Object)null)
				{
					val = componentInChildren2.font;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
				foreach (TMP_FontAsset val3 in array)
				{
					if (((Object)val3).name.Contains("3270"))
					{
						val = val3;
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				TMP_Text val4 = Object.FindObjectOfType<TMP_Text>();
				if ((Object)(object)((val4 != null) ? val4.font : null) != (Object)null)
				{
					val = val4.font;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			_terminalFont = val;
			return _terminalFont;
		}

		public static void AddScanlines(Transform parent, float alpha = 0.06f, int lineHeight = 2)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_005f: Expected O, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Scanlines");
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			int num = lineHeight * 2;
			Texture2D val3 = new Texture2D(1, num, (TextureFormat)4, false);
			((Texture)val3).filterMode = (FilterMode)0;
			((Texture)val3).wrapMode = (TextureWrapMode)0;
			for (int i = 0; i < num; i++)
			{
				bool flag = i < lineHeight;
				val3.SetPixel(0, i, (Color)(flag ? new Color(0f, 0f, 0f, alpha) : Color.clear));
			}
			val3.Apply();
			RawImage val4 = val.AddComponent<RawImage>();
			val4.texture = (Texture)(object)val3;
			((Graphic)val4).color = Color.white;
			val4.uvRect = new Rect(0f, 0f, 1f, 270f);
			((Graphic)val4).raycastTarget = false;
		}

		public static void MakeSeparator(Transform parent, float topOffset)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Separator");
			val.transform.SetParent(parent, false);
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).color = Palette.Separator;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0.5f, 1f);
			component.offsetMin = new Vector2(8f, 0f - topOffset - 1f);
			component.offsetMax = new Vector2(-8f, 0f - topOffset);
		}

		private static void ResolveSounds()
		{
			if (_soundResolved)
			{
				return;
			}
			_soundResolved = true;
			Terminal val = Object.FindObjectOfType<Terminal>();
			if ((Object)(object)val != (Object)null)
			{
				FieldInfo[] fields = typeof(Terminal).GetFields(BindingFlags.Instance | BindingFlags.Public);
				FieldInfo[] array = fields;
				foreach (FieldInfo fieldInfo in array)
				{
					if (fieldInfo.FieldType == typeof(AudioClip))
					{
						string text = fieldInfo.Name.ToLowerInvariant();
						if ((Object)(object)_confirmClip == (Object)null && (text.Contains("buy") || text.Contains("purchase")))
						{
							object? value = fieldInfo.GetValue(val);
							_confirmClip = (AudioClip)((value is AudioClip) ? value : null);
						}
					}
				}
			}
			AudioClip[] array2 = Resources.FindObjectsOfTypeAll<AudioClip>();
			AudioClip[] array3 = array2;
			foreach (AudioClip val2 in array3)
			{
				string text2 = ((Object)val2).name.ToLowerInvariant();
				if ((Object)(object)_hoverClip == (Object)null && (text2.Contains("hover") || text2.Contains("button1") || text2.Contains("buttonhover")))
				{
					_hoverClip = val2;
				}
				if ((Object)(object)_confirmClip == (Object)null && (text2.Contains("cash") || text2.Contains("confirm") || text2.Contains("buy") || text2.Contains("purchasesfx") || text2.Contains("button3")))
				{
					_confirmClip = val2;
				}
				if ((Object)(object)_cancelClip == (Object)null && (text2.Contains("cancel") || text2.Contains("error") || text2.Contains("warning") || text2.Contains("button2")))
				{
					_cancelClip = val2;
				}
			}
			if ((Object)(object)_confirmClip == (Object)null)
			{
				_confirmClip = _hoverClip;
			}
			if ((Object)(object)_cancelClip == (Object)null)
			{
				_cancelClip = _hoverClip;
			}
		}

		public static void PlayHover()
		{
			PlayClip(_hoverClip, 0.55f);
		}

		public static void PlayConfirm()
		{
			PlayClip(_confirmClip, 0.7f);
		}

		public static void PlayCancel()
		{
			PlayClip(_cancelClip, 0.6f);
		}

		public static void PlayPurchase()
		{
			if ((Object)(object)PurchaseSource != (Object)null && (Object)(object)PurchaseSource.clip != (Object)null)
			{
				PurchaseSource.PlayOneShot(PurchaseSource.clip);
				return;
			}
			if ((Object)(object)_purchaseClip == (Object)null)
			{
				Terminal val = Object.FindObjectOfType<Terminal>();
				if ((Object)(object)val != (Object)null)
				{
					FieldInfo[] fields = typeof(Terminal).GetFields(BindingFlags.Instance | BindingFlags.Public);
					foreach (FieldInfo fieldInfo in fields)
					{
						if (fieldInfo.FieldType != typeof(AudioClip))
						{
							continue;
						}
						string text = fieldInfo.Name.ToLowerInvariant();
						if (text.Contains("buy") || text.Contains("purchase"))
						{
							object? value = fieldInfo.GetValue(val);
							_purchaseClip = (AudioClip)((value is AudioClip) ? value : null);
							if ((Object)(object)_purchaseClip != (Object)null)
							{
								break;
							}
						}
					}
				}
				if ((Object)(object)_purchaseClip == (Object)null)
				{
					AudioClip[] array = Resources.FindObjectsOfTypeAll<AudioClip>();
					foreach (AudioClip val2 in array)
					{
						string text2 = ((Object)val2).name.ToLowerInvariant();
						if (text2.Contains("purchasesfx") || text2.Contains("cashpurchase") || text2 == "cash")
						{
							_purchaseClip = val2;
							break;
						}
					}
				}
			}
			if ((Object)(object)_purchaseClip != (Object)null)
			{
				if ((Object)(object)HUDManager.Instance?.UIAudio != (Object)null)
				{
					HUDManager.Instance.UIAudio.PlayOneShot(_purchaseClip, 0.7f);
				}
			}
			else
			{
				PlayConfirm();
			}
		}

		private static void PlayClip(AudioClip clip, float volume)
		{
			ResolveSounds();
			if (!((Object)(object)clip == (Object)null) && (Object)(object)HUDManager.Instance?.UIAudio != (Object)null)
			{
				HUDManager.Instance.UIAudio.PlayOneShot(clip, volume);
			}
		}
	}
	public class PurchaseMenu
	{
		public enum UpgradeColorType
		{
			Speed,
			Defense,
			Offense,
			Stealth,
			Loot,
			Team
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__70_0;

			public static UnityAction <>9__102_0;

			public static UnityAction <>9__102_1;

			public static UnityAction <>9__102_2;

			public static Func<CustomTerminalNode, bool> <>9__108_1;

			public static Func<CustomTerminalNode, bool> <>9__108_2;

			public static Comparison<CustomTerminalNode> <>9__108_4;

			public static Comparison<CustomTerminalNode> <>9__108_3;

			public static Func<PlayerControllerB, string> <>9__112_0;

			public static Func<(int rarity, string name), bool> <>9__123_0;

			public static Func<(string emoteName, string displayName, object obj, int rarity, string rarityName, Color rarityColor), bool> <>9__125_0;

			public static Func<(string emoteName, string displayName, object obj, int rarity, string rarityName, Color rarityColor), bool> <>9__125_1;

			public static Func<(string emoteName, string displayName, object obj, int rarity, string rarityName, Color rarityColor), bool> <>9__129_0;

			public static Func<Assembly, bool> <>9__153_0;

			public static Func<KeyValuePair<int, string>, int> <>9__181_0;

			public static Func<KeyValuePair<int, string>, (int Key, string Value)> <>9__181_1;

			internal void <BuildHeader>b__70_0()
			{
				UI.PlayCancel();
				GameObject root = _root;
				if (root != null)
				{
					root.GetComponent<MenuController>()?.CloseMenu();
				}
			}

			internal void <BuildNav>b__102_0()
			{
				UI.PlayHover();
				showPlayerLevel(resetScroll: true);
			}

			internal void <BuildNav>b__102_1()
			{
				UI.PlayHover();
				showUpgrades(shared: false, resetScroll: true);
			}

			internal void <BuildNav>b__102_2()
			{
				UI.PlayHover();
				showTradeGui();
			}

			internal bool <showUpgrades>b__108_1(CustomTerminalNode x)
			{
				return !HiddenUpgrades.Contains(x.Name);
			}

			internal bool <showUpgrades>b__108_2(CustomTerminalNode x)
			{
				return GetCategory(x.Name) == _activeCategory;
			}

			internal int <showUpgrades>b__108_4(CustomTerminalNode a, CustomTerminalNode b)
			{
				return string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase);
			}

			internal int <showUpgrades>b__108_3(CustomTerminalNode a, CustomTerminalNode b)
			{
				return string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase);
			}

			internal string <showTradeGui>b__112_0(PlayerControllerB p)
			{
				return p.playerUsername;
			}

			internal bool <showPlayerLevel>b__123_0((int rarity, string name) t)
			{
				return t.rarity == _activeEmoteTier;
			}

			internal bool <EnsureAutoPreviewForActiveTier>b__125_0((string emoteName, string displayName, object obj, int rarity, string rarityName, Color rarityColor) e)
			{
				return e.rarity == _activeEmoteTier;
			}

			internal bool <EnsureAutoPreviewForActiveTier>b__125_1((string emoteName, string displayName, object obj, int rarity, string rarityName, Color rarityColor) e)
			{
				return e.obj == _previewingEmote;
			}

			internal bool <BuildEmotesSection>b__129_0((string emoteName, string displayName, object obj, int rarity, string rarityName, Color rarityColor) e)
			{
				return e.rarity == _activeEmoteTier;
			}

			internal bool <LogPostPlayDiag>b__153_0(Assembly a)
			{
				return a.GetName().Name == "TooManyEmotes";
			}

			internal int <EnsureEmoteTiersDiscovered>b__181_0(KeyValuePair<int, string> kv)
			{
				return kv.Key;
			}

			internal (int Key, string Value) <EnsureEmoteTiersDiscovered>b__181_1(KeyValuePair<int, string> kv)
			{
				return (kv.Key, kv.Value);
			}

			internal string <.cctor>b__195_0(KeyValuePair<string, string> kv)
			{
				return kv.Key;
			}

			internal string <.cctor>b__195_1(KeyValuePair<string, string> kv)
			{
				return SubCategoryMain[kv.Value];
			}
		}

		[CompilerGenerated]
		private sealed class <DeferredAutoPreview>d__124 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DeferredAutoPreview>d__124(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (_activeCosCategory != "EMOTES")
					{
						return false;
					}
					if (!_emotesAvailable)
					{
						return false;
					}
					if (_selectedEmoteForPurchase != null)
					{
						return false;
					}
					EnsureAutoPreviewForActiveTier();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private const float PanelW = 680f;

		private const float PanelH = 590f;

		private const float HeaderH = 48f;

		private const float RankBarH = 50f;

		private const float NavH = 38f;

		private const float FooterH = 44f;

		private const float RowH = 36f;

		private const float FontSm = 11f;

		private const float FontMd = 13f;

		private const float FontLg = 15f;

		private const int LowCurrency = 50;

		private const string CatDexterity = "Athletics";

		private const string CatCombat = "Combat";

		private const string CatScavenging = "Utility";

		private const float CatTabH = 32f;

		private static readonly string[] Categories = new string[3] { "Athletics", "Combat", "Utility" };

		private const string SubSpeed = "Speed";

		private const string SubDexterity = "Dexterity";

		private const string SubLethality = "Lethality";

		private const string SubSurvival = "Survival";

		private const string SubLogistics = "Logistics";

		private const string SubOperations = "Operations";

		private static readonly Dictionary<string, string> SubCategoryMain = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			{ "Speed", "Athletics" },
			{ "Dexterity", "Athletics" },
			{ "Lethality", "Combat" },
			{ "Survival", "Combat" },
			{ "Logistics", "Utility" },
			{ "Operations", "Utility" }
		};

		private static readonly Dictionary<string, string[]> SubCategoriesByMain = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase)
		{
			{
				"Athletics",
				new string[2] { "Speed", "Dexterity" }
			},
			{
				"Combat",
				new string[2] { "Lethality", "Survival" }
			},
			{
				"Utility",
				new string[2] { "Logistics", "Operations" }
			}
		};

		private static readonly Dictionary<string, string> UpgradeSubCategories = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			{ "Physical Conditioning", "Speed" },
			{ "Reinforced Boots", "Speed" },
			{ "Climbing Gloves", "Dexterity" },
			{ "Grounded", "Dexterity" },
			{ "Locksmith", "Dexterity" },
			{ "Mechanical Arms", "Dexterity" },
			{ "Quick Hands", "Dexterity" },
			{ "Flare Burst", "Lethality" },
			{ "Lethal Hands Training", "Lethality" },
			{ "Pipe Bomb", "Lethality" },
			{ "Protein Powder", "Lethality" },
			{ "Retaliation", "Lethality" },
			{ "Sleight of Hand", "Lethality" },
			{ "Adrenaline Rush", "Survival" },
			{ "Bandaids", "Survival" },
			{ "Don't Shoot", "Survival" },
			{ "Dont Shoot", "Survival" },
			{ "Light Feet", "Survival" },
			{ "Lone Wolf", "Survival" },
			{ "NPC", "Survival" },
			{ "Shadow Step", "Survival" },
			{ "Spatial Awareness", "Survival" },
			{ "Stimpack", "Survival" },
			{ "Thick Skin", "Survival" },
			{ "Back Muscles", "Logistics" },
			{ "Better Scanner", "Logistics" },
			{ "Deeper Pockets", "Logistics" },
			{ "Extra Inventory Slot", "Logistics" },
			{ "Salvager", "Logistics" },
			{ "Aluminium Coils", "Operations" },
			{ "Escape Protocol", "Operations" },
			{ "Glow in the Dark", "Operations" },
			{ "Lithium Batteries", "Operations" },
			{ "Predator Instinct", "Operations" },
			{ "Squad Sight", "Operations" }
		};

		private static readonly Dictionary<string, Color> SubCategoryColors = new Dictionary<string, Color>(StringComparer.OrdinalIgnoreCase)
		{
			{
				"Speed",
				Hex("#00D4FF")
			},
			{
				"Dexterity",
				Hex("#A8D838")
			},
			{
				"Lethality",
				Hex("#E63946")
			},
			{
				"Survival",
				Hex("#F4A261")
			},
			{
				"Logistics",
				Hex("#FFB74D")
			},
			{
				"Operations",
				Hex("#B388FF")
			}
		};

		private static readonly HashSet<string> HiddenUpgrades = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Oxygen Canisters", "Beekeeper", "Hollow Point", "Long Barrel" };

		private static readonly Dictionary<string, string> UpgradeCategories = UpgradeSubCategories.ToDictionary<KeyValuePair<string, string>, string, string>((KeyValuePair<string, string> kv) => kv.Key, (KeyValuePair<string, string> kv) => SubCategoryMain[kv.Value], StringComparer.OrdinalIgnoreCase);

		private static string _activeCategory = "Athletics";

		private static readonly Dictionary<string, UpgradeColorType> UpgradeColors = new Dictionary<string, UpgradeColorType>(StringComparer.OrdinalIgnoreCase)
		{
			{
				"Reinforced Boots",
				UpgradeColorType.Speed
			},
			{
				"Physical Conditioning",
				UpgradeColorType.Speed
			},
			{
				"Quick Hands",
				UpgradeColorType.Speed
			},
			{
				"Climbing Gloves",
				UpgradeColorType.Speed
			},
			{
				"Mechanical Arms",
				UpgradeColorType.Speed
			},
			{
				"Locksmith",
				UpgradeColorType.Speed
			},
			{
				"Light Feet",
				UpgradeColorType.Defense
			},
			{
				"Lethal Hands Training",
				UpgradeColorType.Offense
			},
			{
				"Lethal Fists",
				UpgradeColorType.Offense
			},
			{
				"Retaliation",
				UpgradeColorType.Offense
			},
			{
				"Protein Powder",
				UpgradeColorType.Offense
			},
			{
				"Flare Burst",
				UpgradeColorType.Offense
			},
			{
				"Predator Instinct",
				UpgradeColorType.Offense
			},
			{
				"Stimpack",
				UpgradeColorType.Defense
			},
			{
				"Bandaids",
				UpgradeColorType.Defense
			},
			{
				"Grounded",
				UpgradeColorType.Defense
			},
			{
				"Adrenaline Rush",
				UpgradeColorType.Defense
			},
			{
				"Dont Shoot",
				UpgradeColorType.Stealth
			},
			{
				"Don't Shoot",
				UpgradeColorType.Stealth
			},
			{
				"NPC",
				UpgradeColorType.Stealth
			},
			{
				"Spatial Awareness",
				UpgradeColorType.Defense
			},
			{
				"Aluminium Coils",
				UpgradeColorType.Stealth
			},
			{
				"Sleight of Hand",
				UpgradeColorType.Stealth
			},
			{
				"Shadow Step",
				UpgradeColorType.Stealth
			},
			{
				"Back Muscles",
				UpgradeColorType.Loot
			},
			{
				"Deeper Pockets",
				UpgradeColorType.Loot
			},
			{
				"Better Scanner",
				UpgradeColorType.Loot
			},
			{
				"Extra Inventory Slot",
				UpgradeColorType.Loot
			},
			{
				"Salvager",
				UpgradeColorType.Loot
			},
			{
				"Lithium Batteries",
				UpgradeColorType.Loot
			},
			{
				"Lone Wolf",
				UpgradeColorType.Team
			},
			{
				"Squad Sight",
				UpgradeColorType.Team
			}
		};

		private static readonly Dictionary<UpgradeColorType, int> ColorSortOrder = new Dictionary<UpgradeColorType, int>
		{
			{
				UpgradeColorType.Speed,
				0
			},
			{
				UpgradeColorType.Defense,
				1
			},
			{
				UpgradeColorType.Offense,
				2
			},
			{
				UpgradeColorType.Stealth,
				3
			},
			{
				UpgradeColorType.Loot,
				4
			},
			{
				UpgradeColorType.Team,
				5
			}
		};

		private static GameObject _root;

		private static TMP_Text _currencyText;

		private static Transform _scrollContent;

		private static ScrollRect _scrollRect;

		private static GameObject _listView;

		private static GameObject _detailView;

		private static GameObject _tradeView;

		private static GameObject _playerLevelView;

		private static GameObject _catTabBar;

		private const string CosCatSuits = "SUITS";

		private const string CosCatCosmetics = "COSMETICS";

		private const string CosCatEmotes = "EMOTES";

		private static string _activeCosCategory = "SUITS";

		private static Transform _cosScrollContent;

		private static ScrollRect _cosScrollRect;

		private static object _selectedEmoteForPurchase;

		private static object _previewingEmote;

		private static int _activeEmoteTier = int.MinValue;

		private static List<(int rarity, string name)> _discoveredTiers;

		private static readonly Dictionary<int, ConfigEntry<int>> _tierPriceConfigs = new Dictionary<int, ConfigEntry<int>>();

		private static readonly Dictionary<int, Color> _tierColors = new Dictionary<int, Color>();

		private static TMP_Text _rankNameText;

		private static TMP_Text _rankBxpText;

		private static Image _rankFillBar;

		public static CustomTerminalNode currentSelection;

		public static string location;

		public static bool isTrackedYet = false;

		private const float SectionGap = 6f;

		private static bool _bxpReflResolved;

		private static FieldInfo _bxpField;

		private static FieldInfo _bxpLevelField;

		private static FieldInfo _bxpLevelsArray;

		private static FieldInfo _lvlNameField;

		private static FieldInfo _lvlXpField;

		private static FieldInfo _lvlXpEndField;

		private static int _rankRefreshTick;

		private static bool _mcReflResolved;

		private static FieldInfo _mcInstancesField;

		private static FieldInfo _mcSelectedField;

		private static MethodInfo _mcToggleMethod;

		private static MethodInfo _mcUpdateDisplayMethod;

		private static MethodInfo _mcWriteMethod;

		private static FieldInfo _mcCosmeticIdField;

		private static FieldInfo _mcIconField;

		private static FieldInfo _mcCosmeticTypeField;

		private static FieldInfo _tmeRenderTexture;

		private static MethodInfo _tmeSetPreviewAnim;

		private static FieldInfo _tmePreviewerEnabled;

		private static bool _tmePreviewResolved;

		private static bool _tmePreviewWarned;

		private static MethodInfo _tmeAudioExists;

		private static MethodInfo _tmeLoadAudioClip;

		private static PropertyInfo _tmeAudioClipName;

		private static PropertyInfo _tmeAudioLoopName;

		private static FieldInfo _tmeTransitionsToClip;

		private static MethodInfo _tmeEmoteLoadAudioClip;

		private static MethodInfo _tmeEmoteLoadAudioLoopClip;

		private static AudioSource _previewAudioSource;

		private static AudioSource _previewAudioLoopSource;

		private static GameObject _previewAudioHolder;

		private static bool _audioDiagDumped;

		private static bool _suitReflResolved;

		private static MethodInfo _switchSuitMethod;

		private static bool _emotesReflResolved;

		private static bool _emotesAvailable;

		private static FieldInfo _tmeAllUnlockableEmotes;

		private static FieldInfo _tmeEmoteName;

		private static FieldInfo _tmeDisplayName;

		private static FieldInfo _tmePurchasable;

		private static FieldInfo _tmeComplementary;

		private static FieldInfo _tmeRarity;

		private static PropertyInfo _tmeRarityText;

		private static MethodInfo _tmeIsEmoteUnlocked;

		private static MethodInfo _tmeUnlockEmoteLocal;

		private static PropertyInfo _tmeNameColor;

		private static FieldInfo _tmeRarityColorCodes;

		private static readonly Color[] _fallbackTierColors = (Color[])(object)new Color[4]
		{
			new Color(0.78f, 0.78f, 0.78f, 1f),
			new Color(0.29f, 0.62f, 1f, 1f),
			new Color(0.69f, 0.29f, 1f, 1f),
			new Color(1f, 0.7f, 0.28f, 1f)
		};

		public static bool BxpAvailable { get; private set; }

		public static int BxpCurrentLevel { get; private set; }

		public static int BxpTotalLevels { get; private set; }

		public static string BxpCurrentName { get; private set; }

		public static int BxpTotal { get; private set; }

		private static Color Hex(string s)
		{
			//IL_0012: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			return ColorUtility.TryParseHtmlString(s, ref val) ? val : Color.white;
		}

		private static string GetSubCategory(string upgradeName)
		{
			string value;
			return (upgradeName != null && UpgradeSubCategories.TryGetValue(upgradeName, out value)) ? value : null;
		}

		private static Color GetRowAccentColor(string upgradeName)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			string subCategory = GetSubCategory(upgradeName);
			if (subCategory != null && SubCategoryColors.TryGetValue(subCategory, out var value))
			{
				return value;
			}
			return GetUpgradeColor(upgradeName);
		}

		private static string GetCategory(string upgradeName)
		{
			string value;
			return UpgradeCategories.TryGetValue(upgradeName, out value) ? value : "Utility";
		}

		public static UpgradeColorType? GetUpgradeColorType(string upgradeName)
		{
			if (upgradeName != null && UpgradeColors.TryGetValue(upgradeName, out var value))
			{
				return value;
			}
			return null;
		}

		public static Color GetUpgradeColor(string upgradeName)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			UpgradeColorType? upgradeColorType = GetUpgradeColorType(upgradeName);
			if (!upgradeColorType.HasValue)
			{
				return Palette.Green;
			}
			return (Color)(upgradeColorType.Value switch
			{
				UpgradeColorType.Speed => Palette.TypeSpeed, 
				UpgradeColorType.Defense => Palette.TypeDefense, 
				UpgradeColorType.Offense => Palette.TypeOffense, 
				UpgradeColorType.Stealth => Palette.TypeStealth, 
				UpgradeColorType.Loot => Palette.TypeLoot, 
				UpgradeColorType.Team => Palette.TypeTeam, 
				_ => Palette.Green, 
			});
		}

		public static int GetUpgradeColorSortOrder(string upgradeName)
		{
			UpgradeColorType? upgradeColorType = GetUpgradeColorType(upgradeName);
			if (upgradeColorType.HasValue && ColorSortOrder.TryGetValue(upgradeColorType.Value, out var value))
			{
				return value;
			}
			return 99;
		}

		public static void initMenu()
		{
			if (!((Object)(object)_root != (Object)null))
			{
				Plugin.ExtendedLogging("Building LGU Menu from code", (LogLevel)16);
				_root = BuildRoot();
				_root.AddComponent<MenuController>().Init(_root);
				OpenCursor();
				showUpgrades(shared: false, resetScroll: true);
			}
		}

		private static GameObject BuildRoot()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UI.MakeCanvas("LGUMenu");
			UI.MakePanel("Overlay", val.transform, Palette.BgOverlay, Vector2.zero, Vector2.one);
			GameObject val2 = UI.MakePanel("Panel", val.transform, Palette.BgPanel, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f));
			RectTransform component = val2.GetComponent<RectTransform>();
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(680f, 590f);
			BuildHeader(val2.transform);
			BuildRankBar(val2.transform);
			BuildNav(val2.transform);
			BuildViews(val2.transform);
			BuildFooter(val2.transform);
			AddOutline(val2);
			UI.AddScanlines(val2.transform, 0.2f, 3);
			return val;
		}

		private static GameObject BuildSectionPanel(string name, Transform panel, Color fallbackColor, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin, Vector2 offsetMax)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UI.CloneBorderedPanel(name, panel, anchorMin, anchorMax, offsetMin, offsetMax);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			return UI.MakePanel(name, panel, fallbackColor, anchorMin, anchorMax, offsetMin, offsetMax);
		}

		private static void BuildHeader(Transform panel)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Expected O, but got Unknown
			GameObject val = BuildSectionPanel("Header", panel, Palette.BgHeader, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, -48f), Vector2.zero);
			string text = StartOfRound.Instance?.localPlayerController?.playerUsername ?? "EMPLOYEE";
			((Component)UI.MakeText("Title", val.transform, "[ " + text.ToUpper() + " ]", 15f, Palette.Green, (TextAlignmentOptions)4097)).GetComponent<RectTransform>().offsetMin = new Vector2(14f, 0f);
			_currencyText = UI.MakeText("Currency", val.transform, "", 15f, Palette.CurrencyGold, (TextAlignmentOptions)4100);
			RectTransform component = ((Component)_currencyText).GetComponent<RectTransform>();
			component.offsetMin = new Vector2(0f, 2f);
			component.offsetMax = new Vector2(-50f, -2f);
			RefreshCurrencyDisplay();
			(Button btn, TMP_Text label) tuple = UI.MakeButton("CloseBtn", panel, "X", 13f, Palette.BtnRed, Palette.BtnRedHl, Palette.Red, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-38f, -48f), new Vector2(0f, 0f));
			Button item = tuple.btn;
			TMP_Text item2 = tuple.label;
			ButtonClickedEvent onClick = item.onClick;
			object obj = <>c.<>9__70_0;
			if (obj == null)
			{
				UnityAction val2 = delegate
				{
					UI.PlayCancel();
					GameObject root = _root;
					if (root != null)
					{
						root.GetComponent<MenuController>()?.CloseMenu();
					}
				};
				<>c.<>9__70_0 = val2;
				obj = (object)val2;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
		}

		private static void BuildRankBar(Transform panel)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			float num = 48f;
			GameObject val = BuildSectionPanel("RankBar", panel, new Color(0.06f, 0.03f, 0.03f, 1f), new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, 0f - (num + 50f)), new Vector2(0f, 0f - num));
			_rankNameText = UI.MakeText("RankName", val.transform, "", 17f, Palette.White, (TextAlignmentOptions)4097);
			RectTransform component = ((Component)_rankNameText).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 0.45f);
			component.anchorMax = new Vector2(0.6f, 1f);
			component.offsetMin = new Vector2(14f, 0f);
			component.offsetMax = new Vector2(-4f, -2f);
			_rankBxpText = UI.MakeText("RankBXP", val.transform, "", 14f, Palette.White, (TextAlignmentOptions)4100);
			RectTransform component2 = ((Component)_rankBxpText).GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0.5f, 0.45f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.offsetMin = new Vector2(4f, 0f);
			component2.offsetMax = new Vector2(-14f, -2f);
			GameObject val2 = UI.MakePanel("ProgBg", val.transform, new Color(0.15f, 0.06f, 0.06f, 1f), new Vector2(0f, 0f), new Vector2(1f, 0.4f), new Vector2(14f, 4f), new Vector2(-14f, -1f));
			Outline val3 = val2.AddComponent<Outline>();
			((Shadow)val3).effectColor = new Color(0.8f, 0.3f, 0.05f, 0.5f);
			((Shadow)val3).effectDistance = new Vector2(1f, 1f);
			GameObject val4 = UI.MakePanel("ProgFill", val2.transform, new Color(0.75f, 0.15f, 0.2f, 1f), new Vector2(0f, 0f), new Vector2(0f, 1f), Vector2.zero, Vector2.zero);
			_rankFillBar = val4.GetComponent<Image>();
			RefreshRankDisplay();
		}

		private static void RefreshRankDisplay()
		{
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_rankNameText == (Object)null)
			{
				return;
			}
			try
			{
				if (!_bxpReflResolved)
				{
					Assembly assembly = null;
					Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
					foreach (Assembly assembly2 in assemblies)
					{
						if (assembly2.GetName().Name == "LCBetterEXP")
						{
							assembly = assembly2;
							break;
						}
					}
					if (assembly != null)
					{
						Type type = assembly.GetType("LCBetterEXP.patches.XPPatch");
						if (type != null)
						{
							_bxpField = type.GetField("betterXp", BindingFlags.Static | BindingFlags.Public);
							_bxpLevelField = type.GetField("level", BindingFlags.Static | BindingFlags.Public);
							_bxpLevelsArray = type.GetField("betterLevels", BindingFlags.Static | BindingFlags.Public);
							if (_bxpLevelsArray != null && _bxpLevelsArray.GetValue(null) is Array array && array.Length > 0)
							{
								Type type2 = array.GetValue(0).GetType();
								_lvlNameField = type2.GetField("name", BindingFlags.Instance | BindingFlags.Public);
								_lvlXpField = type2.GetField("xp", BindingFlags.Instance | BindingFlags.Public);
								_lvlXpEndField = type2.GetField("xpEnd", BindingFlags.Instance | BindingFlags.Public);
							}
						}
					}
					_bxpReflResolved = true;
				}
				if (_bxpField != null && _bxpLevelField != null && _bxpLevelsArray != null)
				{
					int num = (int)_bxpField.GetValue(null);
					int num2 = (int)_bxpLevelField.GetValue(null);
					if (_bxpLevelsArray.GetValue(null) is Array array2 && num2 >= 0 && num2 < array2.Length)
					{
						object value = array2.GetValue(num2);
						string text = (string)_lvlNameField.GetValue(value);
						int num3 = (int)_lvlXpField.GetValue(value);
						int num4 = (int)_lvlXpEndField.GetValue(value);
						_rankNameText.text = text;
						_rankBxpText.text = $"{num} BXP";
						BxpAvailable = true;
						BxpCurrentLevel = num2;
						BxpTotalLevels = array2.Length;
						BxpCurrentName = text;
						BxpTotal = num;
						float num5 = (float)(num - num3) / (float)Mathf.Max(1, num4 - num3);
						num5 = Mathf.Clamp01(num5);
						RectTransform component = ((Component)_rankFillBar).GetComponent<RectTransform>();
						component.anchorMax = new Vector2(num5, 1f);
						NotifyRankChanged();
						return;
					}
				}
			}
			catch (Exception)
			{
			}
			BxpAvailable = false;
			BxpCurrentLevel = 0;
			BxpTotalLevels = 0;
			BxpCurrentName = "";
			BxpTotal = 0;
			_rankNameText.text = "";
			_rankBxpText.text = "";
			if ((Object)(object)_rankFillBar != (Object)null)
			{
				RectTransform component2 = ((Component)_rankFillBar).GetComponent<RectTransform>();
				component2.anchorMax = new Vector2(0f, 1f);
			}
			NotifyRankChanged();
		}

		private static void NotifyRankChanged()
		{
			_rankRefreshTick++;
		}

		private static void BuildNav(Transform panel)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Expected O, but got Unknown
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Expected O, but got Unknown
			float num = 98f;
			GameObject val = BuildSectionPanel("Nav", panel, Palette.BgPanel, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, 0f - (num + 38f)), new Vector2(0f, 0f - num));
			float num2 = 1f / 3f;
			(Button btn, TMP_Text label) tuple = UI.MakeButton("PlayerLevelBtn", val.transform, "PLAYER COSMETICS", 11f, Palette.BtnBlue, Palette.BtnBlueHl, Palette.Cyan, new Vector2(0f, 0f), new Vector2(num2, 1f), new Vector2(4f, 3f), new Vector2(-2f, -3f));
			Button item = tuple.btn;
			TMP_Text item2 = tuple.label;
			ButtonClickedEvent onClick = item.onClick;
			object obj = <>c.<>9__102_0;
			if (obj == null)
			{
				UnityAction val2 = delegate
				{
					UI.PlayHover();
					showPlayerLevel(resetScroll: true);
				};
				<>c.<>9__102_0 = val2;
				obj = (object)val2;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			(Button btn, TMP_Text label) tuple2 = UI.MakeButton("IndivBtn", val.transform, "ENHANCEMENTS", 11f, Palette.BtnNormal, Palette.BtnHighlight, Palette.Green, new Vector2(num2, 0f), new Vector2(num2 * 2f, 1f), new Vector2(2f, 3f), new Vector2(-2f, -3f));
			Button item3 = tuple2.btn;
			TMP_Text item4 = tuple2.label;
			ButtonClickedEvent onClick2 = item3.onClick;
			object obj2 = <>c.<>9__102_1;
			if (obj2 == null)
			{
				UnityAction val3 = delegate
				{
					UI.PlayHover();
					showUpgrades(shared: false, resetScroll: true);
				};
				<>c.<>9__102_1 = val3;
				obj2 = (object)val3;
			}
			((UnityEvent)onClick2).AddListener((UnityAction)obj2);
			(Button btn, TMP_Text label) tuple3 = UI.MakeButton("TradeBtn", val.transform, "TRADE", 11f, Palette.BtnBlue, Palette.BtnBlueHl, Palette.Cyan, new Vector2(num2 * 2f, 0f), new Vector2(1f, 1f), new Vector2(2f, 3f), new Vector2(-4f, -3f));
			Button item5 = tuple3.btn;
			TMP_Text item6 = tuple3.label;
			ButtonClickedEvent onClick3 = item5.onClick;
			object obj3 = <>c.<>9__102_2;
			if (obj3 == null)
			{
				UnityAction val4 = delegate
				{
					UI.PlayHover();
					showTradeGui();
				};
				<>c.<>9__102_2 = val4;
				obj3 = (object)val4;
			}
			((UnityEvent)onClick3).AddListener((UnityAction)obj3);
		}

		private static void BuildViews(Transform panel)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00ca: 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)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Expected O, but got Unknown
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Expected O, but got Unknown
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Expected O, but got Unknown
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			float num = 138f;
			float num2 = 44f;
			_listView = new GameObject("ListView");
			_listView.transform.SetParent(panel, false);
			RectTransform val = _listView.AddComponent<RectTransform>();
			val.anchorMin = new Vector2(0f, 0f);
			val.anchorMax = new Vector2(1f, 1f);
			val.offsetMin = new Vector2(0f, num2);
			val.offsetMax = new Vector2(0f, 0f - num);
			_catTabBar = new GameObject("CatTabBar");
			_catTabBar.transform.SetParent(_listView.transform, false);
			RectTransform val2 = _catTabBar.AddComponent<RectTransform>();
			val2.anchorMin = new Vector2(0f, 1f);
			val2.anchorMax = new Vector2(1f, 1f);
			val2.pivot = new Vector2(0.5f, 1f);
			val2.offsetMin = new Vector2(0f, -32f);
			val2.offsetMax = Vector2.zero;
			Image val3 = _catTabBar.AddComponent<Image>();
			((Graphic)val3).color = new Color(0.06f, 0.03f, 0.03f, 1f);
			BuildCategoryTabs();
			(GameObject scrollGo, Transform content) tuple = UI.MakeScrollView("Scroll", _listView.transform, Vector2.zero, Vector2.one, new Vector2(0f, 0f), new Vector2(0f, -32f), addScrollbar: true);
			GameObject item = tuple.scrollGo;
			Transform item2 = tuple.content;
			_scrollContent = item2;
			_scrollRect = item.GetComponent<ScrollRect>();
			_detailView = new GameObject("DetailView");
			_detailView.transform.SetParent(panel, false);
			RectTransform val4 = _detailView.AddComponent<RectTransform>();
			val4.anchorMin = new Vector2(0f, 0f);
			val4.anchorMax = new Vector2(1f, 1f);
			val4.offsetMin = new Vector2(0f, num2);
			val4.offsetMax = new Vector2(0f, 0f - num);
			_detailView.SetActive(false);
			_tradeView = new GameObject("TradeView");
			_tradeView.transform.SetParent(panel, false);
			RectTransform val5 = _tradeView.AddComponent<RectTransform>();
			val5.anchorMin = new Vector2(0f, 0f);
			val5.anchorMax = new Vector2(1f, 1f);
			val5.offsetMin = new Vector2(0f, num2);
			val5.offsetMax = new Vector2(0f, 0f - num);
			_tradeView.SetActive(false);
			_playerLevelView = new GameObject("PlayerLevelView");
			_playerLevelView.transform.SetParent(panel, false);
			RectTransform val6 = _playerLevelView.AddComponent<RectTransform>();
			val6.anchorMin = new Vector2(0f, 0f);
			val6.anchorMax = new Vector2(1f, 1f);
			val6.offsetMin = new Vector2(0f, num2);
			val6.offsetMax = new Vector2(0f, 0f - num);
			_playerLevelView.SetActive(false);
		}

		private static void BuildCategoryTabs()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Expected O, but got Unknown
			foreach (Transform item3 in _catTabBar.transform)
			{
				Transform val = item3;
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			float num = 1f / (float)Categories.Length;
			for (int i = 0; i < Categories.Length; i++)
			{
				string text = Categories[i];
				bool flag = text == _activeCategory;
				Color bgColor = (flag ? Palette.BtnActive : Palette.BtnNormal);
				Color hlColor = (flag ? Palette.BtnActive : Palette.BtnHighlight);
				Color textColor = (flag ? Palette.White : Palette.Dim);
				(Button btn, TMP_Text label) tuple = UI.MakeButton($"CatTab_{i}", _catTabBar.transform, text.ToUpper(), 10f, bgColor, hlColor, textColor, new Vector2(num * (float)i, 0f), new Vector2(num * (float)(i + 1), 1f), new Vector2(2f, 2f), new Vector2(-2f, -2f));
				Button item = tuple.btn;
				TMP_Text item2 = tu

LGUHome.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using InteractiveTerminalAPI.UI;
using InteractiveTerminalAPI.UI.Application;
using InteractiveTerminalAPI.UI.Cursor;
using InteractiveTerminalAPI.UI.Page;
using InteractiveTerminalAPI.UI.Screen;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("DunGen")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")]
[assembly: IgnoresAccessChecksTo("Unity.XR.Management")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LGUHome")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8c5521e37f37e3d76518a16d04e5d1051842f105")]
[assembly: AssemblyProduct("LGUHome")]
[assembly: AssemblyTitle("LGUHome")]
[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 LGUHome
{
	internal class LGUHomeApplication : PageApplication<CursorElement>
	{
		[CompilerGenerated]
		private sealed class <ClearNavigatingFlag>d__8 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ClearNavigatingFlag>d__8(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					Plugin.IsNavigating = false;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <SubmitNextFrame>d__10 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Terminal terminal;

			public string keyword;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SubmitNextFrame>d__10(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					Plugin.IsNavigating = false;
					if ((Object)(object)terminal == (Object)null)
					{
						return false;
					}
					TMP_InputField screenText = terminal.screenText;
					screenText.text += keyword;
					terminal.textAdded = keyword.Length;
					terminal.OnSubmit();
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private Terminal _terminal;

		private static Func<string> _consNameGetter;

		private static bool _reflectionDone;

		public override void Initialization()
		{
			_terminal = Object.FindObjectOfType<Terminal>();
			if (!_reflectionDone)
			{
				_reflectionDone = true;
				BuildReflectionCache();
			}
			BuildHomeScreen();
		}

		private static void BuildReflectionCache()
		{
			try
			{
				Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "LethalConstellations");
				if (assembly == null)
				{
					return;
				}
				FieldInfo currentField = assembly.GetType("LethalConstellations.PluginCore.Collections")?.GetField("CurrentConstellationCM", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				FieldInfo consNameField = currentField?.FieldType.GetField("consName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(currentField == null) && !(consNameField == null))
				{
					_consNameGetter = delegate
					{
						object value = currentField.GetValue(null);
						return (value == null) ? null : ((string)consNameField.GetValue(value));
					};
					Plugin.Log.LogInfo((object)"[Home] Constellation name getter cached.");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[Home] Could not cache constellation name getter: " + ex.Message));
			}
		}

		private void BuildHomeScreen()
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			string text = null;
			try
			{
				text = _consNameGetter?.Invoke();
			}
			catch
			{
			}
			string text2 = (string.IsNullOrEmpty(text) ? "  <color=#e6b800>CONSTELLATIONS</color>" : ("  <color=#e6b800>CONSTELLATIONS  [" + text.ToUpperInvariant() + "]</color>"));
			CursorElement[] array = (CursorElement[])(object)new CursorElement[4]
			{
				CursorElement.Create(text2, "", (Action)delegate
				{
					NavigateTo(Plugin.ConstellationsKeyword.Value);
				}, (Func<CursorElement, bool>)null, true),
				CursorElement.Create("  MOONS", "", (Action)delegate
				{
					NavigateTo(Plugin.MoonsKeyword.Value);
				}, (Func<CursorElement, bool>)null, true),
				CursorElement.Create("  SHOP", "", (Action)delegate
				{
					NavigateTo(Plugin.ShopKeyword.Value);
				}, (Func<CursorElement, bool>)null, true),
				CursorElement.Create("  TERMINAL PROMPT", "", (Action)TerminalPromptSelected, (Func<CursorElement, bool>)null, true)
			};
			CursorMenu<CursorElement> val = CursorMenu<CursorElement>.Create(0, '>', array, (Func<CursorElement, CursorElement, int>[])null);
			BoxedScreen val2 = new BoxedScreen();
			val2.Title = Plugin.MenuTitle.Value;
			val2.elements = (ITextElement[])(object)new ITextElement[2]
			{
				(ITextElement)new TextElement
				{
					Text = " "
				},
				(ITextElement)val
			};
			BoxedScreen val3 = val2;
			base.currentPage = PageCursorElement<CursorElement>.Create(0, (IScreen[])(object)new IScreen[1] { (IScreen)val3 }, new BaseCursorMenu<CursorElement>[1] { (BaseCursorMenu<CursorElement>)(object)val });
			((BaseInteractiveApplication<CursorElement>)(object)this).currentCursorMenu = (BaseCursorMenu<CursorElement>)(object)val;
			((TerminalApplication)this).currentScreen = (IScreen)(object)val3;
		}

		protected override int GetEntriesPerPage<K>(K[] entries)
		{
			return entries.Length;
		}

		private void TerminalPromptSelected()
		{
			Plugin.BypassLoadNewNodeRedirect = true;
			Plugin.IsNavigating = true;
			Object.Destroy((Object)(object)InteractiveTerminalManager.Instance);
			if ((Object)(object)_terminal != (Object)null)
			{
				((MonoBehaviour)_terminal).StartCoroutine(ClearNavigatingFlag());
				return;
			}
			Plugin.Log.LogWarning((object)"[Home] TerminalPromptSelected: terminal reference is null — clearing navigating flag synchronously.");
			Plugin.IsNavigating = false;
		}

		[IteratorStateMachine(typeof(<ClearNavigatingFlag>d__8))]
		private static IEnumerator ClearNavigatingFlag()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ClearNavigatingFlag>d__8(0);
		}

		private void NavigateTo(string keyword)
		{
			Terminal terminal = _terminal;
			Plugin.IsNavigating = true;
			Object.Destroy((Object)(object)InteractiveTerminalManager.Instance);
			if ((Object)(object)terminal == (Object)null)
			{
				Plugin.Log.LogWarning((object)("[Home] NavigateTo('" + keyword + "'): terminal reference is null — cannot submit keyword."));
				Plugin.IsNavigating = false;
			}
			else
			{
				((MonoBehaviour)terminal).StartCoroutine(SubmitNextFrame(terminal, keyword));
			}
		}

		[IteratorStateMachine(typeof(<SubmitNextFrame>d__10))]
		private static IEnumerator SubmitNextFrame(Terminal terminal, string keyword)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SubmitNextFrame>d__10(0)
			{
				terminal = terminal,
				keyword = keyword
			};
		}
	}
	[HarmonyPatch(typeof(Terminal), "BeginUsingTerminal")]
	internal static class BeginUsingTerminalPatch
	{
		[CompilerGenerated]
		private sealed class <LaunchHomeOnOpen>d__1 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Terminal terminal;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LaunchHomeOnOpen>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.15f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					if ((Object)(object)terminal == (Object)null || !terminal.terminalInUse)
					{
						return false;
					}
					if ((Object)(object)InteractiveTerminalManager.Instance != (Object)null)
					{
						Plugin.Log.LogInfo((object)"[Home] BeginUsingTerminal fallback skipped — ITAPI already active.");
						return false;
					}
					Plugin.Log.LogInfo((object)"[Home] BeginUsingTerminal fallback: submitting home keyword.");
					TMP_InputField screenText = terminal.screenText;
					screenText.text += Plugin.HomeKeyword.Value;
					terminal.textAdded = Plugin.HomeKeyword.Value.Length;
					terminal.OnSubmit();
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[HarmonyPostfix]
		private static void Postfix(Terminal __instance)
		{
			try
			{
				if ((Object)(object)__instance == (Object)null)
				{
					Plugin.Log.LogWarning((object)"[Home] BeginUsingTerminal Postfix: terminal is null — skipping fallback launch.");
					return;
				}
				Plugin.Log.LogInfo((object)"[Home] BeginUsingTerminal fired.");
				((MonoBehaviour)__instance).StartCoroutine(LaunchHomeOnOpen(__instance));
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"[Home] BeginUsingTerminal Postfix swallowed exception to protect specialInteractAnimation: {arg}");
			}
		}

		[IteratorStateMachine(typeof(<LaunchHomeOnOpen>d__1))]
		private static IEnumerator LaunchHomeOnOpen(Terminal terminal)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LaunchHomeOnOpen>d__1(0)
			{
				terminal = terminal
			};
		}
	}
	[HarmonyPatch(typeof(Terminal), "LoadNewNode")]
	internal static class LoadNewNodePatch
	{
		private static bool _isRedirecting;

		private static readonly HashSet<string> _loggedNodes = new HashSet<string>();

		[HarmonyPrefix]
		private static bool Prefix(Terminal __instance, TerminalNode node)
		{
			if ((Object)(object)node == (Object)null)
			{
				return true;
			}
			string text = ((Object)node).name ?? "<null>";
			if (_loggedNodes.Add(text))
			{
				string displayText = node.displayText;
				string text2 = ((displayText != null && displayText.Length > 60) ? node.displayText.Substring(0, 60) : (node.displayText ?? "")).Replace("\n", "\\n");
				Plugin.Log.LogInfo((object)("[Home] LoadNewNode: name='" + text + "' displayText='" + text2 + "'"));
			}
			if (_isRedirecting)
			{
				return true;
			}
			if (Plugin.IsNavigating)
			{
				return true;
			}
			if ((Object)(object)InteractiveTerminalManager.Instance != (Object)null)
			{
				return true;
			}
			if (!ShouldRedirectToHome(__instance, node))
			{
				return true;
			}
			if (Plugin.BypassLoadNewNodeRedirect)
			{
				Plugin.BypassLoadNewNodeRedirect = false;
				Plugin.Log.LogInfo((object)("[Home] LoadNewNode bypass active for '" + text + "' — letting it load."));
				return true;
			}
			Plugin.Log.LogInfo((object)("[Home] LoadNewNode intercepted '" + text + "' — redirecting to home via ITAPI."));
			_isRedirecting = true;
			TMP_InputField screenText = __instance.screenText;
			screenText.text += Plugin.HomeKeyword.Value;
			__instance.textAdded = Plugin.HomeKeyword.Value.Length;
			__instance.OnSubmit();
			_isRedirecting = false;
			return false;
		}

		private static bool ShouldRedirectToHome(Terminal terminal, TerminalNode node)
		{
			List<TerminalNode> list = terminal.terminalNodes?.specialNodes;
			if (list != null && list.Count > 1 && (Object)(object)node == (Object)(object)list[1])
			{
				return true;
			}
			if (string.Equals(((Object)node).name ?? "", Plugin.HomeKeyword.Value, StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			return false;
		}
	}
	[BepInPlugin("com.y4ngz.lguhome", "LGUHome", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "com.y4ngz.lguhome";

		public const string PLUGIN_NAME = "LGUHome";

		public const string PLUGIN_VERSION = "1.0.0";

		internal static ManualLogSource Log;

		internal static Plugin Instance;

		internal static bool IsNavigating;

		internal static bool BypassLoadNewNodeRedirect;

		internal static ConfigEntry<string> HomeKeyword;

		internal static ConfigEntry<string> ConstellationsKeyword;

		internal static ConfigEntry<string> MoonsKeyword;

		internal static ConfigEntry<string> ShopKeyword;

		internal static ConfigEntry<string> MenuTitle;

		private void Awake()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			try
			{
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				ManualLogSource log = Log;
				string[] obj = new string[5]
				{
					"[Home][Lifecycle] Plugin Awake on GameObject '",
					((Object)((Component)this).gameObject).name,
					"' (sceneRoot? ",
					null,
					null
				};
				Scene scene = ((Component)this).gameObject.scene;
				obj[3] = ((Scene)(ref scene)).name;
				obj[4] = "). DontDestroyOnLoad applied.";
				log.LogInfo((object)string.Concat(obj));
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[Home][Lifecycle] DontDestroyOnLoad threw: " + ex.Message));
			}
			SceneManager.sceneLoaded += OnSceneLoaded_Diag;
			SceneManager.sceneUnloaded += OnSceneUnloaded_Diag;
			HomeKeyword = ((BaseUnityPlugin)this).Config.Bind<string>("Main", "HomeKeyword", "home", "Terminal keyword that opens this home menu. Must match TerminalStuff's TerminalStartPage value.");
			ConstellationsKeyword = ((BaseUnityPlugin)this).Config.Bind<string>("Main", "ConstellationsKeyword", "constellations", "Terminal keyword submitted when Constellations is selected from the home menu.");
			MoonsKeyword = ((BaseUnityPlugin)this).Config.Bind<string>("Main", "MoonsKeyword", "moons", "Terminal keyword submitted when Moons is selected from the home menu.");
			ShopKeyword = ((BaseUnityPlugin)this).Config.Bind<string>("Main", "ShopKeyword", "shop", "Terminal keyword submitted when Shop is selected from the home menu.");
			MenuTitle = ((BaseUnityPlugin)this).Config.Bind<string>("Main", "MenuTitle", "FORTUNE-93 // MAIN TERMINAL", "Title shown at the top of the home menu box.");
			try
			{
				InteractiveTerminalManager.RegisterApplication<LGUHomeApplication>(HomeKeyword.Value);
				Log.LogInfo((object)("LGUHome v1.0.0 loaded — home menu on keyword '" + HomeKeyword.Value + "'."));
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to register home application: {arg}");
			}
			new Harmony("com.y4ngz.lguhome").PatchAll(typeof(Plugin).Assembly);
		}

		private void OnDestroy()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			string text = "<unavailable>";
			try
			{
				text = Environment.StackTrace;
			}
			catch
			{
			}
			try
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					string[] obj2 = new string[6]
					{
						"[Home][Lifecycle] Plugin.OnDestroy fired on GameObject '",
						((Object)(object)((Component)this).gameObject != (Object)null) ? ((Object)((Component)this).gameObject).name : "<null>",
						"' (active scene: '",
						null,
						null,
						null
					};
					Scene activeScene = SceneManager.GetActiveScene();
					obj2[3] = ((Scene)(ref activeScene)).name;
					obj2[4] = "'). Stack:\n";
					obj2[5] = text;
					log.LogWarning((object)string.Concat(obj2));
				}
			}
			catch
			{
			}
		}

		private static void OnSceneLoaded_Diag(Scene scene, LoadSceneMode mode)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)$"[Home][Lifecycle] Scene loaded: '{((Scene)(ref scene)).name}' (mode={mode}). Plugin.Instance unity-null={(Object)(object)Instance == (Object)null}");
			}
		}

		private static void OnSceneUnloaded_Diag(Scene scene)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)$"[Home][Lifecycle] Scene unloaded: '{((Scene)(ref scene)).name}'. Plugin.Instance unity-null={(Object)(object)Instance == (Object)null}");
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

LGUMonitorTakeover.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;

[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("LGUMonitorTakeover")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Y4NGZ monitor takeover sequence for Lethal Company")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8c5521e37f37e3d76518a16d04e5d1051842f105")]
[assembly: AssemblyProduct("LGUMonitorTakeover")]
[assembly: AssemblyTitle("LGUMonitorTakeover")]
[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 LGUMonitorTakeover
{
	internal static class ConstellationBridgeReflection
	{
		private static bool _initialized;

		private static bool _bridgeAvailable;

		private static MethodInfo _checkAndNotifyMethod;

		private static void Init()
		{
			if (_initialized)
			{
				return;
			}
			_initialized = true;
			try
			{
				Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "LGUConstellationsBridge");
				if (assembly == null)
				{
					Plugin.Log.LogInfo((object)"[TakeoverBridge] LGUConstellationsBridge not loaded — skipping notification.");
					return;
				}
				Type type = assembly.GetType("LGUConstellationsBridge.ConstellationNotification");
				if (type == null)
				{
					Plugin.Log.LogWarning((object)"[TakeoverBridge] ConstellationNotification type not found in bridge.");
					return;
				}
				_checkAndNotifyMethod = type.GetMethod("CheckAndNotify", BindingFlags.Static | BindingFlags.Public);
				if (_checkAndNotifyMethod == null)
				{
					Plugin.Log.LogWarning((object)"[TakeoverBridge] CheckAndNotify method not found.");
					return;
				}
				_bridgeAvailable = true;
				Plugin.Log.LogInfo((object)"[TakeoverBridge] Constellation notification bridge ready.");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[TakeoverBridge] Init failed: " + ex.Message));
			}
		}

		public static void TryShowConstellationNotification()
		{
			Init();
			if (!_bridgeAvailable)
			{
				return;
			}
			try
			{
				_checkAndNotifyMethod.Invoke(null, null);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[TakeoverBridge] Notification call failed: " + ex.Message));
			}
		}
	}
	internal class MonitorDebugger : MonoBehaviour
	{
		internal static void DumpAll()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Invalid comparison between Unknown and I4
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_070a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0711: Expected O, but got Unknown
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("========== Y4NGZ MONITOR DEBUGGER ==========");
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				Plugin.Log.LogWarning((object)"StartOfRound.Instance is null — are you in-game?");
				return;
			}
			stringBuilder.AppendLine("\n--- screenLevelVideoReel (VideoPlayer) ---");
			VideoPlayer screenLevelVideoReel = instance.screenLevelVideoReel;
			if ((Object)(object)screenLevelVideoReel == (Object)null)
			{
				stringBuilder.AppendLine("  NULL");
			}
			else
			{
				stringBuilder.AppendLine($"  renderMode      : {screenLevelVideoReel.renderMode}");
				stringBuilder.AppendLine("  targetTexture   : " + (((Object)(object)screenLevelVideoReel.targetTexture != (Object)null) ? ((Object)screenLevelVideoReel.targetTexture).name : "null"));
				stringBuilder.AppendLine("  clip            : " + (((Object)(object)screenLevelVideoReel.clip != (Object)null) ? ((Object)screenLevelVideoReel.clip).name : "null"));
				stringBuilder.AppendLine($"  isPlaying       : {screenLevelVideoReel.isPlaying}");
				stringBuilder.AppendLine("  gameObject path : " + GetPath(((Component)screenLevelVideoReel).gameObject));
				if ((int)screenLevelVideoReel.renderMode == 3)
				{
					Renderer val = ((Component)screenLevelVideoReel).GetComponent<Renderer>() ?? ((Component)screenLevelVideoReel).GetComponentInChildren<Renderer>();
					stringBuilder.AppendLine("  MaterialOverride renderer: " + (((Object)(object)val != (Object)null) ? GetPath(((Component)val).gameObject) : "none on same GO"));
				}
			}
			stringBuilder.AppendLine("\n--- mapScreen (ManualCameraRenderer) ---");
			ManualCameraRenderer mapScreen = instance.mapScreen;
			if ((Object)(object)mapScreen == (Object)null)
			{
				stringBuilder.AppendLine("  NULL");
			}
			else
			{
				stringBuilder.AppendLine("  gameObject path : " + GetPath(((Component)mapScreen).gameObject));
				stringBuilder.AppendLine("  cam             : " + (((Object)(object)mapScreen.cam != (Object)null) ? ((Object)mapScreen.cam).name : "null"));
				if ((Object)(object)mapScreen.cam != (Object)null)
				{
					stringBuilder.AppendLine("  cam.targetTexture: " + (((Object)(object)mapScreen.cam.targetTexture != (Object)null) ? ((Object)mapScreen.cam.targetTexture).name : "null"));
				}
				stringBuilder.AppendLine("  mapCamera       : " + (((Object)(object)mapScreen.mapCamera != (Object)null) ? ((Object)mapScreen.mapCamera).name : "null"));
				if ((Object)(object)mapScreen.mapCamera != (Object)null)
				{
					stringBuilder.AppendLine("  mapCamera.targetTexture: " + (((Object)(object)mapScreen.mapCamera.targetTexture != (Object)null) ? ((Object)mapScreen.mapCamera.targetTexture).name : "null"));
				}
			}
			stringBuilder.AppendLine("\n--- upperMonitorsCanvas ---");
			GameObject upperMonitorsCanvas = instance.upperMonitorsCanvas;
			if ((Object)(object)upperMonitorsCanvas == (Object)null)
			{
				stringBuilder.AppendLine("  NULL");
			}
			else
			{
				stringBuilder.AppendLine("  path            : " + GetPath(upperMonitorsCanvas));
				stringBuilder.AppendLine("  parent          : " + (((Object)(object)upperMonitorsCanvas.transform.parent != (Object)null) ? GetPath(((Component)upperMonitorsCanvas.transform.parent).gameObject) : "none"));
				Canvas[] componentsInChildren = upperMonitorsCanvas.GetComponentsInChildren<Canvas>(true);
				stringBuilder.AppendLine($"  child Canvas count: {componentsInChildren.Length}");
				Canvas[] array = componentsInChildren;
				foreach (Canvas val2 in array)
				{
					stringBuilder.AppendLine($"    Canvas: {GetPath(((Component)val2).gameObject)}  renderMode={val2.renderMode}");
				}
				if ((Object)(object)upperMonitorsCanvas.transform.parent != (Object)null)
				{
					MeshRenderer[] componentsInChildren2 = ((Component)upperMonitorsCanvas.transform.parent).GetComponentsInChildren<MeshRenderer>(true);
					stringBuilder.AppendLine($"  MeshRenderers in parent ({((Object)upperMonitorsCanvas.transform.parent).name}): {componentsInChildren2.Length}");
					MeshRenderer[] array2 = componentsInChildren2;
					foreach (MeshRenderer val3 in array2)
					{
						Material sharedMaterial = ((Renderer)val3).sharedMaterial;
						string text = (((Object)(object)((sharedMaterial != null) ? sharedMaterial.mainTexture : null) != (Object)null) ? (((object)sharedMaterial.mainTexture).GetType().Name + ":" + ((Object)sharedMaterial.mainTexture).name) : "no mainTexture");
						stringBuilder.AppendLine("    " + GetPath(((Component)val3).gameObject) + "  mat=" + ((sharedMaterial != null) ? ((Object)sharedMaterial).name : null) + "  tex=" + text);
					}
				}
			}
			stringBuilder.AppendLine("\n--- Ship MeshRenderers with RenderTexture mainTexture ---");
			GameObject val4 = GameObject.Find("Environment/HangarShip") ?? GameObject.Find("HangarShip");
			if ((Object)(object)val4 == (Object)null)
			{
				stringBuilder.AppendLine("  HangarShip not found in scene");
			}
			else
			{
				int num = 0;
				MeshRenderer[] array2 = val4.GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val5 in array2)
				{
					Material sharedMaterial2 = ((Renderer)val5).sharedMaterial;
					Texture obj = ((sharedMaterial2 != null) ? sharedMaterial2.mainTexture : null);
					RenderTexture val6 = (RenderTexture)(object)((obj is RenderTexture) ? obj : null);
					if (val6 != null)
					{
						stringBuilder.AppendLine("  " + GetPath(((Component)val5).gameObject));
						stringBuilder.AppendLine($"    material={((Object)((Renderer)val5).sharedMaterial).name}  RT={((Object)val6).name} ({((Texture)val6).width}x{((Texture)val6).height})");
						num++;
					}
				}
				if (num == 0)
				{
					stringBuilder.AppendLine("  (none found)");
				}
			}
			stringBuilder.AppendLine("\n--- Top monitor UI components ---");
			LogUIComponent(stringBuilder, "profitQuotaMonitorBGImage", (Component)(object)instance.profitQuotaMonitorBGImage);
			LogUIComponent(stringBuilder, "profitQuotaMonitorText", (Component)(object)instance.profitQuotaMonitorText);
			LogUIComponent(stringBuilder, "deadlineMonitorBGImage", (Component)(object)instance.deadlineMonitorBGImage);
			LogUIComponent(stringBuilder, "deadlineMonitorText", (Component)(object)instance.deadlineMonitorText);
			stringBuilder.AppendLine("\n--- HUDContainer ---");
			HUDManager instance2 = HUDManager.Instance;
			if ((Object)(object)instance2?.HUDContainer != (Object)null)
			{
				stringBuilder.AppendLine($"  path: {GetPath(instance2.HUDContainer)}  active={instance2.HUDContainer.activeSelf}");
			}
			else
			{
				stringBuilder.AppendLine("  HUDManager or HUDContainer is null");
			}
			stringBuilder.AppendLine("\n--- MonitorWall ALL MeshRenderers ---");
			GameObject val7 = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall");
			if ((Object)(object)val7 == (Object)null)
			{
				stringBuilder.AppendLine("  MonitorWall not found!");
			}
			else
			{
				MeshRenderer[] array2 = val7.GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val8 in array2)
				{
					Material sharedMaterial3 = ((Renderer)val8).sharedMaterial;
					string text2 = (((Object)(object)((sharedMaterial3 != null) ? sharedMaterial3.mainTexture : null) != (Object)null) ? (((object)sharedMaterial3.mainTexture).GetType().Name + ":" + ((Object)sharedMaterial3.mainTexture).name) : "null");
					string text3 = "n/a";
					try
					{
						MaterialPropertyBlock val9 = new MaterialPropertyBlock();
						((Renderer)val8).GetPropertyBlock(val9);
						Texture texture = val9.GetTexture("_MainTex");
						text3 = (((Object)(object)texture != (Object)null) ? ("MPB:" + ((Object)texture).name) : "no MPB");
					}
					catch
					{
					}
					stringBuilder.AppendLine("  " + GetPath(((Component)val8).gameObject));
					stringBuilder.AppendLine("    sharedMat=" + ((sharedMaterial3 != null) ? ((Object)sharedMaterial3).name : null) + "  sharedTex=" + text2 + "  instCheck=" + text3);
				}
			}
			stringBuilder.AppendLine("\n========== END DEBUGGER ==========");
			Plugin.Log.LogInfo((object)stringBuilder.ToString());
		}

		private static void LogUIComponent(StringBuilder sb, string label, Component c)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)c == (Object)null)
			{
				sb.AppendLine("  " + label + ": NULL");
				return;
			}
			sb.AppendLine("  " + label + ":");
			sb.AppendLine("    path          : " + GetPath(c.gameObject));
			sb.AppendLine($"    world position: {c.transform.position}");
			sb.AppendLine($"    enabled       : {((Behaviour)c).enabled}");
		}

		private static string GetPath(GameObject go)
		{
			if ((Object)(object)go == (Object)null)
			{
				return "(null)";
			}
			string text = ((Object)go).name;
			Transform parent = go.transform.parent;
			int num = 0;
			while ((Object)(object)parent != (Object)null && num < 8)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
				num++;
			}
			return text;
		}
	}
	internal static class OpenBodyCamsCompat
	{
		private const string PluginGuid = "Zaggy1024.OpenBodyCams";

		private static bool _resolved;

		private static bool _present;

		private static Behaviour _bodyCamBehaviour;

		private static bool _wasEnabled;

		private static GameObject _overlayMeshGO;

		private static bool _overlayWasActive;

		private static void Resolve()
		{
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Expected O, but got Unknown
			_resolved = true;
			try
			{
				if (!Chainloader.PluginInfos.ContainsKey("Zaggy1024.OpenBodyCams"))
				{
					return;
				}
				GameObject val = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall/Cube.001");
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Log.LogInfo((object)"[OBCCompat] OpenBodyCams loaded but Cube.001 not found at resolve time.");
					return;
				}
				Type type = null;
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					if (!(assembly.GetName().Name != "OpenBodyCams"))
					{
						type = assembly.GetType("OpenBodyCams.Components.BodyCamComponent", throwOnError: false) ?? assembly.GetType("OpenBodyCams.BodyCamComponent", throwOnError: false);
						if (type != null)
						{
							break;
						}
					}
				}
				if (type == null)
				{
					Plugin.Log.LogWarning((object)"[OBCCompat] BodyCamComponent type not found in OpenBodyCams assembly.");
					return;
				}
				Component component = val.GetComponent(type);
				Behaviour val2 = (Behaviour)(object)((component is Behaviour) ? component : null);
				if (val2 == null)
				{
					Plugin.Log.LogInfo((object)"[OBCCompat] BodyCamComponent not attached to Cube.001 — nothing to suppress.");
					return;
				}
				_bodyCamBehaviour = val2;
				_present = true;
				Plugin.Log.LogInfo((object)"[OBCCompat] Detected OpenBodyCams BodyCamComponent on Cube.001.");
				GameObject val3 = GameObject.Find("Environment/HangarShip/ShipModels2b/MonitorWall");
				if (!((Object)(object)val3 != (Object)null))
				{
					return;
				}
				foreach (Transform item in val3.transform)
				{
					Transform val4 = item;
					if ((Object)(object)val4 != (Object)null && ((Object)val4).name != null && ((Object)val4).name.StartsWith("BodyCamOverlayMesh"))
					{
						_overlayMeshGO = ((Component)val4).gameObject;
						Plugin.Log.LogInfo((object)("[OBCCompat] Detected OBC overlay mesh: " + ((Object)val4).name));
						break;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[OBCCompat] Resolve failed: " + ex.Message));
			}
		}

		internal static void Suppress()
		{
			if (!_resolved)
			{
				Resolve();
			}
			if (!_present || (Object)(object)_bodyCamBehaviour == (Object)null)
			{
				return;
			}
			try
			{
				_wasEnabled = _bodyCamBehaviour.enabled;
				if (_wasEnabled)
				{
					_bodyCamBehaviour.enabled = false;
					Plugin.Log.LogInfo((object)"[OBCCompat] Suppressed OpenBodyCams BodyCamComponent on Cube.001.");
				}
				if ((Object)(object)_overlayMeshGO != (Object)null)
				{
					_overlayWasActive = _overlayMeshGO.activeSelf;
					if (_overlayWasActive)
					{
						_overlayMeshGO.SetActive(false);
						Plugin.Log.LogInfo((object)"[OBCCompat] Hid OBC overlay mesh under MonitorWall.");
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[OBCCompat] Suppress failed: " + ex.Message));
			}
		}

		internal static void Restore()
		{
			if (!_present || (Object)(object)_bodyCamBehaviour == (Object)null)
			{
				return;
			}
			try
			{
				if ((Object)(object)_overlayMeshGO != (Object)null && _overlayWasActive && !_overlayMeshGO.activeSelf)
				{
					_overlayMeshGO.SetActive(true);
					Plugin.Log.LogInfo((object)"[OBCCompat] Restored OBC overlay mesh under MonitorWall.");
				}
				if (_wasEnabled && !_bodyCamBehaviour.enabled)
				{
					_bodyCamBehaviour.enabled = true;
					Plugin.Log.LogInfo((object)"[OBCCompat] Restored OpenBodyCams BodyCamComponent on Cube.001.");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[OBCCompat] Restore failed: " + ex.Message));
			}
		}
	}
	internal static class Patches
	{
		[HarmonyPatch(typeof(TimeOfDay), "SetNewProfitQuota")]
		[HarmonyPostfix]
		private static void OnSetNewProfitQuota()
		{
			Plugin.QuotaJustCompleted = true;
			Plugin.Log.LogInfo((object)"[LGUMonitorTakeover] Quota fulfilled (server) — takeover queued.");
			CheckMaskManTrigger("server");
		}

		[HarmonyPatch(typeof(TimeOfDay), "SyncNewProfitQuotaClientRpc")]
		[HarmonyPostfix]
		private static void OnSyncNewProfitQuotaClientRpc()
		{
			Plugin.QuotaJustCompleted = true;
			Plugin.Log.LogInfo((object)"[LGUMonitorTakeover] Quota sync received (client) — takeover queued.");
			CheckMaskManTrigger("client");
		}

		private static void CheckMaskManTrigger(string source)
		{
			try
			{
				TimeOfDay instance = TimeOfDay.Instance;
				int num = (((Object)(object)instance != (Object)null) ? instance.timesFulfilledQuota : (-1));
				bool flag = false;
				try
				{
					string text = GameNetworkManager.Instance?.currentSaveFileName;
					if (!string.IsNullOrEmpty(text))
					{
						flag = ES3.Load<bool>("Y4NGZ_MaskManFired", text, false);
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[LGUMonitorTakeover] Failed to read Y4NGZ_MaskManFired from save: " + ex.Message));
				}
				Plugin.Log.LogInfo((object)($"[LGUMonitorTakeover] MaskMan check ({source}): timesFulfilledQuota={num} " + $"alreadyFiredThisSave={flag}"));
				if ((Object)(object)instance != (Object)null && num == 3 && !flag)
				{
					Plugin.MaskManPending = true;
					Plugin.QuotaJustCompleted = false;
					Plugin.Log.LogInfo((object)"[LGUMonitorTakeover] Quota 3 completed — Mask Man takeover queued (one-shot per save). Y4NGZ takeover suppressed for this orbit.");
				}
			}
			catch (Exception ex2)
			{
				Plugin.Log.LogWarning((object)("[LGUMonitorTakeover] CheckMaskManTrigger (" + source + ") failed: " + ex2.Message));
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "SetShipReadyToLand")]
		[HarmonyPostfix]
		private static void OnSetShipReadyToLand(StartOfRound __instance)
		{
			MonitorDebugger.DumpAll();
			if (Plugin.MaskManPending)
			{
				Plugin.MaskManPending = false;
				TakeoverManager.EnsureInstance();
				if ((Object)(object)TakeoverManager.Instance != (Object)null)
				{
					Plugin.Log.LogInfo((object)"[LGUMonitorTakeover] Ship reached orbit. Starting MASK MAN takeover.");
					TakeoverManager.Instance.BeginMaskManTakeover();
				}
			}
			else if (Plugin.QuotaJustCompleted)
			{
				Plugin.QuotaJustCompleted = false;
				TakeoverManager.EnsureInstance();
				if ((Object)(object)TakeoverManager.Instance != (Object)null)
				{
					Plugin.Log.LogInfo((object)"[LGUMonitorTakeover] Ship reached orbit. Starting takeover coroutine.");
					TakeoverManager.Instance.BeginTakeover();
				}
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "Disconnect")]
		[HarmonyPostfix]
		private static void OnDisconnect()
		{
			TakeoverManager.Instance?.ForceRestore("disconnect");
		}

		[HarmonyPatch(typeof(StartOfRound), "ShipLeave")]
		[HarmonyPostfix]
		private static void OnShipLeave()
		{
			TakeoverManager.Instance?.ForceRestore("ShipLeave");
		}

		[HarmonyPatch(typeof(StartOfRound), "ShipLeaveAutomatically")]
		[HarmonyPostfix]
		private static void OnShipLeaveAutomatically()
		{
			TakeoverManager.Instance?.ForceRestore("ShipLeaveAutomatically");
		}
	}
	[BepInPlugin("com.y4ngz.lgumonitortakeover", "LGUMonitorTakeover", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "com.y4ngz.lgumonitortakeover";

		public const string PLUGIN_NAME = "LGUMonitorTakeover";

		public const string PLUGIN_VERSION = "1.0.0";

		internal static ManualLogSource Log;

		internal static bool QuotaJustCompleted = false;

		internal static bool MaskManPending = false;

		internal static VideoClip TakeoverVideoClip;

		internal static AudioClip[] MumbleClips = Array.Empty<AudioClip>();

		internal static AudioClip AlarmClip;

		internal static VideoClip MaskManVideoClip;

		internal static AudioClip MaskManAudioClip;

		internal static ConfigEntry<bool> CfgEnabled;

		internal static ConfigEntry<float> CfgTakeoverDuration;

		internal static ConfigEntry<float> CfgOrbitDelay;

		internal static ConfigEntry<float> CfgMumbleVolume;

		internal static ConfigEntry<float> CfgTypewriterSpeed;

		internal static ConfigEntry<bool> CfgHideHUD;

		internal static ConfigEntry<bool> CfgDimLights;

		internal static ConfigEntry<float> CfgLightDimIntensity;

		internal static ConfigEntry<bool> CfgOverrideFifthMonitor;

		internal static ConfigEntry<float> CfgMaskManTailBuffer;

		private Harmony _harmony;

		internal static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			BindConfig();
			if (!CfgEnabled.Value)
			{
				Log.LogInfo((object)"LGUMonitorTakeover v1.0.0 — disabled via config.");
				return;
			}
			if (!LoadBundle())
			{
				Log.LogError((object)"Asset bundle failed to load — mod is disabled.");
				((Behaviour)this).enabled = false;
				return;
			}
			_harmony = new Harmony("com.y4ngz.lgumonitortakeover");
			_harmony.PatchAll(typeof(Patches));
			Log.LogInfo((object)("LGUMonitorTakeover v1.0.0 loaded. Video: " + (((Object)(object)TakeoverVideoClip != (Object)null) ? "OK" : "MISSING") + ", " + $"Mumble clips: {MumbleClips.Length}/5, " + "MaskManVideo: " + (((Object)(object)MaskManVideoClip != (Object)null) ? "OK" : "MISSING") + ", MaskManAudio: " + (((Object)(object)MaskManAudioClip != (Object)null) ? "OK" : "MISSING")));
		}

		private void BindConfig()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Expected O, but got Unknown
			CfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Enabled", true, "Master toggle. Set to false to completely disable the mod.");
			CfgTakeoverDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Takeover Duration", 11f, "Total seconds the monitor takeover lasts before reverting to normal.");
			CfgOrbitDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Orbit Delay", 4f, "Seconds to wait after the ship enters orbit before starting the takeover.");
			CfgMumbleVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Mumble Volume", 0.6f, new ConfigDescription("Volume of Y4NGZ mumble audio (0 = silent, 1 = full).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			CfgTypewriterSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Typewriter Speed", 0.026f, "Seconds between characters in the typewriter dialogue effect. Lower = faster. Default 0.026 reveals the longest dialogue ~2s before sequence ends.");
			CfgHideHUD = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Hide HUD", true, "Hide all player HUD elements during the takeover.");
			CfgDimLights = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Dim Lights", true, "Dim ship interior lights during the takeover.");
			CfgLightDimIntensity = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Light Dim Intensity", 0.12f, new ConfigDescription("How dim the ship lights go (fraction of original intensity). Lower = darker.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			CfgOverrideFifthMonitor = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Override Fifth Monitor", true, "If true, any additional MeshRenderer under MonitorWall beyond the four known monitor meshes is also overridden during takeover (catches small side screens).");
			CfgMaskManTailBuffer = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Mask Man Tail Buffer", 1.5f, new ConfigDescription("Seconds of held-on-monitor time after the Mask Man audio clip finishes before restoring.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
		}

		private bool LoadBundle()
		{
			try
			{
				string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "monitortakeover.lethalbundle");
				if (!File.Exists(text))
				{
					Log.LogError((object)("Bundle not found: " + text));
					Log.LogError((object)"Deploy monitortakeover.lethalbundle alongside LGUMonitorTakeover.dll.");
					return false;
				}
				AssetBundle val = AssetBundle.LoadFromFile(text);
				if ((Object)(object)val == (Object)null)
				{
					Log.LogError((object)"AssetBundle.LoadFromFile returned null (corrupt bundle?).");
					return false;
				}
				try
				{
					string[] allAssetNames = val.GetAllAssetNames();
					Log.LogInfo((object)$"[LGUMonitorTakeover] Bundle asset dump: {allAssetNames.Length} entries.");
					string[] array = allAssetNames;
					foreach (string text2 in array)
					{
						Log.LogInfo((object)("[LGUMonitorTakeover]   asset: " + text2));
					}
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("[LGUMonitorTakeover] Bundle asset dump failed: " + ex.Message));
				}
				TakeoverVideoClip = val.LoadAsset<VideoClip>("y4ngz_monitor_takeover");
				if ((Object)(object)TakeoverVideoClip == (Object)null)
				{
					Log.LogWarning((object)"Could not load 'y4ngz_monitor_takeover' from bundle. Monitors will go dark instead of showing video.");
				}
				List<AudioClip> list = new List<AudioClip>();
				for (int j = 1; j <= 5; j++)
				{
					AudioClip val2 = val.LoadAsset<AudioClip>($"mumble_0{j}");
					if ((Object)(object)val2 != (Object)null)
					{
						list.Add(val2);
					}
					else
					{
						Log.LogWarning((object)$"Could not load 'mumble_0{j}' from bundle.");
					}
				}
				MumbleClips = list.ToArray();
				AlarmClip = val.LoadAsset<AudioClip>("alarm_takeover");
				if ((Object)(object)AlarmClip == (Object)null)
				{
					Log.LogInfo((object)"Bundle has no 'alarm_takeover' clip — TakeoverManager will fall back to an in-game alarm. (TODO: ship a dedicated takeover alarm asset.)");
				}
				MaskManVideoClip = val.LoadAsset<VideoClip>("mask_man_video");
				if ((Object)(object)MaskManVideoClip == (Object)null)
				{
					Log.LogWarning((object)"Could not load 'mask_man_video' from bundle — Mask Man takeover will be skipped. Verify the exact asset name from the bundle dump above.");
				}
				MaskManAudioClip = val.LoadAsset<AudioClip>("mask_man_audio");
				if ((Object)(object)MaskManAudioClip == (Object)null)
				{
					Log.LogWarning((object)"Could not load 'mask_man_audio' from bundle — Mask Man takeover will be skipped. Verify the exact asset name from the bundle dump above.");
				}
				val.Unload(false);
				Log.LogInfo((object)"Bundle loaded successfully.");
				return true;
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Exception loading bundle: {arg}");
				return false;
			}
		}
	}
	internal class TakeoverManager : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <BlitMapScreenLoop>d__71 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TakeoverManager <>4__this;

			private WaitForEndOfFrame <eof>5__2;

			private bool <logged>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <BlitMapScreenLoop>d__71(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<eof>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Expected O, but got Unknown
				int num = <>1__state;
				TakeoverManager takeoverManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<eof>5__2 = new WaitForEndOfFrame();
					<logged>5__3 = false;
					break;
				case 1:
					<>1__state = -1;
					if (!<logged>5__3)
					{
						Plugin.Log.LogInfo((object)($"[Diag/Blit] first blit: src=_renderTexture(id={((Object)takeoverManager._renderTexture).GetInstanceID()} {((Texture)takeoverManager._renderTexture).width}x{((Texture)takeoverManager._renderTexture).height}) " + $"dst=_mapScreenRT(id={((Object)takeoverManager._mapScreenRT).GetInstanceID()} {((Texture)takeoverManager._mapScreenRT).width}x{((Texture)takeoverManager._mapScreenRT).height})"));
						<logged>5__3 = true;
					}
					try
					{
						Graphics.Blit((Texture)(object)takeoverManager._renderTexture, takeoverManager._mapScreenRT);
					}
					catch
					{
					}
					break;
				}
				if (takeoverManager._takeoverActive && (Object)(object)takeoverManager._mapScreenRT != (Object)null && (Object)(object)takeoverManager._renderTexture != (Object)null)
				{
					<>2__current = <eof>5__2;
					<>1__state = 1;
					return true;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <CRTTransition>d__75 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TakeoverManager <>4__this;

			private Texture2D <white>5__2;

			private Texture2D <black>5__3;

			private Texture2D <noise>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CRTTransition>d__75(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<white>5__2 = null;
				<black>5__3 = null;
				<noise>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0111: Unknown result type (might be due to invalid IL or missing references)
				//IL_011b: Expected O, but got Unknown
				//IL_013d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0147: Expected O, but got Unknown
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ef: Expected O, but got Unknown
				int num = <>1__state;
				TakeoverManager takeoverManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if ((Object)(object)takeoverManager._dialogueCanvasGO != (Object)null)
					{
						Object.Destroy((Object)(object)takeoverManager._dialogueCanvasGO);
						takeoverManager._dialogueCanvasGO = null;
					}
					if ((Object)(object)takeoverManager._mumbleSource != (Object)null)
					{
						takeoverManager._mumbleSource.Stop();
					}
					if ((Object)(object)takeoverManager._alarmSource != (Object)null)
					{
						takeoverManager._alarmSource.Stop();
					}
					if ((Object)(object)takeoverManager._droneSource != (Object)null)
					{
						takeoverManager._droneSource.Stop();
					}
					<white>5__2 = CreateSolidTexture(Color.white);
					<black>5__3 = CreateSolidTexture(Color.black);
					<noise>5__4 = CreateNoiseTexture(256, 256);
					takeoverManager.PlayStaticBurst();
					takeoverManager.SetAllMonitorTexture((Texture)(object)<white>5__2);
					<>2__current = (object)new WaitForSeconds(0.06f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					takeoverManager.SetAllMonitorTexture((Texture)(object)<noise>5__4);
					<>2__current = (object)new WaitForSeconds(0.25f);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					takeoverManager.SetAllMonitorTexture((Texture)(object)<black>5__3);
					<>2__current = (object)new WaitForSeconds(0.15f);
					<>1__state = 3;
					return true;
				case 3:
					<>1__state = -1;
					Object.Destroy((Object)(object)<white>5__2, 5f);
					Object.Destroy((Object)(object)<black>5__3, 5f);
					Object.Destroy((Object)(object)<noise>5__4, 5f);
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <DiagRTReadbackAfterDelay>d__62 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public float delay;

			public TakeoverManager <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DiagRTReadbackAfterDelay>d__62(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Expected O, but got Unknown
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Expected O, but got Unknown
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Expected O, but got Unknown
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0108: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0146: Unknown result type (might be due to invalid IL or missing references)
				//IL_012a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0154: Unknown result type (might be due to invalid IL or missing references)
				//IL_0138: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_0162: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				TakeoverManager takeoverManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(delay);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)takeoverManager._renderTexture == (Object)null)
					{
						Plugin.Log.LogInfo((object)"[Diag/RT] readback: _renderTexture is null");
						return false;
					}
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					try
					{
						RenderTexture active = RenderTexture.active;
						RenderTexture.active = takeoverManager._renderTexture;
						Texture2D val = new Texture2D(4, 4, (TextureFormat)3, false);
						val.ReadPixels(new Rect(0f, 0f, 4f, 4f), 0, 0);
						val.Apply();
						RenderTexture.active = active;
						Color val2 = Color.black;
						Color[] pixels = val.GetPixels();
						Color[] array = pixels;
						foreach (Color val3 in array)
						{
							val2 += val3;
						}
						val2 /= (float)pixels.Length;
						Object.Destroy((Object)(object)val);
						string text = ((val2.r > 0.9f && val2.g > 0.9f && val2.b > 0.9f) ? "WHITE (RT empty — video not decoding)" : ((val2.r < 0.05f && val2.g < 0.05f && val2.b < 0.05f) ? "BLACK (RT cleared/uninitialized)" : "HAS COLOR (video decoding into RT)"));
						Plugin.Log.LogInfo((object)$"[Diag/RT] readback at t={delay}s: avg=({val2.r:F3},{val2.g:F3},{val2.b:F3}) — {text}");
					}
					catch (Exception ex)
					{
						Plugin.Log.LogWarning((object)("[Diag/RT] readback failed: " + ex.Message));
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <DiagVideoStateLoop>d__61 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TakeoverManager <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DiagVideoStateLoop>d__61(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0187: Unknown result type (might be due to invalid IL or missing references)
				//IL_0191: Expected O, but got Unknown
				int num = <>1__state;
				TakeoverManager takeoverManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if ((Object)(object)takeoverManager._videoPlayer == (Object)null)
					{
						return false;
					}
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (takeoverManager._takeoverActive && (Object)(object)takeoverManager._videoPlayer != (Object)null)
				{
					Plugin.Log.LogInfo((object)($"[Diag/Video] isPrepared={takeoverManager._videoPlayer.isPrepared} isPlaying={takeoverManager._videoPlayer.isPlaying} " + $"isPaused={takeoverManager._videoPlayer.isPaused} frame={takeoverManager._videoPlayer.frame}/{takeoverManager._videoPlayer.frameCount} " + string.Format("time={0:F2} clip='{1}' ", takeoverManager._videoPlayer.time, ((Object)(object)takeoverManager._videoPlayer.clip != (Object)null) ? ((Object)takeoverManager._videoPlayer.clip).name : "null") + "url='" + takeoverManager._videoPlayer.url + "' targetTex-id=" + (((Object)(object)takeoverManager._videoPlayer.targetTexture != (Object)null) ? ((Object)takeoverManager._videoPlayer.targetTexture).GetInstanceID().ToString() : "NULL") + " rt-id=" + (((Object)(object)takeoverManager._renderTexture != (Object)null) ? ((Object)takeoverManager._renderTexture).GetInstanceID().ToString() : "NULL")));
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <DimLights>d__44 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TakeoverManager <>4__this;

			private float <dimDuration>5__2;

			private float <elapsed>5__3;

			private float <target>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DimLights>d__44(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0137: Unknown result type (might be due to invalid IL or missing references)
				//IL_013c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_0163: Unknown result type (might be due to invalid IL or missing references)
				//IL_0165: Unknown result type (might be due to invalid IL or missing references)
				//IL_017c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0189: Unknown result type (might be due to invalid IL or missing references)
				//IL_0196: Unknown result type (might be due to invalid IL or missing references)
				//IL_019d: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				TakeoverManager takeoverManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					takeoverManager._savedLights.Clear();
					GameObject val = GameObject.Find("Environment/HangarShip") ?? GameObject.Find("HangarShip");
					Light[] array = (((Object)(object)val != (Object)null) ? val.GetComponentsInChildren<Light>(true) : Object.FindObjectsOfType<Light>());
					foreach (Light val2 in array)
					{
						if (!((Object)(object)val2 == (Object)null) && ((Component)val2).gameObject.activeInHierarchy)
						{
							takeoverManager._savedLights.Add((val2, val2.intensity, val2.color));
						}
					}
					takeoverManager.PlayAlarm();
					<dimDuration>5__2 = 1.5f;
					<elapsed>5__3 = 0f;
					<target>5__4 = Plugin.CfgLightDimIntensity.Value;
					break;
				}
				case 1:
					<>1__state = -1;
					break;
				}
				if (<elapsed>5__3 < <dimDuration>5__2)
				{
					<elapsed>5__3 += Time.deltaTime;
					float num2 = Mathf.SmoothStep(0f, 1f, <elapsed>5__3 / <dimDuration>5__2);
					foreach (var (val3, num3, val4) in takeoverManager._savedLights)
					{
						if (!((Object)(object)val3 == (Object)null))
						{
							val3.intensity = Mathf.Lerp(num3, num3 * <target>5__4, num2);
							val3.color = Color.Lerp(val4, new Color(Mathf.Min(val4.r + 0.15f, 1f), val4.g * 0.7f, val4.b * 0.7f, val4.a), num2);
						}
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <FlashLightsLoop>d__45 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TakeoverManager <>4__this;

			private float <halfPeriod>5__2;

			private bool <bright>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <FlashLightsLoop>d__45(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_006e: 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_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_0113: Expected O, but got Unknown
				//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				TakeoverManager takeoverManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<halfPeriod>5__2 = 1f / 6f;
					<bright>5__3 = false;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (takeoverManager._takeoverActive)
				{
					<bright>5__3 = !<bright>5__3;
					foreach (var (val, num2, val2) in takeoverManager._savedLights)
					{
						if (!((Object)(object)val == (Object)null))
						{
							if (<bright>5__3)
							{
								val.intensity = num2 * 0.6f;
								val.color = new Color(0.1f, 1f, 0.1f, val2.a);
							}
							else
							{
								val.intensity = num2 * 0.03f;
								val.color = new Color(0f, 0.4f, 0f, val2.a);
							}
						}
					}
					<>2__current = (object)new WaitForSeconds(<halfPeriod>5__2);
					<>1__state = 1;
					return true;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <MaskManSequence>d__43 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TakeoverManager <>4__this;

			private StartOfRound <sor>5__2;

			private float <duration>5__3;

			private float <elapsed>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <MaskManSequence>d__43(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<sor>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Expected O, but got Unknown
				//IL_0238: Unknown result type (might be due to invalid IL or missing references)
				//IL_023e: Expected O, but got Unknown
				//IL_0465: Unknown result type (might be due to invalid IL or missing references)
				//IL_046f: Expected O, but got Unknown
				//IL_0280: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				TakeoverManager takeoverManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					takeoverManager._takeoverActive = true;
					<>2__current = (object)new WaitForSeconds(Plugin.CfgOrbitDelay.Value);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)StartOfRound.Instance == (Object)null || !StartOfRound.Instance.inShipPhase)
					{
						takeoverManager._takeoverActive = false;
						takeoverManager._takeoverCoroutine = null;
						return false;
					}
					if ((Object)(object)Plugin.MaskManVideoClip == (Object)null || (Object)(object)Plugin.MaskManAudioClip == (Object)null)
					{
						Plugin.Log.LogError((object)"[TakeoverManager] MaskManSequence: assets null at runtime — aborting.");
						takeoverManager.RestoreAll(immediate: true);
						takeoverManager._takeoverActive = false;
						takeoverManager._takeoverCoroutine = null;
						return false;
					}
					<sor>5__2 = StartOfRound.Instance;
					if ((Object)(object)<sor>5__2.speakerAudioSource != (Object)null)
					{
						takeoverManager._savedSpeakerVolume = <sor>5__2.speakerAudioSource.volume;
						<sor>5__2.speakerAudioSource.volume = 0f;
						takeoverManager._speakerVolumeSaved = true;
					}
					<duration>5__3 = Plugin.MaskManAudioClip.length + Plugin.CfgMaskManTailBuffer.Value;
					<elapsed>5__4 = 0f;
					Plugin.Log.LogInfo((object)($"[TakeoverManager] MaskMan: duration={<duration>5__3:F2}s " + $"(audio={Plugin.MaskManAudioClip.length:F2}s + buffer={Plugin.CfgMaskManTailBuffer.Value:F2}s)."));
					takeoverManager.PlayPowerDownWhine();
					if (Plugin.CfgDimLights.Value)
					{
						<>2__current = ((MonoBehaviour)takeoverManager).StartCoroutine(takeoverManager.DimLights());
						<>1__state = 2;
						return true;
					}
					takeoverManager.PlayAlarm();
					goto IL_01e2;
				case 2:
					<>1__state = -1;
					takeoverManager._flashCoroutine = ((MonoBehaviour)takeoverManager).StartCoroutine(takeoverManager.FlashLightsLoop());
					goto IL_01e2;
				case 3:
				{
					<>1__state = -1;
					takeoverManager.OverrideMonitors();
					GameObject val = new GameObject("MaskMan_Audio");
					Object.DontDestroyOnLoad((Object)(object)val);
					takeoverManager._mumbleSource = val.AddComponent<AudioSource>();
					if ((Object)(object)<sor>5__2?.speakerAudioSource != (Object)null)
					{
						val.transform.position = ((Component)<sor>5__2.speakerAudioSource).transform.position;
					}
					else if ((Object)(object)<sor>5__2 != (Object)null)
					{
						val.transform.position = ((Component)<sor>5__2).transform.position;
					}
					takeoverManager._mumbleSource.spatialBlend = 0f;
					takeoverManager._mumbleSource.volume = 1f;
					takeoverManager._mumbleSource.loop = false;
					takeoverManager._mumbleSource.playOnAwake = false;
					takeoverManager._mumbleSource.PlayOneShot(Plugin.MaskManAudioClip);
					Plugin.Log.LogInfo((object)("[TakeoverManager] MaskMan: PlayOneShot '" + ((Object)Plugin.MaskManAudioClip).name + "' " + $"({Plugin.MaskManAudioClip.length:F2}s) isPlaying={takeoverManager._mumbleSource.isPlaying}."));
					try
					{
						string text = GameNetworkManager.Instance?.currentSaveFileName;
						if (!string.IsNullOrEmpty(text))
						{
							ES3.Save<bool>("Y4NGZ_MaskManFired", true, text);
							Plugin.Log.LogInfo((object)("[TakeoverManager] Persisted Y4NGZ_MaskManFired=true to save '" + text + "'."));
						}
						else
						{
							Plugin.Log.LogWarning((object)"[TakeoverManager] Could not persist Y4NGZ_MaskManFired — currentSaveFileName is null.");
						}
					}
					catch (Exception ex)
					{
						Plugin.Log.LogWarning((object)("[TakeoverManager] Failed to persist Y4NGZ_MaskManFired: " + ex.Message));
					}
					goto IL_03e4;
				}
				case 4:
					<>1__state = -1;
					goto IL_03e4;
				case 5:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)takeoverManager).StartCoroutine(takeoverManager.RestoreCoroutine());
					<>1__state = 6;
					return true;
				case 6:
					<>1__state = -1;
					takeoverManager._takeoverActive = false;
					takeoverManager._takeoverCoroutine = null;
					<>2__current = (object)new WaitForSeconds(1.5f);
					<>1__state = 7;
					return true;
				case 7:
					{
						<>1__state = -1;
						ConstellationBridgeReflection.TryShowConstellationNotification();
						return false;
					}
					IL_03e4:
					if (<elapsed>5__4 < <duration>5__3)
					{
						<elapsed>5__4 += Time.deltaTime;
						<>2__current = null;
						<>1__state = 4;
						return true;
					}
					if (takeoverManager._flashCoroutine != null)
					{
						((MonoBehaviour)takeoverManager).StopCoroutine(takeoverManager._flashCoroutine);
						takeoverManager._flashCoroutine = null;
					}
					<>2__current = ((MonoBehaviour)takeoverManager).StartCoroutine(takeoverManager.CRTTransition());
					<>1__state = 5;
					return true;
					IL_01e2:
					takeoverManager.StartDrone();
					if (Plugin.CfgHideHUD.Value)
					{
						takeoverManager.HideHUD();
					}
					OpenBodyCamsCompat.Suppress();
					takeoverManager.SetupVideoFor(Plugin.MaskManVideoClip, looping: true);
					<>2__current = ((MonoBehaviour)takeoverManager).StartCoroutine(takeoverManager.WaitForVideoPrepared());
					<>1__state = 3;
					return true;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <PlayMumbleSequence>d__72 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TakeoverManager <>4__this;

			private AudioClip <clip>5__2;

			private float <elapsed>5__3;

			private float <gap>5__4;

			private float <gapElapsed>5__5;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <PlayMumbleSequence>d__72(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<clip>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Expected O, but got Unknown
				//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0106: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				TakeoverManager takeoverManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					Plugin.Log.LogInfo((object)$"[TakeoverManager] PlayMumbleSequence: entered. MumbleClips.Length={Plugin.MumbleClips.Length}");
					if (Plugin.MumbleClips.Length == 0)
					{
						Plugin.Log.LogWarning((object)"[TakeoverManager] PlayMumbleSequence: no mumble clips loaded — yielding break.");
						return false;
					}
					StartOfRound instance = StartOfRound.Instance;
					if ((Object)(object)instance == (Object)null)
					{
						Plugin.Log.LogWarning((object)"[TakeoverManager] PlayMumbleSequence: StartOfRound.Instance is null — position will default.");
					}
					GameObject val = new GameObject("Y4NGZ_MumbleAudio");
					Object.DontDestroyOnLoad((Object)(object)val);
					takeoverManager._mumbleSource = val.AddComponent<AudioSource>();
					if ((Object)(object)takeoverManager._mumbleSource == (Object)null)
					{
						Plugin.Log.LogWarning((object)"[TakeoverManager] PlayMumbleSequence: AddComponent<AudioSource> returned null — abort.");
						return false;
					}
					if ((Object)(object)instance?.speakerAudioSource != (Object)null)
					{
						val.transform.position = ((Component)instance.speakerAudioSource).transform.position;
					}
					else if ((Object)(object)instance != (Object)null)
					{
						val.transform.position = ((Component)instance).transform.position;
					}
					takeoverManager._mumbleSource.spatialBlend = 0f;
					takeoverManager._mumbleSource.volume = Mathf.Min(Plugin.CfgMumbleVolume.Value * 1.6f, 1f);
					takeoverManager._mumbleSource.loop = false;
					takeoverManager._mumbleSource.playOnAwake = false;
					AudioHighPassFilter obj = val.AddComponent<AudioHighPassFilter>();
					obj.cutoffFrequency = 300f;
					obj.highpassResonanceQ = 1f;
					AudioLowPassFilter obj2 = val.AddComponent<AudioLowPassFilter>();
					obj2.cutoffFrequency = 2200f;
					obj2.lowpassResonanceQ = 1.5f;
					val.AddComponent<AudioDistortionFilter>().distortionLevel = 0.3f;
					Plugin.Log.LogInfo((object)($"[TakeoverManager] PlayMumbleSequence: source ready. spatial={takeoverManager._mumbleSource.spatialBlend:F2} " + $"vol={takeoverManager._mumbleSource.volume:F2} clips={Plugin.MumbleClips.Length}. Entering loop."));
					goto IL_0379;
				}
				case 1:
					<>1__state = -1;
					goto IL_0379;
				case 2:
					<>1__state = -1;
					goto IL_02da;
				case 3:
					{
						<>1__state = -1;
						goto IL_035c;
					}
					IL_035c:
					if (<gapElapsed>5__5 < <gap>5__4 && takeoverManager._takeoverActive)
					{
						<gapElapsed>5__5 += Time.deltaTime;
						<>2__current = null;
						<>1__state = 3;
						return true;
					}
					<clip>5__2 = null;
					goto IL_0379;
					IL_0379:
					if (!takeoverManager._takeoverActive || !((Object)(object)takeoverManager._mumbleSource != (Object)null) || Plugin.MumbleClips.Length == 0)
					{
						break;
					}
					<clip>5__2 = Plugin.MumbleClips[Random.Range(0, Plugin.MumbleClips.Length)];
					if ((Object)(object)<clip>5__2 == (Object)null)
					{
						Plugin.Log.LogWarning((object)"[TakeoverManager] PlayMumbleSequence: picked null clip — skipping frame.");
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					takeoverManager._mumbleSource.clip = <clip>5__2;
					takeoverManager._mumbleSource.Play();
					Plugin.Log.LogInfo((object)$"[TakeoverManager] PlayMumbleSequence: playing '{((Object)<clip>5__2).name}' ({<clip>5__2.length:F2}s) isPlaying={takeoverManager._mumbleSource.isPlaying}");
					<elapsed>5__3 = 0f;
					goto IL_02da;
					IL_02da:
					if (<elapsed>5__3 < <clip>5__2.length && takeoverManager._takeoverActive)
					{
						<elapsed>5__3 += Time.deltaTime;
						<>2__current = null;
						<>1__state = 2;
						return true;
					}
					if (!takeoverManager._takeoverActive || (Object)(object)takeoverManager._mumbleSource == (Object)null)
					{
						break;
					}
					<gap>5__4 = Random.Range(0.4f, 1.2f);
					<gapElapsed>5__5 = 0f;
					goto IL_035c;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <RestoreCoroutine>d__80 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TakeoverManager <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <RestoreCoroutine>d__80(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				TakeoverManager takeoverManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (Plugin.CfgDimLights.Value && takeoverManager._savedLights.Count > 0)
					{
						<>2__current = ((MonoBehaviour)takeoverManager).StartCoroutine(takeoverManager.RestoreLights());
						<>1__state = 1;
						return true;
					}
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				takeoverManager.RestoreAll(immediate: false);
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <RestoreLights>d__81 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TakeoverManager <>4__this;

			private List<(Light l, float curI, Color curC, float targI, Color targC)> <snapshot>5__2;

			private float <duration>5__3;

			private float <elapsed>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <RestoreLights>d__81(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<snapshot>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0050: 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_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_010c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0111: Unknown result type (might be due to invalid IL or missing references)
				//IL_011b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0120: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0140: Unknown result type (might be due to invalid IL or missing references)
				//IL_0142: Unknown result type (might be due to invalid IL or missing references)
				//IL_0146: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				TakeoverManager takeoverManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<snapshot>5__2 = new List<(Light, float, Color, float, Color)>();
					foreach (var (val, item, item2) in takeoverManager._savedLights)
					{
						if ((Object)(object)val != (Object)null)
						{
							<snapshot>5__2.Add((val, val.intensity, val.color, item, item2));
						}
					}
					<duration>5__3 = 1.5f;
					<elapsed>5__4 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<elapsed>5__4 < <duration>5__3)
				{
					<elapsed>5__4 += Time.deltaTime;
					float num2 = Mathf.SmoothStep(0f, 1f, <elapsed>5__4 / <duration>5__3);
					foreach (var (val2, num3, val3, num4, val4) in <snapshot>5__2)
					{
						if (!((Object)(object)val2 == (Object)null))
						{
							val2.intensity = Mathf.Lerp(num3, num4, num2);
							val2.color = Color.Lerp(val3, val4, num2);
						}
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				foreach (var (val5, _, _, intensity, color) in <snapshot>5__2)
				{
					if ((Object)(object)val5 != (Object)null)
					{
						val5.intensity = intensity;
						val5.color = color;
					}
				}
				takeoverManager._savedLights.Clear();
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <ShowDialogue>d__73 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TakeoverManager <>4__this;

			public string passage;

			private TextMeshProUGUI <tmp>5__2;

			private float <charDelay>5__3;

			private AudioClip <tickClip>5__4;

			private AudioSource <tickSrc>5__5;

			private string <built>5__6;

			private string <>7__wrap6;

			private int <>7__wrap7;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ShowDialogue>d__73(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<tmp>5__2 = null;
				<tickClip>5__4 = null;
				<tickSrc>5__5 = null;
				<built>5__6 = null;
				<>7__wrap6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Expected O, but got Unknown
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a8: Expected O, but got Unknown
				//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0158: Unknown result type (might be due to invalid IL or missing references)
				//IL_016d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0178: Unknown result type (might be due to invalid IL or missing references)
				//IL_0182: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b2: Expected O, but got Unknown
				//IL_029e: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a8: Expected O, but got Unknown
				int num = <>1__state;
				TakeoverManager takeoverManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					takeoverManager._dialogueCanvasGO = new GameObject("Y4NGZ_DialogueCanvas");
					Object.DontDestroyOnLoad((Object)(object)takeoverManager._dialogueCanvasGO);
					Canvas obj = takeoverManager._dialogueCanvasGO.AddComponent<Canvas>();
					obj.renderMode = (RenderMode)0;
					obj.sortingOrder = 500;
					CanvasScaler obj2 = takeoverManager._dialogueCanvasGO.AddComponent<CanvasScaler>();
					obj2.uiScaleMode = (ScaleMode)1;
					obj2.referenceResolution = new Vector2(1920f, 1080f);
					obj2.matchWidthOrHeight = 1f;
					takeoverManager._dialogueCanvasGO.AddComponent<GraphicRaycaster>();
					GameObject val = new GameObject("Y4NGZ_DialogueText");
					val.transform.SetParent(takeoverManager._dialogueCanvasGO.transform, false);
					<tmp>5__2 = val.AddComponent<TextMeshProUGUI>();
					((TMP_Text)<tmp>5__2).fontSize = 28f;
					((Graphic)<tmp>5__2).color = new Color(0f, 1f, 0.255f, 1f);
					((TMP_Text)<tmp>5__2).alignment = (TextAlignmentOptions)1026;
					((TMP_Text)<tmp>5__2).enableWordWrapping = true;
					((TMP_Text)<tmp>5__2).overflowMode = (TextOverflowModes)0;
					((TMP_Text)<tmp>5__2).text = "";
					AssignVanillaFont(<tmp>5__2);
					RectTransform rectTransform = ((TMP_Text)<tmp>5__2).rectTransform;
					rectTransform.anchorMin = new Vector2(0.1f, 0.02f);
					rectTransform.anchorMax = new Vector2(0.9f, 0.3f);
					rectTransform.offsetMin = Vector2.zero;
					rectTransform.offsetMax = Vector2.zero;
					<charDelay>5__3 = Plugin.CfgTypewriterSpeed.Value;
					<tickClip>5__4 = CreateTypewriterTick();
					GameObject val2 = new GameObject("Y4NGZ_TypewriterTick");
					val2.transform.SetParent(takeoverManager._dialogueCanvasGO.transform);
					<tickSrc>5__5 = val2.AddComponent<AudioSource>();
					<tickSrc>5__5.spatialBlend = 0f;
					<tickSrc>5__5.volume = 0.8f;
					<tickSrc>5__5.playOnAwake = false;
					<built>5__6 = "";
					<>7__wrap6 = passage;
					<>7__wrap7 = 0;
					goto IL_02c6;
				}
				case 1:
					<>1__state = -1;
					goto IL_02b8;
				case 2:
					{
						<>1__state = -1;
						break;
					}
					IL_02c6:
					if (<>7__wrap7 < <>7__wrap6.Length)
					{
						char c = <>7__wrap6[<>7__wrap7];
						if ((Object)(object)<tmp>5__2 == (Object)null)
						{
							return false;
						}
						<built>5__6 += c;
						((TMP_Text)<tmp>5__2).text = <built>5__6;
						if (!char.IsWhiteSpace(c))
						{
							if ((Object)(object)<tickSrc>5__5 != (Object)null)
							{
								<tickSrc>5__5.PlayOneShot(<tickClip>5__4);
							}
							<>2__current = (object)new WaitForSeconds(<charDelay>5__3);
							<>1__state = 1;
							return true;
						}
						goto IL_02b8;
					}
					<>7__wrap6 = null;
					break;
					IL_02b8:
					<>7__wrap7++;
					goto IL_02c6;
				}
				if ((Object)(object)takeoverManager._dialogueCanvasGO != (Object)null)
				{
					<>2__current = null;
					<>1__state = 2;
					return true;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <TakeoverSequence>d__42 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TakeoverManager <>4__this;

			private float <duration>5__2;

			private float <elapsed>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TakeoverSequence>d__42(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Expected O, but got Unknown
				//IL_041a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0424: Expected O, but got Unknown
				int num = <>1__state;
				TakeoverManager takeoverManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					takeoverManager._takeoverActive = true;
					<>2__current = (object)new WaitForSeconds(Plugin.CfgOrbitDelay.Value);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					if ((Object)(object)StartOfRound.Instance == (Object)null || !StartOfRound.Instance.inShipPhase)
					{
						takeoverManager._takeoverActive = false;
						return false;
					}
					StartOfRound instance = StartOfRound.Instance;
					if ((Object)(object)instance.speakerAudioSource != (Object)null)
					{
						takeoverManager._savedSpeakerVolume = instance.speakerAudioSource.volume;
						instance.speakerAudioSource.volume = 0f;
						takeoverManager._speakerVolumeSaved = true;
					}
					<duration>5__2 = Plugin.CfgTakeoverDuration.Value;
					<elapsed>5__3 = 0f;
					Plugin.Log.LogInfo((object)"[TakeoverManager] Seq: calling PlayPowerDownWhine.");
					takeoverManager.PlayPowerDownWhine();
					if (Plugin.CfgDimLights.Value)
					{
						<>2__current = ((MonoBehaviour)takeoverManager).StartCoroutine(takeoverManager.DimLights());
						<>1__state = 2;
						return true;
					}
					takeoverManager.PlayAlarm();
					goto IL_013f;
				}
				case 2:
					<>1__state = -1;
					takeoverManager._flashCoroutine = ((MonoBehaviour)takeoverManager).StartCoroutine(takeoverManager.FlashLightsLoop());
					goto IL_013f;
				case 3:
				{
					<>1__state = -1;
					ManualLogSource log = Plugin.Log;
					string[] obj = new string[6]
					{
						"[Diag/RT] at OverrideMonitors: _renderTexture id=",
						((Object)(object)takeoverManager._renderTexture != (Object)null) ? ((Object)takeoverManager._renderTexture).GetInstanceID().ToString() : "NULL",
						" VP.targetTexture id=",
						null,
						null,
						null
					};
					VideoPlayer videoPlayer = takeoverManager._videoPlayer;
					obj[3] = (((Object)(object)((videoPlayer != null) ? videoPlayer.targetTexture : null) != (Object)null) ? ((Object)takeoverManager._videoPlayer.targetTexture).GetInstanceID().ToString() : "NULL");
					obj[4] = " ";
					VideoPlayer videoPlayer2 = takeoverManager._videoPlayer;
					obj[5] = $"match={(Object)(object)((videoPlayer2 != null) ? videoPlayer2.targetTexture : null) == (Object)(object)takeoverManager._renderTexture}";
					log.LogInfo((object)string.Concat(obj));
					takeoverManager.OverrideMonitors();
					((MonoBehaviour)takeoverManager).StartCoroutine(takeoverManager.DiagVideoStateLoop());
					((MonoBehaviour)takeoverManager).StartCoroutine(takeoverManager.DiagRTReadbackAfterDelay(3f));
					Plugin.Log.LogInfo((object)"[TakeoverManager] Seq: starting PlayMumbleSequence coroutine.");
					((MonoBehaviour)takeoverManager).StartCoroutine(takeoverManager.PlayMumbleSequence());
					string passage = DialoguePool[Random.Range(0, DialoguePool.Length)];
					((MonoBehaviour)takeoverManager).StartCoroutine(takeoverManager.ShowDialogue(passage));
					goto IL_0399;
				}
				case 4:
					<>1__state = -1;
					goto IL_0399;
				case 5:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)takeoverManager).StartCoroutine(takeoverManager.RestoreCoroutine());
					<>1__state = 6;
					return true;
				case 6:
					<>1__state = -1;
					takeoverManager._takeoverActive = false;
					takeoverManager._takeoverCoroutine = null;
					<>2__current = (object)new WaitForSeconds(1.5f);
					<>1__state = 7;
					return true;
				case 7:
					{
						<>1__state = -1;
						ConstellationBridgeReflection.TryShowConstellationNotification();
						return false;
					}
					IL_0399:
					if (<elapsed>5__3 < <duration>5__2)
					{
						<elapsed>5__3 += Time.deltaTime;
						<>2__current = null;
						<>1__state = 4;
						return true;
					}
					if (takeoverManager._flashCoroutine != null)
					{
						((MonoBehaviour)takeoverManager).StopCoroutine(takeoverManager._flashCoroutine);
						takeoverManager._flashCoroutine = null;
					}
					<>2__current = ((MonoBehaviour)takeoverManager).StartCoroutine(takeoverManager.CRTTransition());
					<>1__state = 5;
					return true;
					IL_013f:
					Plugin.Log.LogInfo((object)"[TakeoverManager] Seq: calling StartDrone.");
					takeoverManager.StartDrone();
					Plugin.Log.LogInfo((object)("[TakeoverManager] Seq: StartDrone returned. _droneSource=" + (((Object)(object)takeoverManager._droneSource != (Object)null) ? "OK" : "NULL") + " clip=" + (((Object)(object)takeoverManager._droneSource != (Object)null && (Object)(object)takeoverManager._droneSource.clip != (Object)null) ? ((Object)takeoverManager._droneSource.clip).name : "<none>") + " " + $"isPlaying={(Object)(object)takeoverManager._droneSource != (Object)null && takeoverManager._droneSource.isPlaying}"));
					if (Plugin.CfgHideHUD.Value)
					{
						takeoverManager.HideHUD();
					}
					OpenBodyCamsCompat.Suppress();
					takeoverManager.SetupVideo();
					<>2__current = ((MonoBehaviour)takeoverManager).StartCoroutine(takeoverManager.WaitForVideoPrepared());
					<>1__state = 3;
					return true;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <VerifyOverridesAfterDelay>d__63 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TakeoverManager <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <VerifyOverridesAfterDelay>d__63(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Expected O, but got Unknown
				int num = <>1__state;
				TakeoverManager takeoverManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(2f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					foreach (var overriddenRenderer in takeoverManager._overriddenRenderers)
					{
						MeshRenderer item = overriddenRenderer.renderer;
						if (!((Object)(object)item == (Object)null))
						{
							Material material;
							try
							{
								material = ((Renderer)item).material;
							}
							catch
							{
								continue;
							}
							if (!((Object)(object)material == (Object)null))
							{
								Texture val = (material.HasProperty("_BaseColorMap") ? material.GetTexture("_BaseColorMap") : null);
								Texture val2 = (material.HasProperty("_EmissiveColorMap") ? material.GetTexture("_EmissiveColorMap") : null);
								Texture mainTexture = material.mainTexture;
								bool flag = (Object)(object)val == (Object)(object)takeoverManager._renderTexture;
								bool flag2 = (Object)(object)val2 == (Object)(object)takeoverManager._renderTexture;
								Plugin.Log.LogInfo((object)("[Diag/Post] '" + ((Object)((Component)item).gameObject).name + "' shader='" + ((Object)material.shader).name + "' " + string.Format("_BaseColorMap={0} (ours={1}) ", ((Object)(object)val != (Object)null) ? ((Object)val).name : "null", flag) + string.Format("_EmissiveColorMap={0} (ours={1}) ", ((Object)(object)val2 != (Object)null) ? ((Object)val2).name : "null", flag2) + "mainTex=" + (((Object)(object)mainTexture != (Object)null) ? ((Object)mainTexture).name : "null")));
							}
						}
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <WaitForVideoPrepared>d__59 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TakeoverManager <>4__this;

			private float <timeout>5__2;

			private float <elapsed>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WaitForVideoPrepared>d__59(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Expected O, but got Unknown
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Expected O, but got Unknown
				int num = <>1__state;
				TakeoverManager takeoverManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if ((Object)(object)takeoverManager._videoPlayer == (Object)null)
					{
						return false;
					}
					<timeout>5__2 = 4f;
					<elapsed>5__3 = 0f;
					goto IL_007e;
				case 1:
					<>1__state = -1;
					goto IL_007e;
				case 2:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 3;
					return true;
				case 3:
					{
						<>1__state = -1;
						return false;
					}
					IL_007e:
					if (!takeoverManager._videoPlayer.isPrepared && <elapsed>5__3 < <timeout>5__2)
					{
						<elapsed>5__3 += Time.deltaTime;
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					takeoverManager._videoPlayer.Play();
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 2;
					return true;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private Coroutine _takeoverCoroutine;

		private Coroutine _flashCoroutine;

		private bool _takeoverActive;

		private bool _profitTextWasEnabled;

		private bool _profitBGWasEnabled;

		private bool _deadlineTextWasEnabled;

		private bool _deadlineBGWasEnabled;

		private bool _levelDescWasEnabled;

		private VideoClip _savedVideoClip;

		private bool _savedVideoLooping;

		private bool _savedVideoPlaying;

		private readonly List<(MeshRenderer renderer, Texture originalTexture)> _overriddenRenderers = new List<(MeshRenderer, Texture)>();

		private readonly Dictionary<MeshRenderer, (bool overridden, Texture mainTex, Texture baseColor, Texture emissive, Color emissiveColor, bool hadEmissionKW, bool hadEmissiveMapKW)[]> _savedHDRPState = new Dictionary<MeshRenderer, (bool, Texture, Texture, Texture, Color, bool, bool)[]>();

		private readonly List<RawImage> _topMonitorOverlayImages = new List<RawImage>();

		private RawImage _videoReelRawImage;

		private Texture _savedVideoReelTexture;

		private readonly List<(CanvasGroup cg, float alpha, bool interact, bool raycast)> _savedHUDGroups = new List<(CanvasGroup, float, bool, bool)>();

		private readonly List<CanvasGroup> _addedHUDGroups = new List<CanvasGroup>();

		private readonly List<(GameObject go, bool wasActive)> _hiddenHotbarObjects = new List<(GameObject, bool)>();

		private RenderTexture _mapScreenRT;

		private Coroutine _mapBlitCoroutine;

		private readonly List<(Light light, float origIntensity, Color origColor)> _savedLights = new List<(Light, float, Color)>();

		private float _savedSpeakerVolume = 1f;

		private bool _speakerVolumeSaved;

		private readonly List<(Behaviour component, bool wasEnabled)> _disabledComponents = new List<(Behaviour, bool)>();

		private VideoPlayer _videoPlayer;

		private RenderTexture _renderTexture;

		private AudioSource _mumbleSource;

		private AudioSource _alarmSource;

		private AudioSource _droneSource;

		private GameObject _dialogueCanvasGO;

		private static readonly string[] DialoguePool = new string[21]
		{
			"First satisfactory output from this crew.\nClean execution. I had the over on you\nfinishing this one alive, paid out nicely.\nReinvesting immediately. I want you to know\nI don't celebrate. Celebration implies surprise.\nI'm not surprised. I'm confirmed.", "Consistent output. I respect the margins\non this run. Reminds me of when I wrote\nTech Talk — calculated, efficient, no wasted\nbars. Every word in that track had a function.\nEvery syllable was load-bearing. That's what\nI need from you. Load-bearing performance.\nNo filler. No ad-libs. Just execution.", "You're demonstrating real value. I moved\nsome numbers around on the back end,\nnothing you need to worry about. Just keep\nperforming. I restructured some of the internal\nmetrics to better reflect what I'm seeing out\nthere. Again, not your concern. Your concern\nis scrap. My concern is everything else.", "I was in New York closing something.\nCan't say what. Point is, I had action on\nfour different outcomes this week and every\nsingle one hit. You were one of them.\nCongratulations. I sat in a steakhouse in\nMurray Hill afterward and ate alone. Not\nbecause I had to. Because the booth across\nfrom me was occupied by a version of me\nwho didn't need to eat. We didn't speak.", "I want you to understand something.\nJuice WRLD recorded hundreds of songs that\nnever came out. Hundreds. That's not waste.\nThat's pipeline. You are pipeline. Keep moving.\nPeople called him prolific. I call him\noperationally sound. He understood throughput.\nMost artists don't. Most crews don't either.", "I've been running the numbers on crew\nsurvivability and I'll be honest, you're\noutperforming the model. I don't like when\nthings outperform the model. It means the\nmodel is wrong. I'll adjust. I've already\nstarted recalibrating. By tomorrow morning\nthe model will expect exactly what you\ndelivered today. You'll have to do better.\nThat's not a threat. That's forecasting.", "Wrote Bruises about a very specific feeling.\nNot pain exactly. More like the moment you\nrealize pain is just overhead. You account\nfor it. You build it into the forecast.\nQuota's done. People thought that song was\nabout a relationship. It was about depreciation.\nPhysical, emotional, structural. Everything\nbruises. The question is whether you write\nit off or capitalize it.", "I placed a parlay — crew survival, scrap\ntotal, and whether anyone would cry on the\nship. Two out of three hit. I won't say which\none missed. The book I use doesn't ask\nquestions. I like that about them. They\nunderstand that a bet is just a belief with\ncollateral. I believe in very specific things.\nYou should find that comforting.", "Took a red-eye to New York. Sat in a booth\nat a restaurant in Midtown for four hours.\nDidn't order anything. Waitress asked if I was\nokay. I said 'Yeah what.' She didn't ask again.\nGood trip overall. Flew back the same night.\nDidn't sleep. Wrote half a verse on the plane\nabout lunar rotation cycles. Scrapped it.\nToo honest.", "I'm going to be transparent with you\nbecause I think you've earned it. Magic Trik\nisn't about magic. It's about making people\nlook where you want them to look. That's all\nmanagement is. Misdirection with benefits.\nI learned that in New York. I learned it again\non Titan. Some lessons you have to learn in\ntwo places before they stick.",
			"I have a spreadsheet. You're on it.\nEveryone's on it. The columns are labeled\nbut I won't share what the labels mean.\nYour column is trending upward. Be grateful\nfor that. I update it manually. Not because\nI have to. The automation works fine. I just\nlike the feeling of typing the numbers myself.\nIt keeps me connected to the data. The data\nkeeps me connected to you.", "Juice never made it this far. Different\ncontext. But I think about it. I think about\nwhat it means to keep going past the point\nwhere someone else stopped. Not better.\nJust still here. Still filing. Still submitting.\nThere's a version of Rockstar Status I never\nreleased where the second verse is just me\nreading quarterly projections over an 808.\nIt goes harder than you'd think.", "I shorted three crews this cycle. Not yours.\nYours I'm long on. That's not loyalty.\nThat's positioning. Rockstar Status was about\npositioning. Nobody understood that. They\nheard the hook and thought it was about fame.\nIt was about leverage. Every bar in that song\nis a hedge against irrelevance. I don't write\nmusic. I write instruments. Financial ones.", "I stood in the ship hallway for forty-five\nminutes this morning. Not thinking. Not\nwaiting. Just auditing. Internally. Everything\nchecks out. Everything always checks out.\nThat's what concerns me. When the numbers\nare too clean it means something isn't being\nmeasured. I've started measuring things that\ndon't have units yet. I'll name the units later.\nOne of them might be named after you.", "Someone asked me what Y4NGZ stands for.\nI told them it doesn't stand for anything.\nThey said everything has to mean something.\nI fired them. Not from a job. Just in general.\nFrom everything. They still exist but in a\nreduced capacity. I think about that interaction\nwhen I'm trying to fall asleep. Not because\nit bothers me. Because it's the only thing\nthat's quiet enough.", "The line on the next quota is steep but\nI've seen your work and frankly the house\nis wrong. The house is always wrong.\nI am the house. I am wrong. This is fine.\nI built the odds myself. Used a model I wrote\non a napkin in JFK. The napkin is framed in\nmy studio now. It's the most important thing\nI've ever written and it's just numbers.", "New York again. Times Square. I looked up\nat one of those billboards and for a second\nit said something meant only for me. Then it\nwent back to normal. I placed a bet on whether\nit would happen again. It did. I'm up on the\nyear. I'm up on the lifetime. The problem is\nI don't know what I'm winning. The money goes\nsomewhere. I go somewhere. We never end up\nin the same place.", "I don't have anything to say right now.\nBut I'm choosing to be here. That's worse\nand I need you to understand that. Silence\nfrom me isn't empty. It's full. It's a room\nwith no furniture that still feels crowded.\nThat's what the next album sounds like.\nYou'll never hear it.", "The next song is called Margin Call.\nIt's three minutes of silence over an 808.\nThe silence is the point. The 808 is for the\nshareholders. I played it for someone once\nand they left the room. Not because it was\nbad. Because they understood it. Understanding\nis the most violent thing you can do to\na person.", "I ran the numbers on your life expectancy.\nBet the under. Nothing personal. Everything\npersonal. Quota's done. I have a policy of\nnever apologizing for a position I've taken.\nThe position is the apology. The odds are the\nexplanation. If you survive long enough I'll\nclose the bet at a loss and I will feel nothing\nabout it. That's not cold. That's solvent.",
			"Every moon is New York if you think about\nit long enough. I have thought about it long\nenough. The same grid. The same strangers.\nThe same feeling that you're being watched\nby something that doesn't care about you\nspecifically but cares about what you represent\nstatistically. I wrote a hook about it.\nIt goes hard. You'll never hear it."
		};

		private const float MinAlarmLength = 1f;

		internal static TakeoverManager Instance { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				ForceRestore("OnDestroy");
				Instance = null;
			}
		}

		internal static void EnsureInstance()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Instance != (Object)null))
			{
				new GameObject("Y4NGZ_TakeoverManager").AddComponent<TakeoverManager>();
			}
		}

		internal void BeginTakeover()
		{
			if (!_takeoverActive)
			{
				if (_takeoverCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(_takeoverCoroutine);
				}
				_takeoverCoroutine = ((MonoBehaviour)this).StartCoroutine(TakeoverSequence());
			}
		}

		internal void BeginMaskManTakeover()
		{
			if (_takeoverActive)
			{
				return;
			}
			if ((Object)(object)Plugin.MaskManVideoClip == (Object)null || (Object)(object)Plugin.MaskManAudioClip == (Object)null)
			{
				Plugin.Log.LogError((object)("[TakeoverManager] BeginMaskManTakeover: missing assets " + $"(video={(Object)(object)Plugin.MaskManVideoClip != (Object)null}, audio={(Object)(object)Plugin.MaskManAudioClip != (Object)null}). Aborting."));
				return;
			}
			if (_takeoverCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_takeoverCoroutine);
			}
			_takeoverCoroutine = ((MonoBehaviour)this).StartCoroutine(MaskManSequence());
		}

		internal void ForceRestore(string reason)
		{
			if (_takeoverActive)
			{
				Plugin.Log.LogInfo((object)("[TakeoverManager] ForceRestore: " + reason));
				if (_takeoverCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(_takeoverCoroutine);
					_takeoverCoroutine = null;
				}
				if (_flashCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(_flashCoroutine);
					_flashCoroutine = null;
				}
				RestoreAll(immediate: true);
			}
		}

		[IteratorStateMachine(typeof(<TakeoverSequence>d__42))]
		private IEnumerator TakeoverSequence()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TakeoverSequence>d__42(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<MaskManSequence>d__43))]
		private IEnumerator MaskManSequence()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <MaskManSequence>d__43(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<DimLights>d__44))]
		private IEnumerator DimLights()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DimLights>d__44(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<FlashLightsLoop>d__45))]
		private IEnumerator FlashLightsLoop()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FlashLightsLoop>d__45(0)
			{
				<>4__this = this
			};
		}

		private void PlayAlarm()
		{
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			AudioClip val = null;
			string text = null;
			if ((Object)(object)Plugin.AlarmClip != (Object)null)
			{
				val = Plugin.AlarmClip;
				text = "bundle:Y4NGZ_Klaxon";
				Plugin.Log.LogInfo((object)$"[TakeoverManager] PlayAlarm: using bundle clip '{((Object)val).name}' ({val.length:F2}s).");
			}
			else
			{
				AudioClip val2 = FindGameAlarmClip();
				if ((Object)(object)val2 != (Object)null && val2.length < 1f)
				{
					Plugin.Log.LogWarning((object)$"[TakeoverManager] PlayAlarm: rejecting scene clip '{((Object)val2).name}' ({val2.length:F2}s) — shorter than 1s threshold.");
					val2 = null;
				}
				if ((Object)(object)val2 != (Object)null)
				{
					val = val2;
					text = "scene:" + ((Object)val2).name;
					Plugin.Log.LogInfo((object)$"[TakeoverManager] PlayAlarm: using scene clip '{((Object)val2).name}' ({val2.length:F2}s).");
				}
				else
				{
					val = CreateKlaxonClip();
					text = "procedural";
					Plugin.Log.LogInfo((object)"[TakeoverManager] PlayAlarm: falling back to procedural klaxon.");
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[TakeoverManager] PlayAlarm: alarmClip null after fallback — aborting.");
				return;
			}
			Plugin.Log.LogInfo((object)("[TakeoverManager] Alarm source: " + ((Object)val).name + " (from " + text + ")"));
			StartOfRound instance = StartOfRound.Instance;
			Vector3 position = (((Object)(object)instance?.speakerAudioSource != (Object)null) ? ((Component)instance.speakerAudioSource).transform.position : (((Object)(object)instance != (Object)null) ? ((Component)instance).transform.position : Vector3.zero));
			GameObject val3 = new GameObject("Y4NGZ_Alarm");
			Object.DontDestroyOnLoad((Object)(object)val3);
			_alarmSource = val3.AddComponent<AudioSource>();
			((Component)_alarmSource).transform.position = position;
			_alarmSource.spatialBlend = 0f;
			_alarmSource.volume = 0.9f;
			_alarmSource.clip = val;
			_alarmSource.loop = true;
			_alarmSource.Play();
		}

		private static AudioClip FindGameAlarmClip()
		{
			Plugin.Log.LogInfo((object)"[TakeoverManager] FindGameAlarmClip: beginning scan.");
			try
			{
				AudioSource[] array = Resources.FindObjectsOfTypeAll<AudioSource>();
				Plugin.Log.LogInfo((object)$"[TakeoverManager]   scene AudioSources found: {array.Length}");
				int num = 0;
				AudioSource[] array2 = array;
				foreach (AudioSource val in array2)
				{
					if (!((Object)(object)val == (Object)null))
					{
						string text = (((Object)(object)val.clip != (Object)null) ? ((Object)val.clip).name : "<null>");
						float num2 = (((Object)(object)val.clip != (Object)null) ? val.clip.length : 0f);
						string text2 = (((Object)(object)((Component)val).gameObject != (Object)null) ? ((Object)((Component)val).gameObject).name : "<no-go>");
						Plugin.Log.LogInfo((object)$"[TakeoverManager]     AudioSource on '{text2}' clip='{text}' len={num2:F2}s spatial={val.spatialBlend:F2}");
						if (++num > 200)
						{
							Plugin.Log.LogInfo((object)"[TakeoverManager]     (truncated AudioSource list at 200)");
							break;
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[TakeoverManager] AudioSource dump failed: " + ex.Message));
			}
			AudioClip[] array3 = Resources.FindObjectsOfTypeAll<AudioClip>();
			Plugin.Log.LogInfo((object)$"[TakeoverManager]   loaded AudioClips found: {array3.Length}");
			string[] array4 = new string[9] { "ShipAlarmHornConstant", "0DaysLeftAlert", "DeadlineAlarm", "FireAlarm", "ShipAlarm", "RedAlarmSFX", "ShipAlarmSFX", "EjectAlarm", "ShipAlarmCord" };
			AudioClip[] array5;
			foreach (string text3 in array4)
			{
				array5 = array3;
				foreach (AudioClip val2 in array5)
				{
					if (!((Object)(object)val2 == (Object)null) && ((Object)val2).name.Equals(text3, StringComparison.OrdinalIgnoreCase))
					{
						if (!(val2.length < 1f))
						{
							Plugin.Log.LogInfo((object)$"[TakeoverManager]   exact MATCH '{((Object)val2).name}' ({val2.length:F2}s) via keyword '{text3}'.");
							return val2;
						}
						Plugin.Log.LogInfo((object)$"[TakeoverManager]   exact '{((Object)val2).name}' matched but rejected ({val2.length:F2}s < {1f:F2}s).");
					}
				}
			}
			Plugin.Log.LogInfo((object)"[TakeoverManager]   no exact match — falling to keyword search.");
			AudioClip val3 = null;
			string arg = null;
			array5 = array3;
			foreach (AudioClip val4 in array5)
			{
				if ((Object)(object)val4 == (Object)null || val4.length < 1f)
				{
					continue;
				}
				string text4 = ((Object)val4).name.ToLower();
				if (text4.Contains("chatter") || text4.Contains("foot") || text4.Contains("spot") || text4.Contains("siren") || text4.Contains("tentacle") || text4.Contains("insanity") || text4.Contains("bomb") || text4.Contains("lrad") || text4.Contains("extension") || text4.Contains("controller"))
				{
					continue;
				}
				string text5 = null;
				if (text4.Contains("alarm"))
				{
					text5 = "alarm";
				}
				else if (text4.Contains("klaxon"))
				{
					text5 = "klaxon";
				}
				else if (text4.Contains("eject"))
				{
					text5 = "eject";
				}
				else if (text4.Contains("alert"))
				{
					text5 = "alert";
				}
				else if (text4.Contains("emergency"))
				{
					text5 = "emergency";
				}
				if (text5 != null)
				{
					Plugin.Log.LogInfo((object)$"[TakeoverManager]   keyword candidate '{((Object)val4).name}' ({val4.length:F2}s) matched='{text5}'.");
					if ((Object)(object)val3 == (Object)null || val4.length > val3.length)
					{
						val3 = val4;
						arg = text5;
					}
				}
			}
			if ((Object)(object)val3 != (Object)null)
			{
				Plugin.Log.LogInfo((object)$"[TakeoverManager]   keyword WINNER '{((Object)val3).name}' ({val3.length:F2}s) via '{arg}'.");
				return val3;
			}
			Plugin.Log.LogWarning((object)"[TakeoverManager] FindGameAlarmClip: no suitable clip — caller will fall back.");
			return null;
		}

		private static AudioClip CreateKlaxonClip()
		{
			int num = 44100;
			float num2 = 0.5f;
			int num3 = (int)((float)num * num2);
			int num4 = 5;
			int num5 = num3 * num4;
			float[] array = new float[num5];
			float num6 = 0f;
			float num7 = 0f;
			for (int i = 0; i < num5; i++)
			{
				float num8 = (float)(i % num3) / (float)num3;
				float num9 = ((num8 < 0.5f) ? Mathf.Lerp(400f, 800f, num8 * 2f) : Mathf.Lerp(800f, 400f, (num8 - 0.5f) * 2f));
				num6 += num9 / (float)num;
				num7 += num9 * 2f / (float)num;
				float num10 = ((Mathf.Sin(num6 * 2f * MathF.PI) > 0f) ? 1f : (-1f));
				float num11 = Mathf.Sin(num7 * 2f * MathF.PI);
				float num12 = num10 * 0.6f + num11 * 0.25f;
				float num13 = (((float)i < (float)num * 0.0

LGUShop.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using InteractiveTerminalAPI.UI;
using InteractiveTerminalAPI.UI.Application;
using InteractiveTerminalAPI.UI.Cursor;
using InteractiveTerminalAPI.UI.Page;
using InteractiveTerminalAPI.UI.Screen;
using Microsoft.CodeAnalysis;
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("LGUShop")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8c5521e37f37e3d76518a16d04e5d1051842f105")]
[assembly: AssemblyProduct("LGUShop")]
[assembly: AssemblyTitle("LGUShop")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 LGUShop
{
	public class ShopItem
	{
		public string Name;

		public int Price;

		public TerminalKeyword BuyKeyword;

		public TerminalKeyword NounKeyword;

		public TerminalNode TriggerNode;

		public Item ItemAsset;

		public override string ToString()
		{
			return $"{Name} (${Price})";
		}
	}
	public static class ItemDiscovery
	{
		public static List<ShopItem> DiscoverItems(Terminal terminal)
		{
			List<ShopItem> list = new List<ShopItem>();
			if ((Object)(object)terminal == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"ItemDiscovery: terminal is null.");
				}
				return list;
			}
			TerminalKeyword val = ((IEnumerable<TerminalKeyword>)terminal.terminalNodes.allKeywords).FirstOrDefault((Func<TerminalKeyword, bool>)((TerminalKeyword k) => (Object)(object)k != (Object)null && k.isVerb && k.word == "buy"));
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"ItemDiscovery: 'buy' verb keyword not found.");
				}
				return list;
			}
			if (val.compatibleNouns == null)
			{
				return list;
			}
			CompatibleNoun[] compatibleNouns = val.compatibleNouns;
			foreach (CompatibleNoun val2 in compatibleNouns)
			{
				if ((Object)(object)val2?.noun == (Object)null || (Object)(object)val2.result == (Object)null)
				{
					continue;
				}
				TerminalKeyword noun = val2.noun;
				TerminalNode result = val2.result;
				if (result.itemCost <= 0 && result.buyItemIndex < 0)
				{
					continue;
				}
				Item val3 = null;
				if (result.buyItemIndex >= 0 && terminal.buyableItemsList != null && result.buyItemIndex < terminal.buyableItemsList.Length)
				{
					val3 = terminal.buyableItemsList[result.buyItemIndex];
				}
				string name = val3?.itemName ?? noun.word ?? "(unnamed)";
				int num = result.itemCost;
				if (num <= 0 && (Object)(object)val3 != (Object)null)
				{
					FieldInfo field = typeof(Item).GetField("creditsWorth", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field != null && field.GetValue(val3) is int num2)
					{
						num = num2;
					}
				}
				list.Add(new ShopItem
				{
					Name = name,
					Price = num,
					BuyKeyword = val,
					NounKeyword = noun,
					TriggerNode = result,
					ItemAsset = val3
				});
			}
			List<ShopItem> list2 = (from s in list
				group s by s.Name.ToLowerInvariant() into g
				select g.First() into s
				orderby s.Name
				select s).ToList();
			ManualLogSource log3 = Plugin.Log;
			if (log3 != null)
			{
				log3.LogInfo((object)$"ItemDiscovery: discovered {list2.Count} buyable items.");
			}
			return list2;
		}
	}
	internal class LGUShopApplication : PageApplication<CursorElement>
	{
		private List<ShopItem> _allItems;

		private Terminal _terminal;

		private bool _onMainMenu;

		public override void Initialization()
		{
			_terminal = Object.FindObjectOfType<Terminal>();
			_allItems = ItemDiscovery.DiscoverItems(_terminal);
			BuildMainCategoryScreen();
		}

		protected override void ScreenExit()
		{
			if (!_onMainMenu)
			{
				BuildMainCategoryScreen();
			}
			else
			{
				((TerminalApplication)this).ScreenExit();
			}
		}

		private void BuildMainCategoryScreen()
		{
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Expected O, but got Unknown
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Expected O, but got Unknown
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Expected O, but got Unknown
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Expected O, but got Unknown
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Expected O, but got Unknown
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Expected O, but got Unknown
			_onMainMenu = true;
			List<ShopCategory> activeCategories = Plugin.ShopCfg.GetActiveCategories();
			List<CursorElement> list = new List<CursorElement>();
			HashSet<string> assigned = new HashSet<string>();
			Dictionary<string, PageCursorElement<CursorElement>> dictionary = new Dictionary<string, PageCursorElement<CursorElement>>();
			foreach (ShopCategory cat in activeCategories)
			{
				List<ShopItem> list2 = (from it in _allItems
					where cat.Matches(it.Name)
					where !assigned.Contains(it.Name.ToLowerInvariant())
					select it).ToList();
				foreach (ShopItem item in list2)
				{
					assigned.Add(item.Name.ToLowerInvariant());
				}
				if (list2.Count != 0)
				{
					PageCursorElement<CursorElement> page = BuildCategoryPage(cat.DisplayName.Value, cat.Subtitle.Value, cat.Description.Value, list2);
					dictionary[cat.Name] = page;
					int count = list2.Count;
					list.Add(CursorElement.Create($"{cat.DisplayName.Value}  ({count})", cat.Description.Value + "\n ", (Action)delegate
					{
						OpenCategoryPage(page);
					}, (Func<CursorElement, bool>)null, true));
				}
			}
			if (Plugin.ShopCfg.ShowOtherCategory.Value)
			{
				List<ShopItem> list3 = _allItems.Where((ShopItem it) => !assigned.Contains(it.Name.ToLowerInvariant())).ToList();
				if (list3.Count > 0)
				{
					PageCursorElement<CursorElement> otherPage = BuildCategoryPage("OTHER", "UNCATEGORIZED", "Items not assigned to a defined category.", list3);
					list.Add(CursorElement.Create($"OTHER  ({list3.Count})", "Uncategorized items.\n ", (Action)delegate
					{
						OpenCategoryPage(otherPage);
					}, (Func<CursorElement, bool>)null, true));
				}
			}
			list.Add(CursorElement.Create("EXIT", "Close the shop.", (Action)delegate
			{
				Object.Destroy((Object)(object)InteractiveTerminalManager.Instance);
			}, (Func<CursorElement, bool>)null, true));
			CursorMenu<CursorElement> val = CursorMenu<CursorElement>.Create(0, '>', list.ToArray(), (Func<CursorElement, CursorElement, int>[])null);
			List<ITextElement> list4 = new List<ITextElement>
			{
				(ITextElement)new TextElement
				{
					Text = " "
				},
				(ITextElement)new TextElement
				{
					Text = $"   Credits: ${_terminal?.groupCredits ?? 0}"
				},
				(ITextElement)new TextElement
				{
					Text = " "
				}
			};
			if (Plugin.ShopCfg.ShowYangzFlavorText.Value)
			{
				list4.Add((ITextElement)new TextElement
				{
					Text = "   The Company appreciates your continued patronage."
				});
				list4.Add((ITextElement)new TextElement
				{
					Text = " "
				});
			}
			list4.Add((ITextElement)(object)val);
			BoxedScreen val2 = new BoxedScreen
			{
				Title = Plugin.ShopCfg.MainTitle.Value,
				elements = list4.ToArray()
			};
			base.currentPage = PageCursorElement<CursorElement>.Create(0, (IScreen[])(object)new IScreen[1] { (IScreen)val2 }, new BaseCursorMenu<CursorElement>[1] { (BaseCursorMenu<CursorElement>)(object)val });
			((BaseInteractiveApplication<CursorElement>)(object)this).currentCursorMenu = (BaseCursorMenu<CursorElement>)(object)val;
			((TerminalApplication)this).currentScreen = (IScreen)(object)val2;
		}

		protected override int GetEntriesPerPage<K>(K[] entries)
		{
			return Mathf.Max(1, Plugin.ShopCfg.ItemsPerPage.Value);
		}

		private void OpenCategoryPage(PageCursorElement<CursorElement> page)
		{
			_onMainMenu = false;
			base.currentPage = page;
			IScreen currentScreen = ((PageElement)page).GetCurrentScreen();
			BaseCursorMenu<CursorElement> currentCursorMenu = page.GetCurrentCursorMenu();
			((BaseInteractiveApplication<CursorElement>)(object)this).SwitchScreen(currentScreen, currentCursorMenu, false);
		}

		private PageCursorElement<CursorElement> BuildCategoryPage(string title, string subtitle, string description, List<ShopItem> items)
		{
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Expected O, but got Unknown
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Expected O, but got Unknown
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Expected O, but got Unknown
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Expected O, but got Unknown
			items = (from i in items
				orderby i.Price, i.Name
				select i).ToList();
			int num = Mathf.Max(1, Plugin.ShopCfg.ItemsPerPage.Value);
			int num2 = Mathf.Max(1, Mathf.CeilToInt((float)items.Count / (float)num));
			IScreen[] array = (IScreen[])(object)new IScreen[num2];
			BaseCursorMenu<CursorElement>[] array2 = new BaseCursorMenu<CursorElement>[num2];
			for (int j = 0; j < num2; j++)
			{
				int num3 = j * num;
				int count = Mathf.Min(num, items.Count - num3);
				List<ShopItem> list = items.Skip(num3).Take(count).ToList();
				CursorElement[] array3 = (CursorElement[])(object)new CursorElement[list.Count];
				for (int k = 0; k < list.Count; k++)
				{
					ShopItem captured = list[k];
					array3[k] = CursorElement.Create(FormatItemRow(captured), "", (Action)delegate
					{
						OpenItemConfirmation(captured);
					}, (Func<CursorElement, bool>)null, true);
				}
				CursorMenu<CursorElement> val = (CursorMenu<CursorElement>)(object)(array2[j] = (BaseCursorMenu<CursorElement>)(object)CursorMenu<CursorElement>.Create(0, '>', array3, (Func<CursorElement, CursorElement, int>[])null));
				int num4 = j;
				BoxedScreen val2 = new BoxedScreen();
				val2.Title = title + " :: " + subtitle;
				val2.elements = (ITextElement[])(object)new ITextElement[6]
				{
					(ITextElement)new TextElement
					{
						Text = " "
					},
					(ITextElement)new TextElement
					{
						Text = "   " + description
					},
					(ITextElement)new TextElement
					{
						Text = " "
					},
					(ITextElement)new TextElement
					{
						Text = $"   Credits: ${_terminal?.groupCredits ?? 0}    Page {j + 1}/{num2}"
					},
					(ITextElement)new TextElement
					{
						Text = " "
					},
					(ITextElement)val
				};
				array[num4] = (IScreen)(object)val2;
			}
			return PageCursorElement<CursorElement>.Create(0, array, array2);
		}

		private static string FormatItemRow(ShopItem item)
		{
			string arg = ((item.Name.Length > 28) ? item.Name.Substring(0, 28) : item.Name.PadRight(28));
			return $"  {arg}  ${item.Price}";
		}

		private void OpenItemConfirmation(ShopItem item)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//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_00b4: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			CursorElement[] array = (CursorElement[])(object)new CursorElement[2]
			{
				CursorElement.Create($"  Purchase  -  ${item.Price}", "", (Action)delegate
				{
					DoPurchase(item, 1);
				}, (Func<CursorElement, bool>)null, true),
				CursorElement.Create("  Cancel", "", (Action)delegate
				{
					BuildMainCategoryScreen();
				}, (Func<CursorElement, bool>)null, true)
			};
			CursorMenu<CursorElement> val = CursorMenu<CursorElement>.Create(0, '>', array, (Func<CursorElement, CursorElement, int>[])null);
			BoxedScreen val2 = new BoxedScreen();
			val2.Title = item.Name.ToUpperInvariant();
			val2.elements = (ITextElement[])(object)new ITextElement[6]
			{
				(ITextElement)new TextElement
				{
					Text = " "
				},
				(ITextElement)new TextElement
				{
					Text = "   Item: " + item.Name
				},
				(ITextElement)new TextElement
				{
					Text = $"   Price: ${item.Price}"
				},
				(ITextElement)new TextElement
				{
					Text = $"   Available credits: ${_terminal?.groupCredits ?? 0}"
				},
				(ITextElement)new TextElement
				{
					Text = " "
				},
				(ITextElement)val
			};
			BoxedScreen val3 = val2;
			((BaseInteractiveApplication<CursorElement>)(object)this).SwitchScreen((IScreen)(object)val3, (BaseCursorMenu<CursorElement>)(object)val, false);
		}

		private void DoPurchase(ShopItem item, int quantity)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Expected O, but got Unknown
			PurchaseFlow.PurchaseResult purchaseResult = PurchaseFlow.AttemptBuy(_terminal, item, quantity);
			string text = PurchaseFlow.ResultToText(purchaseResult, item, quantity);
			CursorMenu<CursorElement> val = CursorMenu<CursorElement>.Create(0, '>', (CursorElement[])(object)new CursorElement[2]
			{
				CursorElement.Create("  Continue Shopping", "", (Action)delegate
				{
					BuildMainCategoryScreen();
				}, (Func<CursorElement, bool>)null, true),
				CursorElement.Create("  Exit", "", (Action)delegate
				{
					Object.Destroy((Object)(object)InteractiveTerminalManager.Instance);
				}, (Func<CursorElement, bool>)null, true)
			}, (Func<CursorElement, CursorElement, int>[])null);
			BoxedScreen val2 = new BoxedScreen();
			val2.Title = ((purchaseResult == PurchaseFlow.PurchaseResult.Success) ? "TRANSACTION COMPLETE" : "TRANSACTION FAILED");
			val2.elements = (ITextElement[])(object)new ITextElement[6]
			{
				(ITextElement)new TextElement
				{
					Text = " "
				},
				(ITextElement)new TextElement
				{
					Text = "   " + text
				},
				(ITextElement)new TextElement
				{
					Text = " "
				},
				(ITextElement)new TextElement
				{
					Text = $"   Remaining credits: ${_terminal?.groupCredits ?? 0}"
				},
				(ITextElement)new TextElement
				{
					Text = " "
				},
				(ITextElement)val
			};
			BoxedScreen val3 = val2;
			((BaseInteractiveApplication<CursorElement>)(object)this).SwitchScreen((IScreen)(object)val3, (BaseCursorMenu<CursorElement>)(object)val, false);
		}
	}
	[BepInPlugin("com.y4ngz.lgushop", "LGUShop", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "com.y4ngz.lgushop";

		public const string PLUGIN_NAME = "LGUShop";

		public const string PLUGIN_VERSION = "1.0.0";

		internal static ManualLogSource Log;

		internal static Plugin Instance;

		internal static ShopConfig ShopCfg;

		internal static ConfigEntry<string> ShopKeywords;

		internal static ConfigEntry<bool> InterceptVanillaStore;

		private void Awake()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ShopKeywords = ((BaseUnityPlugin)this).Config.Bind<string>("Main", "ShopKeywords", "shop", "Comma-separated keywords that open the shop. Type any of these in the terminal to launch the interactive shop UI. Default: 'shop'. Note: do NOT add 'store' here unless you have disabled TerminalStuff's StorePlus, or both will conflict.");
			InterceptVanillaStore = ((BaseUnityPlugin)this).Config.Bind<bool>("Main", "InterceptVanillaStore", false, "If true, ALSO intercept the vanilla 'store' keyword. Recommended only when TerminalStuff's StorePlus (TerminalStorePlus = false) is disabled.");
			ShopCfg = new ShopConfig(((BaseUnityPlugin)this).Config);
			try
			{
				new Harmony("com.y4ngz.lgushop").PatchAll(typeof(Plugin).Assembly);
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Harmony patch failed: {arg}");
			}
			try
			{
				List<string> list = (from s in ShopKeywords.Value.Split(',')
					select s.Trim() into s
					where !string.IsNullOrEmpty(s)
					select s).ToList();
				if (InterceptVanillaStore.Value && !list.Contains("store"))
				{
					list.Add("store");
				}
				if (list.Count == 0)
				{
					Log.LogWarning((object)"No shop keywords configured; shop will not be reachable.");
				}
				else if (list.Count == 1)
				{
					InteractiveTerminalManager.RegisterApplication<LGUShopApplication>(list[0]);
					Log.LogInfo((object)("Registered shop on keyword '" + list[0] + "'."));
				}
				else
				{
					InteractiveTerminalManager.RegisterApplication<LGUShopApplication>(list.ToArray());
					Log.LogInfo((object)("Registered shop on keywords: " + string.Join(", ", list)));
				}
			}
			catch (Exception arg2)
			{
				Log.LogError((object)$"Failed to register shop application: {arg2}");
			}
			Log.LogInfo((object)"LGUShop v1.0.0 loaded.");
		}
	}
	public static class PurchaseFlow
	{
		public enum PurchaseResult
		{
			Success,
			NotEnoughCredits,
			DropshipFull,
			NoTerminal,
			UnknownError
		}

		public static PurchaseResult AttemptBuy(Terminal terminal, ShopItem item, int quantity = 1)
		{
			if ((Object)(object)terminal == (Object)null)
			{
				return PurchaseResult.NoTerminal;
			}
			if ((Object)(object)item?.TriggerNode == (Object)null)
			{
				return PurchaseResult.UnknownError;
			}
			int num = item.Price * quantity;
			if (terminal.groupCredits < num)
			{
				return PurchaseResult.NotEnoughCredits;
			}
			int num2 = terminal.orderedItemsFromTerminal?.Count ?? 0;
			try
			{
				_ = terminal.numberOfItemsInDropship;
			}
			catch
			{
			}
			if (num2 + quantity > 12 && num2 >= 12)
			{
				return PurchaseResult.DropshipFull;
			}
			try
			{
				for (int i = 0; i < quantity; i++)
				{
					terminal.orderedItemsFromTerminal.Add(item.TriggerNode.buyItemIndex);
				}
				terminal.groupCredits = Mathf.Max(0, terminal.groupCredits - num);
				terminal.SyncGroupCreditsServerRpc(terminal.groupCredits, terminal.numberOfItemsInDropship);
				return PurchaseResult.Success;
			}
			catch (Exception arg)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)$"PurchaseFlow.AttemptBuy failed: {arg}");
				}
				return PurchaseResult.UnknownError;
			}
		}

		public static string ResultToText(PurchaseResult result, ShopItem item, int quantity)
		{
			switch (result)
			{
			case PurchaseResult.Success:
				if (quantity != 1)
				{
					return $"Purchased: {quantity}x {item.Name} for ${item.Price * quantity}.";
				}
				return $"Purchased: {item.Name} for ${item.Price}.";
			case PurchaseResult.NotEnoughCredits:
				return "Insufficient credits to purchase " + item.Name + ".";
			case PurchaseResult.DropshipFull:
				return "Dropship is at maximum capacity.";
			case PurchaseResult.NoTerminal:
				return "Terminal not available.";
			default:
				return "Purchase failed.";
			}
		}
	}
	public class ShopConfig
	{
		public List<ShopCategory> Categories { get; }

		public ConfigEntry<string> CategoryOrder { get; }

		public ConfigEntry<bool> ShowOtherCategory { get; }

		public ConfigEntry<int> ItemsPerPage { get; }

		public ConfigEntry<string> MainTitle { get; }

		public ConfigEntry<bool> ShowYangzFlavorText { get; }

		public ShopConfig(ConfigFile config)
		{
			ItemsPerPage = config.Bind<int>("Display", "ItemsPerPage", 10, "How many items to show per scroll page within a category. Default: 10.");
			MainTitle = config.Bind<string>("Display", "MainTitle", "FORTUNE-93 // EMPLOYEE PROVISIONS", "Title shown at the top of the main category-picker screen.");
			ShowYangzFlavorText = config.Bind<bool>("Display", "ShowYangzFlavorText", true, "Show Y4NGZ flavor lines on the main screen and category descriptions.");
			ShowOtherCategory = config.Bind<bool>("Categories", "ShowOtherCategory", true, "Show an 'Other' category for items not matched by any defined category. If false, unmatched items are silently hidden — only useful if you've defined categories that cover everything.");
			CategoryOrder = config.Bind<string>("Categories", "CategoryOrder", "Tools,Combat,Utility,Cosmetic", "Comma-separated list of category names in display order. Each name listed here must have a matching `[Category.<Name>]` section below. Names not listed here won't appear in the shop.");
			Categories = new List<ShopCategory>();
			DefineCategory(config, "Tools", "STANDARD ISSUE", "Standard-issue gear. The Company expects these to be returned in working order.", "flashlight,pro-flashlight,walkie,walkie-talkie,shovel,extension ladder,boombox,radar-booster,radar booster");
			DefineCategory(config, "Combat", "OFFENSIVE LOADOUT", "Offensive equipment. Use of lethal force on hostile fauna is encouraged.", "stun grenade,zap gun,shotgun,kitchen knife,knife,yield sign,stop sign,gun");
			DefineCategory(config, "Utility", "AUXILIARY EQUIPMENT", "Mission-critical support gear. Item availability subject to clearance.", "jetpack,tzp-inhalant,tzp,inhalant,key,lockpicker,lockpick,spray paint,spraypaint,mapper");
			DefineCategory(config, "Cosmetic", "EMPLOYEE EXPRESSION", "Approved morale items. Limited stock. No refunds.", "suit,hat,cosmetic,clothing");
		}

		private void DefineCategory(ConfigFile config, string name, string subtitle, string description, string items)
		{
			string text = "Category." + name;
			ConfigEntry<bool> enabled = config.Bind<bool>(text, "Enabled", true, "Whether the " + name + " category should appear in the shop.");
			ConfigEntry<string> displayName = config.Bind<string>(text, "DisplayName", name.ToUpperInvariant(), "Text shown on the main category-picker screen.");
			ConfigEntry<string> subtitle2 = config.Bind<string>(text, "Subtitle", subtitle, "Header text shown when this category is open.");
			ConfigEntry<string> description2 = config.Bind<string>(text, "Description", description, "Flavor text shown on the category page.");
			ConfigEntry<string> itemNameMatches = config.Bind<string>(text, "ItemNameMatches", items, "Comma-separated list of substrings to match against item names. Case-insensitive. An item belongs to this category if its name contains any substring here. First-match-wins across categories — list more-specific items first within a single category, and order categories by specificity in CategoryOrder.");
			Categories.Add(new ShopCategory
			{
				Name = name,
				Enabled = enabled,
				DisplayName = displayName,
				Subtitle = subtitle2,
				Description = description2,
				ItemNameMatches = itemNameMatches
			});
		}

		public List<ShopCategory> GetActiveCategories()
		{
			List<string> list = (from s in CategoryOrder.Value.Split(',')
				select s.Trim() into s
				where !string.IsNullOrEmpty(s)
				select s).ToList();
			Dictionary<string, ShopCategory> dictionary = Categories.Where((ShopCategory c) => c.Enabled.Value).ToDictionary((ShopCategory c) => c.Name, (ShopCategory c) => c);
			List<ShopCategory> list2 = new List<ShopCategory>();
			foreach (string item in list)
			{
				if (dictionary.TryGetValue(item, out var value))
				{
					list2.Add(value);
				}
			}
			return list2;
		}
	}
	public class ShopCategory
	{
		public string Name;

		public ConfigEntry<bool> Enabled;

		public ConfigEntry<string> DisplayName;

		public ConfigEntry<string> Subtitle;

		public ConfigEntry<string> Description;

		public ConfigEntry<string> ItemNameMatches;

		public IEnumerable<string> GetMatchSubstrings()
		{
			return from s in ItemNameMatches.Value.Split(',')
				select s.Trim().ToLowerInvariant() into s
				where !string.IsNullOrEmpty(s)
				select s;
		}

		public bool Matches(string itemName)
		{
			if (string.IsNullOrEmpty(itemName))
			{
				return false;
			}
			string text = itemName.ToLowerInvariant();
			foreach (string matchSubstring in GetMatchSubstrings())
			{
				if (text.Contains(matchSubstring))
				{
					return true;
				}
			}
			return false;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LGUShop";

		public const string PLUGIN_NAME = "LGUShop";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}

LGUSportsbook.dll

Decompiled 4 days ago
using System;
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.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
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("LGUSportsbook")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8c5521e37f37e3d76518a16d04e5d1051842f105")]
[assembly: AssemblyProduct("LGUSportsbook")]
[assembly: AssemblyTitle("LGUSportsbook")]
[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 LGUSportsbook
{
	[BepInPlugin("com.y4ngz.lgusportsbook", "LGUSportsbook", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "com.y4ngz.lgusportsbook";

		public const string PLUGIN_NAME = "LGUSportsbook";

		public const string PLUGIN_VERSION = "0.1.0";

		private const string LETHAL_CASINO_GUID = "mrgrm7.LethalCasino";

		private const string BUNDLE_FILENAME = "sportsbook.lethalbundle";

		internal static ManualLogSource Log;

		public static AssetBundle SportsbookBundle;

		public static GameObject Y4NGZ_MarqueePrefab;

		public static GameObject SportsbookCounterPrefab;

		public static GameObject FrozenHoarderBugPrefab;

		private Harmony _harmony;

		internal static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			LoadBundle();
			NetcodeWeaver();
			_harmony = new Harmony("com.y4ngz.lgusportsbook");
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			Log.LogInfo((object)"LGUSportsbook 0.1.0 loaded.");
		}

		private void LoadBundle()
		{
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "sportsbook.lethalbundle");
			if (!File.Exists(text))
			{
				Log.LogError((object)("Bundle not found at " + text + ". Sign + counter visuals will be skipped."));
				return;
			}
			SportsbookBundle = AssetBundle.LoadFromFile(text);
			if ((Object)(object)SportsbookBundle == (Object)null)
			{
				Log.LogError((object)("Failed to load bundle: " + text));
				return;
			}
			Y4NGZ_MarqueePrefab = SportsbookBundle.LoadAsset<GameObject>("Y4NGZ_Marquee");
			SportsbookCounterPrefab = SportsbookBundle.LoadAsset<GameObject>("SportsbookCounter");
			FrozenHoarderBugPrefab = SportsbookBundle.LoadAsset<GameObject>("FrozenHoarderBug");
			if ((Object)(object)Y4NGZ_MarqueePrefab == (Object)null)
			{
				Log.LogWarning((object)"Y4NGZ_Marquee not found in bundle.");
			}
			if ((Object)(object)SportsbookCounterPrefab == (Object)null)
			{
				Log.LogWarning((object)"SportsbookCounter not found in bundle.");
			}
		}

		private static void NetcodeWeaver()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				MethodInfo[] methods = types[i].GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LGUSportsbook";

		public const string PLUGIN_NAME = "LGUSportsbook";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace LGUSportsbook.Patches
{
	[HarmonyPatch]
	internal static class CasinoBuildingPatch
	{
		private static readonly string[] LetterChildren = new string[6] { "LettersBulb01_C", "LettersBulb01_A (2)", "LettersBulb01_S", "LettersBulb01_I", "LettersBulb01_N", "LettersBulb01_O" };

		private static readonly Vector3 MarqueeLocalPos = new Vector3(-2.95f, 7.1f, 2.55f);

		private static readonly Quaternion MarqueeLocalRot = Quaternion.Euler(0f, 180f, 0f);

		private static readonly Vector3 MarqueeLocalScale = new Vector3(1.35f, 1.35f, 1.3f);

		private static readonly Vector3 CounterWorldPos = new Vector3(-12f, -2.53f, 13f);

		private static readonly Quaternion CounterWorldRot = Quaternion.Euler(0f, 90f, 0f);

		private static MethodBase TargetMethod()
		{
			return AccessTools.Method("LethalCasino.Custom.CasinoBuilding:Awake", (Type[])null, (Type[])null);
		}

		private static void Postfix(Component __instance)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = __instance.transform;
			string[] letterChildren = LetterChildren;
			foreach (string text in letterChildren)
			{
				Transform val = transform.Find(text);
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).gameObject.SetActive(false);
				}
				else
				{
					Plugin.Log.LogWarning((object)("CASINO letter not found: " + text));
				}
			}
			if ((Object)(object)Plugin.Y4NGZ_MarqueePrefab == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[LGUSportsbook] Y4NGZ_Marquee prefab not loaded, skipping marquee instantiation");
			}
			else
			{
				GameObject obj = Object.Instantiate<GameObject>(Plugin.Y4NGZ_MarqueePrefab, transform, false);
				obj.transform.localPosition = MarqueeLocalPos;
				obj.transform.localRotation = MarqueeLocalRot;
				obj.transform.localScale = MarqueeLocalScale;
				Plugin.Log.LogInfo((object)"[LGUSportsbook] Y4NGZ_Marquee instantiated at local (-2.95, 7.1, 2.55) rot (0, 180, 0) scale (1.35, 1.35, 1.3)");
			}
			if ((Object)(object)Plugin.SportsbookCounterPrefab != (Object)null)
			{
				GameObject obj2 = Object.Instantiate<GameObject>(Plugin.SportsbookCounterPrefab, transform);
				obj2.transform.localPosition = transform.InverseTransformPoint(CounterWorldPos);
				obj2.transform.localRotation = Quaternion.Inverse(transform.rotation) * CounterWorldRot;
				obj2.transform.localScale = Vector3.one;
			}
			else
			{
				Plugin.Log.LogWarning((object)"SportsbookCounterPrefab not loaded — skipping counter placement.");
			}
		}
	}
}
namespace LGUSportsbook.Components
{
	public class FrozenHoarderBug : MonoBehaviour
	{
	}
	public class SportsbookCounter : MonoBehaviour
	{
		private void Start()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			Transform val = ((Component)this).transform.Find("InteractTrigger");
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"SportsbookCounter: child 'InteractTrigger' not found.");
				return;
			}
			InteractTrigger component = ((Component)val).GetComponent<InteractTrigger>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.Log.LogWarning((object)"SportsbookCounter: 'InteractTrigger' GameObject has no InteractTrigger component.");
				return;
			}
			if (component.onInteract == null)
			{
				component.onInteract = new InteractEvent();
			}
			((UnityEvent<PlayerControllerB>)(object)component.onInteract).AddListener((UnityAction<PlayerControllerB>)OnInteract);
		}

		private void OnInteract(PlayerControllerB player)
		{
			if (!((Object)(object)player == (Object)null))
			{
				Plugin.Log.LogInfo((object)("[LGUSportsbook] Counter interacted by " + player.playerUsername));
			}
		}
	}
}

LGUTerminalBridge.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MoreShipUpgrades.API;
using MoreShipUpgrades.Managers;
using MoreShipUpgrades.UI.TerminalNodes;
using TerminalApi;
using TerminalApi.Classes;
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("LGUTerminalBridge")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8c5521e37f37e3d76518a16d04e5d1051842f105")]
[assembly: AssemblyProduct("LGUTerminalBridge")]
[assembly: AssemblyTitle("LGUTerminalBridge")]
[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 LGUTerminalBridge
{
	internal static class CompatibleNounHelper
	{
		internal static CompatibleNoun Create(TerminalKeyword noun, TerminalNode result)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			CompatibleNoun val = (CompatibleNoun)FormatterServices.GetUninitializedObject(typeof(CompatibleNoun));
			val.noun = noun;
			val.result = result;
			return val;
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyAfter(new string[] { "mrov.TerminalFormatter", "darmuh.TerminalStuff", "atomic.terminalapi", "com.malco.lethalcompany.moreshipupgrades" })]
	internal static class TerminalStartPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void Postfix(Terminal __instance)
		{
			Plugin.CachedTerminal = __instance;
			Plugin.Log.LogInfo((object)"Terminal reference cached.");
			try
			{
				BuildCustomNodesPatch.RegisterPendingKeywords();
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Deferred keyword registration error: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	[HarmonyAfter(new string[] { "mrov.TerminalFormatter", "darmuh.TerminalStuff", "atomic.terminalapi", "com.malco.lethalcompany.moreshipupgrades" })]
	internal static class LoadNewNodePatch
	{
		[HarmonyPatch("LoadNewNode")]
		[HarmonyPrefix]
		private static void Prefix(TerminalNode node)
		{
			try
			{
				foreach (KeyValuePair<string, TerminalNode> item in Plugin.NameToConfirmNode)
				{
					if (!((Object)(object)item.Value == (Object)(object)node))
					{
						continue;
					}
					string upgradeName = item.Key;
					CustomTerminalNode val = ((IEnumerable<CustomTerminalNode>)Plugin.SharedUpgradeNodes).FirstOrDefault((Func<CustomTerminalNode, bool>)((CustomTerminalNode n) => n.OriginalName == upgradeName || n.Name == upgradeName));
					if (val != null)
					{
						int currentPrice = val.GetCurrentPrice();
						string arg = "";
						if (val.MaxUpgrade > 0)
						{
							arg = $" (Tier {val.GetCurrentLevel()} -> {val.GetCurrentLevel() + 1})";
						}
						node.displayText = $"You are about to purchase: {val.Name}{arg}\nCost: ${currentPrice}\n\nPlease CONFIRM or DENY.\n\n";
					}
					break;
				}
			}
			catch (Exception arg2)
			{
				Plugin.Log.LogError((object)$"LoadNewNode prefix error: {arg2}");
			}
		}

		[HarmonyPatch("LoadNewNode")]
		[HarmonyPostfix]
		private static void Postfix(Terminal __instance, TerminalNode node)
		{
			try
			{
				if (Plugin.PurchaseNodeToName.TryGetValue(node, out var upgradeName))
				{
					CustomTerminalNode val = ((IEnumerable<CustomTerminalNode>)Plugin.SharedUpgradeNodes).FirstOrDefault((Func<CustomTerminalNode, bool>)((CustomTerminalNode n) => n.OriginalName == upgradeName || n.Name == upgradeName));
					if (val == null)
					{
						Plugin.Log.LogWarning((object)("Could not find upgrade node for '" + upgradeName + "'."));
					}
					else
					{
						ExecuteLGUPurchase(__instance, val, node);
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"LoadNewNode postfix error: {arg}");
			}
		}

		private static void ExecuteLGUPurchase(Terminal terminal, CustomTerminalNode upgradeNode, TerminalNode displayNode)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected I4, but got Unknown
			int currentPrice = upgradeNode.GetCurrentPrice();
			if (currentPrice == int.MaxValue)
			{
				displayNode.displayText = upgradeNode.Name + " is already at maximum level!\n\n";
				return;
			}
			bool flag = false;
			PurchaseMode purchaseMode = upgradeNode.PurchaseMode;
			switch ((int)purchaseMode)
			{
			case 1:
				if (terminal.groupCredits >= currentPrice)
				{
					terminal.groupCredits -= currentPrice;
					terminal.SyncGroupCreditsServerRpc(terminal.groupCredits, terminal.numberOfItemsInDropship);
					flag = true;
				}
				break;
			case 0:
				flag = true;
				break;
			case 2:
				if (terminal.groupCredits >= currentPrice)
				{
					terminal.groupCredits -= currentPrice;
					terminal.SyncGroupCreditsServerRpc(terminal.groupCredits, terminal.numberOfItemsInDropship);
				}
				flag = true;
				break;
			}
			if (!flag)
			{
				displayNode.displayText = $"You cannot afford {upgradeNode.Name}! (${currentPrice})\n\n";
				return;
			}
			UpgradeApi.TriggerUpgradeRankup(upgradeNode);
			string text = ((upgradeNode.MaxUpgrade > 0) ? $" to tier {upgradeNode.GetCurrentLevel()}" : "");
			displayNode.displayText = "Successfully purchased " + upgradeNode.Name + text + "!\n\n";
			Plugin.Log.LogInfo((object)$"Purchased LGU upgrade: {upgradeNode.Name} for ${currentPrice}");
		}
	}
	[HarmonyPatch(typeof(UpgradeBus), "BuildCustomNodes")]
	[HarmonyAfter(new string[] { "com.malco.lethalcompany.moreshipupgrades" })]
	internal static class BuildCustomNodesPatch
	{
		private static List<(CustomTerminalNode node, string keyName)> _pending = new List<(CustomTerminalNode, string)>();

		[HarmonyPostfix]
		private static void Postfix()
		{
			try
			{
				RefreshSharedUpgrades();
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"BuildCustomNodes postfix error: {arg}");
			}
		}

		private static void RefreshSharedUpgrades()
		{
			List<CustomTerminalNode> upgradeNodes = UpgradeApi.GetUpgradeNodes();
			if (upgradeNodes == null || upgradeNodes.Count == 0)
			{
				return;
			}
			Plugin.SharedUpgradeNodes.Clear();
			_pending.Clear();
			foreach (CustomTerminalNode item in upgradeNodes)
			{
				if (item.SharedUpgrade && item.Visible && (item.UnlockPrice > 0 || (item.Prices != null && item.Prices.Length != 0)))
				{
					Plugin.SharedUpgradeNodes.Add(item);
					item.Visible = false;
					string text = item.OriginalName ?? item.Name;
					if (!Plugin.RegisteredKeywords.Contains(text))
					{
						_pending.Add((item, text));
					}
				}
			}
			Plugin.Log.LogInfo((object)$"Refreshed {Plugin.SharedUpgradeNodes.Count} shared upgrades, {_pending.Count} pending.");
			if ((Object)(object)Plugin.CachedTerminal != (Object)null)
			{
				RegisterPendingKeywords();
			}
			else
			{
				Plugin.Log.LogInfo((object)"Terminal not ready. Keywords deferred to Terminal.Start.");
			}
			if (!Plugin.DarmuhPresent)
			{
				return;
			}
			try
			{
				StorePlusMenuPatch.AddLGUUpgradesToMenu();
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"StorePlus LGU push error: {arg}");
			}
		}

		internal static void RegisterPendingKeywords()
		{
			Terminal val = Plugin.CachedTerminal;
			if ((Object)(object)val == (Object)null)
			{
				val = Object.FindObjectOfType<Terminal>();
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
			}
			if (_pending.Count == 0)
			{
				return;
			}
			TerminalKeyword val2 = null;
			TerminalKeyword val3 = null;
			TerminalKeyword buyKw = null;
			if ((Object)(object)val.terminalNodes != (Object)null && val.terminalNodes.allKeywords != null)
			{
				TerminalKeyword[] allKeywords = val.terminalNodes.allKeywords;
				foreach (TerminalKeyword val4 in allKeywords)
				{
					if (val4.word == "confirm")
					{
						val2 = val4;
					}
					else if (val4.word == "deny")
					{
						val3 = val4;
					}
					else if (val4.word == "buy")
					{
						buyKw = val4;
					}
				}
			}
			if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
			{
				Plugin.Log.LogWarning((object)"confirm/deny keywords not found. Skipping.");
				return;
			}
			int num = 0;
			foreach (var (upgradeNode, text) in _pending)
			{
				if (!Plugin.RegisteredKeywords.Contains(text))
				{
					try
					{
						RegisterBuyKeyword(val, upgradeNode, text, val2, val3, buyKw);
						Plugin.RegisteredKeywords.Add(text);
						num++;
					}
					catch (Exception arg)
					{
						Plugin.Log.LogError((object)$"Failed to register '{text}': {arg}");
					}
				}
			}
			Plugin.Log.LogInfo((object)$"Registered {num} buy keywords.");
			_pending.Clear();
		}

		private static void RegisterBuyKeyword(Terminal terminal, CustomTerminalNode upgradeNode, string keyName, TerminalKeyword confirmKw, TerminalKeyword denyKw, TerminalKeyword buyKw)
		{
			string text = upgradeNode.Name.ToLowerInvariant().Replace(" ", "-");
			int currentPrice = upgradeNode.GetCurrentPrice();
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			val.displayText = "Purchased " + upgradeNode.Name + "!\n\n";
			val.clearPreviousText = true;
			val.maxCharactersToType = 25;
			Plugin.NameToPurchaseNode[keyName] = val;
			Plugin.PurchaseNodeToName[val] = keyName;
			TerminalNode val2 = ScriptableObject.CreateInstance<TerminalNode>();
			val2.displayText = "Cancelled order.\n\n";
			val2.clearPreviousText = true;
			TerminalNode val3 = ScriptableObject.CreateInstance<TerminalNode>();
			val3.displayText = $"You are about to purchase: {upgradeNode.Name}\nCost: ${currentPrice}\n\nPlease CONFIRM or DENY.\n\n";
			val3.clearPreviousText = true;
			val3.overrideOptions = true;
			val3.maxCharactersToType = 25;
			val3.itemCost = currentPrice;
			Plugin.NameToConfirmNode[keyName] = val3;
			val3.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2]
			{
				CompatibleNounHelper.Create(confirmKw, val),
				CompatibleNounHelper.Create(denyKw, val2)
			};
			TerminalKeyword val4 = TerminalApi.CreateTerminalKeyword(text, false, val3);
			if (!((Object)(object)val4 == (Object)null) && (Object)(object)buyKw != (Object)null)
			{
				CompatibleNoun[] compatibleNouns = buyKw.compatibleNouns;
				int num = ((compatibleNouns != null) ? compatibleNouns.Length : 0);
				CompatibleNoun[] array = (CompatibleNoun[])(object)new CompatibleNoun[num + 1];
				if (num > 0)
				{
					Array.Copy(compatibleNouns, array, num);
				}
				array[num] = CompatibleNounHelper.Create(val4, val3);
				buyKw.compatibleNouns = array;
				TerminalApi.AddTerminalKeyword(val4);
				Plugin.Log.LogInfo((object)("Registered buy keyword '" + text + "' for: " + upgradeNode.Name));
			}
		}
	}
	[HarmonyPatch]
	[HarmonyAfter(new string[] { "com.malco.lethalcompany.moreshipupgrades" })]
	internal static class ContractsPatch
	{
		private static bool Prepare()
		{
			return Chainloader.PluginInfos.ContainsKey("com.malco.lethalcompany.moreshipupgrades");
		}

		[HarmonyPatch(typeof(Terminal), "Start")]
		[HarmonyPostfix]
		[HarmonyPriority(200)]
		private static void TerminalStart_Postfix(Terminal __instance)
		{
			try
			{
				CleanContractsFromLGUHelp(__instance);
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Contracts cleanup error: {arg}");
			}
		}

		private static void CleanContractsFromLGUHelp(Terminal terminal)
		{
			if ((Object)(object)terminal.terminalNodes == (Object)null || terminal.terminalNodes.allKeywords == null)
			{
				return;
			}
			TerminalKeyword[] allKeywords = terminal.terminalNodes.allKeywords;
			foreach (TerminalKeyword val in allKeywords)
			{
				if (!(val.word == "lgu") || !((Object)(object)val.specialKeywordResult != (Object)null))
				{
					continue;
				}
				TerminalNode specialKeywordResult = val.specialKeywordResult;
				if (specialKeywordResult.displayText != null && specialKeywordResult.displayText.Contains("contract"))
				{
					string[] value = (from l in specialKeywordResult.displayText.Split('\n')
						where !l.ToLowerInvariant().Contains("contract")
						select l).ToArray();
					specialKeywordResult.displayText = string.Join("\n", value);
					Plugin.Log.LogInfo((object)"Removed contracts references from LGU help text.");
				}
				break;
			}
			Plugin.Log.LogInfo((object)"Contracts command verified as standalone.");
		}
	}
	[HarmonyPatch]
	[HarmonyAfter(new string[] { "darmuh.TerminalStuff", "com.malco.lethalcompany.moreshipupgrades", "atomic.terminalapi" })]
	internal static class StorePlusMenuPatch
	{
		private static Type t_StorePlus;

		private static Type t_StoreMenuItem;

		private static Type t_MenuItem;

		private static ConstructorInfo ctor_Name;

		private static ConstructorInfo ctor_Keyword;

		private static PropertyInfo p_Name;

		private static PropertyInfo p_NestedMenus;

		private static MethodInfo m_SetParentMenu;

		private static FieldInfo f_keyword;

		private static FieldInfo f_StoreItem;

		internal static object FurnitureMenu;

		internal static object ContractsMenu;

		private static object _theMainMenu;

		private static object _upgrades;

		private static object _buyables;

		private static object _vehicles;

		private static object _suits;

		private static bool _menusCreated;

		private static HashSet<string> _addedLGUKeywords = new HashSet<string>();

		private static bool Prepare()
		{
			if (!Chainloader.PluginInfos.ContainsKey("darmuh.TerminalStuff"))
			{
				return false;
			}
			t_StorePlus = AccessTools.TypeByName("TerminalStuff.StoreTweaks.StorePlus");
			t_StoreMenuItem = AccessTools.TypeByName("TerminalStuff.StoreTweaks.StoreMenuItem");
			if (t_StorePlus == null || t_StoreMenuItem == null)
			{
				Plugin.Log.LogWarning((object)"StorePlus types not found.");
				return false;
			}
			t_MenuItem = t_StoreMenuItem.BaseType;
			ctor_Name = t_StoreMenuItem.GetConstructor(new Type[1] { typeof(string) });
			ctor_Keyword = t_StoreMenuItem.GetConstructor(new Type[3]
			{
				typeof(string),
				typeof(string),
				t_MenuItem
			});
			p_Name = t_StoreMenuItem.GetProperty("Name") ?? t_MenuItem?.GetProperty("Name");
			p_NestedMenus = t_StoreMenuItem.GetProperty("NestedMenus") ?? t_MenuItem?.GetProperty("NestedMenus");
			m_SetParentMenu = t_MenuItem?.GetMethod("SetParentMenu", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { t_MenuItem }, null);
			f_keyword = AccessTools.Field(t_StoreMenuItem, "keyword");
			f_StoreItem = AccessTools.Field(t_StoreMenuItem, "StoreItem");
			if (ctor_Name == null || p_NestedMenus == null || m_SetParentMenu == null)
			{
				Plugin.Log.LogWarning((object)"Reflection incomplete. StorePlus patches disabled.");
				return false;
			}
			Plugin.Log.LogInfo((object)"StorePlus reflection targets resolved.");
			return true;
		}

		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(t_StorePlus, "GetStoreItems", (Type[])null, (Type[])null);
		}

		[HarmonyPostfix]
		private static void Postfix()
		{
			try
			{
				CacheStaticFields();
				if (!_menusCreated)
				{
					CreateMenuStructure();
					_menusCreated = true;
				}
				MoveFurnitureItems();
				RemoveLGUFromExternalMods();
				AddLGUUpgradesToMenu();
				ReorderMainMenu();
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"StorePlus restructure error: {arg}");
			}
		}

		private static void CacheStaticFields()
		{
			_theMainMenu = AccessTools.Field(t_StorePlus, "TheMainMenu")?.GetValue(null);
			_upgrades = AccessTools.Field(t_StorePlus, "Upgrades")?.GetValue(null);
			_buyables = AccessTools.Field(t_StorePlus, "Buyables")?.GetValue(null);
			_vehicles = AccessTools.Field(t_StorePlus, "Vehicles")?.GetValue(null);
			_suits = AccessTools.Field(t_StorePlus, "Suits")?.GetValue(null);
		}

		private static void CreateMenuStructure()
		{
			if (_theMainMenu != null && _upgrades != null)
			{
				p_Name?.SetValue(_upgrades, "Upgrades");
				FurnitureMenu = ctor_Name.Invoke(new object[1] { "Furniture" });
				m_SetParentMenu.Invoke(FurnitureMenu, new object[1] { _theMainMenu });
				if (ctor_Keyword != null)
				{
					ContractsMenu = ctor_Keyword.Invoke(new object[3] { "Contracts", "contracts", _theMainMenu });
				}
				else
				{
					ContractsMenu = ctor_Name.Invoke(new object[1] { "Contracts" });
					m_SetParentMenu.Invoke(ContractsMenu, new object[1] { _theMainMenu });
				}
				Plugin.Log.LogInfo((object)"Created Furniture and Contracts StorePlus submenus.");
			}
		}

		private static void MoveFurnitureItems()
		{
			if (_upgrades == null || FurnitureMenu == null || !(p_NestedMenus.GetValue(_upgrades) is IList list) || list.Count == 0)
			{
				return;
			}
			List<object> list2 = new List<object>();
			foreach (object item in list)
			{
				if (IsItemFurniture(item))
				{
					list2.Add(item);
				}
			}
			foreach (object item2 in list2)
			{
				m_SetParentMenu.Invoke(item2, new object[1] { FurnitureMenu });
			}
			if (list2.Count > 0)
			{
				Plugin.Log.LogDebug((object)$"Moved {list2.Count} furniture items to Furniture menu.");
			}
		}

		private static bool IsItemFurniture(object menuItem)
		{
			if (f_StoreItem == null)
			{
				return false;
			}
			object value = f_StoreItem.GetValue(menuItem);
			if (value == null)
			{
				return false;
			}
			FieldInfo fieldInfo = AccessTools.Field(value.GetType(), "Unlockable");
			if (fieldInfo == null)
			{
				return false;
			}
			object value2 = fieldInfo.GetValue(value);
			if (value2 == null)
			{
				return false;
			}
			FieldInfo fieldInfo2 = AccessTools.Field(value2.GetType(), "alwaysInStock");
			if (fieldInfo2 == null)
			{
				return false;
			}
			return !(bool)fieldInfo2.GetValue(value2);
		}

		private static void RemoveLGUFromExternalMods()
		{
			object obj = AccessTools.Field(t_StorePlus, "ExternalMods")?.GetValue(null);
			if (obj == null || !(p_NestedMenus.GetValue(obj) is IList list))
			{
				return;
			}
			List<object> list2 = new List<object>();
			foreach (object item in list)
			{
				if (!(f_keyword == null))
				{
					string text = f_keyword.GetValue(item) as string;
					if (text == "lgu" || text == "contracts")
					{
						list2.Add(item);
					}
				}
			}
			foreach (object item2 in list2)
			{
				list.Remove(item2);
			}
		}

		internal static void AddLGUUpgradesToMenu()
		{
			if (_upgrades == null || (ctor_Keyword == null && ctor_Name == null))
			{
				return;
			}
			if (_addedLGUKeywords.Count > 0)
			{
				if (p_NestedMenus.GetValue(_upgrades) is IList list)
				{
					List<object> list2 = new List<object>();
					foreach (object item2 in list)
					{
						if (!(f_keyword == null) && f_keyword.GetValue(item2) is string item && _addedLGUKeywords.Contains(item))
						{
							list2.Add(item2);
						}
					}
					foreach (object item3 in list2)
					{
						list.Remove(item3);
					}
				}
				_addedLGUKeywords.Clear();
			}
			foreach (CustomTerminalNode sharedUpgradeNode in Plugin.SharedUpgradeNodes)
			{
				string text = sharedUpgradeNode.Name.ToLowerInvariant().Replace(" ", "-");
				if (_addedLGUKeywords.Contains(text))
				{
					continue;
				}
				try
				{
					int currentPrice = sharedUpgradeNode.GetCurrentPrice();
					string text2;
					if (currentPrice == int.MaxValue || (sharedUpgradeNode.Unlocked && sharedUpgradeNode.CurrentUpgrade >= sharedUpgradeNode.MaxUpgrade))
					{
						text2 = sharedUpgradeNode.Name + " [MAXED]";
					}
					else
					{
						string arg = ((sharedUpgradeNode.MaxUpgrade > 0) ? $" [T{sharedUpgradeNode.GetCurrentLevel()}/{sharedUpgradeNode.MaxUpgrade + 1}]" : "");
						text2 = $"${currentPrice} {sharedUpgradeNode.Name}{arg}";
					}
					if (ctor_Keyword != null)
					{
						ctor_Keyword.Invoke(new object[3] { text2, text, _upgrades });
					}
					else
					{
						object obj = ctor_Name.Invoke(new object[1] { text2 });
						m_SetParentMenu.Invoke(obj, new object[1] { _upgrades });
					}
					_addedLGUKeywords.Add(text);
					Plugin.Log.LogDebug((object)("Added LGU upgrade: " + text2));
				}
				catch (Exception arg2)
				{
					Plugin.Log.LogError((object)$"Failed to add '{sharedUpgradeNode.Name}' to StorePlus: {arg2}");
				}
			}
		}

		private static void ReorderMainMenu()
		{
			if (_theMainMenu == null || !(p_NestedMenus.GetValue(_theMainMenu) is IList list) || list.Count == 0)
			{
				return;
			}
			Type type = list.GetType();
			MethodInfo method = type.GetMethod("RemoveAt", new Type[1] { typeof(int) });
			MethodInfo method2 = type.GetMethod("Insert");
			object[] array = new object[6] { _buyables, _upgrades, _vehicles, FurnitureMenu, ContractsMenu, _suits };
			List<object> list2 = new List<object>();
			for (int i = 0; i < list.Count; i++)
			{
				list2.Add(list[i]);
			}
			List<object> list3 = new List<object>();
			object[] array2 = array;
			foreach (object obj in array2)
			{
				if (obj == null)
				{
					continue;
				}
				for (int k = 0; k < list2.Count; k++)
				{
					if (list2[k] == obj)
					{
						list3.Add(obj);
						list2.RemoveAt(k);
						break;
					}
				}
			}
			list3.AddRange(list2);
			for (int num = list.Count - 1; num >= 0; num--)
			{
				method.Invoke(list, new object[1] { num });
			}
			for (int l = 0; l < list3.Count; l++)
			{
				method2.Invoke(list, new object[2]
				{
					l,
					list3[l]
				});
			}
			IEnumerable<string> values = list3.Select((object o) => p_Name?.GetValue(o)?.ToString() ?? "?");
			Plugin.Log.LogInfo((object)("Menu reordered: " + string.Join(", ", values)));
		}
	}
	[HarmonyPatch]
	internal static class TerminalPCsRenamePatch
	{
		private static readonly Regex RxPCs = new Regex("\\bPCs\\b", RegexOptions.Compiled);

		private static readonly Regex RxPC = new Regex("\\bPC\\b", RegexOptions.Compiled);

		internal static string Rename(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				return s;
			}
			s = s.Replace("Player Credits", "Player BXP");
			s = s.Replace("player credits", "player BXP");
			s = s.Replace("PLAYER CREDITS", "PLAYER BXP");
			s = RxPCs.Replace(s, "BXPs");
			s = RxPC.Replace(s, "BXP");
			return s;
		}

		[HarmonyPatch(typeof(Terminal), "TextPostProcess")]
		[HarmonyPostfix]
		private static void TextPostProcess_Postfix(ref string __result)
		{
			__result = Rename(__result);
		}

		[HarmonyPatch(typeof(Terminal), "LoadNewNode")]
		[HarmonyPostfix]
		private static void LoadNewNode_Postfix(TerminalNode node)
		{
			if ((Object)(object)node != (Object)null && !string.IsNullOrEmpty(node.displayText))
			{
				node.displayText = Rename(node.displayText);
			}
		}
	}
	[HarmonyPatch(typeof(HUDManager), "DisplayTip")]
	internal static class DisplayTipBxpRenamePatch
	{
		[HarmonyPrefix]
		private static void Prefix(ref string headerText, ref string bodyText)
		{
			try
			{
				headerText = TerminalPCsRenamePatch.Rename(headerText);
				bodyText = TerminalPCsRenamePatch.Rename(bodyText);
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"DisplayTip rename prefix error: {arg}");
			}
		}
	}
	[HarmonyPatch]
	internal static class CurrencyManagerNotificationPatch
	{
		[CompilerGenerated]
		private sealed class <TargetMethods>d__3 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private MethodBase <>2__current;

			private int <>l__initialThreadId;

			MethodBase IEnumerator<MethodBase>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TargetMethods>d__3(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (_addCurrencyAmountFromQuota != null)
					{
						<>2__current = _addCurrencyAmountFromQuota;
						<>1__state = 1;
						return true;
					}
					goto IL_004a;
				case 1:
					<>1__state = -1;
					goto IL_004a;
				case 2:
					{
						<>1__state = -1;
						break;
					}
					IL_004a:
					if (_tradePlayerCreditsClientRpc != null)
					{
						<>2__current = _tradePlayerCreditsClientRpc;
						<>1__state = 2;
						return true;
					}
					break;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <TargetMethods>d__3(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<MethodBase>)this).GetEnumerator();
			}
		}

		private static MethodInfo _addCurrencyAmountFromQuota;

		private static MethodInfo _tradePlayerCreditsClientRpc;

		private static bool Prepare()
		{
			if (!Chainloader.PluginInfos.ContainsKey("com.malco.lethalcompany.moreshipupgrades"))
			{
				return false;
			}
			Type type = AccessTools.TypeByName("MoreShipUpgrades.Managers.CurrencyManager");
			if (type == null)
			{
				return false;
			}
			_addCurrencyAmountFromQuota = AccessTools.Method(type, "AddCurrencyAmountFromQuota", (Type[])null, (Type[])null);
			_tradePlayerCreditsClientRpc = AccessTools.Method(type, "TradePlayerCreditsClientRpc", (Type[])null, (Type[])null);
			if (!(_addCurrencyAmountFromQuota != null))
			{
				return _tradePlayerCreditsClientRpc != null;
			}
			return true;
		}

		[IteratorStateMachine(typeof(<TargetMethods>d__3))]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TargetMethods>d__3(-2);
		}

		[HarmonyPostfix]
		private static void Postfix(MethodBase __originalMethod)
		{
			Plugin.Log.LogDebug((object)("[BXP] LGU notification fired: " + __originalMethod?.Name + " (rewritten via DisplayTip prefix)."));
		}
	}
	[HarmonyPatch(typeof(Debug))]
	internal static class FontWarningSuppressionPatch
	{
		[HarmonyPatch("LogWarning", new Type[] { typeof(object) })]
		[HarmonyPrefix]
		private static bool Prefix(object message)
		{
			if (message is string text && text.Contains("3270-Regular SDF"))
			{
				return false;
			}
			return true;
		}
	}
	[BepInPlugin("com.lguterminalbridge", "LGUTerminalBridge", "1.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "com.lguterminalbridge";

		public const string NAME = "LGUTerminalBridge";

		public const string VERSION = "1.2.0";

		internal const string DARMUH_GUID = "darmuh.TerminalStuff";

		internal static ManualLogSource Log;

		internal static Terminal CachedTerminal;

		internal static List<CustomTerminalNode> SharedUpgradeNodes = new List<CustomTerminalNode>();

		internal static Dictionary<string, TerminalNode> NameToPurchaseNode = new Dictionary<string, TerminalNode>();

		internal static Dictionary<string, TerminalNode> NameToConfirmNode = new Dictionary<string, TerminalNode>();

		internal static Dictionary<TerminalNode, string> PurchaseNodeToName = new Dictionary<TerminalNode, string>();

		internal static HashSet<string> RegisteredKeywords = new HashSet<string>();

		internal static bool DarmuhPresent => Chainloader.PluginInfos.ContainsKey("darmuh.TerminalStuff");

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			new Harmony("com.lguterminalbridge").PatchAll();
			RegisterStoreCommands();
			if (DarmuhPresent)
			{
				Log.LogInfo((object)"darmuh's TerminalStuff detected. StorePlus patches will activate.");
			}
			else
			{
				Log.LogInfo((object)"darmuh's TerminalStuff not detected. TerminalApi fallback active.");
			}
			Log.LogInfo((object)"LGUTerminalBridge v1.2.0 loaded!");
		}

		private void RegisterStoreCommands()
		{
			//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)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			CommandInfo val = new CommandInfo
			{
				Title = "Furniture",
				Category = "Store",
				Description = "Browse available furniture and decorations.",
				DisplayTextSupplier = BuildFurnitureDisplay
			};
			TerminalApi.AddCommand("furniture", val, (string)null, true);
			CommandInfo val2 = new CommandInfo
			{
				Title = "Upgrades",
				Category = "Store",
				Description = "Browse available ship upgrades.",
				DisplayTextSupplier = BuildUpgradesDisplay
			};
			TerminalApi.AddCommand("upgrades", val2, (string)null, true);
			Log.LogInfo((object)"Registered 'furniture' and 'upgrades' terminal commands.");
		}

		internal static string BuildFurnitureDisplay()
		{
			Terminal val = CachedTerminal;
			if ((Object)(object)val == (Object)null)
			{
				val = Object.FindObjectOfType<Terminal>();
				if ((Object)(object)val == (Object)null)
				{
					return "Terminal not available.\n\n";
				}
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("FURNITURE STORE");
			stringBuilder.AppendLine("==============================\n");
			stringBuilder.AppendLine("Decorations rotate each quota. Type BUY [item] to purchase.\n");
			if (val.ShipDecorSelection == null || val.ShipDecorSelection.Count == 0)
			{
				stringBuilder.AppendLine("[No furniture available]\n");
			}
			else
			{
				foreach (TerminalNode item in val.ShipDecorSelection)
				{
					stringBuilder.AppendLine($"* {item.creatureName}  //  Price: ${item.itemCost}");
				}
				stringBuilder.AppendLine();
			}
			stringBuilder.AppendLine($"Your balance is ${val.groupCredits}.\n");
			return stringBuilder.ToString();
		}

		internal static string BuildUpgradesDisplay()
		{
			Terminal val = CachedTerminal;
			if ((Object)(object)val == (Object)null)
			{
				val = Object.FindObjectOfType<Terminal>();
				if ((Object)(object)val == (Object)null)
				{
					return "Terminal not available.\n\n";
				}
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("UPGRADES STORE");
			stringBuilder.AppendLine("==============================\n");
			stringBuilder.AppendLine("Type BUY [item] to purchase.\n");
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance != (Object)null)
			{
				for (int i = 0; i < instance.unlockablesList.unlockables.Count; i++)
				{
					UnlockableItem val2 = instance.unlockablesList.unlockables[i];
					if ((Object)(object)val2.shopSelectionNode != (Object)null && val2.alwaysInStock)
					{
						string arg = ((val2.hasBeenUnlockedByPlayer || val2.alreadyUnlocked) ? " [OWNED]" : "");
						stringBuilder.AppendLine($"* {val2.shopSelectionNode.creatureName}  //  Price: ${val2.shopSelectionNode.itemCost}{arg}");
					}
				}
			}
			if (SharedUpgradeNodes.Count > 0)
			{
				stringBuilder.AppendLine("\n-- Shared Upgrades (LGU) --\n");
				foreach (CustomTerminalNode sharedUpgradeNode in SharedUpgradeNodes)
				{
					int currentPrice = sharedUpgradeNode.GetCurrentPrice();
					string text = sharedUpgradeNode.Name.ToLowerInvariant().Replace(" ", "-");
					string text2 = "";
					if (sharedUpgradeNode.MaxUpgrade > 0)
					{
						text2 = $" [Tier {sharedUpgradeNode.GetCurrentLevel()}/{sharedUpgradeNode.MaxUpgrade + 1}]";
					}
					if (currentPrice == int.MaxValue || (sharedUpgradeNode.Unlocked && sharedUpgradeNode.CurrentUpgrade >= sharedUpgradeNode.MaxUpgrade))
					{
						stringBuilder.AppendLine("* " + sharedUpgradeNode.Name + text2 + "  [MAXED]");
						continue;
					}
					string text3 = (sharedUpgradeNode.Unlocked ? " [OWNED]" : "");
					stringBuilder.AppendLine($"* {sharedUpgradeNode.Name} ({text})  //  ${currentPrice}{text2}{text3}");
				}
			}
			stringBuilder.AppendLine($"\nYour balance is ${val.groupCredits}.\n");
			return stringBuilder.ToString();
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LGUTerminalBridge";

		public const string PLUGIN_NAME = "LGUTerminalBridge";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}

LGUUpgradeMerge.dll

Decompiled 4 days 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 BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using LGUUpgradeMerge.Upgrades;
using Microsoft.CodeAnalysis;
using MoreShipUpgrades.Managers;
using MoreShipUpgrades.Misc.Upgrades;
using MoreShipUpgrades.UI.TerminalNodes;
using MoreShipUpgrades.UpgradeComponents.TierUpgrades;
using MoreShipUpgrades.UpgradeComponents.TierUpgrades.AttributeUpgrades;
using MoreShipUpgrades.UpgradeComponents.TierUpgrades.Player;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("MoreShipUpgrades")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LGUUpgradeMerge")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Merged tier upgrades for LateGameUpgrades")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8c5521e37f37e3d76518a16d04e5d1051842f105")]
[assembly: AssemblyProduct("LGUUpgradeMerge")]
[assembly: AssemblyTitle("LGUUpgradeMerge")]
[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 LGUUpgradeMerge
{
	[BepInPlugin("com.lguupgrademerge", "LGUUpgradeMerge", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "com.lguupgrademerge";

		public const string NAME = "LGUUpgradeMerge";

		public const string VERSION = "1.0.0";

		internal static ManualLogSource Log;

		internal static readonly Dictionary<string, GameObject> networkPrefabs = new Dictionary<string, GameObject>();

		private void Awake()
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			MergedReinforcedBoots.RegisterUpgrade();
			PhysicalConditioning.RegisterUpgrade();
			ThickSkin.RegisterUpgrade();
			QuickHandsMerge.RegisterUpgrade();
			UpgradeBus.Instance.upgradeTypes.Add(typeof(MergedReinforcedBoots));
			UpgradeBus.Instance.upgradeTypes.Add(typeof(PhysicalConditioning));
			UpgradeBus.Instance.upgradeTypes.Add(typeof(ThickSkin));
			UpgradeBus.Instance.upgradeTypes.Add(typeof(QuickHandsMerge));
			Harmony val = new Harmony("com.lguupgrademerge");
			val.PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)"LGUUpgradeMerge v1.0.0 loaded successfully.");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LGUUpgradeMerge";

		public const string PLUGIN_NAME = "LGUUpgradeMerge";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace LGUUpgradeMerge.Upgrades
{
	public class MergedReinforcedBoots : TierUpgrade
	{
		public const string UPGRADE_NAME = "Reinforced Boots";

		public const string PRICES = "500,1100,1800,2400,3000";

		public const float RUBBER_BOOTS_DECREASE = 20f;

		public const float TRACTION_INCREASE = 25f;

		public const float HIKING_SLOPE_DECREASE = 25f;

		public const float CARBON_CROUCH_DECREASE = 20f;

		public const float FALL_DAMAGE_REDUCTION = 25f;

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Reinforced Boots";
			((BaseUpgrade)this).overridenUpgradeName = "Reinforced Boots";
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			string text = $"LVL 1 - {FormatPrice(initialPrice)} - Reduces water/quicksand movement penalty by {20f}%\n";
			if (incrementalPrices != null)
			{
				if (incrementalPrices.Length != 0)
				{
					text += $"LVL 2 - {FormatPrice(incrementalPrices[0])} - Increases ground traction by {25f}%\n";
				}
				if (incrementalPrices.Length > 1)
				{
					text += $"LVL 3 - {FormatPrice(incrementalPrices[1])} - Reduces uphill slope debuff by {25f}%\n";
				}
				if (incrementalPrices.Length > 2)
				{
					text += $"LVL 4 - {FormatPrice(incrementalPrices[2])} - Reduces crouch speed penalty by {20f}%\n";
				}
				if (incrementalPrices.Length > 3)
				{
					text += $"LVL 5 - {FormatPrice(incrementalPrices[3])} - Reduces fall damage by {25f}%\n";
				}
			}
			return text;
		}

		public static void RegisterUpgrade()
		{
			GameObject val = ItemManager.CreateNetworkPrefab("Reinforced Boots");
			val.AddComponent<MergedReinforcedBoots>();
			Plugin.networkPrefabs["Reinforced Boots"] = val;
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!Plugin.networkPrefabs.ContainsKey("Reinforced Boots"))
			{
				return null;
			}
			int[] array = ParsePrices("500,1100,1800,2400,3000");
			int num = array[0];
			int[] array2 = new int[array.Length - 1];
			Array.Copy(array, 1, array2, 0, array2.Length);
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Reinforced Boots", false, true, num, array2, "", Plugin.networkPrefabs["Reinforced Boots"], true, (PurchaseMode)2, false, 1f);
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Reinforced Boots", Array.Empty<string>());
		}

		internal static string FormatPrice(int price)
		{
			return BaseUpgrade.GetUpgradePrice(price, (PurchaseMode)2);
		}

		internal static int[] ParsePrices(string prices)
		{
			string[] array = prices.Split(',');
			int[] array2 = new int[array.Length];
			for (int i = 0; i < array.Length; i++)
			{
				int.TryParse(array[i].Trim(), out array2[i]);
			}
			return array2;
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "MergedReinforcedBoots";
		}
	}
	public class PhysicalConditioning : TierUpgrade
	{
		public const string UPGRADE_NAME = "Physical Conditioning";

		public const string PRICES = "1000,1700,2300,3000";

		public const float MOVEMENT_SPEED_INITIAL = 1.4f;

		public const float SPRINT_TIME_INITIAL = 6f;

		public const float STAMINA_REGEN_MULT = 1.05f;

		public const float JUMP_FORCE_INITIAL = 3f;

		public const float JUMP_FORCE_INCREMENT = 0.75f;

		public const float NOISE_REDUCTION = 10f;

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Physical Conditioning";
			((BaseUpgrade)this).overridenUpgradeName = "Physical Conditioning";
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			string text = $"LVL 1 - {FormatPrice(initialPrice)} - Increases movement speed by {1.4f}\n";
			if (incrementalPrices != null)
			{
				if (incrementalPrices.Length != 0)
				{
					text += $"LVL 2 - {FormatPrice(incrementalPrices[0])} - Increases stamina by {6f}s, regen by {4.999995f}%\n";
				}
				if (incrementalPrices.Length > 1)
				{
					text += $"LVL 3 - {FormatPrice(incrementalPrices[1])} - Increases jump height by {3f}\n";
				}
				if (incrementalPrices.Length > 2)
				{
					text += $"LVL 4 - {FormatPrice(incrementalPrices[2])} - Jump height +{0.75f}, footstep noise -{10f}\n";
				}
			}
			return text;
		}

		public static void RegisterUpgrade()
		{
			GameObject val = ItemManager.CreateNetworkPrefab("Physical Conditioning");
			val.AddComponent<PhysicalConditioning>();
			Plugin.networkPrefabs["Physical Conditioning"] = val;
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!Plugin.networkPrefabs.ContainsKey("Physical Conditioning"))
			{
				return null;
			}
			int[] array = MergedReinforcedBoots.ParsePrices("1000,1700,2300,3000");
			int num = array[0];
			int[] array2 = new int[array.Length - 1];
			Array.Copy(array, 1, array2, 0, array2.Length);
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Physical Conditioning", false, true, num, array2, "", Plugin.networkPrefabs["Physical Conditioning"], true, (PurchaseMode)2, false, 1f);
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Physical Conditioning", Array.Empty<string>());
		}

		private static string FormatPrice(int price)
		{
			return BaseUpgrade.GetUpgradePrice(price, (PurchaseMode)2);
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "PhysicalConditioning";
		}
	}
	public class QuickHandsMerge : TierUpgrade
	{
		public const string UPGRADE_NAME = "Quick Hands";

		public const string PRICES = "400,500,750,1000,1250";

		public const float GRAB_DISTANCE_PER_TIER = 1f;

		public const int MECHANICAL_ARMS_MAX_TIERS = 4;

		public const int INTERACTION_SPEED_PER_TIER = 20;

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Quick Hands";
			((BaseUpgrade)this).overridenUpgradeName = "Quick Hands";
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			string text = "";
			int[] array = ParsePrices("400,500,750,1000,1250");
			for (int i = 0; i < array.Length; i++)
			{
				int num = i + 1;
				string text2 = FormatPrice(array[i]);
				float num2 = (float)Mathf.Min(num, 4) * 1f;
				int num3 = num * 20;
				text = ((num > 4) ? (text + $"LVL {num} - {text2} - +{num3}% interaction speed\n") : (text + $"LVL {num} - {text2} - +{num2} interaction range, +{num3}% interaction speed\n"));
			}
			return text;
		}

		public static void RegisterUpgrade()
		{
			GameObject val = ItemManager.CreateNetworkPrefab("Quick Hands");
			val.AddComponent<QuickHandsMerge>();
			Plugin.networkPrefabs["Quick Hands"] = val;
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!Plugin.networkPrefabs.ContainsKey("Quick Hands"))
			{
				return null;
			}
			int[] array = ParsePrices("400,500,750,1000,1250");
			int num = array[0];
			int[] array2 = new int[array.Length - 1];
			Array.Copy(array, 1, array2, 0, array2.Length);
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Quick Hands", false, true, num, array2, "", Plugin.networkPrefabs["Quick Hands"], true, (PurchaseMode)2, false, 1f);
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Quick Hands", Array.Empty<string>());
		}

		internal static string FormatPrice(int price)
		{
			return BaseUpgrade.GetUpgradePrice(price, (PurchaseMode)2);
		}

		internal static int[] ParsePrices(string prices)
		{
			string[] array = prices.Split(',');
			int[] array2 = new int[array.Length];
			for (int i = 0; i < array.Length; i++)
			{
				int.TryParse(array[i].Trim(), out array2[i]);
			}
			return array2;
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "QuickHandsMerge";
		}
	}
	public class ThickSkin : TierUpgrade
	{
		public const string UPGRADE_NAME = "Thick Skin";

		public const string PRICES = "1000,1500,2000,2500";

		public const int HEALTH_REGEN_INCREASE = 1;

		public const float HEALTH_CAP_PERCENT = 50f;

		public const int HEALTH_INCREASE_PER_TIER = 20;

		public override bool CanInitializeOnStart => false;

		private void Awake()
		{
			((BaseUpgrade)this).upgradeName = "Thick Skin";
			((BaseUpgrade)this).overridenUpgradeName = "Thick Skin";
		}

		public override string GetDisplayInfo(int initialPrice = -1, int maxLevels = -1, int[] incrementalPrices = null)
		{
			int[] array = MergedReinforcedBoots.ParsePrices("1000,1500,2000,2500");
			string text = "";
			for (int i = 0; i < array.Length; i++)
			{
				int num = i + 1;
				int num2 = num * 20;
				string text2 = FormatPrice(array[i]);
				text = num switch
				{
					1 => text + $"LVL {num} - {text2} - +{num2} max HP, +{1} health regen\n", 
					2 => text + $"LVL {num} - {text2} - +{num2} max HP, +{50f}% regen cap\n", 
					_ => text + $"LVL {num} - {text2} - +{num2} max HP\n", 
				};
			}
			return text;
		}

		public static void RegisterUpgrade()
		{
			GameObject val = ItemManager.CreateNetworkPrefab("Thick Skin");
			val.AddComponent<ThickSkin>();
			Plugin.networkPrefabs["Thick Skin"] = val;
		}

		public static CustomTerminalNode RegisterTerminalNode()
		{
			if (!Plugin.networkPrefabs.ContainsKey("Thick Skin"))
			{
				return null;
			}
			int[] array = MergedReinforcedBoots.ParsePrices("1000,1500,2000,2500");
			int num = array[0];
			int[] array2 = new int[array.Length - 1];
			Array.Copy(array, 1, array2, 0, array2.Length);
			return UpgradeBus.Instance.SetupMultiplePurchasableTerminalNode("Thick Skin", false, true, num, array2, "", Plugin.networkPrefabs["Thick Skin"], true, (PurchaseMode)2, false, 1f);
		}

		public static (string, string[]) RegisterScrapToUpgrade()
		{
			return ("Thick Skin", Array.Empty<string>());
		}

		private static string FormatPrice(int price)
		{
			return BaseUpgrade.GetUpgradePrice(price, (PurchaseMode)2);
		}

		public override void __initializeVariables()
		{
			((TierUpgrade)this).__initializeVariables();
		}

		public override void __initializeRpcs()
		{
			((TierUpgrade)this).__initializeRpcs();
		}

		public override string __getTypeName()
		{
			return "ThickSkin";
		}
	}
}
namespace LGUUpgradeMerge.Patches
{
	[HarmonyPatch(typeof(RunningShoes), "GetAdditionalMovementSpeed")]
	internal static class RunningShoesMovementPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref float __result, float defaultValue)
		{
			if (BaseUpgrade.GetActiveUpgrade("Physical Conditioning"))
			{
				float num = Mathf.Clamp(defaultValue + 1.4f, defaultValue, float.MaxValue);
				__result = Mathf.Max(__result, num);
			}
		}
	}
	[HarmonyPatch(typeof(BiggerLungs), "GetAdditionalStaminaTime")]
	internal static class BiggerLungsStaminaTimePatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref float __result, float defaultValue)
		{
			if (BaseUpgrade.GetActiveUpgrade("Physical Conditioning") && BaseUpgrade.GetUpgradeLevel("Physical Conditioning") >= 1)
			{
				float num = Mathf.Clamp(defaultValue + 6f, defaultValue, float.MaxValue);
				__result = Mathf.Max(__result, num);
			}
		}
	}
	[HarmonyPatch(typeof(BiggerLungs), "ApplyPossibleIncreasedStaminaRegen")]
	internal static class BiggerLungsStaminaRegenPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref float __result, float regenValue)
		{
			if (BaseUpgrade.GetActiveUpgrade("Physical Conditioning") && BaseUpgrade.GetUpgradeLevel("Physical Conditioning") >= 1)
			{
				float num = regenValue * 1.05f;
				__result = Mathf.Max(__result, num);
			}
		}
	}
	[HarmonyPatch(typeof(StrongLegs), "GetAdditionalJumpForce")]
	internal static class StrongLegsJumpPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref float __result, float defaultValue)
		{
			if (!BaseUpgrade.GetActiveUpgrade("Physical Conditioning"))
			{
				return;
			}
			int upgradeLevel = BaseUpgrade.GetUpgradeLevel("Physical Conditioning");
			if (upgradeLevel >= 2)
			{
				float num = 3f;
				if (upgradeLevel >= 3)
				{
					num += 0.75f;
				}
				float num2 = Mathf.Clamp(defaultValue + num, defaultValue, float.MaxValue);
				__result = Mathf.Max(__result, num2);
			}
		}
	}
	[HarmonyPatch(typeof(RunningShoes), "ApplyPossibleReducedNoiseRange")]
	internal static class RunningShoesNoisePatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref float __result, float defaultValue)
		{
			if (BaseUpgrade.GetActiveUpgrade("Physical Conditioning") && BaseUpgrade.GetUpgradeLevel("Physical Conditioning") >= 3)
			{
				float num = Mathf.Clamp(defaultValue - 10f, 0f, defaultValue);
				__result = Mathf.Min(__result, num);
			}
		}
	}
	[HarmonyPatch(typeof(MechanicalArms), "GetIncreasedGrabDistance")]
	internal static class MechanicalArmsGrabDistancePatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref float __result, float defaultValue)
		{
			try
			{
				if (BaseUpgrade.GetActiveUpgrade("Quick Hands"))
				{
					int upgradeLevel = BaseUpgrade.GetUpgradeLevel("Quick Hands");
					int num = Math.Min(upgradeLevel + 1, 4);
					float num2 = (float)num * 1f;
					float num3 = Mathf.Clamp(defaultValue + num2, defaultValue, float.MaxValue);
					__result = Mathf.Max(__result, num3);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"QuickHandsMerge MechanicalArms patch failed: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(QuickHands), "IncreaseInteractionSpeed")]
	internal static class QuickHandsInteractionSpeedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref float __result, float defaultValue)
		{
			try
			{
				if (BaseUpgrade.GetActiveUpgrade("Quick Hands"))
				{
					int upgradeLevel = BaseUpgrade.GetUpgradeLevel("Quick Hands");
					int num = upgradeLevel + 1;
					float num2 = (float)(num * 20) / 100f;
					float num3 = (int)Mathf.Clamp(defaultValue + defaultValue * num2, defaultValue, float.MaxValue);
					__result = Mathf.Max(__result, num3);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"QuickHandsMerge QuickHands patch failed: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(RubberBoots), "CalculateDecreaseMultiplier")]
	internal static class RubberBootsDecreaseMultiplierPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref float __result)
		{
			if (BaseUpgrade.GetActiveUpgrade("Reinforced Boots"))
			{
				float num = 0.2f;
				__result = Mathf.Max(__result, num);
			}
		}
	}
	[HarmonyPatch(typeof(TractionBoots), "GetAdditionalTractionForce")]
	internal static class TractionBootsForcePatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref float __result, float defaultValue)
		{
			if (BaseUpgrade.GetActiveUpgrade("Reinforced Boots") && BaseUpgrade.GetUpgradeLevel("Reinforced Boots") >= 1)
			{
				float num = 1.25f;
				float num2 = Mathf.Clamp(num * defaultValue, defaultValue, float.MaxValue);
				__result = Mathf.Max(__result, num2);
			}
		}
	}
	[HarmonyPatch(typeof(HikingBoots), "ReduceUphillSlopeDebuff")]
	internal static class HikingBootsSlopePatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref float __result, float defaultValue)
		{
			if (BaseUpgrade.GetActiveUpgrade("Reinforced Boots") && BaseUpgrade.GetUpgradeLevel("Reinforced Boots") >= 2)
			{
				float num = 0.75f;
				float num2 = Mathf.Clamp(defaultValue * num, 0f, defaultValue);
				__result = Mathf.Min(__result, num2);
			}
		}
	}
	[HarmonyPatch(typeof(CarbonKneejoints), "CalculateDecreaseMultiplier")]
	internal static class CarbonKneejointsDecreaseMultiplierPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref float __result)
		{
			if (BaseUpgrade.GetActiveUpgrade("Reinforced Boots") && BaseUpgrade.GetUpgradeLevel("Reinforced Boots") >= 3)
			{
				float num = 0.2f;
				__result = Mathf.Max(__result, num);
			}
		}
	}
	[HarmonyPatch(typeof(ReinforcedBoots), "ReduceFallDamage")]
	internal static class ReinforcedBootsFallDamagePatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref int __result, int defaultValue)
		{
			if (BaseUpgrade.GetActiveUpgrade("Reinforced Boots") && BaseUpgrade.GetUpgradeLevel("Reinforced Boots") >= 4)
			{
				float num = 0.75f;
				int num2 = (int)Mathf.Clamp((float)defaultValue * num, 0f, (float)defaultValue);
				__result = Mathf.Min(__result, num2);
			}
		}
	}
	[HarmonyPatch(typeof(Stimpack), "CheckForAdditionalHealth")]
	internal static class StimpackCheckForAdditionalHealthPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref int __result, int health)
		{
			try
			{
				if (BaseUpgrade.GetActiveUpgrade("Thick Skin"))
				{
					int upgradeLevel = BaseUpgrade.GetUpgradeLevel("Thick Skin");
					int num = upgradeLevel + 1;
					int num2 = num * 20;
					int num3 = health + num2;
					__result = Mathf.Max(__result, num3);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"ThickSkin Stimpack patch failed: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(EffectiveBandaids), "GetIncreasedHealthRegenerated")]
	internal static class EffectiveBandaidsPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref int __result, int defaultValue)
		{
			try
			{
				if (BaseUpgrade.GetActiveUpgrade("Thick Skin"))
				{
					int num = Mathf.Clamp(defaultValue + 1, defaultValue, Stimpack.CheckForAdditionalHealth(100));
					__result = Mathf.Max(__result, num);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"ThickSkin EffectiveBandaids patch failed: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(MedicalNanobots), "GetIncreasedHealthRegeneration")]
	internal static class MedicalNanobotsPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref int __result, int defaultValue)
		{
			try
			{
				if (BaseUpgrade.GetActiveUpgrade("Thick Skin") && BaseUpgrade.GetUpgradeLevel("Thick Skin") >= 1)
				{
					float num = 0.5f;
					int num2 = Mathf.Clamp(defaultValue + (int)((float)defaultValue * num), defaultValue, Stimpack.CheckForAdditionalHealth(100));
					__result = Mathf.Max(__result, num2);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"ThickSkin MedicalNanobots patch failed: {arg}");
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}