Decompiled source of AvatarStatsLoader v1.2.3

Mods/AvatarStatsLoader.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using AvatarStatsLoader;
using AvatarStatsLoader.BoneMenu;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.BoneMenu.Elements;
using BoneLib.BoneMenu.UI;
using HarmonyLib;
using Il2CppSystem.IO;
using MelonLoader;
using MelonLoader.Preferences;
using Newtonsoft.Json;
using SLZ.VRMK;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("AvatarStatsLoader")]
[assembly: AssemblyDescription("Customized stats loader for BoneLab")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AvatarStatsLoader")]
[assembly: AssemblyCopyright("Copyright © FirEmerald 2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("649c4263-395f-44aa-bb88-6841559df396")]
[assembly: AssemblyFileVersion("1.2.3")]
[assembly: MelonInfo(typeof(AvatarStatsMod), "Avatar Stats Loader", "1.2.3", "FirEmerald", "https://bonelab.thunderstore.io/package/FirEmerald/AvatarStatsLoader/")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.2.3.0")]
namespace AvatarStatsLoader
{
	public class AvatarStatsMod : MelonMod
	{
		internal static readonly string STATS_FOLDER = Path.Combine(MelonUtils.UserDataDirectory, "AvatarStats");

		internal static readonly string MASS_FOLDER = Path.Combine(MelonUtils.UserDataDirectory, "AvatarMass");

		internal static AvatarStatsMod instance;

		internal static MelonPreferences_Category mpCat;

		internal static MelonPreferences_Entry<float> agility;

		internal static MelonPreferences_Entry<float> strengthUpper;

		internal static MelonPreferences_Entry<float> strengthLower;

		internal static MelonPreferences_Entry<float> vitality;

		internal static MelonPreferences_Entry<float> speed;

		internal static MelonPreferences_Entry<float> intelligence;

		internal static MelonPreferences_Entry<bool> loadStats;

		internal static MelonPreferences_Entry<bool> saveStats;

		internal static MelonPreferences_Entry<float> massChest;

		internal static MelonPreferences_Entry<float> massPelvis;

		internal static MelonPreferences_Entry<float> massHead;

		internal static MelonPreferences_Entry<float> massArm;

		internal static MelonPreferences_Entry<float> massLeg;

		internal static MelonPreferences_Entry<bool> loadMasses;

		internal static MelonPreferences_Entry<bool> saveMasses;

		internal static Avatar currentAvatar = null;

		internal static bool isLoadingAvatarValues = false;

		public AvatarStatsMod()
		{
			instance = this;
		}

		public override void OnInitializeMelon()
		{
			Hooking.OnSwitchAvatarPostfix += delegate(Avatar avatar)
			{
				if ((Object)(object)avatar != (Object)null && !avatar.isEmptyRig())
				{
					if ((Object)(object)avatar != (Object)(object)currentAvatar)
					{
						Log("Setting avatar to " + avatar.getName());
						isLoadingAvatarValues = true;
						agility.DefaultValue = avatar.getDefAgility();
						agility.Value = avatar._agility;
						strengthUpper.DefaultValue = avatar.getDefStrengthUpper();
						strengthUpper.Value = avatar._strengthUpper;
						strengthLower.DefaultValue = avatar.getDefStrengthLower();
						strengthLower.Value = avatar._strengthLower;
						vitality.DefaultValue = avatar.getDefVitality();
						vitality.Value = avatar._vitality;
						speed.DefaultValue = avatar.getDefSpeed();
						speed.Value = avatar._speed;
						intelligence.DefaultValue = avatar.getDefIntelligence();
						intelligence.Value = avatar._intelligence;
						massChest.DefaultValue = avatar.getDefMassChest();
						massChest.Value = avatar._massChest;
						massPelvis.DefaultValue = avatar.getDefMassPelvis();
						massPelvis.Value = avatar._massPelvis;
						massHead.DefaultValue = avatar.getDefMassHead();
						massHead.Value = avatar._massHead;
						massArm.DefaultValue = avatar.getDefMassArm();
						massArm.Value = avatar._massArm;
						massLeg.DefaultValue = avatar.getDefMassLeg();
						massLeg.Value = avatar._massLeg;
						currentAvatar = avatar;
						isLoadingAvatarValues = false;
					}
				}
				else
				{
					Log("Setting avatar to null");
					currentAvatar = null;
				}
			};
			LemonAction<float, float> val = delegate
			{
				refreshAvatarStats();
			};
			mpCat = MelonPreferences.CreateCategory("AvatarStatsMod");
			agility = mpCat.CreateEntry<float>("agility", 0f, "Agility", "Determines how fast an avatar can acclerate or decelerate.", false, true, (ValueValidator)null, (string)null);
			strengthUpper = mpCat.CreateEntry<float>("strengthUpper", 0f, "Arm strength", "Determines the arm strength, affecting weapon holding and climbing.", false, true, (ValueValidator)null, (string)null);
			strengthLower = mpCat.CreateEntry<float>("strengthLower", 0f, "Leg strength", "Determines leg strength, affecting running and jumping.", false, true, (ValueValidator)null, (string)null);
			vitality = mpCat.CreateEntry<float>("vitality", 0f, "Vitality", "Determines how much damage an avatar takes.", false, true, (ValueValidator)null, (string)null);
			speed = mpCat.CreateEntry<float>("speed", 0f, "Speed", "Determines how fast an avatar can run.", false, true, (ValueValidator)null, (string)null);
			intelligence = mpCat.CreateEntry<float>("intelligence", 0f, "Intelligence", "Currently has no effect.", false, true, (ValueValidator)null, (string)null);
			((MelonEventBase<LemonAction<float, float>>)(object)agility.OnEntryValueChanged).Subscribe(val, int.MaxValue, false);
			((MelonEventBase<LemonAction<float, float>>)(object)strengthUpper.OnEntryValueChanged).Subscribe(val, int.MaxValue, false);
			((MelonEventBase<LemonAction<float, float>>)(object)strengthLower.OnEntryValueChanged).Subscribe(val, int.MaxValue, false);
			((MelonEventBase<LemonAction<float, float>>)(object)vitality.OnEntryValueChanged).Subscribe(val, int.MaxValue, false);
			((MelonEventBase<LemonAction<float, float>>)(object)speed.OnEntryValueChanged).Subscribe(val, int.MaxValue, false);
			((MelonEventBase<LemonAction<float, float>>)(object)intelligence.OnEntryValueChanged).Subscribe(val, int.MaxValue, false);
			loadStats = mpCat.CreateEntry<bool>("loadStats", false, "Reload stats", "loads the previously loaded stats of the current avatar into the preferences.", false, false, (ValueValidator)null, (string)null);
			((MelonEventBase<LemonAction<bool, bool>>)(object)loadStats.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate(bool prev, bool cur)
			{
				if (cur)
				{
					loadStatValues();
					((MelonPreferences_Entry)loadStats).ResetToDefault();
				}
			}, 0, false);
			saveStats = mpCat.CreateEntry<bool>("saveStats", false, "Save stats", "Saves the current stat preferences into the override file of the current avatar.", false, false, (ValueValidator)null, (string)null);
			((MelonEventBase<LemonAction<bool, bool>>)(object)saveStats.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate(bool prev, bool cur)
			{
				if (cur)
				{
					SaveStatsToFile();
					((MelonPreferences_Entry)saveStats).ResetToDefault();
				}
			}, 0, false);
			massChest = mpCat.CreateEntry<float>("massChest", 0f, "Chest mass", "Chest mass of the last loaded avatar.", false, true, (ValueValidator)null, (string)null);
			massPelvis = mpCat.CreateEntry<float>("massPelvis", 0f, "Pelvis mass", "Pelvis mass of the last loaded avatar.", false, true, (ValueValidator)null, (string)null);
			massHead = mpCat.CreateEntry<float>("massHead", 0f, "Head mass", "Head mass of the last loaded avatar.", false, true, (ValueValidator)null, (string)null);
			massArm = mpCat.CreateEntry<float>("massArm", 0f, "Arm mass", "Arm mass of the last loaded avatar.", false, true, (ValueValidator)null, (string)null);
			massLeg = mpCat.CreateEntry<float>("massLeg", 0f, "Leg mass", "Leg mass of the last loaded avatar.", false, true, (ValueValidator)null, (string)null);
			((MelonEventBase<LemonAction<float, float>>)(object)massChest.OnEntryValueChanged).Subscribe(val, int.MaxValue, false);
			((MelonEventBase<LemonAction<float, float>>)(object)massPelvis.OnEntryValueChanged).Subscribe(val, int.MaxValue, false);
			((MelonEventBase<LemonAction<float, float>>)(object)massHead.OnEntryValueChanged).Subscribe(val, int.MaxValue, false);
			((MelonEventBase<LemonAction<float, float>>)(object)massArm.OnEntryValueChanged).Subscribe(val, int.MaxValue, false);
			((MelonEventBase<LemonAction<float, float>>)(object)massLeg.OnEntryValueChanged).Subscribe(val, int.MaxValue, false);
			loadMasses = mpCat.CreateEntry<bool>("loadMasses", false, "Reload masses", "Reloads the mass of the current avatar into the preferences.", false, false, (ValueValidator)null, (string)null);
			((MelonEventBase<LemonAction<bool, bool>>)(object)loadMasses.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate(bool prev, bool cur)
			{
				if (cur)
				{
					loadMassValues();
					((MelonPreferences_Entry)loadMasses).ResetToDefault();
				}
			}, 0, false);
			saveMasses = mpCat.CreateEntry<bool>("saveMasses", false, "Save masses", "Saves the current mass preferences into the override file of the current avatar.", false, false, (ValueValidator)null, (string)null);
			((MelonEventBase<LemonAction<bool, bool>>)(object)saveMasses.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate(bool prev, bool cur)
			{
				if (cur)
				{
					SaveMassesToFile();
					((MelonPreferences_Entry)saveMasses).ResetToDefault();
				}
			}, 0, false);
			mpCat.SaveToFile(true);
		}

		public override void OnLateInitializeMelon()
		{
			if (Version.TryParse(typeof(BuildInfo).GetField("Version").GetRawConstantValue() as string, out Version result))
			{
				if (result.Major >= 2)
				{
					Log("BoneLib >= 2.0.0 detected, adding to BoneMenu");
					StatsBoneMenu.init();
					MassesBoneMenu.init();
				}
				else
				{
					Log("BoneLib < 2.0.0 detected, BoneMenu functionality disabled. Consider updating BoneLib if possible.");
				}
			}
			else
			{
				Warn("Could not parse BoneLib version, not loading BoneMenu functionality");
			}
		}

		public void refreshAvatarStats()
		{
			if (!isLoadingAvatarValues && (Object)(object)currentAvatar != (Object)null)
			{
				Log("Refreshing " + currentAvatar.getName());
				Player.rigManager.SwapAvatar(currentAvatar);
			}
		}

		public static void SaveStatsToFile()
		{
			if ((Object)(object)currentAvatar != (Object)null)
			{
				if (!Directory.Exists(STATS_FOLDER))
				{
					DirectoryInfo val = Directory.CreateDirectory(STATS_FOLDER);
					Log("Avatar stats folder did not exist, created at " + ((FileSystemInfo)val).Name);
				}
				string text = Path.Combine(STATS_FOLDER, currentAvatar.getName() + ".json");
				Log("Saving stats to " + text);
				File.WriteAllText(text, JsonConvert.SerializeObject((object)new AvatarStats(agility.Value, strengthUpper.Value, strengthLower.Value, vitality.Value, speed.Value, intelligence.Value)));
			}
		}

		internal static void loadStatValues()
		{
			if ((Object)(object)currentAvatar != (Object)null)
			{
				loadStatValues(currentAvatar);
			}
		}

		internal static void loadStatValues(Avatar avatar)
		{
			agility.Value = avatar._agility;
			strengthUpper.Value = avatar._strengthUpper;
			strengthLower.Value = avatar._strengthLower;
			vitality.Value = avatar._vitality;
			speed.Value = avatar._speed;
			intelligence.Value = avatar._intelligence;
		}

		public static void SaveMassesToFile()
		{
			if ((Object)(object)currentAvatar != (Object)null)
			{
				if (!Directory.Exists(MASS_FOLDER))
				{
					DirectoryInfo val = Directory.CreateDirectory(MASS_FOLDER);
					Log("Avatar masses folder did not exist, created at " + ((FileSystemInfo)val).Name);
				}
				string text = Path.Combine(MASS_FOLDER, currentAvatar.getName() + ".json");
				Log("Saving masses to " + text);
				File.WriteAllText(text, JsonConvert.SerializeObject((object)new AvatarMass(massChest.Value, massPelvis.Value, massHead.Value, massArm.Value, massLeg.Value)));
			}
		}

		internal static void loadMassValues()
		{
			if ((Object)(object)currentAvatar != (Object)null)
			{
				loadMassValues(currentAvatar);
			}
		}

		internal static void loadMassValues(Avatar avatar)
		{
			massChest.Value = avatar._massChest;
			massPelvis.Value = avatar._massPelvis;
			massHead.Value = avatar._massHead;
			massArm.Value = avatar._massArm;
			massLeg.Value = avatar._massLeg;
		}

		internal static void Log(string str)
		{
			((MelonBase)instance).LoggerInstance.Msg(str);
		}

		internal static void Log(object obj)
		{
			((MelonBase)instance).LoggerInstance.Msg(obj?.ToString() ?? "null");
		}

		internal static void Warn(string str)
		{
			((MelonBase)instance).LoggerInstance.Warning(str);
		}

		internal static void Warn(object obj)
		{
			((MelonBase)instance).LoggerInstance.Warning(obj?.ToString() ?? "null");
		}

		internal static void Error(string str)
		{
			((MelonBase)instance).LoggerInstance.Error(str);
		}

		internal static void Error(object obj)
		{
			((MelonBase)instance).LoggerInstance.Error(obj?.ToString() ?? "null");
		}
	}
	[HarmonyPatch(typeof(Avatar), "ComputeBaseStats")]
	public static class AvatarComputeStatChange
	{
		public static void Postfix(Avatar __instance)
		{
			if (__instance.isEmptyRig())
			{
				return;
			}
			string name = __instance.getName();
			if ((Object)(object)__instance == (Object)(object)AvatarStatsMod.currentAvatar)
			{
				AvatarStatsMod.Log("Overriding stats for " + name + " with values from preferences.");
				__instance._agility = AvatarStatsMod.agility.Value;
				__instance._strengthUpper = AvatarStatsMod.strengthUpper.Value;
				__instance._strengthLower = AvatarStatsMod.strengthLower.Value;
				__instance._vitality = AvatarStatsMod.vitality.Value;
				__instance._speed = AvatarStatsMod.speed.Value;
				__instance._intelligence = AvatarStatsMod.intelligence.Value;
				return;
			}
			__instance.setDefStats();
			AvatarStatsMod.Log("Load stats: " + name);
			if (Directory.Exists(AvatarStatsMod.STATS_FOLDER))
			{
				string text = Path.Combine(AvatarStatsMod.STATS_FOLDER, name + ".json");
				if (File.Exists(text))
				{
					AvatarStatsMod.Log("Overriding stats with values from " + text);
					JsonConvert.DeserializeObject<AvatarStats>(File.ReadAllText(text)).apply(__instance);
				}
			}
			__instance.setLoadStats();
		}
	}
	public class AvatarStats
	{
		public float agility;

		public float strengthUpper;

		public float strengthLower;

		public float vitality;

		public float speed;

		public float intelligence;

		public AvatarStats()
		{
		}

		public AvatarStats(float agility, float strengthUpper, float strengthLower, float vitality, float speed, float intelligence)
		{
			this.agility = agility;
			this.strengthUpper = strengthUpper;
			this.strengthLower = strengthLower;
			this.vitality = vitality;
			this.speed = speed;
			this.intelligence = intelligence;
		}

		public AvatarStats(Avatar avatar)
		{
			agility = avatar._agility;
			strengthUpper = avatar._strengthUpper;
			strengthLower = avatar._strengthLower;
			vitality = avatar._vitality;
			speed = avatar._speed;
			intelligence = avatar._intelligence;
		}

		public void apply(Avatar avatar)
		{
			avatar._agility = agility;
			avatar._strengthUpper = strengthUpper;
			avatar._strengthLower = strengthLower;
			avatar._vitality = vitality;
			avatar._speed = speed;
			avatar._intelligence = intelligence;
		}
	}
	[HarmonyPatch(typeof(Avatar), "ComputeMass")]
	public static class AvatarComputeMassChange
	{
		public static void Postfix(Avatar __instance, float normalizeTo82)
		{
			if (__instance.isEmptyRig())
			{
				return;
			}
			string name = __instance.getName();
			if ((Object)(object)__instance == (Object)(object)AvatarStatsMod.currentAvatar)
			{
				AvatarStatsMod.Log("Overriding mass for " + name + " with values from preferences.");
				__instance._massChest = AvatarStatsMod.massChest.Value;
				__instance._massPelvis = AvatarStatsMod.massPelvis.Value;
				__instance._massHead = AvatarStatsMod.massHead.Value;
				__instance._massArm = AvatarStatsMod.massArm.Value;
				__instance._massLeg = AvatarStatsMod.massLeg.Value;
				__instance.recalculateTotalMass();
				return;
			}
			__instance.setDefMasses();
			AvatarStatsMod.Log("Load mass: " + name);
			if (Directory.Exists(AvatarStatsMod.MASS_FOLDER))
			{
				string text = Path.Combine(AvatarStatsMod.MASS_FOLDER, ".json");
				if (File.Exists(text))
				{
					AvatarStatsMod.Log("Overriding mass with values from " + text);
					JsonConvert.DeserializeObject<AvatarMass>(File.ReadAllText(text)).apply(__instance);
				}
			}
			__instance.setLoadMasses();
		}
	}
	public class AvatarMass
	{
		public float massChest;

		public float massPelvis;

		public float massHead;

		public float massArm;

		public float massLeg;

		public AvatarMass()
		{
		}

		public AvatarMass(float massChest, float massPelvis, float massHead, float massArm, float massLeg)
		{
			this.massChest = massChest;
			this.massPelvis = massPelvis;
			this.massHead = massHead;
			this.massArm = massArm;
			this.massLeg = massLeg;
		}

		public AvatarMass(Avatar avatar)
		{
			massChest = avatar._massChest;
			massPelvis = avatar._massPelvis;
			massHead = avatar._massHead;
			massArm = avatar._massArm;
			massLeg = avatar._massLeg;
		}

		public void apply(Avatar avatar)
		{
			avatar._massChest = massChest;
			avatar._massPelvis = massPelvis;
			avatar._massHead = massHead;
			avatar._massArm = massArm;
			avatar._massLeg = massLeg;
			avatar.recalculateTotalMass();
		}
	}
	public static class AvatarExtensions
	{
		private static float defAgility;

		private static float defStrengthUpper;

		private static float defStrengthLower;

		private static float defVitality;

		private static float defSpeed;

		private static float defIntelligence;

		private static float loadAgility;

		private static float loadStrengthUpper;

		private static float loadStrengthLower;

		private static float loadVitality;

		private static float loadSpeed;

		private static float loadIntelligence;

		private static float defMassChest;

		private static float defMassPelvis;

		private static float defMassHead;

		private static float defMassArm;

		private static float defMassLeg;

		private static float loadMassChest;

		private static float loadMassPelvis;

		private static float loadMassHead;

		private static float loadMassArm;

		private static float loadMassLeg;

		public static void setDefStats(this Avatar avatar)
		{
			defAgility = avatar._agility;
			defStrengthUpper = avatar._strengthUpper;
			defStrengthLower = avatar._strengthLower;
			defVitality = avatar._vitality;
			defSpeed = avatar._speed;
			defIntelligence = avatar._intelligence;
		}

		public static float getDefAgility(this Avatar avatar)
		{
			return defAgility;
		}

		public static float getDefStrengthUpper(this Avatar avatar)
		{
			return defStrengthUpper;
		}

		public static float getDefStrengthLower(this Avatar avatar)
		{
			return defStrengthLower;
		}

		public static float getDefVitality(this Avatar avatar)
		{
			return defVitality;
		}

		public static float getDefSpeed(this Avatar avatar)
		{
			return defSpeed;
		}

		public static float getDefIntelligence(this Avatar avatar)
		{
			return defIntelligence;
		}

		public static void setLoadStats(this Avatar avatar)
		{
			loadAgility = avatar._agility;
			loadStrengthUpper = avatar._strengthUpper;
			loadStrengthLower = avatar._strengthLower;
			loadVitality = avatar._vitality;
			loadSpeed = avatar._speed;
			loadIntelligence = avatar._intelligence;
		}

		public static float getLoadAgility(this Avatar avatar)
		{
			return loadAgility;
		}

		public static float getLoadStrengthUpper(this Avatar avatar)
		{
			return loadStrengthUpper;
		}

		public static float getLoadStrengthLower(this Avatar avatar)
		{
			return loadStrengthLower;
		}

		public static float getLoadVitality(this Avatar avatar)
		{
			return loadVitality;
		}

		public static float getLoadSpeed(this Avatar avatar)
		{
			return loadSpeed;
		}

		public static float getLoadIntelligence(this Avatar avatar)
		{
			return loadIntelligence;
		}

		public static void setDefMasses(this Avatar avatar)
		{
			defMassChest = avatar._massChest;
			defMassPelvis = avatar._massPelvis;
			defMassHead = avatar._massHead;
			defMassArm = avatar._massArm;
			defMassLeg = avatar._massLeg;
		}

		public static float getDefMassChest(this Avatar avatar)
		{
			return defMassChest;
		}

		public static float getDefMassPelvis(this Avatar avatar)
		{
			return defMassPelvis;
		}

		public static float getDefMassHead(this Avatar avatar)
		{
			return defMassHead;
		}

		public static float getDefMassArm(this Avatar avatar)
		{
			return defMassArm;
		}

		public static float getDefMassLeg(this Avatar avatar)
		{
			return defMassLeg;
		}

		public static void setLoadMasses(this Avatar avatar)
		{
			loadMassChest = avatar._massChest;
			loadMassPelvis = avatar._massPelvis;
			loadMassHead = avatar._massHead;
			loadMassArm = avatar._massArm;
			loadMassLeg = avatar._massLeg;
		}

		public static float getLoadMassChest(this Avatar avatar)
		{
			return loadMassChest;
		}

		public static float getLoadMassPelvis(this Avatar avatar)
		{
			return loadMassPelvis;
		}

		public static float getLoadMassHead(this Avatar avatar)
		{
			return loadMassHead;
		}

		public static float getLoadMassArm(this Avatar avatar)
		{
			return loadMassArm;
		}

		public static float getLoadMassLeg(this Avatar avatar)
		{
			return loadMassLeg;
		}

		public static bool isEmptyRig(this Avatar avatar)
		{
			return ((Object)avatar).name == "[RealHeptaRig (Marrow1)]";
		}

		public static string getName(this Avatar avatar)
		{
			if (((Object)avatar).name.EndsWith("(Clone)"))
			{
				return ((Object)avatar).name.Substring(0, ((Object)avatar).name.Length - "(Clone)".Length);
			}
			return ((Object)avatar).name;
		}

		public static void recalculateTotalMass(this Avatar avatar)
		{
			avatar._massTotal = avatar._massChest + avatar._massPelvis + avatar._massHead + (avatar._massArm + avatar._massLeg) * 2f;
		}
	}
}
namespace AvatarStatsLoader.BoneMenu
{
	public class EntryFloatElement : MenuElement
	{
		protected readonly MelonPreferences_Entry<float> entry;

		protected readonly float increment;

		public override ElementType Type => (ElementType)5;

		public override string DisplayValue => entry.Value.ToString();

		public EntryFloatElement(string name, Color color, MelonPreferences_Entry<float> entry, float increment)
			: base(name, color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			this.entry = entry;
			this.increment = increment;
		}

		public override void OnSelectLeft()
		{
			MelonPreferences_Entry<float> obj = entry;
			obj.Value += increment;
		}

		public override void OnSelectRight()
		{
			MelonPreferences_Entry<float> obj = entry;
			obj.Value -= increment;
		}
	}
	public class EntryFloatIncrementElement : MenuElement
	{
		protected readonly MelonPreferences_Entry<float> entry;

		protected readonly float increment;

		public override ElementType Type => (ElementType)5;

		public override string DisplayValue
		{
			get
			{
				float num = increment;
				return "+/- " + num;
			}
		}

		public EntryFloatIncrementElement(string name, Color color, MelonPreferences_Entry<float> entry, float increment)
			: base(name, color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			this.entry = entry;
			this.increment = increment;
		}

		public float GetValue()
		{
			return entry.Value;
		}

		public void SetValue(float value)
		{
			entry.Value = value;
		}

		public override void OnSelectLeft()
		{
			MelonPreferences_Entry<float> obj = entry;
			obj.Value += increment;
		}

		public override void OnSelectRight()
		{
			MelonPreferences_Entry<float> obj = entry;
			obj.Value -= increment;
		}
	}
	public static class MenuCategoryExtensions
	{
		public static EntryFloatElement CreateEntryFloatElement(this MenuCategory category, string name, string hexColor, MelonPreferences_Entry<float> entry, float increment)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Color32 val = default(Color32);
			ColorUtility.DoTryParseHtmlColor(hexColor, ref val);
			return category.CreateEntryElement(name, Color32.op_Implicit(val), entry, increment);
		}

		public static EntryFloatElement CreateEntryElement(this MenuCategory category, string name, Color color, MelonPreferences_Entry<float> entry, float increment)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			EntryFloatElement entryFloatElement = new EntryFloatElement(name, color, entry, increment);
			category.Elements?.Add((MenuElement)(object)entryFloatElement);
			SafeActions.InvokeActionSafe<MenuCategory, MenuElement>(MenuCategory.OnElementCreated, category, (MenuElement)(object)entryFloatElement);
			return entryFloatElement;
		}

		public static EntryFloatIncrementElement CreateEntryFloatIncrementElement(this MenuCategory category, string hexColor, MelonPreferences_Entry<float> entry, float increment)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Color32 val = default(Color32);
			ColorUtility.DoTryParseHtmlColor(hexColor, ref val);
			return category.CreateEntryFloatIncrementElement(Color32.op_Implicit(val), entry, increment);
		}

		public static EntryFloatIncrementElement CreateEntryFloatIncrementElement(this MenuCategory category, Color color, MelonPreferences_Entry<float> entry, float increment)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			EntryFloatIncrementElement entryFloatIncrementElement = new EntryFloatIncrementElement("", color, entry, increment);
			category.Elements?.Add((MenuElement)(object)entryFloatIncrementElement);
			SafeActions.InvokeActionSafe<MenuCategory, MenuElement>(MenuCategory.OnElementCreated, category, (MenuElement)(object)entryFloatIncrementElement);
			return entryFloatIncrementElement;
		}
	}
	internal class EntryMenu
	{
		public readonly MenuCategory menu;

		public readonly EntryFloatElement value;

		public readonly EntryFloatIncrementElement incrementPointOne;

		public readonly EntryFloatIncrementElement incrementPointZeroOne;

		public readonly EntryFloatIncrementElement incrementPointZeroZeroOne;

		public readonly FunctionElement setToOne;

		public readonly FunctionElement loadFromAvatar;

		public readonly FunctionElement loadFromAvatarCalculated;

		public EntryMenu(MenuCategory parentMenu, string name, Func<float> getFromLoaded, MelonPreferences_Entry<float> entry)
		{
			EntryMenu entryMenu = this;
			menu = parentMenu.CreateCategory(name, "ffffff");
			value = menu.CreateEntryFloatElement("value", "ffffff", entry, 1f);
			incrementPointOne = menu.CreateEntryFloatIncrementElement("ffffff", entry, 0.1f);
			incrementPointZeroOne = menu.CreateEntryFloatIncrementElement("ffffff", entry, 0.01f);
			incrementPointZeroZeroOne = menu.CreateEntryFloatIncrementElement("ffffff", entry, 0.001f);
			setToOne = menu.CreateFunctionElement("Set to 1.0", "ffffff", (Action)delegate
			{
				entry.Value = 1f;
			});
			loadFromAvatar = menu.CreateFunctionElement("Load from avatar's loaded value", "ffffff", (Action)delegate
			{
				entry.Value = getFromLoaded();
			});
			loadFromAvatarCalculated = menu.CreateFunctionElement("Load from avatar's computed value", "ffffff", (Action)delegate
			{
				((MelonPreferences_Entry)entry).ResetToDefault();
			});
			((MelonEventBase<LemonAction<float, float>>)(object)entry.OnEntryValueChanged).Subscribe((LemonAction<float, float>)delegate
			{
				entryMenu.refreshDisplayValue();
			}, int.MaxValue, false);
		}

		public void refreshDisplayValue()
		{
			foreach (UIValueField item in Object.FindObjectsOfType<UIValueField>())
			{
				if (((TMP_Text)((UIElement)item).NameText).text == ((MenuElement)value).Name)
				{
					((UIElement)item).SetText(((MenuElement)value).Name, ((MenuElement)value).DisplayValue);
				}
			}
		}
	}
	internal class MassesBoneMenu
	{
		public static MenuCategory menu;

		public static EntryMenu massChest;

		public static EntryMenu massPelvis;

		public static EntryMenu massHead;

		public static EntryMenu massArm;

		public static EntryMenu massLeg;

		public static FunctionElement saveMasses;

		public static void init()
		{
			menu = MenuManager.CreateCategory("Avatar Mass", "ffffff");
			massChest = new EntryMenu(menu, "Chest Mass", () => AvatarStatsMod.currentAvatar.getLoadMassChest(), AvatarStatsMod.massChest);
			massPelvis = new EntryMenu(menu, "Pelvis Mass", () => AvatarStatsMod.currentAvatar.getLoadMassPelvis(), AvatarStatsMod.massPelvis);
			massHead = new EntryMenu(menu, "Head Mass", () => AvatarStatsMod.currentAvatar.getLoadMassHead(), AvatarStatsMod.massHead);
			massArm = new EntryMenu(menu, "Arm Mass", () => AvatarStatsMod.currentAvatar.getLoadMassArm(), AvatarStatsMod.massArm);
			massLeg = new EntryMenu(menu, "Leg Mass", () => AvatarStatsMod.currentAvatar.getLoadMassLeg(), AvatarStatsMod.massLeg);
			saveMasses = menu.CreateFunctionElement("Save masses", "ffffff", (Action)delegate
			{
				AvatarStatsMod.SaveMassesToFile();
			});
		}
	}
	internal class StatsBoneMenu
	{
		public static MenuCategory menu;

		public static EntryMenu agility;

		public static EntryMenu strengthUpper;

		public static EntryMenu strengthLower;

		public static EntryMenu vitality;

		public static EntryMenu speed;

		public static EntryMenu intelligence;

		public static FunctionElement saveStats;

		public static void init()
		{
			menu = MenuManager.CreateCategory("Avatar Stats", "ffffff");
			agility = new EntryMenu(menu, "Agility", () => AvatarStatsMod.currentAvatar.getLoadAgility(), AvatarStatsMod.agility);
			strengthUpper = new EntryMenu(menu, "Strength Upper", () => AvatarStatsMod.currentAvatar.getLoadStrengthUpper(), AvatarStatsMod.strengthUpper);
			strengthLower = new EntryMenu(menu, "Strength Lower", () => AvatarStatsMod.currentAvatar.getLoadStrengthLower(), AvatarStatsMod.strengthLower);
			vitality = new EntryMenu(menu, "Vitality", () => AvatarStatsMod.currentAvatar.getLoadVitality(), AvatarStatsMod.vitality);
			speed = new EntryMenu(menu, "Speed", () => AvatarStatsMod.currentAvatar.getLoadSpeed(), AvatarStatsMod.speed);
			intelligence = new EntryMenu(menu, "Intelligence", () => AvatarStatsMod.currentAvatar.getLoadIntelligence(), AvatarStatsMod.intelligence);
			saveStats = menu.CreateFunctionElement("Save stats", "ffffff", (Action)delegate
			{
				AvatarStatsMod.SaveStatsToFile();
			});
		}
	}
}