Decompiled source of ULTRAKILLPlus v1.0.0

ULTRAKILLPlus.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
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("ULTRAKILLPlus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ULTRAKILLPlus")]
[assembly: AssemblyTitle("ULTRAKILLPlus")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 ULTRAKILLPlus
{
	[BepInPlugin("parody.ultrakill.plus", "ULTRAKILL+", "0.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		private ConfigEntry<bool> enabled;

		private ConfigEntry<bool> ads;

		private ConfigEntry<bool> bossChaos;

		private ConfigEntry<bool> damageLimit;

		private ConfigEntry<int> shotgunPrice;

		private ConfigEntry<int> premiumPrice;

		private ConfigEntry<int> deluxePrice;

		private ConfigEntry<int> duration;

		private ConfigEntry<int> adSeconds;

		private ConfigEntry<int> swapWindow;

		private ConfigEntry<int> upgradePrice;

		private bool menu;

		private bool adShowing;

		private bool damagePrompt;

		private bool damageUsed;

		private bool wasBoss;

		private float shotgunLeft;

		private float premiumLeft;

		private float deluxeLeft;

		private float adLeft;

		private float swapLeft;

		private float noticeLeft;

		private float lastBossCheck;

		private string notice = "Welcome to ULTRAKILL+. All charges are imaginary dollars paid in real game P.";

		private Rect window = new Rect(35f, 35f, 490f, 565f);

		private Type progressType;

		private Type gunType;

		private object gun;

		private static Plugin activePlugin;

		private Harmony weaponHarmony;

		private int previousAccess = -1;

		private bool changingWeapon;

		private int? lastBalance;

		private GUIStyle panelStyle;

		private GUIStyle cardStyle;

		private GUIStyle titleStyle;

		private GUIStyle subtitleStyle;

		private GUIStyle textStyle;

		private GUIStyle smallStyle;

		private GUIStyle priceStyle;

		private GUIStyle buttonStyle;

		private GUIStyle noticeStyle;

		private GUIStyle headerStyle;

		private GUIStyle premiumPopupTitle;

		private GUIStyle premiumPopupSmall;

		private Texture2D darkTexture;

		private Texture2D cardTexture;

		private Texture2D redTexture;

		private Vector2 scrollPosition;

		private int AccessLevel()
		{
			if (enabled == null || !enabled.Value)
			{
				return 3;
			}
			if (deluxeLeft > 0f)
			{
				return 3;
			}
			if (premiumLeft > 0f)
			{
				return 2;
			}
			if (shotgunLeft > 0f)
			{
				return 1;
			}
			return 0;
		}

		private bool CanUseSlot(int slot)
		{
			if (slot <= 1 || slot == 6)
			{
				return true;
			}
			int num = AccessLevel();
			switch (slot)
			{
			case 2:
				return num >= 1;
			case 3:
			case 4:
				return num >= 2;
			case 5:
				return num >= 3;
			default:
				return true;
			}
		}

		private static bool SwitchPrefix(int targetSlotIndex)
		{
			Plugin plugin = activePlugin;
			if ((Object)(object)plugin == (Object)null || plugin.changingWeapon || plugin.CanUseSlot(targetSlotIndex))
			{
				return true;
			}
			if (plugin.noticeLeft <= 0f)
			{
				plugin.Notify("WEAPON LOCKED. PLEASE UPGRADE TO ULTRAKILL+.");
			}
			return false;
		}

		private static bool ForcePrefix(object __instance, GameObject weapon)
		{
			Plugin plugin = activePlugin;
			if ((Object)(object)plugin == (Object)null || plugin.changingWeapon || (Object)(object)weapon == (Object)null)
			{
				return true;
			}
			string text = ((Object)weapon).name.ToLowerInvariant();
			int num = 0;
			if (text.Contains("shotgun") || text.Contains("jackhammer"))
			{
				num = 2;
			}
			else if (text.Contains("nailgun") || text.Contains("sawblade") || text.Contains("sawgun"))
			{
				num = 3;
			}
			else if (text.Contains("railcannon") || text.Contains("railgun"))
			{
				num = 4;
			}
			else if (text.Contains("rocket"))
			{
				num = 5;
			}
			if (num == 0 || plugin.CanUseSlot(num))
			{
				return true;
			}
			if (plugin.noticeLeft <= 0f)
			{
				plugin.Notify("WEAPON LOCKED. PLEASE UPGRADE TO ULTRAKILL+.");
			}
			return false;
		}

		private void InstallWeaponPatches()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			try
			{
				if (gunType == null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"GunControl not found; weapon restrictions inactive.");
					return;
				}
				weaponHarmony = new Harmony("parody.ultrakill.plus.weaponlocks");
				MethodInfo methodInfo = AccessTools.Method(gunType, "SwitchWeapon", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(gunType, "ForceWeapon", new Type[2]
				{
					typeof(GameObject),
					typeof(bool)
				}, (Type[])null);
				BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.NonPublic;
				if (methodInfo != null)
				{
					weaponHarmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Plugin).GetMethod("SwitchPrefix", bindingAttr)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"SwitchWeapon not found; restriction patch incomplete.");
				}
				if (methodInfo2 != null)
				{
					weaponHarmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(Plugin).GetMethod("ForcePrefix", bindingAttr)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"ForceWeapon not found; alternate weapon selection may bypass restrictions.");
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)"ULTRAKILL+  weapon patches installed.");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Weapon patch failed: " + ex));
			}
		}

		private void CheckHeldWeapon()
		{
			if (gun == null || gunType == null)
			{
				return;
			}
			int num = AccessLevel();
			if (num == previousAccess)
			{
				return;
			}
			previousAccess = num;
			try
			{
				if (!(Member(gun, "currentSlotIndex") is int slot) || CanUseSlot(slot) || !(Member(gun, "slot1") is IList { Count: not 0 }))
				{
					return;
				}
				MethodInfo methodInfo = AccessTools.Method(gunType, "SwitchWeapon", (Type[])null, (Type[])null);
				if (!(methodInfo == null))
				{
					changingWeapon = true;
					methodInfo.Invoke(gun, new object[5] { 1, 0, false, false, false });
					if (noticeLeft <= 0f)
					{
						Notify("SUBSCRIPTION EXPIRED. REVOLVER TIER RESTORED.");
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not correct held weapon: " + ex.Message));
			}
			finally
			{
				changingWeapon = false;
			}
		}

		private void Awake()
		{
			enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch");
			ads = ((BaseUnityPlugin)this).Config.Bind<bool>("Ads", "Enabled", true, "Show fictional advertisements");
			bossChaos = ((BaseUnityPlugin)this).Config.Bind<bool>("Chaos", "EarlyExpiryOnBoss", false, "Optional early expiration on boss encounter");
			damageLimit = ((BaseUnityPlugin)this).Config.Bind<bool>("Chaos", "DailyDamageLimit", false, "Optional once-per-level interruption");
			shotgunPrice = ((BaseUnityPlugin)this).Config.Bind<int>("Prices", "Shotgun", 999, "P cost");
			premiumPrice = ((BaseUnityPlugin)this).Config.Bind<int>("Prices", "Premium", 1999, "P cost");
			deluxePrice = ((BaseUnityPlugin)this).Config.Bind<int>("Prices", "Deluxe", 2999, "P cost");
			upgradePrice = ((BaseUnityPlugin)this).Config.Bind<int>("Prices", "DamageLimitUpgrade", 499, "P cost");
			duration = ((BaseUnityPlugin)this).Config.Bind<int>("Timers", "SubscriptionSeconds", 600, "Active gameplay seconds");
			adSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("Timers", "AdSeconds", 5, "Fake advertisement seconds");
			swapWindow = ((BaseUnityPlugin)this).Config.Bind<int>("Timers", "SwapWindowSeconds", 30, "Swap grace period after advertisement");
			progressType = FindType("GameProgressSaver");
			gunType = FindType("GunControl");
			activePlugin = this;
			InstallWeaponPatches();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ULTRAKILL+  loaded. Enter opens the menu. P integration: " + (progressType != null)));
		}

		private Type FindType(string name)
		{
			Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "Assembly-CSharp");
			if (assembly == null)
			{
				return null;
			}
			return assembly.GetType(name, throwOnError: false);
		}

		private object Member(object obj, string name)
		{
			if (obj == null)
			{
				return null;
			}
			Type type = (obj as Type) ?? obj.GetType();
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			FieldInfo field = type.GetField(name, bindingAttr);
			if (field != null)
			{
				return field.GetValue((obj is Type) ? null : obj);
			}
			return type.GetProperty(name, bindingAttr)?.GetValue((obj is Type) ? null : obj, null);
		}

		private object InvokeStatic(Type t, string name, params object[] args)
		{
			if (t == null)
			{
				return null;
			}
			foreach (MethodInfo item in from m in t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
				where m.Name == name && m.GetParameters().Length == args.Length
				select m)
			{
				try
				{
					return item.Invoke(null, args);
				}
				catch
				{
				}
			}
			return null;
		}

		private int? Balance()
		{
			if (progressType == null)
			{
				progressType = FindType("GameProgressSaver");
			}
			string[] array = new string[2] { "GetMoney", "GetPoints" };
			foreach (string name in array)
			{
				object obj = InvokeStatic(progressType, name);
				if (obj is int)
				{
					return (int)obj;
				}
			}
			return null;
		}

		private bool Spend(int amount)
		{
			if (amount < 0)
			{
				return false;
			}
			int? num = Balance();
			if (!num.HasValue)
			{
				Notify("P API not found: purchase cancelled safely.");
				return false;
			}
			if (num.Value < amount)
			{
				Notify("INSUFFICIENT P. TRY BEING RICHER.");
				return false;
			}
			if (amount == 0)
			{
				return true;
			}
			InvokeStatic(progressType, "AddMoney", -amount);
			if (Balance() == num.Value - amount)
			{
				return true;
			}
			Notify("P deduction not confirmed. No subscription granted.");
			return false;
		}

		private void Notify(string s)
		{
			notice = s;
			noticeLeft = 5f;
			((BaseUnityPlugin)this).Logger.LogInfo((object)s);
		}

		private void Buy(int cost, int tier)
		{
			if (enabled.Value && !adShowing && Spend(cost))
			{
				float num = Math.Max(1, duration.Value);
				if (tier == 1)
				{
					shotgunLeft = num;
				}
				if (tier == 2)
				{
					premiumLeft = num;
				}
				if (tier == 3)
				{
					deluxeLeft = num;
				}
				Notify("PURCHASE COMPLETE. THANK YOU FOR YOUR P.");
			}
		}

		private bool Playing()
		{
			if (gun != null)
			{
				return Time.timeScale > 0.01f;
			}
			return false;
		}

		private void LockCorporateSettings()
		{
			enabled.Value = true;
			ads.Value = true;
			bossChaos.Value = true;
			damageLimit.Value = true;
		}

		private void Update()
		{
			if (Input.GetKeyDown((KeyCode)13))
			{
				menu = !menu;
			}
			if (!enabled.Value)
			{
				previousAccess = -1;
				return;
			}
			if (gunType == null)
			{
				gunType = FindType("GunControl");
			}
			if (gun == null && gunType != null)
			{
				try
				{
					gun = Object.FindObjectOfType(gunType);
				}
				catch
				{
				}
			}
			float unscaledDeltaTime = Time.unscaledDeltaTime;
			if (noticeLeft > 0f)
			{
				noticeLeft -= unscaledDeltaTime;
			}
			if (adShowing)
			{
				adLeft -= unscaledDeltaTime;
				if (adLeft <= 0f)
				{
					adShowing = false;
					swapLeft = Math.Max(1, swapWindow.Value);
					Notify("AD COMPLETE. ENJOY LIMITED FREEDOM.");
				}
			}
			else if (Playing())
			{
				unscaledDeltaTime = Time.deltaTime;
				shotgunLeft = Math.Max(0f, shotgunLeft - unscaledDeltaTime);
				premiumLeft = Math.Max(0f, premiumLeft - unscaledDeltaTime);
				deluxeLeft = Math.Max(0f, deluxeLeft - unscaledDeltaTime);
				swapLeft = Math.Max(0f, swapLeft - unscaledDeltaTime);
				if (Time.time - lastBossCheck > 2f)
				{
					lastBossCheck = Time.time;
					CheckBoss();
				}
				CheckHeldWeapon();
			}
		}

		private void CheckBoss()
		{
			bool flag = false;
			try
			{
				Type type = FindType("EnemyIdentifier");
				if (type != null)
				{
					Object[] array = Object.FindObjectsOfType(type);
					foreach (Object obj in array)
					{
						Component val = (Component)(object)((obj is Component) ? obj : null);
						if ((Object)(object)val != (Object)null && val.gameObject.activeInHierarchy && ((Object)val.gameObject).name.IndexOf("boss", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							flag = true;
							break;
						}
					}
				}
			}
			catch
			{
			}
			if (flag && !wasBoss)
			{
				if (bossChaos.Value)
				{
					shotgunLeft = 0f;
					premiumLeft = 0f;
					deluxeLeft = 0f;
					Notify("BOSS SURCHARGE! ALL SUBSCRIPTIONS EXPIRED.");
				}
				if (damageLimit.Value && !damageUsed)
				{
					damagePrompt = true;
					damageUsed = true;
					menu = true;
				}
			}
			wasBoss = flag;
		}

		private string HeldName()
		{
			if (gun == null)
			{
				return "";
			}
			object obj = Member(gun, "currentWeapon") ?? Member(gun, "currentGun");
			Component val = (Component)((obj is Component) ? obj : null);
			if (val != null)
			{
				return ((Object)val.gameObject).name.ToLowerInvariant();
			}
			GameObject val2 = (GameObject)((obj is GameObject) ? obj : null);
			if (val2 != null)
			{
				return ((Object)val2).name.ToLowerInvariant();
			}
			return obj?.ToString().ToLowerInvariant() ?? "";
		}

		private void EnforceHeld()
		{
			string text = HeldName();
			if (string.IsNullOrEmpty(text))
			{
				return;
			}
			string text2 = null;
			bool flag = true;
			if (text.Contains("shotgun") || text.Contains("jackhammer"))
			{
				text2 = "SHOTGUN+";
				flag = shotgunLeft > 0f || premiumLeft > 0f || deluxeLeft > 0f;
			}
			else if (text.Contains("nailgun") || text.Contains("sawblade") || text.Contains("sawgun") || text.Contains("railcannon") || text.Contains("railgun"))
			{
				text2 = "PREMIUM+";
				flag = premiumLeft > 0f || deluxeLeft > 0f;
			}
			else if (text.Contains("rocket"))
			{
				text2 = "DELUXE+";
				flag = deluxeLeft > 0f;
			}
			if (flag || text2 == null)
			{
				return;
			}
			MethodInfo methodInfo = gunType?.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "SwitchWeapon" && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(int));
			if (methodInfo == null)
			{
				if (noticeLeft <= 0f)
				{
					Notify("YOU DO NOT OWN " + text2 + " CURRENTLY");
				}
				return;
			}
			try
			{
				methodInfo.Invoke(gun, new object[1] { 1 });
				if (noticeLeft <= 0f)
				{
					Notify("YOU DO NOT OWN " + text2 + " CURRENTLY");
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Weapon switch failed: " + ex.Message));
			}
		}

		private void BeginAd()
		{
			if (!ads.Value)
			{
				Notify("Ads disabled in config.");
				return;
			}
			adShowing = true;
			adLeft = Math.Max(1, adSeconds.Value);
			menu = true;
		}

		private Texture2D Solid(Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1);
			val.SetPixel(0, 0, color);
			val.Apply();
			return val;
		}

		private void SetupStyles()
		{
			//IL_001f: 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_0069: 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_008d: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_015a: 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_0179: Expected O, but got Unknown
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Expected O, but got Unknown
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Expected O, but got Unknown
			//IL_0226: 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_0241: Expected O, but got Unknown
			//IL_0268: 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_0283: Expected O, but got Unknown
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Expected O, but got Unknown
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Expected O, but got Unknown
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Expected O, but got Unknown
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Expected O, but got Unknown
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			if (panelStyle == null)
			{
				darkTexture = Solid(new Color(0.065f, 0.045f, 0.055f, 0.98f));
				cardTexture = Solid(new Color(0.15f, 0.09f, 0.105f, 0.98f));
				redTexture = Solid(new Color(0.62f, 0.12f, 0.16f, 1f));
				panelStyle = new GUIStyle(GUI.skin.box);
				panelStyle.normal.background = darkTexture;
				panelStyle.padding = new RectOffset(12, 12, 12, 12);
				cardStyle = new GUIStyle(GUI.skin.box);
				cardStyle.normal.background = cardTexture;
				cardStyle.padding = new RectOffset(14, 14, 12, 12);
				cardStyle.margin = new RectOffset(0, 0, 5, 7);
				titleStyle = new GUIStyle(GUI.skin.label);
				titleStyle.fontSize = 27;
				titleStyle.fontStyle = (FontStyle)1;
				titleStyle.normal.textColor = new Color(1f, 0.24f, 0.28f);
				headerStyle = new GUIStyle(GUI.skin.label);
				headerStyle.fontSize = 15;
				headerStyle.fontStyle = (FontStyle)1;
				headerStyle.normal.textColor = Color.white;
				subtitleStyle = new GUIStyle(GUI.skin.label);
				subtitleStyle.fontSize = 11;
				subtitleStyle.normal.textColor = new Color(0.72f, 0.62f, 0.63f);
				textStyle = new GUIStyle(GUI.skin.label);
				textStyle.fontSize = 13;
				textStyle.wordWrap = true;
				textStyle.normal.textColor = Color.white;
				smallStyle = new GUIStyle(textStyle);
				smallStyle.fontSize = 11;
				smallStyle.normal.textColor = new Color(0.75f, 0.68f, 0.69f);
				priceStyle = new GUIStyle(textStyle);
				priceStyle.fontSize = 18;
				priceStyle.fontStyle = (FontStyle)1;
				priceStyle.normal.textColor = new Color(1f, 0.32f, 0.34f);
				buttonStyle = new GUIStyle(GUI.skin.button);
				buttonStyle.normal.background = redTexture;
				buttonStyle.hover.background = redTexture;
				buttonStyle.active.background = redTexture;
				buttonStyle.normal.textColor = Color.white;
				buttonStyle.hover.textColor = Color.white;
				buttonStyle.active.textColor = Color.white;
				buttonStyle.fontSize = 13;
				buttonStyle.fontStyle = (FontStyle)1;
				buttonStyle.padding = new RectOffset(10, 10, 10, 10);
				buttonStyle.margin = new RectOffset(0, 0, 7, 5);
				noticeStyle = new GUIStyle(GUI.skin.box);
				noticeStyle.normal.background = cardTexture;
				noticeStyle.normal.textColor = Color.white;
				noticeStyle.fontSize = 13;
				noticeStyle.wordWrap = true;
				noticeStyle.alignment = (TextAnchor)4;
			}
		}

		private void SetupPremiumPopup()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			if (premiumPopupTitle == null)
			{
				SetupStyles();
				premiumPopupTitle = new GUIStyle(GUI.skin.label);
				premiumPopupTitle.fontSize = 23;
				premiumPopupTitle.fontStyle = (FontStyle)1;
				premiumPopupTitle.alignment = (TextAnchor)4;
				premiumPopupTitle.normal.textColor = Color.white;
				premiumPopupSmall = new GUIStyle(GUI.skin.label);
				premiumPopupSmall.fontSize = 11;
				premiumPopupSmall.alignment = (TextAnchor)4;
				premiumPopupSmall.normal.textColor = new Color(0.78f, 0.72f, 0.72f);
			}
		}

		private void DrawPremiumPopup()
		{
			//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)
			//IL_00d2: 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)
			SetupPremiumPopup();
			float num = Mathf.Min(270f, (float)Screen.width - 20f);
			float num2 = 104f;
			if (!(num < 120f) && !((float)Screen.height < num2 + 20f))
			{
				Rect val = default(Rect);
				((Rect)(ref val))..ctor((float)Screen.width - num - 15f, (float)Screen.height - num2 - 15f, num, num2);
				GUI.Box(val, "", cardStyle);
				GUI.Label(new Rect(((Rect)(ref val)).x + 8f, ((Rect)(ref val)).y + 9f, num - 16f, 22f), "ULTRAKILL+  ADVERTISEMENT", subtitleStyle);
				GUI.Label(new Rect(((Rect)(ref val)).x + 8f, ((Rect)(ref val)).y + 32f, num - 16f, 38f), "BUY PREMIUM", premiumPopupTitle);
				GUI.Label(new Rect(((Rect)(ref val)).x + 8f, ((Rect)(ref val)).y + 72f, num - 16f, 20f), "click enter to continue", premiumPopupSmall);
			}
		}

		private void OnDestroy()
		{
			if (weaponHarmony != null)
			{
				weaponHarmony.UnpatchSelf();
			}
			if ((Object)(object)activePlugin == (Object)(object)this)
			{
				activePlugin = null;
			}
			if ((Object)(object)darkTexture != (Object)null)
			{
				Object.Destroy((Object)(object)darkTexture);
			}
			if ((Object)(object)cardTexture != (Object)null)
			{
				Object.Destroy((Object)(object)cardTexture);
			}
			if ((Object)(object)redTexture != (Object)null)
			{
				Object.Destroy((Object)(object)redTexture);
			}
		}

		private void OnGUI()
		{
			//IL_004b: 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_0191: 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_01b2: Expected O, but got Unknown
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			SetupStyles();
			GUI.depth = -100;
			DrawPremiumPopup();
			if (noticeLeft > 0f)
			{
				float num = Mathf.Min((float)Screen.width - 20f, 560f);
				GUI.Box(new Rect(10f, (float)(Screen.height - 65), num, 52f), notice, noticeStyle);
			}
			if (adShowing)
			{
				float num2 = Mathf.Min((float)Screen.width - 20f, 480f);
				GUI.Box(new Rect(((float)Screen.width - num2) / 2f, ((float)Screen.height - 170f) / 2f, num2, 170f), "ULTRAKILL+  SPONSORED INTERRUPTION\n\nBUY NOTHING. OWN NOTHING.\n\nAD ENDS IN " + Math.Ceiling(adLeft) + " SECONDS", noticeStyle);
			}
			if (menu)
			{
				float num3 = Mathf.Min(570f, (float)Screen.width - 20f);
				float num4 = Mathf.Min(680f, (float)Screen.height - 20f);
				if (!(num3 < 200f) && !(num4 < 150f))
				{
					((Rect)(ref window)).width = num3;
					((Rect)(ref window)).height = num4;
					((Rect)(ref window)).x = Mathf.Clamp(((Rect)(ref window)).x, 0f, (float)Screen.width - num3);
					((Rect)(ref window)).y = Mathf.Clamp(((Rect)(ref window)).y, 0f, (float)Screen.height - num4);
					window = GUI.Window(938122, window, new WindowFunction(DrawWindow), "", panelStyle);
				}
			}
		}

		private void SubscriptionCard(string name, string description, int cost, float remaining, int tier)
		{
			GUILayout.BeginVertical(cardStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label(name, headerStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label(description, smallStyle, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(cost.ToString("N0") + " P", priceStyle, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUILayout.Label((remaining > 0f) ? ("ACTIVE " + Format(remaining)) : "EXPIRED", smallStyle, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			if (GUILayout.Button((remaining > 0f) ? "RENEW SUBSCRIPTION" : "PURCHASE LICENSE", buttonStyle, Array.Empty<GUILayoutOption>()))
			{
				Buy(cost, tier);
			}
			GUILayout.EndVertical();
		}

		private void DrawWindow(int id)
		{
			//IL_0014: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0481: Unknown result type (might be due to invalid IL or missing references)
			GUI.Label(new Rect(18f, 8f, 350f, 38f), "ULTRAKILL+", titleStyle);
			GUI.Label(new Rect(20f, 39f, 400f, 16f), "CORPORATE GREED EDITION", subtitleStyle);
			if (GUI.Button(new Rect(((Rect)(ref window)).width - 47f, 12f, 30f, 30f), "X", buttonStyle))
			{
				menu = false;
			}
			GUILayout.BeginArea(new Rect(15f, 63f, ((Rect)(ref window)).width - 30f, ((Rect)(ref window)).height - 78f));
			scrollPosition = GUILayout.BeginScrollView(scrollPosition, Array.Empty<GUILayoutOption>());
			GUILayout.Label("YOUR VIOLENCE. OUR REVENUE.", headerStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(7f);
			GUILayout.BeginVertical(cardStyle, Array.Empty<GUILayoutOption>());
			int? num = Balance();
			GUILayout.Label("YOUR ACCOUNT BALANCE", smallStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label(num.HasValue ? (num.Value.ToString("N0") + " P") : "P BALANCE UNAVAILABLE", priceStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("100 P = $1.00 (FICTIONAL CONVERSION ONLY)", smallStyle, Array.Empty<GUILayoutOption>());
			GUILayout.EndVertical();
			GUILayout.Space(8f);
			GUILayout.Label("SUBSCRIPTION PLANS", headerStyle, Array.Empty<GUILayoutOption>());
			SubscriptionCard("SHOTGUN+", "Your shotgun now requires a license. Obviously.", shotgunPrice.Value, shotgunLeft, 1);
			SubscriptionCard("PREMIUM+", "Premium weapon privileges for premium customers.", premiumPrice.Value, premiumLeft, 2);
			SubscriptionCard("DELUXE+", "The ultimate imaginary subscription.", deluxePrice.Value, deluxeLeft, 3);
			GUILayout.Space(9f);
			GUILayout.Label("SPONSORED CONTENT", headerStyle, Array.Empty<GUILayoutOption>());
			GUILayout.BeginVertical(cardStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("FREE REVOLVER TIER: AD SUPPORTED", textStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Ad-free swapping window: " + Format(swapLeft), smallStyle, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("WATCH A FAKE " + adSeconds.Value + " SECOND AD", buttonStyle, Array.Empty<GUILayoutOption>()))
			{
				BeginAd();
			}
			GUILayout.EndVertical();
			if (damagePrompt)
			{
				GUILayout.Space(8f);
				GUILayout.Label("DAMAGE LIMIT REACHED", headerStyle, Array.Empty<GUILayoutOption>());
				GUILayout.BeginVertical(cardStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Label("Congratulations! You have reached your fictional corporate damage allowance.", textStyle, Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("PAY " + upgradePrice.Value + " P TO DISMISS", buttonStyle, Array.Empty<GUILayoutOption>()) && Spend(upgradePrice.Value))
				{
					damagePrompt = false;
				}
				if (GUILayout.Button("WATCH FREE FAKE AD TO DISMISS", buttonStyle, Array.Empty<GUILayoutOption>()))
				{
					damagePrompt = false;
					BeginAd();
				}
				GUILayout.EndVertical();
			}
			GUILayout.Space(8f);
			GUILayout.Label("CORPORATE SETTINGS", headerStyle, Array.Empty<GUILayoutOption>());
			GUILayout.BeginVertical(cardStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("ULTRAKILL+: ALWAYS ENABLED", textStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("FAKE ADS: ALWAYS ENABLED", textStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("BOSS SURCHARGE: ALWAYS ENABLED", textStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("DAMAGE LIMIT: ALWAYS ENABLED", textStyle, Array.Empty<GUILayoutOption>());
			GUILayout.EndVertical();
			GUILayout.Space(12f);
			GUILayout.Label("ENTER: OPEN / CLOSE MENU", smallStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("NO REFUNDS. NO MERCY. NO REAL PAYMENTS.", smallStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(8f);
			if (GUILayout.Button("CLOSE MENU", buttonStyle, Array.Empty<GUILayoutOption>()))
			{
				menu = false;
			}
			GUILayout.EndScrollView();
			GUILayout.EndArea();
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref window)).width - 55f, 57f));
		}

		private string Format(float s)
		{
			return ((int)s / 60).ToString("00") + ":" + ((int)s % 60).ToString("00");
		}
	}
}