Decompiled source of RumbleTrees v3.0.0

Mods/RumbleTrees.dll

Decompiled 21 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppRUMBLE.Combat.ShiftStones;
using Il2CppRUMBLE.Managers;
using Il2CppRUMBLE.Pools;
using Il2CppRUMBLE.Utilities;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using RumbleModdingAPI.RMAPI;
using RumbleTrees;
using UIFramework;
using UIFramework.Models;
using UIFramework.UiExtensions;
using UnityEngine;
using UnityEngine.VFX;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "RumbleTrees", "3.0.0", "Orangenal", "https://thunderstore.io/c/rumble/p/Orangenal/RumbleTrees/")]
[assembly: MelonGame("Buckethead Entertainment", "RUMBLE")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("RumbleTrees")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+c79b080c8d535cd5c1a8f7be5a0db0e28d32718c")]
[assembly: AssemblyProduct("RumbleTrees")]
[assembly: AssemblyTitle("RumbleTrees")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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 RumbleTrees
{
	public static class BuildInfo
	{
		public const string Version = "3.0.0";

		public const string Name = "RumbleTrees";

		public const string Author = "Orangenal";

		public const string DownloadLink = "https://thunderstore.io/c/rumble/p/Orangenal/RumbleTrees/";
	}
	public class Validator : TextInputBehaviorDescriptor
	{
		private string[] themes = new string[4] { "cherry", "orange", "yellow", "red" };

		public static string[] stones = new string[8] { "flow", "vigor", "volatile", "adamant", "charge", "guard", "stubborn", "surge" };

		public static string[] mats = new string[9] { "flow", "vigor", "volatile", "adamant", "charge", "guard", "stubborn", "surge", "vanilla" };

		private string type;

		private object lastValidValue;

		private readonly Func<MelonPreferences_Entry<string>> getEntry;

		public Validator(string type, object defaultValue, Func<MelonPreferences_Entry<string>> getEntry)
		{
			this.type = type;
			lastValidValue = defaultValue;
			this.getEntry = getEntry;
			((TextInputBehaviorDescriptor)this).IsReadOnly = false;
		}

		public override bool IsValid(object value)
		{
			if (value.GetType() != typeof(string))
			{
				return false;
			}
			string text = (string)value;
			string pattern = "^(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)\\s(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)\\s(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)$";
			string pattern2 = "^#?[0-9A-Fa-f]{6}$";
			if (text.ToLower() == "random")
			{
				lastValidValue = value;
				return true;
			}
			if (text.ToLower() == "vanilla")
			{
				lastValidValue = value;
				return true;
			}
			if (type.EndsWith("Mat"))
			{
				if (((ReadOnlySpan<string>)mats).Contains(text.ToLower()))
				{
					lastValidValue = value;
					return true;
				}
				return false;
			}
			if (text.ToLower() == "rainbow")
			{
				lastValidValue = value;
				return true;
			}
			if (Regex.IsMatch(text, pattern) || Regex.IsMatch(text, pattern2))
			{
				lastValidValue = value;
				return true;
			}
			text = text.ToLower();
			if (((ReadOnlySpan<string>)themes).Contains(text) && type == "leaf")
			{
				lastValidValue = value;
				return true;
			}
			return false;
		}

		public override object EnsureValid(object value)
		{
			if (!((ValueValidator)this).IsValid(value))
			{
				Core.loggerInstance.Warning($"New value \"{value}\" was determined to be invalid. Reverting to previous value: \"{lastValidValue}\"");
				MelonPreferences_Entry<string> val = getEntry();
				if (val == null)
				{
					throw new NullReferenceException($"Entry with value \"{value}\" is null!");
				}
				MelonCoroutines.Start(DisplayError(val));
				return lastValidValue;
			}
			return value;
		}

		private IEnumerator DisplayError(MelonPreferences_Entry<string> entry)
		{
			entry.EditedValue = "<#FF0000>Invalid input!";
			((TextInputBehaviorDescriptor)this).IsReadOnly = true;
			yield return (object)new WaitForSeconds(2f);
			entry.EditedValue = (string)lastValidValue;
			((TextInputBehaviorDescriptor)this).IsReadOnly = false;
			((ModModelBase)Core.UIFModel).RequestUpdateUI();
		}
	}
	public class Core : MelonMod
	{
		[Flags]
		private enum fruitSelector
		{
			Bottom = 1,
			Top = 2,
			Both = 3
		}

		private string currentScene = "Loader";

		private bool enabled = true;

		private int sceneID = -1;

		private AssetBundle assetBundle;

		private Random rand = new Random();

		private List<GameObject> leafObjects = new List<GameObject>();

		private List<GameObject> fruitObjects = new List<GameObject>();

		private GameObject VFXsObject;

		private Color originalLeafColour;

		private Material originalLeafMaterial;

		private Material originalFruitMaterial;

		private Il2CppStructArray<GradientColorKey> originalVFXColours;

		internal static MelonModel UIFModel;

		private MelonPreferences_Category mprefsCategoryMod;

		private MelonPreferences_Category mprefsCategoryLeaves;

		private MelonPreferences_Category mprefsCategoryFruits;

		private List<MelonPreferences_Entry<bool>> mprefs_scenes = new List<MelonPreferences_Entry<bool>>();

		private MelonPreferences_Entry<bool> mpref_VFXEnabled;

		private MelonPreferences_Entry<int> mpref_rainbowSpeed;

		private MelonPreferences_Entry<string> mpref_leafMaterial;

		private MelonPreferences_Entry<string> mpref_fruitMaterial;

		private MelonPreferences_Entry<fruitSelector> mpref_fruitSelector;

		private MelonPreferences_Entry<string> mpref_leafColour;

		private MelonPreferences_Entry<string> mpref_fruitColour;

		private Color selectedLeafColour;

		private Color selectedFruitColour = Color.white;

		private Material customFruitMatBottom;

		private Material customFruitMatTop;

		private object rainbowLeafCoroutine;

		private string[] GymTrees = new string[1] { "SCENE/GYMMoss" };

		private string[] RingTrees = new string[1] { "Scene/Map0Leaves" };

		private string[] ParkTrees = new string[2] { "SCENE/PARKMos", "INTERACTABLES/Fruit/Fruit" };

		private Color cherryColour = new Color(0.86f, 0.54f, 0.9f, 1f);

		private Color orangeColour = new Color(1f, 0.44f, 0f, 1f);

		private Color yellowColour = new Color(1f, 0.78f, 0f, 1f);

		private Color redColour = new Color(0.66f, 0f, 0f, 1f);

		private const string USER_DATA = "UserData/RumbleTrees/";

		private const string CONFIG_FILE = "config.cfg";

		internal static Instance loggerInstance;

		public static Material stringToStone(string stoneName)
		{
			if (!((ReadOnlySpan<string>)Validator.stones).Contains(stoneName))
			{
				loggerInstance.Error("\"" + stoneName + "\" is not the name of a valid shiftstone!");
				throw new Exception("Provided stone name is invalid");
			}
			string accurateStoneName = "";
			if (stoneName.EndsWith("Stone"))
			{
				accurateStoneName = stoneName;
			}
			else
			{
				switch (stoneName)
				{
				case "flow":
					accurateStoneName = "FlowStone";
					break;
				case "volatile":
					accurateStoneName = "VolatileStone";
					break;
				case "adamant":
					accurateStoneName = "AdamantStone";
					break;
				case "charge":
					accurateStoneName = "ChargeStone";
					break;
				case "stubborn":
					accurateStoneName = "StubbornStone";
					break;
				case "guard":
					accurateStoneName = "GuardStone";
					break;
				case "vigor":
					accurateStoneName = "VigorStone";
					break;
				case "surge":
					accurateStoneName = "SurgeStone";
					break;
				}
			}
			List<GameObject> list = new List<GameObject>();
			for (int i = 0; i < ((Il2CppArrayBase<ShiftStone>)(object)ScriptableObjectSingleton<ShiftstoneLookupTable>.instance.availableShiftstones).Count; i++)
			{
				list.Add(((Component)((Il2CppArrayBase<ShiftStone>)(object)ScriptableObjectSingleton<ShiftstoneLookupTable>.instance.availableShiftstones)[i]).gameObject);
			}
			return ((Renderer)((Component)list.Where((GameObject val) => ((Object)val).name == accurateStoneName).First().transform.GetChild(0)).GetComponent<MeshRenderer>()).material;
		}

		private dynamic LoadAsset<T>(string assetName, AssetBundle assetBundle)
		{
			if ((Object)(object)assetBundle == (Object)null)
			{
				loggerInstance.Error("AssetBundle cannot be null!");
				return null;
			}
			if (assetName == null || assetName == "")
			{
				loggerInstance.Error("No asset name provided!");
				return null;
			}
			if (typeof(T) == typeof(Material))
			{
				if (assetName == "FruitMatBottom")
				{
					Material obj = assetBundle.LoadAsset<Material>("assets/rumbletrees/fruitfinal.mat");
					if ((Object)(object)obj == (Object)null)
					{
						throw new NullReferenceException("Material is null");
					}
					return obj;
				}
				if (assetName == "FruitMatTop")
				{
					Material obj2 = assetBundle.LoadAsset<Material>("assets/rumbletrees/fruit2.mat");
					if ((Object)(object)obj2 == (Object)null)
					{
						throw new NullReferenceException("Material is null");
					}
					return obj2;
				}
				loggerInstance.Warning("Asset not found!");
				return null;
			}
			loggerInstance.Error("No valid type provided!");
			return null;
		}

		public override void OnInitializeMelon()
		{
			mprefsCategoryMod = MelonPreferences.CreateCategory("RumbleTrees_Mod", "General");
			mprefsCategoryLeaves = MelonPreferences.CreateCategory("RumbleTrees_Trees", "Trees");
			mprefsCategoryFruits = MelonPreferences.CreateCategory("RumbleTrees_Fruits", "Fruits");
			if (!Directory.Exists("UserData/RumbleTrees/"))
			{
				Directory.CreateDirectory("UserData/RumbleTrees/");
			}
			mprefsCategoryMod.SetFilePath(Path.Combine("UserData/RumbleTrees/", "config.cfg"));
			mprefsCategoryLeaves.SetFilePath(Path.Combine("UserData/RumbleTrees/", "config.cfg"));
			mprefsCategoryFruits.SetFilePath(Path.Combine("UserData/RumbleTrees/", "config.cfg"));
			mpref_leafColour = mprefsCategoryLeaves.CreateEntry<string>("LeafColour", "Cherry", "Leaf Colour", "The colour to set the tree leaves (moss) to. Can be either \"Vanilla,\" \"Random,\" \"Rainbow,\" or a custom colour in one of the supported formats: 255 255 255 / FFFFFF", false, false, (ValueValidator)(object)new Validator("leaf", "Cherry", () => mpref_leafColour), (string)null);
			mpref_leafMaterial = mprefsCategoryLeaves.CreateEntry<string>("LeafMaterial", "Vanilla", "Leaf Material", "Allows you to turn the trees into shiftstones.", false, false, (ValueValidator)(object)new Validator("leafMat", "Vanilla", () => mpref_leafMaterial), (string)null);
			mpref_fruitColour = mprefsCategoryFruits.CreateEntry<string>("FruitColour", "Vanilla", "Fruit Colour", "The colour to set the fruits to. Can be either \"Vanilla,\" \"Random,\" \"Rainbow,\" or a custom colour in one of the supported formats: 255 255 255 / FFFFFF", false, false, (ValueValidator)(object)new Validator("fruit", "Vanilla", () => mpref_fruitColour), (string)null);
			mpref_fruitMaterial = mprefsCategoryFruits.CreateEntry<string>("FruitMaterial", "Vanilla", "Fruit Material", "Allows you to turn the fruit into shiftstones.", false, false, (ValueValidator)(object)new Validator("fruitMat", "Vanilla", () => mpref_fruitMaterial), (string)null);
			mpref_fruitSelector = mprefsCategoryFruits.CreateEntry<fruitSelector>("FruitSelector", fruitSelector.Bottom, "Fruit material area", "The part of the fruit that should turn into the shiftstone.", false, false, (ValueValidator)null, (string)null);
			string[] array = new string[3] { "Gym", "Park", "Ring" };
			foreach (string scene in array)
			{
				mprefs_scenes.Add(mprefsCategoryMod.CreateEntry<bool>("EnabledIn" + scene, true, "Enabled in " + scene, "Whether the mod should be active in the " + scene.ToLower(), false, false, (ValueValidator)null, (string)null));
				((MelonEventBase<LemonAction<bool, bool>>)(object)mprefs_scenes.Last().OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate(bool oldVal, bool newVal)
				{
					OnEnabledScenesChange(oldVal, newVal, scene);
				}, 0, false);
			}
			mpref_VFXEnabled = mprefsCategoryLeaves.CreateEntry<bool>("VFXEnabled", false, "Falling Leaf VFX Enabled", (string)null, false, false, (ValueValidator)null, (string)null);
			mpref_rainbowSpeed = mprefsCategoryMod.CreateEntry<int>("RainbowSpeed", 50, "Rainbow speed", "The speed of rainbow leaves / fruits (if selected)", false, false, (ValueValidator)(object)new ValueRange<int>(-6000, 6000), (string)null);
			if (mpref_leafColour.Value.ToLower() != "vanilla" && mpref_leafColour.Value.ToLower() != "rainbow")
			{
				setSelectedLeafColour(mpref_leafColour.Value);
			}
			if (mpref_fruitColour.Value.ToLower() != "vanilla" && mpref_fruitColour.Value.ToLower() != "rainbow")
			{
				setSelectedFruitColour(mpref_fruitColour.Value.ToLower());
			}
			((MelonEventBase<LemonAction<bool, bool>>)(object)mpref_VFXEnabled.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)OnToggleVFXs, 0, false);
			((MelonEventBase<LemonAction<int, int>>)(object)mpref_rainbowSpeed.OnEntryValueChanged).Subscribe((LemonAction<int, int>)delegate
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				if (enabled && mpref_fruitColour.Value.ToLower() == "rainbow")
				{
					UpdateFruitColour(selectedFruitColour);
				}
			}, 0, false);
			((MelonEventBase<LemonAction<string, string>>)(object)mpref_leafColour.OnEntryValueChanged).Subscribe((LemonAction<string, string>)OnLeafColourChange, 0, false);
			((MelonEventBase<LemonAction<string, string>>)(object)mpref_fruitColour.OnEntryValueChanged).Subscribe((LemonAction<string, string>)OnFruitColourChange, 0, false);
			((MelonEventBase<LemonAction<string, string>>)(object)mpref_leafMaterial.OnEntryValueChanged).Subscribe((LemonAction<string, string>)OnLeafMaterialChange, 0, false);
			((MelonEventBase<LemonAction<string, string>>)(object)mpref_fruitMaterial.OnEntryValueChanged).Subscribe((LemonAction<string, string>)OnFruitMaterialChange, 0, false);
			((MelonEventBase<LemonAction<fruitSelector, fruitSelector>>)(object)mpref_fruitSelector.OnEntryValueChanged).Subscribe((LemonAction<fruitSelector, fruitSelector>)OnFruitMatAreaChange, 0, false);
			UIFModel = UI.RegisterMelon((MelonBase)(object)this, (MelonPreferences_Category[])(object)new MelonPreferences_Category[3] { mprefsCategoryMod, mprefsCategoryFruits, mprefsCategoryLeaves });
			assetBundle = AssetBundles.LoadAssetBundleFromStream((MelonMod)(object)this, "RumbleTrees.rumbletrees");
			customFruitMatBottom = new Material(LoadAsset<Material>("FruitMatBottom", assetBundle));
			((Object)customFruitMatBottom).hideFlags = (HideFlags)32;
			customFruitMatTop = new Material(LoadAsset<Material>("FruitMatTop", assetBundle));
			((Object)customFruitMatTop).hideFlags = (HideFlags)32;
			loggerInstance = ((MelonBase)this).LoggerInstance;
			loggerInstance.Msg("Initialised.");
		}

		public override void OnLateInitializeMelon()
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<PooledMonoBehaviour> enumerator = Singleton<PoolManager>.Instance.GetPool("Fruit").PooledObjects.GetEnumerator();
			while (enumerator.MoveNext())
			{
				PooledMonoBehaviour current = enumerator.Current;
				fruitObjects.Add(((Component)current).gameObject);
				MeshRenderer component = ((Component)current).gameObject.GetComponent<MeshRenderer>();
				List<Material> list = new List<Material>();
				list.Add(((Renderer)component).material);
				list.Add(customFruitMatTop);
				list.Add(customFruitMatBottom);
				((Renderer)component).materials = Il2CppReferenceArray<Material>.op_Implicit(list.ToArray());
			}
			if (mpref_fruitColour.Value.ToLower() == "vanilla" || !enabled)
			{
				ResetFruitColour();
			}
			else if (mpref_fruitColour.Value.ToLower() == "rainbow")
			{
				selectedFruitColour = Color.red;
				UpdateFruitColour(selectedFruitColour);
			}
			else if (mpref_fruitMaterial.Value.ToLower() == "vanilla" || mpref_fruitSelector.Value.HasFlag(fruitSelector.Top))
			{
				UpdateFruitColour(selectedFruitColour);
			}
			if (enabled)
			{
				MelonCoroutines.Start(UpdateFruitMaterial(mpref_fruitMaterial.Value.ToLower()));
			}
		}

		private void OnEnabledScenesChange(bool oldVal, bool newVal, string scene)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			if (!(scene == currentScene))
			{
				return;
			}
			enabled = !enabled;
			ToggleVFXs(mpref_VFXEnabled.Value && enabled);
			if (enabled)
			{
				if (mpref_leafColour.Value.ToLower() != "vanilla")
				{
					UpdateLeafColour(selectedLeafColour);
				}
				if (mpref_fruitColour.Value.ToLower() != "vanilla")
				{
					UpdateFruitColour(selectedFruitColour);
				}
				if (mpref_leafMaterial.Value.ToLower() != "vanilla")
				{
					MelonCoroutines.Start(UpdateLeafMaterial(mpref_leafMaterial.Value.ToLower()));
				}
				if (mpref_fruitMaterial.Value.ToLower() != "vanilla")
				{
					MelonCoroutines.Start(UpdateFruitMaterial(mpref_fruitMaterial.Value.ToLower()));
				}
				if (mpref_leafColour.Value.ToLower() == "rainbow")
				{
					rainbowLeafCoroutine = MelonCoroutines.Start(RAINBOWLEAVES());
				}
				if (mpref_fruitColour.Value.ToLower() == "rainbow")
				{
					selectedFruitColour = Color.red;
					UpdateFruitColour(selectedFruitColour);
				}
			}
			else
			{
				ResetLeafColour();
				ResetFruitColour();
				ResetLeafMaterial();
				ResetFruitMaterial();
			}
		}

		private void OnLeafColourChange(string oldVal, string newVal)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (rainbowLeafCoroutine != null)
			{
				MelonCoroutines.Stop(rainbowLeafCoroutine);
				rainbowLeafCoroutine = null;
			}
			if (newVal.ToLower() == "vanilla")
			{
				ResetLeafColour();
				return;
			}
			if (newVal.ToLower() == "rainbow")
			{
				rainbowLeafCoroutine = MelonCoroutines.Start(RAINBOWLEAVES());
				return;
			}
			setSelectedLeafColour(newVal);
			UpdateLeafColour(selectedLeafColour);
		}

		private void OnToggleVFXs(bool oldVal, bool newVal)
		{
			ToggleVFXs(enabled && newVal);
		}

		private void OnLeafMaterialChange(string oldVal, string newVal)
		{
			if (newVal.ToLower() == "vanilla")
			{
				ResetLeafMaterial();
			}
			else
			{
				MelonCoroutines.Start(UpdateLeafMaterial(newVal.ToLower()));
			}
		}

		private void OnFruitColourChange(string oldVal, string newVal)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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)
			if (newVal.ToLower() == "rainbow" && enabled)
			{
				selectedFruitColour = Color.red;
				UpdateFruitColour(selectedFruitColour);
				return;
			}
			if (newVal.ToLower() == "vanilla")
			{
				ResetFruitColour();
				return;
			}
			if (newVal.ToLower() != "rainbow")
			{
				setSelectedFruitColour(newVal.ToLower());
			}
			if (enabled)
			{
				UpdateFruitColour(selectedFruitColour);
			}
		}

		private void OnFruitMaterialChange(string oldVal, string newVal)
		{
			if (newVal.ToLower() == "vanilla")
			{
				ResetFruitMaterial();
			}
			else if (enabled)
			{
				MelonCoroutines.Start(UpdateFruitMaterial(newVal.ToLower()));
			}
		}

		private void OnFruitMatAreaChange(fruitSelector oldVal, fruitSelector newVal)
		{
			if (mpref_fruitMaterial.Value.ToLower() != "vanilla" && enabled)
			{
				MelonCoroutines.Start(UpdateFruitMaterial(mpref_fruitMaterial.Value.ToLower()));
			}
		}

		private void setSelectedLeafColour(string colour)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			switch (colour.ToLower())
			{
			case "cherry":
				selectedLeafColour = cherryColour;
				break;
			case "orange":
				selectedLeafColour = orangeColour;
				break;
			case "yellow":
				selectedLeafColour = yellowColour;
				break;
			case "red":
				selectedLeafColour = redColour;
				break;
			case "random":
				break;
			default:
				selectedLeafColour = stringToColour(colour.ToLower());
				break;
			}
		}

		private void setSelectedFruitColour(string colour)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (colour != "random")
			{
				selectedFruitColour = stringToColour(colour);
			}
		}

		public Color stringToColour(string colour)
		{
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			colour = colour.Replace("#", "");
			colour = colour.Replace("0x", "");
			if (colour.Contains(" "))
			{
				string[] array = colour.Split(' ');
				if (array.Length == 3 && byte.TryParse(array[0], out var result) && byte.TryParse(array[1], out var result2) && byte.TryParse(array[2], out var result3))
				{
					return new Color((float)(int)result / 255f, (float)(int)result2 / 255f, (float)(int)result3 / 255f);
				}
				loggerInstance.Error("\"" + colour + "\" is somehow not a valid colour");
				throw new Exception("Provided string is not in a valid format.");
			}
			if (colour.Length == 6 && int.TryParse(colour, NumberStyles.HexNumber, null, out var result4))
			{
				float num = (float)((result4 >> 16) & 0xFF) / 255f;
				float num2 = (float)((result4 >> 8) & 0xFF) / 255f;
				float num3 = (float)(result4 & 0xFF) / 255f;
				return new Color(num, num2, num3);
			}
			loggerInstance.Error("\"" + colour + "\" is somehow not a valid colour");
			throw new Exception("Provided string is not in a valid format.");
		}

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			if (sceneName == "Park")
			{
				fruitObjects.RemoveAt(fruitObjects.Count - 1);
			}
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: 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)
			leafObjects = new List<GameObject>();
			VFXsObject = null;
			originalLeafColour = default(Color);
			originalLeafMaterial = null;
			originalVFXColours = null;
			if (rainbowLeafCoroutine != null)
			{
				MelonCoroutines.Stop(rainbowLeafCoroutine);
				rainbowLeafCoroutine = null;
			}
			if (sceneName == "Gym")
			{
				currentScene = sceneName;
				sceneID = 0;
				leafObjects.Add(GameObject.Find(GymTrees[0]));
				VFXsObject = FallingLeafVFXs.GetGameObject();
			}
			if (sceneName == "Map0")
			{
				currentScene = "Ring";
				sceneID = 2;
				GameObject item = GameObject.Find(RingTrees[0]);
				leafObjects.Add(item);
			}
			if (sceneName == "Park")
			{
				currentScene = "Park";
				sceneID = 1;
				GameObject item2 = GameObject.Find(ParkTrees[0]);
				leafObjects.Add(item2);
				VFXsObject = FallingLeafVFXs.GetGameObject();
				fruitObjects.Add(GameObject.Find(ParkTrees[1]));
				if (mpref_fruitColour.Value.ToLower() != "vanilla")
				{
					UpdateFruitColour(selectedFruitColour);
				}
			}
			if (sceneName == "Loader")
			{
				return;
			}
			enabled = mprefs_scenes[sceneID].Value;
			if (enabled)
			{
				if (mpref_leafColour.Value.ToLower() != "vanilla")
				{
					UpdateLeafColour(selectedLeafColour);
				}
				ToggleVFXs(mpref_VFXEnabled.Value);
				if (mpref_leafMaterial.Value.ToLower() != "vanilla")
				{
					MelonCoroutines.Start(UpdateLeafMaterial(mpref_leafMaterial.Value.ToLower()));
				}
				if (mpref_leafColour.Value.ToLower() == "rainbow" && rainbowLeafCoroutine == null)
				{
					rainbowLeafCoroutine = MelonCoroutines.Start(RAINBOWLEAVES());
				}
			}
			if (!enabled)
			{
				ResetFruitMaterial();
				ResetFruitColour();
			}
			else
			{
				UpdateFruitColour(selectedFruitColour);
				MelonCoroutines.Start(UpdateFruitMaterial(mpref_fruitMaterial.Value.ToLower()));
			}
		}

		private void ToggleVFXs(bool enable)
		{
			if ((Object)(object)VFXsObject != (Object)null)
			{
				Transform parent = VFXsObject.transform.parent;
				((Component)parent.GetChild(0)).gameObject.active = false;
				((Component)parent.GetChild(1)).gameObject.active = false;
				((Component)parent).gameObject.active = enable;
			}
		}

		private void UpdateLeafColour(Color colour)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			if (!enabled)
			{
				return;
			}
			if (mpref_leafColour.Value.ToLower() == "random")
			{
				((Color)(ref colour))..ctor((float)rand.NextDouble(), (float)rand.NextDouble(), (float)rand.NextDouble());
			}
			if (leafObjects.Count == 0)
			{
				return;
			}
			foreach (GameObject leafObject in leafObjects)
			{
				Material material = ((Renderer)leafObject.GetComponent<MeshRenderer>()).material;
				if (originalLeafColour == default(Color))
				{
					originalLeafColour = material.GetColor("_Main_color");
				}
				material.SetColor("_Main_color", colour);
			}
			if (mpref_leafMaterial.Value.ToLower() == "vanilla")
			{
				UpdateVFXsColour(colour);
			}
		}

		private void UpdateVFXsColour(Color colour)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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)
			if (!enabled)
			{
				return;
			}
			if ((Object)(object)VFXsObject != (Object)null)
			{
				for (int i = 0; i < VFXsObject.transform.GetChildCount(); i++)
				{
					VisualEffect component = ((Component)VFXsObject.transform.GetChild(i)).gameObject.GetComponent<VisualEffect>();
					GradientColorKey[] array = (GradientColorKey[])(object)new GradientColorKey[2];
					Gradient gradient = component.GetGradient("Leaf Color Gradient");
					if (originalVFXColours == null)
					{
						originalVFXColours = gradient.colorKeys;
					}
					array[0].color = colour;
					array[1].color = colour;
					gradient.colorKeys = Il2CppStructArray<GradientColorKey>.op_Implicit(array);
					component.SetGradient("Leaf Color Gradient", gradient);
				}
			}
			else if (currentScene != "Ring")
			{
				loggerInstance.Warning("Leaf VFX object not found!");
			}
		}

		private void UpdateFruitColour(Color colour)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if (mpref_fruitColour.Value.ToLower() == "random")
			{
				((Color)(ref colour))..ctor((float)rand.NextDouble(), (float)rand.NextDouble(), (float)rand.NextDouble());
			}
			foreach (GameObject fruitObject in fruitObjects)
			{
				MeshRenderer component = fruitObject.GetComponent<MeshRenderer>();
				if ((Object)(object)component != (Object)null && ((Il2CppArrayBase<Material>)(object)((Renderer)component).materials).Length == 3)
				{
					((IEnumerable<Material>)((Renderer)component).materials).Last().color = colour;
					((IEnumerable<Material>)((Renderer)component).materials).Last().SetInt("_VanillaOverride", 0);
					((IEnumerable<Material>)((Renderer)component).materials).Last().SetInt("_Enabled", (!mpref_fruitSelector.Value.HasFlag(fruitSelector.Bottom) || !(mpref_fruitMaterial.Value.ToLower() != "vanilla")) ? 1 : 0);
					((IEnumerable<Material>)((Renderer)component).materials).Last().SetFloat("_RainbowSpeed", (float)((mpref_fruitColour.Value.ToLower() == "rainbow") ? mpref_rainbowSpeed.Value : 0));
				}
			}
		}

		private void ResetLeafColour()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if (rainbowLeafCoroutine != null)
			{
				MelonCoroutines.Stop(rainbowLeafCoroutine);
				rainbowLeafCoroutine = null;
			}
			if (originalLeafColour != default(Color) && leafObjects.Count != 0)
			{
				foreach (GameObject leafObject in leafObjects)
				{
					((Renderer)leafObject.GetComponent<MeshRenderer>()).material.SetColor("_Main_color", originalLeafColour);
				}
			}
			if (mpref_leafMaterial.Value.ToLower() == "vanilla")
			{
				ResetVFXs();
			}
		}

		private void ResetVFXs()
		{
			if (originalVFXColours != null && (Object)(object)VFXsObject != (Object)null)
			{
				for (int i = 0; i < VFXsObject.transform.GetChildCount(); i++)
				{
					VisualEffect component = ((Component)VFXsObject.transform.GetChild(i)).gameObject.GetComponent<VisualEffect>();
					Gradient gradient = component.GetGradient("Leaf Color Gradient");
					gradient.colorKeys = originalVFXColours;
					component.SetGradient("Leaf Color Gradient", gradient);
				}
			}
		}

		private void ResetFruitColour()
		{
			foreach (GameObject fruitObject in fruitObjects)
			{
				MeshRenderer component = fruitObject.GetComponent<MeshRenderer>();
				if ((Object)(object)component != (Object)null && ((Il2CppArrayBase<Material>)(object)((Renderer)component).materials).Length == 3)
				{
					if (mpref_fruitMaterial.Value.ToLower() == "vanilla" || !enabled)
					{
						((IEnumerable<Material>)((Renderer)component).materials).Last().SetInt("_Enabled", 0);
					}
					else
					{
						((IEnumerable<Material>)((Renderer)component).materials).Last().SetInt("_VanillaOverride", 1);
					}
					((IEnumerable<Material>)((Renderer)component).materials).Last().SetFloat("_RainbowSpeed", 0f);
				}
			}
		}

		private IEnumerator UpdateLeafMaterial(string materialName)
		{
			if (currentScene == "Loader" || !enabled || leafObjects.Count == 0)
			{
				yield break;
			}
			if ((Object)(object)originalLeafMaterial == (Object)null)
			{
				originalLeafMaterial = ((Renderer)leafObjects.First().GetComponent<MeshRenderer>()).sharedMaterial;
			}
			yield return null;
			yield return null;
			yield return null;
			if (materialName == "random" && enabled)
			{
				materialName = Validator.mats[rand.Next(Validator.mats.Length)];
			}
			foreach (GameObject leafObject in leafObjects)
			{
				MeshRenderer component = leafObject.GetComponent<MeshRenderer>();
				if (materialName == "vanilla")
				{
					ResetLeafMaterial();
					UpdateLeafColour(selectedLeafColour);
					if (mpref_leafColour.Value.ToLower() == "rainbow" && rainbowLeafCoroutine == null)
					{
						rainbowLeafCoroutine = MelonCoroutines.Start(RAINBOWLEAVES());
					}
					continue;
				}
				if (mpref_leafColour.Value.ToLower() == "rainbow" && rainbowLeafCoroutine != null)
				{
					MelonCoroutines.Stop(rainbowLeafCoroutine);
					rainbowLeafCoroutine = null;
				}
				((Renderer)component).material = stringToStone(materialName);
				UpdateVFXsColour(((Renderer)component).material.color);
			}
		}

		private IEnumerator UpdateFruitMaterial(string materialName)
		{
			if (!enabled || fruitObjects.Count == 0)
			{
				yield break;
			}
			if ((Object)(object)originalFruitMaterial == (Object)null)
			{
				originalFruitMaterial = new Material(((Renderer)fruitObjects.First().GetComponent<MeshRenderer>()).sharedMaterial);
				((Object)originalFruitMaterial).hideFlags = (HideFlags)32;
			}
			yield return null;
			if (materialName == "random")
			{
				materialName = Validator.mats[rand.Next(Validator.mats.Length)];
			}
			else if (materialName == "vanilla")
			{
				ResetFruitMaterial();
				yield break;
			}
			foreach (GameObject fruitObject in fruitObjects)
			{
				MeshRenderer component = fruitObject.GetComponent<MeshRenderer>();
				((Renderer)component).material = stringToStone(materialName);
				if (((Il2CppArrayBase<Material>)(object)((Renderer)component).materials).Length == 3)
				{
					((IEnumerable<Material>)((Renderer)component).materials).Last().SetInt("_Enabled", (!mpref_fruitSelector.Value.HasFlag(fruitSelector.Bottom)) ? 1 : 0);
					((IEnumerable<Material>)((Renderer)component).materials).Last().SetInt("_VanillaOverride", (mpref_fruitSelector.Value.HasFlag(fruitSelector.Top) && mpref_fruitColour.Value.ToLower() == "vanilla") ? 1 : 0);
					((Il2CppArrayBase<Material>)(object)((Renderer)component).materials)[1].SetInt("_Enabled", (!mpref_fruitSelector.Value.HasFlag(fruitSelector.Top)) ? 1 : 0);
				}
			}
		}

		private void ResetLeafMaterial()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if (currentScene == "Loader" || (Object)(object)originalLeafMaterial == (Object)null || leafObjects.Count == 0)
			{
				return;
			}
			foreach (GameObject leafObject in leafObjects)
			{
				((Renderer)leafObject.GetComponent<MeshRenderer>()).material = originalLeafMaterial;
			}
			if (enabled && mpref_leafColour.Value.ToLower() != "vanilla")
			{
				UpdateLeafColour(selectedLeafColour);
				if (mpref_leafColour.Value.ToLower() == "rainbow" && rainbowLeafCoroutine == null)
				{
					rainbowLeafCoroutine = MelonCoroutines.Start(RAINBOWLEAVES());
				}
			}
			else
			{
				ResetLeafColour();
			}
		}

		private void ResetFruitMaterial()
		{
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			if (currentScene == "Loader")
			{
				return;
			}
			if ((Object)(object)originalFruitMaterial == (Object)null)
			{
				loggerInstance.Warning("originalFruitMaterial is null, skipping reset");
			}
			else
			{
				if (fruitObjects.Count == 0)
				{
					return;
				}
				foreach (GameObject fruitObject in fruitObjects)
				{
					MeshRenderer component = fruitObject.GetComponent<MeshRenderer>();
					((Renderer)component).material = originalFruitMaterial;
					if (((Il2CppArrayBase<Material>)(object)((Renderer)component).materials).Length != 3)
					{
						continue;
					}
					if (mpref_fruitSelector.Value.HasFlag(fruitSelector.Bottom))
					{
						Material obj = ((Il2CppArrayBase<Material>)(object)((Renderer)component).materials)[1];
						if (obj != null)
						{
							obj.SetInt("_Enabled", 0);
						}
					}
					if (mpref_fruitSelector.Value.HasFlag(fruitSelector.Top))
					{
						((IEnumerable<Material>)((Renderer)component).materials).Last().SetInt("_VanillaOverride", 0);
					}
				}
				if (enabled && mpref_fruitColour.Value.ToLower() != "vanilla")
				{
					if (mpref_fruitColour.Value.ToLower() == "rainbow")
					{
						selectedFruitColour = Color.red;
					}
					UpdateFruitColour(selectedFruitColour);
				}
				else
				{
					ResetFruitColour();
				}
			}
		}

		private IEnumerator RAINBOWLEAVES()
		{
			WaitForFixedUpdate waitForFixedUpdate = new WaitForFixedUpdate();
			int FrameCounter = 0;
			float rainbowHue = 0f;
			while (true)
			{
				if (FrameCounter >= 2)
				{
					if (rainbowHue >= 360f)
					{
						rainbowHue -= 360f;
					}
					if (rainbowHue < 0f)
					{
						rainbowHue += 360f;
					}
					selectedLeafColour = Color.HSVToRGB(rainbowHue / 360f, 1f, 1f);
					UpdateLeafColour(selectedLeafColour);
					rainbowHue += (float)mpref_rainbowSpeed.Value / 50f;
					FrameCounter = 0;
				}
				FrameCounter++;
				yield return waitForFixedUpdate;
			}
		}
	}
}