Decompiled source of Princess Usas Bike Gang Mod v1.2.2

BepInEx/plugins/PrincessUsasBikeGangMod/PrincessUsasBikeGangMod.dll

Decompiled 3 months 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 BepInEx;
using BepInEx.Configuration;
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("PrincessUsasBikeGangMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PrincessUsasBikeGangMod")]
[assembly: AssemblyTitle("PrincessUsasBikeGangMod")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 PrincessUsasBikeGangMod
{
	[BepInPlugin("CandyKane.PrincessUsasBikeGangMod", "Princess Usa's Bike Gang Mod", "1.2.2")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "CandyKane.PrincessUsasBikeGangMod";

		public const string PluginName = "Princess Usa's Bike Gang Mod";

		public const string PluginVersion = "1.2.2";

		internal static ManualLogSource Log;

		internal static ConfigEntry<int> MaxCopies;

		internal static ConfigEntry<int> ShopPoolCopies;

		internal static ConfigEntry<bool> DebugLogging;

		internal static ConfigEntry<bool> EnableVehicleColors;

		internal static ConfigEntry<KeyCode> PaletteKey;

		internal static ConfigEntry<bool> ExteriorPaintOnly;

		private Harmony _harmony;

		private PhysGrabObject? _paletteTarget;

		private bool _paletteOpen;

		private CursorLockMode _previousCursorLock;

		private bool _previousCursorVisible;

		private void Awake()
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			MaxCopies = ((BaseUnityPlugin)this).Config.Bind<int>("Shop", "ScoutHaulerMaxCopies", 10, "Maximum number of Scouts or Haulers allowed by their Item shop/purchase limits. Minimum effective value is 2.");
			ShopPoolCopies = ((BaseUnityPlugin)this).Config.Bind<int>("Shop", "ScoutHaulerShopPoolCopies", 5, "How many copies of each Scout/Hauler Item are placed in the normal shop candidate pool. Range 1-10. This makes Bike Gang self-contained for vehicle duplicates.");
			EnableVehicleColors = ((BaseUnityPlugin)this).Config.Bind<bool>("Vehicle Colors", "EnableVehicleColors", true, "Enable the per-vehicle Scout/Hauler color palette.");
			PaletteKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Vehicle Colors", "PaletteKey", (KeyCode)99, "Key used to open/close the color palette while holding a Scout or Hauler.");
			ExteriorPaintOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("Vehicle Colors", "ExteriorPaintOnly", true, "When true, recolor only likely exterior/body paint renderers. Set false to use the broader 1.2.0-style recoloring.");
			DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugLogging", false, "Enable verbose logging.");
			_harmony = new Harmony("CandyKane.PrincessUsasBikeGangMod");
			_harmony.PatchAll();
			((MonoBehaviour)this).StartCoroutine(ApplyWhenReady());
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Princess Usa's Bike Gang Mod 1.2.2 loaded. Multi-buy shop logic and per-vehicle color palette enabled.");
		}

		private void Update()
		{
			//IL_0038: 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_00a7: 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)
			if (!EnableVehicleColors.Value)
			{
				if (_paletteOpen)
				{
					ClosePalette();
				}
			}
			else if (Input.GetKeyDown((KeyCode)27) && _paletteOpen)
			{
				ClosePalette();
			}
			else
			{
				if (!Input.GetKeyDown(PaletteKey.Value))
				{
					return;
				}
				if (_paletteOpen)
				{
					ClosePalette();
					return;
				}
				PhysGrabObject val = VehicleColorSystem.FindHeldVehicle();
				if ((Object)(object)val == (Object)null)
				{
					if (DebugLogging.Value)
					{
						Log.LogDebug((object)$"Palette key {PaletteKey.Value} pressed, but no held Scout/Hauler was found.");
					}
					return;
				}
				_paletteTarget = val;
				_paletteOpen = true;
				_previousCursorLock = Cursor.lockState;
				_previousCursorVisible = Cursor.visible;
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
				Log.LogInfo((object)("Opened color palette for " + ((Object)val).name + "."));
			}
		}

		private void OnGUI()
		{
			if (_paletteOpen && !((Object)(object)_paletteTarget == (Object)null))
			{
				VehicleColorPalette.Draw(_paletteTarget, ClosePalette);
			}
		}

		private void ClosePalette()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (_paletteOpen)
			{
				_paletteOpen = false;
				_paletteTarget = null;
				Cursor.lockState = _previousCursorLock;
				Cursor.visible = _previousCursorVisible;
			}
		}

		private IEnumerator ApplyWhenReady()
		{
			for (int i = 0; i < 120; i++)
			{
				if (VehicleShopLimits.Apply())
				{
					yield break;
				}
				yield return (object)new WaitForSeconds(0.5f);
			}
			Log.LogWarning((object)"Could not find StatsManager/itemDictionary during startup. Shop patches will retry when the shop initializes.");
		}
	}
	internal static class VehicleIdentity
	{
		internal static bool IsScoutOrHauler(string key, Item item)
		{
			if (LooksLikeVehicleName(key) || LooksLikeVehicleName(((Object)item).name))
			{
				return true;
			}
			FieldInfo[] fields = ((object)item).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				try
				{
					object value = fieldInfo.GetValue(item);
					if (value is string text && LooksLikeVehicleName(text))
					{
						return true;
					}
					Object val = (Object)((value is Object) ? value : null);
					if (val != null && val != (Object)null && LooksLikeVehicleName(val.name))
					{
						return true;
					}
				}
				catch
				{
				}
			}
			return false;
		}

		internal static bool IsScoutOrHauler(Item item)
		{
			if ((Object)(object)item != (Object)null)
			{
				return IsScoutOrHauler(((Object)item).name, item);
			}
			return false;
		}

		private static bool LooksLikeVehicleName(string? text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			string text2 = text.ToLowerInvariant();
			if (!text2.Contains("semiscooter") && !text2.Contains("hauler"))
			{
				return text2.Contains("scout");
			}
			return true;
		}
	}
	internal static class VehicleShopLimits
	{
		internal static bool Apply()
		{
			if ((Object)(object)StatsManager.instance == (Object)null || StatsManager.instance.itemDictionary == null)
			{
				return false;
			}
			if (SemiFunc.IsMultiplayer() && !SemiFunc.IsMasterClient())
			{
				return true;
			}
			int num = Math.Max(2, Plugin.MaxCopies.Value);
			int num2 = 0;
			foreach (KeyValuePair<string, Item> item in StatsManager.instance.itemDictionary)
			{
				Item value = item.Value;
				if (!((Object)(object)value == (Object)null) && VehicleIdentity.IsScoutOrHauler(item.Key, value))
				{
					bool num3 = value.maxAmountInShop != num || value.maxAmount != num || value.maxPurchase || value.maxPurchaseAmount != 0;
					value.maxAmountInShop = num;
					value.maxAmount = num;
					value.maxPurchase = false;
					value.maxPurchaseAmount = 0;
					if (num3)
					{
						num2++;
						Plugin.Log.LogInfo((object)$"Enabled repeat purchase for '{item.Key}' / '{((Object)value).name}' (max copies: {num}).");
					}
					else if (Plugin.DebugLogging.Value)
					{
						Plugin.Log.LogDebug((object)("Scout/Hauler limits already patched for '" + item.Key + "' / '" + ((Object)value).name + "'."));
					}
				}
			}
			if (Plugin.DebugLogging.Value)
			{
				Plugin.Log.LogDebug((object)$"Vehicle shop limit pass complete; {num2} item(s) changed.");
			}
			return true;
		}
	}
	internal static class VehicleShopPool
	{
		private const string PotentialItemsField = "potentialItems";

		internal static void Apply(ShopManager manager, string source)
		{
			if ((Object)(object)manager == (Object)null || (SemiFunc.IsMultiplayer() && !SemiFunc.IsMasterClient()))
			{
				return;
			}
			VehicleShopLimits.Apply();
			FieldInfo field = ((object)manager).GetType().GetField("potentialItems", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				if (Plugin.DebugLogging.Value)
				{
					Plugin.Log.LogWarning((object)("Could not find ShopManager.potentialItems during " + source + "."));
				}
				return;
			}
			if (!(field.GetValue(manager) is IList list))
			{
				if (Plugin.DebugLogging.Value)
				{
					Plugin.Log.LogWarning((object)("ShopManager.potentialItems was not an IList during " + source + "."));
				}
				return;
			}
			if (list.IsReadOnly || list.IsFixedSize)
			{
				Plugin.Log.LogWarning((object)"ShopManager.potentialItems cannot be expanded; Bike Gang vehicle duplicates were not added.");
				return;
			}
			int num = Math.Max(1, Math.Min(10, Plugin.ShopPoolCopies.Value));
			List<Item> list2 = new List<Item>();
			Dictionary<Item, int> dictionary = new Dictionary<Item, int>();
			for (int i = 0; i < list.Count; i++)
			{
				object? obj = list[i];
				Item val = (Item)((obj is Item) ? obj : null);
				if (val != null && !((Object)(object)val == (Object)null) && VehicleIdentity.IsScoutOrHauler(val))
				{
					if (!dictionary.ContainsKey(val))
					{
						dictionary[val] = 0;
						list2.Add(val);
					}
					dictionary[val]++;
				}
			}
			int num2 = 0;
			foreach (Item item in list2)
			{
				int num3 = dictionary[item];
				int num4 = Math.Max(0, num - num3);
				for (int j = 0; j < num4; j++)
				{
					list.Add(item);
					num2++;
				}
				if (num4 > 0 || Plugin.DebugLogging.Value)
				{
					Plugin.Log.LogInfo((object)$"Bike Gang shop pool: '{((Object)item).name}' {num3} -> {num3 + num4} candidate copies (target {num}).");
				}
			}
			if (list2.Count == 0 && Plugin.DebugLogging.Value)
			{
				Plugin.Log.LogDebug((object)("No Scout/Hauler Item was present in potentialItems during " + source + "; nothing to top up."));
			}
			else if (Plugin.DebugLogging.Value)
			{
				Plugin.Log.LogDebug((object)$"Bike Gang {source} pool pass complete; added {num2} vehicle candidate entries.");
			}
		}
	}
	internal static class VehicleColorSystem
	{
		private static readonly Dictionary<int, Dictionary<Material, Color>> OriginalColors = new Dictionary<int, Dictionary<Material, Color>>();

		private static readonly string[] NonPaintWords = new string[48]
		{
			"wheel", "tire", "tyre", "glass", "window", "light", "lamp", "emiss", "seat", "screen",
			"display", "handle", "grip", "steer", "pedal", "brake", "suspension", "spring", "shock", "axle",
			"hub", "bearing", "motor", "engine", "battery", "cable", "wire", "chain", "gear", "drive",
			"drivetrain", "exhaust", "pipe", "hose", "bolt", "screw", "joint", "collider", "trigger", "audio",
			"shadow", "decal", "logo", "text", "ui", "icon", "floor", "ground"
		};

		private static readonly string[] PaintWords = new string[18]
		{
			"body", "paint", "shell", "panel", "fairing", "fender", "mudguard", "cover", "cowling", "chassis",
			"frame", "hood", "bonnet", "bumper", "trim", "scooter", "semiscooter", "vehicle"
		};

		internal static PhysGrabObject? FindHeldVehicle()
		{
			PhysGrabObject[] array = Object.FindObjectsOfType<PhysGrabObject>();
			foreach (PhysGrabObject val in array)
			{
				if (!((Object)(object)val == (Object)null) && IsHeldByLocalPlayer(val) && IsVehicleObject(val))
				{
					return val;
				}
			}
			return null;
		}

		private static bool IsVehicleObject(PhysGrabObject pgo)
		{
			Transform val = ((Component)pgo).transform;
			int num = 0;
			while ((Object)(object)val != (Object)null && num < 5)
			{
				if (LooksLikeVehicleName(((Object)val).name ?? string.Empty))
				{
					return true;
				}
				num++;
				val = val.parent;
			}
			return false;
		}

		private static bool LooksLikeVehicleName(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			string text2 = text.ToLowerInvariant();
			if (!text2.Contains("semiscooter") && !text2.Contains("hauler"))
			{
				return text2.Contains("scout");
			}
			return true;
		}

		private static bool IsHeldByLocalPlayer(PhysGrabObject pgo)
		{
			try
			{
				Type type = ((object)pgo).GetType();
				FieldInfo fieldInfo = AccessTools.Field(type, "grabbedLocal") ?? AccessTools.Field(type, "isGrabbedLocal");
				if (fieldInfo != null && fieldInfo.FieldType == typeof(bool))
				{
					return (bool)fieldInfo.GetValue(pgo);
				}
				PropertyInfo propertyInfo = AccessTools.Property(type, "grabbedLocal") ?? AccessTools.Property(type, "isGrabbedLocal");
				if (propertyInfo != null && propertyInfo.PropertyType == typeof(bool))
				{
					return (bool)propertyInfo.GetValue(pgo, null);
				}
			}
			catch (Exception ex)
			{
				if (Plugin.DebugLogging.Value)
				{
					Plugin.Log.LogDebug((object)("Could not inspect held state for " + ((Object)pgo).name + ": " + ex.Message));
				}
			}
			return false;
		}

		internal static void ApplyColor(PhysGrabObject vehicle, Color chosen)
		{
			//IL_0071: 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_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_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: 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_01b7: 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_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: 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_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: 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_019e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)vehicle == (Object)null)
			{
				return;
			}
			Transform val = ResolveVehicleRootTransform(((Component)vehicle).transform);
			int instanceID = ((Object)val).GetInstanceID();
			if (!OriginalColors.TryGetValue(instanceID, out Dictionary<Material, Color> value))
			{
				value = new Dictionary<Material, Color>();
				OriginalColors[instanceID] = value;
			}
			Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true);
			float num = 0f;
			Renderer[] array = componentsInChildren;
			foreach (Renderer val2 in array)
			{
				if (!((Object)(object)val2 == (Object)null) && !ShouldSkipRenderer(val2))
				{
					Bounds bounds = val2.bounds;
					Vector3 size = ((Bounds)(ref bounds)).size;
					float sqrMagnitude = ((Vector3)(ref size)).sqrMagnitude;
					if (sqrMagnitude > num)
					{
						num = sqrMagnitude;
					}
				}
			}
			int num2 = 0;
			int num3 = 0;
			array = componentsInChildren;
			Color val6 = default(Color);
			foreach (Renderer val3 in array)
			{
				if ((Object)(object)val3 == (Object)null || ShouldSkipRenderer(val3))
				{
					num3++;
					continue;
				}
				Material[] materials;
				try
				{
					materials = val3.materials;
				}
				catch
				{
					num3++;
					continue;
				}
				Material[] array2 = materials;
				foreach (Material val4 in array2)
				{
					if ((Object)(object)val4 == (Object)null || ShouldSkipMaterial(val4))
					{
						num3++;
						continue;
					}
					if (!val4.HasProperty("_Color") && !val4.HasProperty("_BaseColor"))
					{
						num3++;
						continue;
					}
					if (Plugin.ExteriorPaintOnly.Value && !LooksLikeExteriorPaint(val3, val4, num))
					{
						num3++;
						continue;
					}
					if (!value.ContainsKey(val4))
					{
						Color value2 = (val4.HasProperty("_BaseColor") ? val4.GetColor("_BaseColor") : val4.color);
						value[val4] = value2;
					}
					Color val5 = value[val4];
					((Color)(ref val6))..ctor(chosen.r, chosen.g, chosen.b, val5.a);
					if (val4.HasProperty("_BaseColor"))
					{
						val4.SetColor("_BaseColor", val6);
					}
					if (val4.HasProperty("_Color"))
					{
						val4.SetColor("_Color", val6);
					}
					num2++;
					if (Plugin.DebugLogging.Value)
					{
						Plugin.Log.LogDebug((object)("Painted renderer '" + GetTransformPath(((Component)val3).transform) + "' material '" + ((Object)val4).name + "'."));
					}
				}
			}
			Plugin.Log.LogInfo((object)$"Recolored {((Object)val).name}: updated {num2} exterior material slot(s), skipped {num3} non-paint slot(s). ExteriorPaintOnly={Plugin.ExteriorPaintOnly.Value}. RootResolvedFrom={((Object)vehicle).name}.");
			if (num2 == 0 && Plugin.ExteriorPaintOnly.Value)
			{
				Plugin.Log.LogWarning((object)("No likely exterior paint renderers were found on " + ((Object)val).name + ". Set Vehicle Colors / ExteriorPaintOnly = false to use broad recoloring and send the log so the body filter can be refined."));
			}
		}

		internal static void RestoreOriginal(PhysGrabObject vehicle)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)vehicle == (Object)null)
			{
				return;
			}
			Transform val = ResolveVehicleRootTransform(((Component)vehicle).transform);
			int instanceID = ((Object)val).GetInstanceID();
			if (!OriginalColors.TryGetValue(instanceID, out Dictionary<Material, Color> value))
			{
				return;
			}
			int num = 0;
			foreach (KeyValuePair<Material, Color> item in value)
			{
				Material key = item.Key;
				if (!((Object)(object)key == (Object)null))
				{
					Color value2 = item.Value;
					if (key.HasProperty("_BaseColor"))
					{
						key.SetColor("_BaseColor", value2);
					}
					if (key.HasProperty("_Color"))
					{
						key.SetColor("_Color", value2);
					}
					num++;
				}
			}
			Plugin.Log.LogInfo((object)$"Restored original colors for {((Object)val).name}: {num} material slot(s). RootResolvedFrom={((Object)vehicle).name}.");
		}

		private static Transform ResolveVehicleRootTransform(Transform start)
		{
			Transform val = start;
			Transform val2 = null;
			int num = 0;
			while ((Object)(object)val != (Object)null && num++ < 16)
			{
				if (LooksLikeVehicleName(((Object)val).name ?? string.Empty))
				{
					val2 = val;
				}
				val = val.parent;
			}
			if ((Object)(object)val2 != (Object)null)
			{
				if (Plugin.DebugLogging.Value && (Object)(object)val2 != (Object)(object)start)
				{
					Plugin.Log.LogDebug((object)("Resolved held object '" + ((Object)start).name + "' to vehicle root '" + ((Object)val2).name + "'."));
				}
				return val2;
			}
			if (Plugin.DebugLogging.Value)
			{
				Plugin.Log.LogDebug((object)("Could not resolve a named vehicle root above '" + ((Object)start).name + "'; using held object as root."));
			}
			return start;
		}

		private static bool LooksLikeExteriorPaint(Renderer renderer, Material mat, float largestRendererSize)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			string text = ((Object)((Component)renderer).gameObject).name.ToLowerInvariant();
			string text2 = ((Object)mat).name.ToLowerInvariant();
			string text3 = GetTransformPath(((Component)renderer).transform).ToLowerInvariant();
			if (ContainsAny(text, NonPaintWords) || ContainsAny(text2, NonPaintWords))
			{
				return false;
			}
			if (ContainsAny(text, PaintWords) || ContainsAny(text2, PaintWords))
			{
				return true;
			}
			bool num = text3.Contains("semiscooter") || text3.Contains("hauler") || text3.Contains("scout");
			Bounds bounds = renderer.bounds;
			Vector3 size = ((Bounds)(ref bounds)).size;
			float sqrMagnitude = ((Vector3)(ref size)).sqrMagnitude;
			bool flag = largestRendererSize > 0f && sqrMagnitude >= largestRendererSize * 0.16f;
			return num && flag;
		}

		private static bool ShouldSkipRenderer(Renderer renderer)
		{
			return ContainsAny(((Object)((Component)renderer).gameObject).name.ToLowerInvariant(), NonPaintWords);
		}

		private static bool ShouldSkipMaterial(Material mat)
		{
			return ContainsAny(((Object)mat).name.ToLowerInvariant(), NonPaintWords);
		}

		private static bool ContainsAny(string text, string[] words)
		{
			foreach (string value in words)
			{
				if (text.Contains(value))
				{
					return true;
				}
			}
			return false;
		}

		private static string GetTransformPath(Transform t)
		{
			string text = ((Object)t).name;
			Transform parent = t.parent;
			int num = 0;
			while ((Object)(object)parent != (Object)null && num++ < 8)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
			}
			return text;
		}
	}
	internal static class VehicleColorPalette
	{
		private readonly struct Swatch
		{
			internal readonly string Name;

			internal readonly Color Color;

			internal Swatch(string name, Color color)
			{
				//IL_0008: 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)
				Name = name;
				Color = color;
			}
		}

		private static readonly Swatch[] Swatches = new Swatch[12]
		{
			new Swatch("Pink", new Color(1f, 0.25f, 0.62f)),
			new Swatch("Purple", new Color(0.62f, 0.28f, 1f)),
			new Swatch("Blue", new Color(0.18f, 0.48f, 1f)),
			new Swatch("Cyan", new Color(0.1f, 0.88f, 1f)),
			new Swatch("Green", new Color(0.2f, 0.85f, 0.35f)),
			new Swatch("Yellow", new Color(1f, 0.86f, 0.15f)),
			new Swatch("Orange", new Color(1f, 0.45f, 0.1f)),
			new Swatch("Red", new Color(0.95f, 0.15f, 0.15f)),
			new Swatch("White", new Color(0.95f, 0.95f, 0.95f)),
			new Swatch("Black", new Color(0.08f, 0.08f, 0.08f)),
			new Swatch("Gold", new Color(1f, 0.65f, 0.1f)),
			new Swatch("Mint", new Color(0.45f, 1f, 0.72f))
		};

		private static Type? _guiType;

		private static MethodInfo? _box;

		private static MethodInfo? _button;

		private static PropertyInfo? _guiColor;

		private static bool _reflectionReady;

		internal static void Draw(PhysGrabObject vehicle, Action close)
		{
			//IL_003a: 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_00a6: 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)
			//IL_00b9: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: 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_016c: Unknown result type (might be due to invalid IL or missing references)
			if (!EnsureGuiReflection())
			{
				return;
			}
			float num = ((float)Screen.width - 430f) * 0.5f;
			float num2 = ((float)Screen.height - 310f) * 0.5f;
			Box(new Rect(num, num2, 430f, 310f), "Princess Usa's Bike Gang - Vehicle Colors");
			float num3 = 92f;
			float num4 = 48f;
			float num5 = num + 20f;
			float num6 = num2 + 45f;
			float num7 = 8f;
			float num8 = 10f;
			for (int i = 0; i < Swatches.Length; i++)
			{
				int num9 = i / 4;
				int num10 = i % 4;
				Rect rect = new Rect(num5 + (float)num10 * (num3 + num7), num6 + (float)num9 * (num4 + num8), num3, num4);
				Color guiColor = GetGuiColor();
				SetGuiColor(Swatches[i].Color);
				bool num11 = Button(rect, Swatches[i].Name);
				SetGuiColor(guiColor);
				if (num11)
				{
					VehicleColorSystem.ApplyColor(vehicle, Swatches[i].Color);
					close();
					return;
				}
			}
			SetGuiColor(Color.white);
			if (Button(new Rect(num + 20f, num2 + 230f, 190f, 45f), "Restore Original"))
			{
				VehicleColorSystem.RestoreOriginal(vehicle);
				close();
			}
			else if (Button(new Rect(num + 220f, num2 + 230f, 190f, 45f), "Cancel"))
			{
				close();
			}
		}

		private static bool EnsureGuiReflection()
		{
			if (_reflectionReady)
			{
				return _guiType != null;
			}
			_reflectionReady = true;
			try
			{
				_guiType = Type.GetType("UnityEngine.GUI, UnityEngine.IMGUIModule");
				if (_guiType == null)
				{
					Plugin.Log.LogError((object)"Unity IMGUI module was not available; vehicle color palette cannot be drawn.");
					return false;
				}
				_box = _guiType.GetMethod("Box", new Type[2]
				{
					typeof(Rect),
					typeof(string)
				});
				_button = _guiType.GetMethod("Button", new Type[2]
				{
					typeof(Rect),
					typeof(string)
				});
				_guiColor = _guiType.GetProperty("color", BindingFlags.Static | BindingFlags.Public);
				if (_box == null || _button == null || _guiColor == null)
				{
					Plugin.Log.LogError((object)"Could not bind Unity GUI methods for Bike Gang color palette.");
					return false;
				}
				return true;
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Failed to initialize Bike Gang color palette: {arg}");
				return false;
			}
		}

		private static void Box(Rect rect, string text)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			_box.Invoke(null, new object[2] { rect, text });
		}

		private static bool Button(Rect rect, string text)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			return (bool)_button.Invoke(null, new object[2] { rect, text });
		}

		private static Color GetGuiColor()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return (Color)_guiColor.GetValue(null, null);
		}

		private static void SetGuiColor(Color color)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			_guiColor.SetValue(null, color, null);
		}
	}
	[HarmonyPatch(typeof(ShopManager), "ShopInitialize")]
	internal static class ShopInitializePatch
	{
		[HarmonyPrefix]
		private static void Prefix()
		{
			VehicleShopLimits.Apply();
		}

		[HarmonyPostfix]
		private static void Postfix(ShopManager __instance)
		{
			VehicleShopLimits.Apply();
			VehicleShopPool.Apply(__instance, "ShopInitialize");
		}
	}
	[HarmonyPatch(typeof(ShopManager), "GetAllItemsFromStatsManager")]
	internal static class ShopItemPoolPatch
	{
		[HarmonyPrefix]
		private static void Prefix()
		{
			VehicleShopLimits.Apply();
		}

		[HarmonyPostfix]
		private static void Postfix(ShopManager __instance)
		{
			VehicleShopLimits.Apply();
			VehicleShopPool.Apply(__instance, "GetAllItemsFromStatsManager");
		}
	}
}