Decompiled source of BRCPlus v1.1.2

BRCPlus.dll

Decompiled a day 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.Cryptography;
using System.Text;
using BRCPlus.Phone;
using BepInEx;
using BepInEx.Configuration;
using CommonAPI.Phone;
using HarmonyLib;
using Reptile;
using Reptile.Phone;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("BRCPlus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BRCPlus")]
[assembly: AssemblyTitle("BRCPlus")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BRCPlus
{
	[BepInPlugin("com.brcplus", "BRC Plus", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class BRCPlusPlugin : BaseUnityPlugin
	{
		private static string _pluginFolder;

		public static readonly string[] SprayModeOptions = new string[3] { "Normal", "Quick", "Auto" };

		public static readonly string[] PlayerSizeOptions = new string[5] { "Normal", "Small", "Big", "Huge", "EXTRA HUGE" };

		public static readonly string[] GravityOptions = new string[3] { "Normal", "Low", "High" };

		private Harmony _harmony;

		public static ConfigEntry<bool> DisableHeat { get; private set; }

		public static ConfigEntry<bool> GodMode { get; private set; }

		public static ConfigEntry<bool> InfiniteBoost { get; private set; }

		public static ConfigEntry<bool> AlwaysInSpeedZone { get; private set; }

		public static ConfigEntry<string> SprayMode { get; private set; }

		public static ConfigEntry<bool> UIVisible_HealthBar { get; private set; }

		public static ConfigEntry<bool> UIVisible_BoostBar { get; private set; }

		public static ConfigEntry<bool> UIVisible_Score { get; private set; }

		public static ConfigEntry<bool> UIVisible_Context { get; private set; }

		public static ConfigEntry<bool> UIVisible_Rep { get; private set; }

		public static ConfigEntry<bool> UIVisible_Combo { get; private set; }

		public static ConfigEntry<string> PlayerSize { get; private set; }

		public static ConfigEntry<string> Gravity { get; private set; }

		public static ConfigEntry<bool> EnabledDebugMenu { get; private set; }

		private void Awake()
		{
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Expected O, but got Unknown
			_pluginFolder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			DisableHeat = ((BaseUnityPlugin)this).Config.Bind<bool>("Heat", "DisableHeat", false, "When true, disables the entire heat/wanted system (no stars, no police chases from crimes).");
			GodMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "GodMode", false, "When true, the player's health cannot go down (invulnerable to damage).");
			InfiniteBoost = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "Infinite Boost", false, "When true, the player's boost is always kept at maximum so they never lose boost.");
			AlwaysInSpeedZone = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "Always In Speed Zone", false, "When true, the game always treats the player as being in a speed zone (e.g. for slide/vert tricks).");
			SprayMode = ((BaseUnityPlugin)this).Config.Bind<string>("Graffiti", "SprayMode", "Normal", "Spray mode: Normal = full minigame. Quick = paint instantly when you start. Auto = paint instantly when in range (no button).");
			NormalizeSprayModeConfig();
			string text = "UI Options";
			UIVisible_HealthBar = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "Health Bar", true, "Show the health bar.");
			UIVisible_BoostBar = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "Boost Bar", true, "Show the boost/charge bar.");
			UIVisible_Score = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "Score", true, "Show the score display.");
			UIVisible_Context = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "Context Icons", true, "Show context icons (graffiti, talk, break chains).");
			UIVisible_Rep = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "Rep", true, "Show the rep display.");
			UIVisible_Combo = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "Combo", true, "Show the combo mascot and combo UI.");
			string text2 = "Fun";
			PlayerSize = ((BaseUnityPlugin)this).Config.Bind<string>(text2, "Player Size", "Normal", "Player scale: Normal, Small, or Big.");
			Gravity = ((BaseUnityPlugin)this).Config.Bind<string>(text2, "Gravity", "Normal", "Gravity: Normal (default), Low (floaty), or High (heavy).");
			EnabledDebugMenu = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnabledDebugMenu", false, "When true, enables the game's debug menu (toggle in-game). Requires restart to take effect.");
			NormalizePlayerSizeConfig();
			NormalizeGravityConfig();
			_harmony = new Harmony("com.brcplus");
			_harmony.PatchAll();
			AppBRCPlus.Initialize();
		}

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

		internal static void NormalizeSprayModeConfig()
		{
			if (SprayMode != null)
			{
				string value = SprayMode.Value;
				if (value != "Normal" && value != "Quick" && value != "Auto")
				{
					SprayMode.Value = "Normal";
				}
			}
		}

		internal static void NormalizePlayerSizeConfig()
		{
			if (PlayerSize != null)
			{
				string value = PlayerSize.Value;
				if (value != "Normal" && value != "Small" && value != "Big" && value != "Huge" && value != "EXTRA HUGE")
				{
					PlayerSize.Value = "Normal";
				}
			}
		}

		internal static void NormalizeGravityConfig()
		{
			if (Gravity != null)
			{
				string value = Gravity.Value;
				if (value != "Normal" && value != "Low" && value != "High")
				{
					Gravity.Value = "Normal";
				}
			}
		}

		public static string GetAppIconPath(string filename)
		{
			if (!string.IsNullOrEmpty(_pluginFolder))
			{
				return Path.Combine(_pluginFolder, filename);
			}
			return null;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "com.brcplus";

		public const string PLUGIN_NAME = "BRC Plus";

		public const string PLUGIN_VERSION = "1.0.0";
	}
	public class GameDebugBridge : AGameDebug
	{
		private UIManager _uiManager;

		private bool _menuCreated;

		public override bool IsShowingDebugMenu
		{
			get
			{
				DebugMenuController value = Traverse.Create((object)_uiManager).Field("debugMenuUIRoot").GetValue<DebugMenuController>();
				if ((Object)(object)value != (Object)null)
				{
					return ((AMenuController)value).IsEnabled;
				}
				return false;
			}
		}

		public GameDebugBridge(BaseModule baseModule, SaveManager saveManager, GameInput gameInput, UIManager uIManager)
			: base(baseModule, saveManager, gameInput, uIManager)
		{
			_uiManager = uIManager;
		}

		protected override void InitializeFPSCounter()
		{
		}

		protected override void UpdateKeyboardInput()
		{
			if (base.baseModule.IsPlayingInStage)
			{
				base.gameInput.EnableControllerMap(3, 0);
			}
			if (base.gameInput.GetButtonNew(40, 0))
			{
				((AGameDebug)this).ToggleDebugMenu();
			}
		}

		protected override void UpdateJoystickInput()
		{
			if (base.baseModule.IsPlayingInStage)
			{
				base.gameInput.EnableControllerMap(3, 0);
			}
			if (base.gameInput.GetButtonNew(40, 0))
			{
				((AGameDebug)this).ToggleDebugMenu();
			}
		}

		public override void ToggleDebugMenu()
		{
			DebugMenuController val = Traverse.Create((object)_uiManager).Field("debugMenuUIRoot").GetValue<DebugMenuController>();
			if ((Object)(object)val != (Object)null && ((AMenuController)val).IsEnabled)
			{
				_uiManager.PopCurrentMenu();
				if (base.baseModule.IsInGamePaused)
				{
					base.baseModule.UnPauseGame((PauseType)64);
				}
				return;
			}
			if ((Object)(object)val == (Object)null && (Object)(object)_uiManager.debugUIPrefab != (Object)null && !_menuCreated)
			{
				_menuCreated = true;
				GameObject obj = Object.Instantiate<GameObject>(_uiManager.debugUIPrefab);
				obj.transform.SetParent(((Component)_uiManager).transform, false);
				DebugMenuController componentInChildren = obj.GetComponentInChildren<DebugMenuController>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.InitDebugMenu((AGameDebug)(object)this, base.baseModule, base.saveManager, _uiManager);
					Traverse.Create((object)_uiManager).Field("debugMenuUIRoot").SetValue((object)componentInChildren);
					val = componentInChildren;
				}
			}
			if ((Object)(object)val != (Object)null && !((AMenuController)val).IsEnabled)
			{
				base.baseModule.PauseGame((PauseType)64);
				((Component)val).gameObject.SetActive(true);
				((AMenuController)val).Activate();
				_uiManager.PushNewMenu((IUIMenuController)(object)val);
				_uiManager.ForceFocusOnTopMenu();
			}
		}

		public override void ToggleFPSCounter()
		{
		}

		public override void CycleFPSCounterPreset()
		{
		}

		public override void RestartStage()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)base.baseModule != (Object)null && base.baseModule.StageManager != null)
			{
				base.baseModule.SwitchStage(base.baseModule.CurrentStage);
			}
		}

		public override void SelectStage(Stage stage)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)base.baseModule != (Object)null)
			{
				base.baseModule.SwitchStage(stage);
			}
		}

		public override void CycleQualitySettings()
		{
		}

		public override void UpdateLocalizationLanguage(SystemLanguage systemLanguage)
		{
		}
	}
	public static class PropDisguiseManager
	{
		private static Dictionary<int, GameObject> _propByIndex = new Dictionary<int, GameObject>();

		private static Dictionary<Player, (GameObject disguise, int id)> _playerDisguises = new Dictionary<Player, (GameObject, int)>();

		private static int HashString(string s)
		{
			byte[] bytes = Encoding.UTF8.GetBytes(s);
			return BitConverter.ToInt32(MD5.Create().ComputeHash(bytes), 0);
		}

		private static string GetHierarchyPath(GameObject go)
		{
			string text = ((Object)go).name;
			Transform val = go.transform;
			while ((Object)(object)val.parent != (Object)null)
			{
				val = val.parent;
				text = ((Object)val).name + "/" + text;
			}
			return text;
		}

		private static int GenerateGameObjectID(GameObject obj)
		{
			return HashString(GetHierarchyPath(obj) + "$" + obj.transform.GetSiblingIndex());
		}

		private static void CacheProps()
		{
			_propByIndex.Clear();
			Junk[] array = Object.FindObjectsOfType<Junk>();
			foreach (Junk val in array)
			{
				StageChunk componentInParent = ((Component)val).GetComponentInParent<StageChunk>();
				JunkStageHandler componentInParent2 = ((Component)val).GetComponentInParent<JunkStageHandler>();
				if (!((Object)(object)componentInParent == (Object)null) || !((Object)(object)componentInParent2 == (Object)null))
				{
					int key = GenerateGameObjectID(((Component)val).gameObject);
					_propByIndex[key] = ((Component)val).gameObject;
				}
			}
			StreetLife[] array2 = Object.FindObjectsOfType<StreetLife>();
			foreach (StreetLife val2 in array2)
			{
				if (!((Object)(object)((Component)val2).GetComponentInParent<StageChunk>() == (Object)null) && !((Object)(object)((Component)val2).GetComponent<MoveAlongPoints>() != (Object)null))
				{
					int key2 = GenerateGameObjectID(((Component)val2).gameObject);
					_propByIndex[key2] = ((Component)val2).gameObject;
				}
			}
		}

		public static List<(int id, string label)> GetPropsForMenu()
		{
			CacheProps();
			List<(int, string)> list = new List<(int, string)>();
			foreach (KeyValuePair<int, GameObject> item in _propByIndex)
			{
				if (!((Object)(object)item.Value == (Object)null))
				{
					list.Add((item.Key, ((Object)item.Value).name));
				}
			}
			return list;
		}

		public static int? GetNearestPropId(Player player)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return null;
			}
			CacheProps();
			if (_propByIndex.Count == 0)
			{
				return null;
			}
			Vector3 position = ((Component)player).transform.position;
			int value = 0;
			float num = float.MaxValue;
			bool flag = true;
			foreach (KeyValuePair<int, GameObject> item in _propByIndex)
			{
				if (!((Object)(object)item.Value == (Object)null))
				{
					float num2 = Vector3.Distance(position, item.Value.transform.position);
					if (flag || num2 < num)
					{
						flag = false;
						num = num2;
						value = item.Key;
					}
				}
			}
			if (!flag)
			{
				return value;
			}
			return null;
		}

		public static bool HasDisguise(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			CleanupNullDisguises();
			if (_playerDisguises.TryGetValue(player, out (GameObject, int) value))
			{
				return (Object)(object)value.Item1 != (Object)null;
			}
			return false;
		}

		private static void CleanupNullDisguises()
		{
			List<Player> list = new List<Player>();
			foreach (KeyValuePair<Player, (GameObject, int)> playerDisguise in _playerDisguises)
			{
				if ((Object)(object)playerDisguise.Value.Item1 == (Object)null)
				{
					list.Add(playerDisguise.Key);
				}
			}
			foreach (Player item in list)
			{
				_playerDisguises.Remove(item);
			}
		}

		private static void SetPlayerVisualVisible(Player player, bool visible)
		{
			Transform value = Traverse.Create((object)player).Field("visualTf").GetValue<Transform>();
			if ((Object)(object)value != (Object)null && (Object)(object)((Component)value).gameObject != (Object)null)
			{
				((Component)value).gameObject.SetActive(visible);
			}
		}

		private static void AutoAdjustProp(GameObject disguise, Player player)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_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_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_0052: 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_006a: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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_00ee: 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_0104: 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_0112: 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_012a: 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_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: 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_0169: 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_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: 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_0199: 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_01a4: 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_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: 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_01ce: 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_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: 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_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: 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_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			Renderer componentInChildren = disguise.GetComponentInChildren<Renderer>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return;
			}
			Bounds localBounds = componentInChildren.localBounds;
			Vector3[] array = (Vector3[])(object)new Vector3[8]
			{
				new Vector3(((Bounds)(ref localBounds)).min.x, ((Bounds)(ref localBounds)).min.y, ((Bounds)(ref localBounds)).min.z),
				new Vector3(((Bounds)(ref localBounds)).min.x, ((Bounds)(ref localBounds)).min.y, ((Bounds)(ref localBounds)).max.z),
				new Vector3(((Bounds)(ref localBounds)).min.x, ((Bounds)(ref localBounds)).max.y, ((Bounds)(ref localBounds)).max.z),
				new Vector3(((Bounds)(ref localBounds)).min.x, ((Bounds)(ref localBounds)).max.y, ((Bounds)(ref localBounds)).min.z),
				new Vector3(((Bounds)(ref localBounds)).max.x, ((Bounds)(ref localBounds)).max.y, ((Bounds)(ref localBounds)).max.z),
				new Vector3(((Bounds)(ref localBounds)).max.x, ((Bounds)(ref localBounds)).max.y, ((Bounds)(ref localBounds)).min.z),
				new Vector3(((Bounds)(ref localBounds)).max.x, ((Bounds)(ref localBounds)).min.y, ((Bounds)(ref localBounds)).min.z),
				new Vector3(((Bounds)(ref localBounds)).max.x, ((Bounds)(ref localBounds)).min.y, ((Bounds)(ref localBounds)).max.z)
			};
			Vector3 val = Vector3.zero;
			float num = float.MaxValue;
			for (int i = 0; i < array.Length; i++)
			{
				Vector3 val2 = ((Component)componentInChildren).transform.TransformPoint(array[i]);
				Vector3 val3 = ((Component)player).transform.InverseTransformPoint(val2);
				val += val3;
				if (val3.y < num)
				{
					num = val3.y;
				}
			}
			val /= (float)array.Length;
			val.y = num;
			disguise.transform.localPosition = -val;
		}

		public static bool ApplyDisguise(Player player, int disguiseId)
		{
			//IL_00de: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			CacheProps();
			if (!_propByIndex.TryGetValue(disguiseId, out var value) || (Object)(object)value == (Object)null)
			{
				return false;
			}
			RemoveDisguise(player);
			SetPlayerVisualVisible(player, visible: false);
			GameObject val = Object.Instantiate<GameObject>(value);
			val.SetActive(true);
			bool flag = false;
			Junk component = val.GetComponent<Junk>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
				flag = true;
			}
			Rigidbody component2 = val.GetComponent<Rigidbody>();
			if ((Object)(object)component2 != (Object)null)
			{
				Object.Destroy((Object)(object)component2);
			}
			StreetLife component3 = val.GetComponent<StreetLife>();
			if ((Object)(object)component3 != (Object)null)
			{
				Animator component4 = val.GetComponent<Animator>();
				if ((Object)(object)component4 != (Object)null)
				{
					int num = Animator.StringToHash(((object)(IdleAnimation)(ref component3.idleAnimation)).ToString());
					component4.Play(num, 0);
				}
				Object.Destroy((Object)(object)component3);
			}
			val.transform.SetParent(((Component)player).transform);
			val.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
			if (flag)
			{
				val.transform.rotation = value.transform.rotation;
			}
			val.transform.localScale = value.transform.localScale;
			if ((Object)(object)WorldHandler.instance != (Object)null && (Object)(object)WorldHandler.instance.GetCurrentPlayer() == (Object)(object)player)
			{
				if ((Object)(object)component3 == (Object)null)
				{
					AutoAdjustProp(val, player);
				}
				val.layer = 15;
				Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>();
				foreach (Collider val2 in componentsInChildren)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						Object.Destroy((Object)(object)val2);
					}
				}
			}
			_playerDisguises[player] = (val, disguiseId);
			return true;
		}

		public static bool RemoveDisguise(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			CleanupNullDisguises();
			if (!_playerDisguises.TryGetValue(player, out (GameObject, int) value))
			{
				return false;
			}
			_playerDisguises.Remove(player);
			if ((Object)(object)value.Item1 != (Object)null)
			{
				Object.Destroy((Object)(object)value.Item1);
			}
			SetPlayerVisualVisible(player, visible: true);
			return true;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "BRCPlus";

		public const string PLUGIN_NAME = "BRCPlus";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace BRCPlus.Phone
{
	public class AppBRCPlus : CustomApp
	{
		private static readonly (string Label, Stage Stage)[] TravelableMaps = new(string, Stage)[8]
		{
			("Hideout", (Stage)5),
			("Police Station", (Stage)8),
			("Versum Hill", (Stage)4),
			("Millennium Mall", (Stage)6),
			("Mataan", (Stage)7),
			("Pyramid Island", (Stage)9),
			("Millennium Square", (Stage)11),
			("Brink Terminal", (Stage)12)
		};

		public static void Initialize()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0062: 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)
			Sprite val = null;
			string appIconPath = BRCPlusPlugin.GetAppIconPath("AppIcon.png");
			if (!string.IsNullOrEmpty(appIconPath) && File.Exists(appIconPath))
			{
				try
				{
					byte[] array = File.ReadAllBytes(appIconPath);
					Texture2D val2 = new Texture2D(2, 2);
					if (ImageConversion.LoadImage(val2, array))
					{
						((Texture)val2).wrapMode = (TextureWrapMode)1;
						((Texture)val2).filterMode = (FilterMode)1;
						val2.Apply();
						val = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f));
					}
				}
				catch
				{
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				PhoneAPI.RegisterApp<AppBRCPlus>("BRC Plus", val);
			}
			else
			{
				PhoneAPI.RegisterApp<AppBRCPlus>("BRC Plus", (Sprite)null);
			}
		}

		public override void OnAppInit()
		{
			((CustomApp)this).OnAppInit();
			((CustomApp)this).CreateIconlessTitleBar("BRC Plus", 80f);
			base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
			PopulateButtons();
		}

		public override void OnAppEnable()
		{
			((App)this).OnAppEnable();
			PopulateButtons();
		}

		private void PopulateButtons()
		{
			base.ScrollView.RemoveAllButtons();
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Fun");
			((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, new Action(ShowFunMenu));
			base.ScrollView.AddButton((PhoneButton)(object)val);
			SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Toggles");
			((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, new Action(ShowTogglesMenu));
			base.ScrollView.AddButton((PhoneButton)(object)val2);
			SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Maps");
			((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, new Action(ShowMapsMenu));
			base.ScrollView.AddButton((PhoneButton)(object)val3);
			SimplePhoneButton val4 = PhoneUIUtility.CreateSimpleButton("Graffiti");
			((PhoneButton)val4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val4).OnConfirm, new Action(ShowGraffitiMenu));
			base.ScrollView.AddButton((PhoneButton)(object)val4);
			SimplePhoneButton val5 = PhoneUIUtility.CreateSimpleButton("Heat");
			((PhoneButton)val5).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val5).OnConfirm, new Action(ShowHeatMenu));
			base.ScrollView.AddButton((PhoneButton)(object)val5);
			SimplePhoneButton val6 = PhoneUIUtility.CreateSimpleButton("UI Options");
			((PhoneButton)val6).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val6).OnConfirm, new Action(ShowUIOptionsMenu));
			base.ScrollView.AddButton((PhoneButton)(object)val6);
		}

		private void ShowFunMenu()
		{
			base.ScrollView.RemoveAllButtons();
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Props");
			((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, new Action(ShowPropsMenu));
			base.ScrollView.AddButton((PhoneButton)(object)val);
			BRCPlusPlugin.NormalizePlayerSizeConfig();
			string text = BRCPlusPlugin.PlayerSize?.Value ?? "Normal";
			SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Player Size: " + text);
			((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate
			{
				if (BRCPlusPlugin.PlayerSize != null)
				{
					string[] playerSizeOptions = BRCPlusPlugin.PlayerSizeOptions;
					int num2 = Array.IndexOf(playerSizeOptions, BRCPlusPlugin.PlayerSize.Value);
					num2 = ((num2 >= 0) ? (num2 + 1) : 0) % playerSizeOptions.Length;
					BRCPlusPlugin.PlayerSize.Value = playerSizeOptions[num2];
					ShowFunMenu();
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val2);
			BRCPlusPlugin.NormalizeGravityConfig();
			string text2 = BRCPlusPlugin.Gravity?.Value ?? "Normal";
			SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Gravity: " + text2);
			((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, (Action)delegate
			{
				if (BRCPlusPlugin.Gravity != null)
				{
					string[] gravityOptions = BRCPlusPlugin.GravityOptions;
					int num = Array.IndexOf(gravityOptions, BRCPlusPlugin.Gravity.Value);
					num = ((num >= 0) ? (num + 1) : 0) % gravityOptions.Length;
					BRCPlusPlugin.Gravity.Value = gravityOptions[num];
					ShowFunMenu();
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val3);
			SimplePhoneButton val4 = PhoneUIUtility.CreateSimpleButton("Back");
			((PhoneButton)val4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val4).OnConfirm, new Action(PopulateButtons));
			base.ScrollView.AddButton((PhoneButton)(object)val4);
		}

		private void ShowPropsMenu()
		{
			base.ScrollView.RemoveAllButtons();
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Turn Into Nearest Prop");
			((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate
			{
				WorldHandler instance2 = WorldHandler.instance;
				Player val6 = ((instance2 != null) ? instance2.GetCurrentPlayer() : null);
				if (!((Object)(object)val6 == (Object)null))
				{
					int? nearestPropId = PropDisguiseManager.GetNearestPropId(val6);
					if (nearestPropId.HasValue)
					{
						PropDisguiseManager.ApplyDisguise(val6, nearestPropId.Value);
					}
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Remove Prop");
			((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate
			{
				WorldHandler instance = WorldHandler.instance;
				Player val5 = ((instance != null) ? instance.GetCurrentPlayer() : null);
				if (!((Object)(object)val5 == (Object)null) && PropDisguiseManager.HasDisguise(val5))
				{
					PropDisguiseManager.RemoveDisguise(val5);
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val2);
			SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Props in this map");
			((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, new Action(ShowPropsInThisMapMenu));
			base.ScrollView.AddButton((PhoneButton)(object)val3);
			SimplePhoneButton val4 = PhoneUIUtility.CreateSimpleButton("Back");
			((PhoneButton)val4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val4).OnConfirm, new Action(ShowFunMenu));
			base.ScrollView.AddButton((PhoneButton)(object)val4);
		}

		private void ShowPropsInThisMapMenu()
		{
			base.ScrollView.RemoveAllButtons();
			foreach (var item3 in PropDisguiseManager.GetPropsForMenu())
			{
				int item = item3.id;
				string item2 = item3.label;
				int propId = item;
				SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton(item2);
				((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate
				{
					WorldHandler instance = WorldHandler.instance;
					Player val3 = ((instance != null) ? instance.GetCurrentPlayer() : null);
					if (!((Object)(object)val3 == (Object)null))
					{
						PropDisguiseManager.ApplyDisguise(val3, propId);
					}
				});
				base.ScrollView.AddButton((PhoneButton)(object)val);
			}
			SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Back");
			((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, new Action(ShowPropsMenu));
			base.ScrollView.AddButton((PhoneButton)(object)val2);
		}

		private void ShowMapsMenu()
		{
			//IL_0023: 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_0043: 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)
			base.ScrollView.RemoveAllButtons();
			(string, Stage)[] travelableMaps = TravelableMaps;
			for (int i = 0; i < travelableMaps.Length; i++)
			{
				(string, Stage) tuple = travelableMaps[i];
				string item = tuple.Item1;
				Stage item2 = tuple.Item2;
				SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton(item);
				Stage stageToLoad = item2;
				((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					TravelToStage(stageToLoad);
				});
				base.ScrollView.AddButton((PhoneButton)(object)val);
			}
			SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Back");
			((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, new Action(PopulateButtons));
			base.ScrollView.AddButton((PhoneButton)(object)val2);
		}

		private void TravelToStage(Stage stage)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			Core instance = Core.Instance;
			if ((Object)(object)((instance != null) ? instance.BaseModule : null) == (Object)null)
			{
				return;
			}
			BaseModule baseModule = instance.BaseModule;
			if (baseModule.IsLoading)
			{
				return;
			}
			StageManager stageManager = baseModule.StageManager;
			if (stageManager != null)
			{
				if (baseModule.IsInGamePaused)
				{
					baseModule.UnPauseGame((PauseType)65535);
				}
				stageManager.ExitCurrentStage(stage, (Stage)(-1));
			}
		}

		private void ShowGraffitiMenu()
		{
			base.ScrollView.RemoveAllButtons();
			BRCPlusPlugin.NormalizeSprayModeConfig();
			string text = BRCPlusPlugin.SprayMode?.Value ?? "Normal";
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Spray Mode: " + text);
			((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate
			{
				if (BRCPlusPlugin.SprayMode != null)
				{
					string[] sprayModeOptions = BRCPlusPlugin.SprayModeOptions;
					int num = Array.IndexOf(sprayModeOptions, BRCPlusPlugin.SprayMode.Value);
					num = ((num >= 0) ? (num + 1) : 0) % sprayModeOptions.Length;
					BRCPlusPlugin.SprayMode.Value = sprayModeOptions[num];
					ShowGraffitiMenu();
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Back");
			((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, new Action(PopulateButtons));
			base.ScrollView.AddButton((PhoneButton)(object)val2);
		}

		private void ShowHeatMenu()
		{
			base.ScrollView.RemoveAllButtons();
			bool flag = BRCPlusPlugin.DisableHeat?.Value ?? false;
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Disable Heat: " + (flag ? "On" : "Off"));
			((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate
			{
				if (BRCPlusPlugin.DisableHeat != null)
				{
					BRCPlusPlugin.DisableHeat.Value = !BRCPlusPlugin.DisableHeat.Value;
					ShowHeatMenu();
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Add Heat");
			((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, new Action(AddHeat));
			base.ScrollView.AddButton((PhoneButton)(object)val2);
			SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Remove Heat");
			((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, new Action(RemoveHeat));
			base.ScrollView.AddButton((PhoneButton)(object)val3);
			SimplePhoneButton val4 = PhoneUIUtility.CreateSimpleButton("Back");
			((PhoneButton)val4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val4).OnConfirm, new Action(PopulateButtons));
			base.ScrollView.AddButton((PhoneButton)(object)val4);
		}

		private void ShowTogglesMenu()
		{
			base.ScrollView.RemoveAllButtons();
			bool flag = BRCPlusPlugin.GodMode?.Value ?? false;
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("God Mode: " + (flag ? "On" : "Off"));
			((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate
			{
				if (BRCPlusPlugin.GodMode != null)
				{
					BRCPlusPlugin.GodMode.Value = !BRCPlusPlugin.GodMode.Value;
					ShowTogglesMenu();
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			bool flag2 = BRCPlusPlugin.InfiniteBoost?.Value ?? false;
			SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Infinite Boost: " + (flag2 ? "On" : "Off"));
			((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate
			{
				if (BRCPlusPlugin.InfiniteBoost != null)
				{
					BRCPlusPlugin.InfiniteBoost.Value = !BRCPlusPlugin.InfiniteBoost.Value;
					ShowTogglesMenu();
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val2);
			bool flag3 = BRCPlusPlugin.AlwaysInSpeedZone?.Value ?? false;
			SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Always In Speed Zone: " + (flag3 ? "On" : "Off"));
			((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, (Action)delegate
			{
				if (BRCPlusPlugin.AlwaysInSpeedZone != null)
				{
					BRCPlusPlugin.AlwaysInSpeedZone.Value = !BRCPlusPlugin.AlwaysInSpeedZone.Value;
					ShowTogglesMenu();
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val3);
			SimplePhoneButton val4 = PhoneUIUtility.CreateSimpleButton("Back");
			((PhoneButton)val4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val4).OnConfirm, new Action(PopulateButtons));
			base.ScrollView.AddButton((PhoneButton)(object)val4);
		}

		private void ShowUIOptionsMenu()
		{
			base.ScrollView.RemoveAllButtons();
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Visible");
			((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, new Action(ShowUIVisibleMenu));
			base.ScrollView.AddButton((PhoneButton)(object)val);
			SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Back");
			((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, new Action(PopulateButtons));
			base.ScrollView.AddButton((PhoneButton)(object)val2);
		}

		private void ShowUIVisibleMenu()
		{
			base.ScrollView.RemoveAllButtons();
			AddUIVisibleToggle("Health Bar", BRCPlusPlugin.UIVisible_HealthBar);
			AddUIVisibleToggle("Boost Bar", BRCPlusPlugin.UIVisible_BoostBar);
			AddUIVisibleToggle("Score", BRCPlusPlugin.UIVisible_Score);
			AddUIVisibleToggle("Context Icons", BRCPlusPlugin.UIVisible_Context);
			AddUIVisibleToggle("Rep", BRCPlusPlugin.UIVisible_Rep);
			AddUIVisibleToggle("Combo", BRCPlusPlugin.UIVisible_Combo);
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Back");
			((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, new Action(ShowUIOptionsMenu));
			base.ScrollView.AddButton((PhoneButton)(object)val);
		}

		private void AddUIVisibleToggle(string label, ConfigEntry<bool> config)
		{
			if (config != null)
			{
				bool value = config.Value;
				SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton(label + ": " + (value ? "Visible" : "Hidden"));
				((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate
				{
					config.Value = !config.Value;
					ShowUIVisibleMenu();
				});
				base.ScrollView.AddButton((PhoneButton)(object)val);
			}
		}

		private void AddHeat()
		{
			ConfigEntry<bool> disableHeat = BRCPlusPlugin.DisableHeat;
			if (disableHeat != null && disableHeat.Value)
			{
				return;
			}
			WantedManager instance = WantedManager.instance;
			if (!((Object)(object)instance == (Object)null))
			{
				int num = Mathf.Min((instance.Wanted ? instance.WantedStars : 0) + 1, 7);
				instance.SetDebugStarAmount(num);
				if (num >= 1 && !instance.Wanted)
				{
					typeof(WantedManager).GetMethod("MakePlayerWanted", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(instance, new object[1] { (object)(Crime)0 });
				}
			}
		}

		private void RemoveHeat()
		{
			ConfigEntry<bool> disableHeat = BRCPlusPlugin.DisableHeat;
			if (disableHeat != null && disableHeat.Value)
			{
				return;
			}
			WantedManager instance = WantedManager.instance;
			if (!((Object)(object)instance == (Object)null) && instance.Wanted)
			{
				if (instance.WantedStars <= 1)
				{
					instance.StopPlayerWantedStatus(true);
				}
				else
				{
					typeof(WantedManager).GetMethod("DecreaseStars", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(instance, null);
				}
			}
		}
	}
}
namespace BRCPlus.Patches
{
	[HarmonyPatch(typeof(APlatform))]
	[HarmonyPatch("CreateDebugInstanceForPlatform")]
	internal static class APlatformCreateDebugInstanceForPlatformPatch
	{
		public static bool Prefix(BaseModule baseModule, SaveManager saveManager, GameInput gameInput, UIManager uIManager, ref AGameDebug __result)
		{
			ConfigEntry<bool> enabledDebugMenu = BRCPlusPlugin.EnabledDebugMenu;
			if (enabledDebugMenu == null || !enabledDebugMenu.Value)
			{
				return true;
			}
			__result = (AGameDebug)(object)new GameDebugBridge(baseModule, saveManager, gameInput, uIManager);
			return false;
		}
	}
	[HarmonyPatch(typeof(Player))]
	internal static class GraffitiPatch
	{
		private static bool IsQuickOrAuto()
		{
			string text = BRCPlusPlugin.SprayMode?.Value ?? "Normal";
			if (!(text == "Quick"))
			{
				return text == "Auto";
			}
			return true;
		}

		private static bool IsAuto()
		{
			return (BRCPlusPlugin.SprayMode?.Value ?? "Normal") == "Auto";
		}

		private static GraffitiArtInfo GetGraffitiArtInfo(GraffitiSpot spot)
		{
			return Traverse.Create((object)spot).Property("GraffitiArtInfo", (object[])null).GetValue<GraffitiArtInfo>();
		}

		private static GraffitiArt GetGraffitiArtForSpot(GraffitiSpot spot, Player player)
		{
			//IL_0022: 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_0029: 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_0031: 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)
			GraffitiArtInfo graffitiArtInfo = GetGraffitiArtInfo(spot);
			if ((Object)(object)graffitiArtInfo == (Object)null)
			{
				return null;
			}
			Characters value = Traverse.Create((object)player).Field("character").GetValue<Characters>();
			if ((int)spot.size == 0)
			{
				return graffitiArtInfo.FindByCharacter(value);
			}
			List<GraffitiArt> list = graffitiArtInfo.FindBySize(spot.size);
			if (list == null || list.Count == 0)
			{
				return null;
			}
			Core instance = Core.Instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				APlatform platform = instance.Platform;
				obj = ((platform != null) ? platform.User : null);
			}
			AUser val = (AUser)obj;
			List<GraffitiArt> list2 = new List<GraffitiArt>();
			for (int i = 0; i < list.Count; i++)
			{
				GraffitiArt val2 = list[i];
				if ((Object)(object)val2?.unlockable != (Object)null && val != null && val.GetUnlockableSaveDataFor((AUnlockable)(object)val2.unlockable).IsUnlocked)
				{
					list2.Add(val2);
				}
			}
			if (list2.Count == 0)
			{
				return graffitiArtInfo.FindByCharacter(value);
			}
			return list2[Random.Range(0, list2.Count)];
		}

		[HarmonyPrefix]
		[HarmonyPatch("StartGraffitiMode")]
		private static bool StartGraffitiMode_Prefix(Player __instance, GraffitiSpot graffitiSpot)
		{
			//IL_01b6: 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_006b: 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_0072: 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_0087: Expected I4, but got Unknown
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Expected I4, but got Unknown
			//IL_02b9: 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_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Expected I4, but got Unknown
			//IL_008b: 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_0095: 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_009d: Invalid comparison between Unknown and I4
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Invalid comparison between Unknown and I4
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			if (!IsQuickOrAuto())
			{
				return true;
			}
			Traverse val = Traverse.Create((object)__instance);
			if (__instance.IsBusyWithSequence() || __instance.IsDead())
			{
				return true;
			}
			if (val.Field("ability").GetValue() == val.Field("danceAbility").GetValue())
			{
				return true;
			}
			if (val.Field("isAI").GetValue<bool>())
			{
				return true;
			}
			GraffitiArt graffitiArtForSpot = GetGraffitiArtForSpot(graffitiSpot, __instance);
			if (graffitiArtForSpot == null)
			{
				return true;
			}
			TrickType val2 = (TrickType)16;
			GraffitiSize size = graffitiSpot.size;
			switch (size - 1)
			{
			case 0:
				val2 = (TrickType)17;
				break;
			case 1:
				val2 = (TrickType)18;
				break;
			case 2:
				val2 = (TrickType)19;
				break;
			}
			bool flag = (int)graffitiSpot.bottomCrew == 1 || (int)graffitiSpot.bottomCrew == 7;
			__instance.DoTrick(val2, graffitiArtForSpot.title, 0);
			typeof(GraffitiSpot).GetMethod("Paint", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(graffitiSpot, new object[3]
			{
				(object)(Crew)1,
				graffitiArtForSpot,
				__instance
			});
			graffitiSpot.GiveRep(false, flag);
			graffitiSpot.SetLastPlayer(__instance);
			graffitiSpot.SetState((GraffitiState)2);
			typeof(GraffitiSpot).GetMethod("SpawnRep", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(graffitiSpot, null);
			try
			{
				__instance.PlayVoice((AudioClipID)498, (VoicePriority)2, true);
			}
			catch
			{
			}
			try
			{
				object value = val.Field("audioManager").GetValue();
				value?.GetType().GetMethod("PlaySfxGameplay", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(value, new object[3]
				{
					(object)(SfxCollectionID)13,
					(object)(AudioClipID)559,
					0f
				});
			}
			catch
			{
			}
			__instance.RemoveGraffitiSlash();
			try
			{
				__instance.CreateGraffitiFinishEffect(((Component)graffitiSpot).transform, graffitiSpot.size);
			}
			catch
			{
			}
			WorldHandler instance = WorldHandler.instance;
			object obj4 = (((Object)(object)instance != (Object)null) ? Traverse.Create((object)instance).Field("currentEncounter").GetValue() : null);
			if (((UnityEventBase)graffitiSpot.OnFinish).GetPersistentEventCount() == 0 && obj4 == null && graffitiSpot.reportAsCrime)
			{
				size = graffitiSpot.size;
				switch ((int)size)
				{
				case 0:
				{
					WantedManager instance5 = WantedManager.instance;
					if (instance5 != null)
					{
						instance5.CrimePerpetrated((Crime)0, false);
					}
					break;
				}
				case 1:
				{
					WantedManager instance3 = WantedManager.instance;
					if (instance3 != null)
					{
						instance3.CrimePerpetrated((Crime)1, false);
					}
					break;
				}
				case 2:
				{
					WantedManager instance4 = WantedManager.instance;
					if (instance4 != null)
					{
						instance4.CrimePerpetrated((Crime)2, false);
					}
					break;
				}
				case 3:
				{
					WantedManager instance2 = WantedManager.instance;
					if (instance2 != null)
					{
						instance2.CrimePerpetrated((Crime)3, false);
					}
					break;
				}
				}
			}
			__instance.RegainAirMobility();
			val.Field("newSpraycan").SetValue((object)true);
			if (val.Field("newGraffitiBonusMulti").GetValue<int>() > 1)
			{
				if (__instance.IsBusyWithSequence())
				{
					__instance.AddBoostCharge(Pickup.boostChargeValue * (float)graffitiSpot.size * 10f);
				}
				else
				{
					((MonoBehaviour)__instance).StartCoroutine(__instance.GiveBoostStack(((Component)graffitiSpot).transform, graffitiSpot.size * 10));
				}
			}
			Core instance6 = Core.Instance;
			if (instance6 != null)
			{
				APlatform platform = instance6.Platform;
				if (((platform != null) ? new bool?(platform.HasAchievementsSupport) : null) == true)
				{
					PlayerAchievements value2 = val.Field("playerAchievements").GetValue<PlayerAchievements>();
					if (value2 != null)
					{
						value2.CheckStageGraffitiAchievement();
					}
				}
			}
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnTriggerStay")]
		private static void OnTriggerStay_Postfix(Player __instance)
		{
			if (IsAuto())
			{
				Traverse.Create((object)__instance).Field("graffitiContextAvailable").SetValue((object)0);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("CheckAvailableGraffitiSpots")]
		private static bool CheckAvailableGraffitiSpots_Prefix(Player __instance)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			if (!IsAuto())
			{
				return true;
			}
			Traverse val = Traverse.Create((object)__instance);
			List<GraffitiSpot> value = val.Field("graffitiSpotsAvailable").GetValue<List<GraffitiSpot>>();
			if (value == null || value.Count == 0)
			{
				return true;
			}
			if (!val.Field("userInputEnabled").GetValue<bool>())
			{
				return true;
			}
			float num = float.MaxValue;
			GraffitiSpot val2 = null;
			MethodInfo method = typeof(GraffitiSpot).GetMethod("ClaimedByPlayableCrew", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
			foreach (GraffitiSpot item in value)
			{
				if (!((Object)(object)item == (Object)null))
				{
					Vector3 val3 = __instance.tf.position - ((Component)item).transform.position;
					float num2 = ((Vector3)(ref val3)).magnitude;
					if (method != null && (bool)method.Invoke(item, null))
					{
						num2 *= 4f;
					}
					if (((object)item).GetType() == typeof(GraffitiSpotFinisher) && ((Component)item).gameObject.activeSelf)
					{
						num2 *= 0.25f;
					}
					if (num2 < num)
					{
						num = num2;
						val2 = item;
					}
				}
			}
			if ((Object)(object)val2 != (Object)null)
			{
				__instance.StartGraffitiMode(val2);
				value.Clear();
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Player))]
	[HarmonyPatch("ChangeHP")]
	internal static class PlayerChangeHPPatch
	{
		public static bool Prefix(int dmg)
		{
			ConfigEntry<bool> godMode = BRCPlusPlugin.GodMode;
			if (godMode != null && godMode.Value && dmg > 0)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Player))]
	[HarmonyPatch("AddBoostCharge")]
	internal static class PlayerAddBoostChargePatch
	{
		public static bool Prefix(Player __instance)
		{
			ConfigEntry<bool> infiniteBoost = BRCPlusPlugin.InfiniteBoost;
			if (infiniteBoost == null || !infiniteBoost.Value)
			{
				return true;
			}
			float value = Traverse.Create((object)__instance).Field("maxBoostCharge").GetValue<float>();
			__instance.boostCharge = value;
			return false;
		}
	}
	[HarmonyPatch(typeof(Player))]
	[HarmonyPatch("UpdateBoostpack")]
	internal static class PlayerUpdateBoostpackPatch
	{
		private static Player _cachedPlayer;

		private static float _cachedMaxBoostCharge;

		public static void Postfix(Player __instance)
		{
			ConfigEntry<bool> infiniteBoost = BRCPlusPlugin.InfiniteBoost;
			if (infiniteBoost != null && infiniteBoost.Value)
			{
				if ((Object)(object)__instance != (Object)(object)_cachedPlayer)
				{
					_cachedPlayer = __instance;
					_cachedMaxBoostCharge = Traverse.Create((object)__instance).Field("maxBoostCharge").GetValue<float>();
				}
				__instance.boostCharge = _cachedMaxBoostCharge;
			}
		}
	}
	[HarmonyPatch(typeof(Player))]
	[HarmonyPatch("UpdateUIDisplay")]
	internal static class PlayerUpdateUIDisplayPatch
	{
		private static void SetActive(object componentOrGo, bool active)
		{
			if (componentOrGo == null)
			{
				return;
			}
			GameObject val = (GameObject)((componentOrGo is GameObject) ? componentOrGo : null);
			if (val != null)
			{
				val.SetActive(active);
				return;
			}
			Component val2 = (Component)((componentOrGo is Component) ? componentOrGo : null);
			if (val2 != null && (Object)(object)val2.gameObject != (Object)null)
			{
				val2.gameObject.SetActive(active);
			}
		}

		private static bool AllUIOptionsVisible()
		{
			ConfigEntry<bool> uIVisible_HealthBar = BRCPlusPlugin.UIVisible_HealthBar;
			if (uIVisible_HealthBar == null || uIVisible_HealthBar.Value)
			{
				ConfigEntry<bool> uIVisible_BoostBar = BRCPlusPlugin.UIVisible_BoostBar;
				if (uIVisible_BoostBar == null || uIVisible_BoostBar.Value)
				{
					ConfigEntry<bool> uIVisible_Score = BRCPlusPlugin.UIVisible_Score;
					if (uIVisible_Score == null || uIVisible_Score.Value)
					{
						ConfigEntry<bool> uIVisible_Context = BRCPlusPlugin.UIVisible_Context;
						if (uIVisible_Context == null || uIVisible_Context.Value)
						{
							ConfigEntry<bool> uIVisible_Rep = BRCPlusPlugin.UIVisible_Rep;
							if (uIVisible_Rep == null || uIVisible_Rep.Value)
							{
								return BRCPlusPlugin.UIVisible_Combo?.Value ?? true;
							}
						}
					}
				}
			}
			return false;
		}

		public static void Postfix(Player __instance)
		{
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<bool> alwaysInSpeedZone = BRCPlusPlugin.AlwaysInSpeedZone;
			if (alwaysInSpeedZone != null && alwaysInSpeedZone.Value)
			{
				Traverse.Create((object)__instance).Field("inSpeedZone").SetValue((object)true);
			}
			string text = BRCPlusPlugin.Gravity?.Value ?? "Normal";
			if ((Object)(object)__instance.motor != (Object)null && text != "Normal")
			{
				if (text == "Low")
				{
					__instance.motor.gravity = 10f;
					__instance.motor.gravityUp = 4f;
				}
				else if (text == "High")
				{
					__instance.motor.gravity = 45f;
					__instance.motor.gravityUp = 18f;
				}
			}
			if (BRCPlusPlugin.PlayerSize != null)
			{
				float num = BRCPlusPlugin.PlayerSize.Value switch
				{
					"EXTRA HUGE" => 6f, 
					"Huge" => 3f, 
					"Big" => 1.5f, 
					"Small" => 0.5f, 
					_ => 1f, 
				};
				((Component)__instance).transform.localScale = new Vector3(num, num, num);
			}
			if (AllUIOptionsVisible())
			{
				return;
			}
			object value = Traverse.Create((object)__instance).Field("ui").GetValue();
			if (value == null)
			{
				return;
			}
			Traverse val = Traverse.Create(value);
			if (BRCPlusPlugin.UIVisible_HealthBar != null && !BRCPlusPlugin.UIVisible_HealthBar.Value)
			{
				SetActive(val.Field("healthBarGroup").GetValue(), active: false);
			}
			if (BRCPlusPlugin.UIVisible_BoostBar != null)
			{
				object value2 = val.Field("chargeBar").GetValue();
				Component val2 = (Component)((value2 is Component) ? value2 : null);
				if (val2 != null && (Object)(object)val2.transform != (Object)null)
				{
					Transform parent = val2.transform.parent;
					Transform val3 = (((Object)(object)parent != (Object)null) ? parent.parent : null);
					(((Object)(object)val3 != (Object)null) ? ((Component)val3).gameObject : (((Object)(object)parent != (Object)null) ? ((Component)parent).gameObject : val2.gameObject)).SetActive(BRCPlusPlugin.UIVisible_BoostBar.Value);
				}
			}
			if (BRCPlusPlugin.UIVisible_Score != null)
			{
				SetActive(val.Field("scoreCalcLabel").GetValue(), BRCPlusPlugin.UIVisible_Score.Value);
			}
			if (BRCPlusPlugin.UIVisible_Context != null && !BRCPlusPlugin.UIVisible_Context.Value)
			{
				SetActive(val.Field("contextLabelGameObject").GetValue(), active: false);
				SetActive(val.Field("contextGraffitiIcon").GetValue(), active: false);
				SetActive(val.Field("contextTalkIcon").GetValue(), active: false);
				SetActive(val.Field("breakChainsContextIcon").GetValue(), active: false);
			}
			if (BRCPlusPlugin.UIVisible_Rep != null && !BRCPlusPlugin.UIVisible_Rep.Value)
			{
				SetActive(val.Field("repGroup").GetValue(), active: false);
			}
			if (BRCPlusPlugin.UIVisible_Combo != null)
			{
				bool value3 = BRCPlusPlugin.UIVisible_Combo.Value;
				SetActive(val.Field("currentTrickTransform").GetValue(), value3);
				SetActive(val.Field("scoreTrickLabel").GetValue(), value3);
				SetActive(val.Field("scoreMultiplierLabel").GetValue(), value3);
				SetActive(val.Field("trickNameLabel").GetValue(), value3);
				SetActive(val.Field("tricksInComboLabel").GetValue(), value3);
				SetActive(val.Field("comboTimeOutBar").GetValue(), value3);
				SetActive(val.Field("comboTimeOutBackdrop").GetValue(), value3);
				if (!value3)
				{
					SetActive(val.Field("comboMascotLabel").GetValue(), active: false);
					SetActive(val.Field("comboMascotIcon").GetValue(), active: false);
				}
			}
		}
	}
	[HarmonyPatch(typeof(WantedManager))]
	[HarmonyPatch("CrimePerpetrated")]
	internal static class WantedManagerCrimePerpetratedPatch
	{
		public static bool Prefix()
		{
			ConfigEntry<bool> disableHeat = BRCPlusPlugin.DisableHeat;
			if (disableHeat != null && disableHeat.Value)
			{
				return false;
			}
			return true;
		}
	}
}