Bonelab mods are targeting MelonLoader version 0.5.7. Newer versions will not work!, so double-check your MelonLoader version if you're having issues.
Decompiled source of AvatarStatsLoader v1.2.3
Mods/AvatarStatsLoader.dll
Decompiled a month agousing 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(); }); } } }