/// <summary> /// This function will handle the main override of the ActionMenuOpener object according /// to the configuration supplied by MelonPrefs /// </summary> /// <param name="__0">Target state for the ActionMenu, either open or close</param> /// <param name="__instance">Instance of ActionMenuOpener __instance.name gives the MenuL or MenuR needed to determine hand</param> public static bool OnActionMenuOpen(bool __0, ref ActionMenuOpener __instance) { //MelonLogger.Log($"ActionMenuOpener OpenActionMenu Called OpenerName: {__instance.name}, BoolState: {__0}"); if ((MelonPreferences.GetEntryValue <bool>(settingsCategory, rightHandSetting) && __instance.name.Equals("MenuR")) || (MelonPreferences.GetEntryValue <bool>(settingsCategory, leftHandSetting) && __instance.name.Equals("MenuL"))) { if (__0) { HandGestureController.Method_Public_Static_Void_Boolean_0(!HandGestureController.Method_Public_Static_Boolean_0()); } else { HandGestureController.Method_Public_Static_Void_Boolean_0(__0); } return(false); //Skip original function } //Check if action menu is disabled for hand if ((MelonPreferences.GetEntryValue <bool>(settingsCategory, rightHandActionDisable) && __instance.name.Equals("MenuR")) || (MelonPreferences.GetEntryValue <bool>(settingsCategory, leftHandActionDisable) && __instance.name.Equals("MenuL"))) { return(false); } return(true); }
public void UiManagerInit() { MelonLogger.Msg("BTK Standalone: Self Portrait - Starting Up"); if (MelonHandler.Mods.Any(x => x.Info.Name.Equals("BTKCompanionLoader", StringComparison.OrdinalIgnoreCase))) { MelonLogger.Msg("Hold on a sec! Looks like you've got BTKCompanion installed, this mod is built in and not needed!"); MelonLogger.Error("BTKSASelfPortrait has not started up! (BTKCompanion Running)"); return; } Instance = this; MelonPreferences.CreateCategory(SettingsCategory, "BTKSA Self Portrait"); MelonPreferences.CreateEntry(SettingsCategory, PrefsCameraDistance, 0.7f, "Camera Distance"); MelonPreferences.CreateEntry(SettingsCategory, PrefsUIAlpha, 70, "UI Display Alpha Percentage"); MelonPreferences.CreateEntry(SettingsCategory, PrefsUIFlip, true, "Flip Display (Matches mirrors)"); MelonPreferences.CreateEntry(SettingsCategory, PrefsReflectOtherPlayers, false, "Reflect Other Players"); MelonPreferences.CreateEntry(SettingsCategory, PrefsFarClippingDist, 5f, "Camera Cutoff Distance"); MelonPreferences.CreateEntry(SettingsCategory, PrefsPosX, 300f, "UI Position X"); MelonPreferences.CreateEntry(SettingsCategory, PrefsPosY, -250f, "UI Position Y"); MelonPreferences.CreateEntry(SettingsCategory, PrefsScaleX, 0.4f, "UI Scale X"); MelonPreferences.CreateEntry(SettingsCategory, PrefsScaleY, 0.47f, "UI Scale Y"); ExpansionKitApi.GetExpandedMenu(ExpandedMenu.QuickMenu).AddSimpleButton("Toggle Self Portrait", ToggleSelfPortrait); //Apply patches applyPatches(typeof(FadePatches)); LoadAssets(); _cameraEye = GameObject.Find("Camera (eye)"); _hudContent = GameObject.Find("/UserInterface/UnscaledUI/HudContent"); OnPreferencesSaved(); }
public static void RegisterConfig() { MelonPreferences.CreateEntry(Category, nameof(SafeSongListReload), true, "Blocks access to song list during song list reload (safety feature)."); MelonPreferences.CreateEntry(Category, nameof(LastSongCount), 0, ""); LastSongCount = MelonPreferences.GetEntryValue <int>(Category, nameof(LastSongCount)); MelonPreferences.CreateEntry(Category, nameof(playlistTitle), "", "[Header]Playlist Settings"); MelonPreferences.CreateEntry(Category, nameof(Shuffle), false, ""); Shuffle = MelonPreferences.GetEntryValue <bool>(Category, nameof(Shuffle)); MelonPreferences.CreateEntry(Category, nameof(ShowScores), false, ""); ShowScores = MelonPreferences.GetEntryValue <bool>(Category, nameof(ShowScores)); MelonPreferences.CreateEntry(Category, nameof(NoFail), false, ""); NoFail = MelonPreferences.GetEntryValue <bool>(Category, nameof(NoFail)); MelonPreferences.CreateEntry(Category, nameof(ResetHealth), false, ""); ResetHealth = MelonPreferences.GetEntryValue <bool>(Category, nameof(ResetHealth)); OnPreferencesSaved(); }
public static void OnPreferencesSaved() { foreach (var fieldInfo in typeof(Config).GetFields(BindingFlags.Static | BindingFlags.NonPublic)) { if (fieldInfo.FieldType == typeof(string)) { fieldInfo.SetValue(null, MelonPreferences.GetEntryValue <string>(Category, fieldInfo.Name)); } else if (fieldInfo.FieldType == typeof(bool)) { fieldInfo.SetValue(null, MelonPreferences.GetEntryValue <bool>(Category, fieldInfo.Name)); } else if (fieldInfo.FieldType == typeof(float)) { fieldInfo.SetValue(null, MelonPreferences.GetEntryValue <float>(Category, fieldInfo.Name)); } else if (fieldInfo.FieldType == typeof(int)) { fieldInfo.SetValue(null, MelonPreferences.GetEntryValue <int>(Category, fieldInfo.Name)); } } MelonLogger.Msg("Mod settings applied"); AssignValues(); }
public override void VRChat_OnUiManagerInit() { Log("BTK Standalone: Nameplate Mod - Starting up"); instance = this; if (MelonHandler.Mods.Any(x => x.Info.Name.Equals("BTKCompanionLoader", StringComparison.OrdinalIgnoreCase))) { MelonLogger.Msg("Hold on a sec! Looks like you've got BTKCompanion installed, this mod is built in and not needed!"); MelonLogger.Error("BTKSANameplateMod has not started up! (BTKCompanion Running)"); return; } MelonPreferences.CreateCategory(settingsCategory, "Nameplate Mod"); MelonPreferences.CreateEntry <bool>(settingsCategory, hiddenCustomSetting, false, "Enable Custom Nameplates (Not ready)"); MelonPreferences.CreateEntry <bool>(settingsCategory, hideFriendsNameplates, false, "Hide Friends Nameplates"); MelonPreferences.CreateEntry <string>(settingsCategory, trustColourMode, "friends", "Trust Colour Mode"); MelonPreferences.CreateEntry <bool>(settingsCategory, nameplateOutlineMode, false, "Nameplate Outline Background"); MelonPreferences.CreateEntry <bool>(settingsCategory, nameplateAlwaysShowQuickStats, false, "Always Show Quick Stats"); MelonPreferences.CreateEntry <bool>(settingsCategory, nameplateCloseRangeFade, false, "Close Range Fade"); MelonPreferences.CreateEntry <float>(settingsCategory, nameplateCloseRangeDistMin, 2f, "Close Range Min Distance"); MelonPreferences.CreateEntry <float>(settingsCategory, nameplateCloseRangeDistMax, 3f, "Close Range Max Distance"); MelonPreferences.CreateEntry <bool>(settingsCategory, nameplateRandomColours, false, "Random Nameplate Colours"); ExpansionKitApi.RegisterSettingAsStringEnum(settingsCategory, trustColourMode, new[] { ("off", "Disable Trust Colours"), ("friends", "Show Friends Colour"), ("trustonly", "Ignore Friends Colour"), ("trustname", "Trust Colour On Name") });
public override void OnApplicationStart() { MelonPreferences.CreateCategory("TeleportCamToYou", "Teleport Camera To You"); MelonPreferences.CreateEntry("TeleportCamToYou", "Distance", 0.1f, "Distance from your head"); ExpansionKitApi.GetExpandedMenu(ExpandedMenu.CameraQuickMenu).AddSimpleButton("Teleport Camera To You", () => { GameObject vrcam = GameObject.Find("TrackingVolume/PlayerObjects/UserCamera/ViewFinder"); if (vrcam is null) { return; } VRCPlayer player = VRCPlayer.field_Internal_Static_VRCPlayer_0; Vector3 pos = GameObject.Find(player.gameObject.name + "/AnimationController/HeadAndHandIK/HeadEffector").transform.position + (player.transform.forward * MelonPreferences.GetEntryValue <float>("TeleportCamToYou", "Distance")); vrcam.transform.position = pos; }); }
public override void OnPreferencesSaved() { _comfyVRMenu = MelonPreferences.GetEntryValue <bool>("ComfyVRMenu", "EnableComfyVRMenu"); }
internal static void InternalConfigRefresh() //The Divide by 10k sets it back to a managable float number { SensitivityValue = MelonPreferences.GetEntryValue <float>("MicSensitivity", "Mic - Microphone Sensitivity") / 10000; UseMod = MelonPreferences.GetEntryValue <bool>("MicSensitivity", "Mic - Enable Mic Sensitivity Mod"); }
public override void Init() { prefCategory = MelonPreferences.CreateCategory(CTG_NAME, $"{CTG_NAME} Settings"); MelonPreferences.Mapper.RegisterMapper(KeycodeReader, KeycodeWriter); }
public override void OnPreferencesSaved() { keybindsEnabled = MelonPreferences.GetEntryValue <bool>("NearClipAdj", "Keyboard"); smallerDefault = MelonPreferences.GetEntryValue <bool>("NearClipAdj", "SmallerDefault"); }
public override void OnPreferencesSaved() { _enabled = MelonPreferences.GetEntryValue <bool>("Udon't", "Enabled"); _publicInstancesOnly = MelonPreferences.GetEntryValue <bool>("Udon't", "PublicInstancesOnly"); }
private void UpdatePreferences() { Pref_DisableOutlines = MelonPreferences.GetEntryValue <bool>(Pref_CategoryName, nameof(Pref_DisableOutlines)); Pref_DisableBeam = MelonPreferences.GetEntryValue <bool>(Pref_CategoryName, nameof(Pref_DisableBeam)); Pref_DebugOutput = MelonPreferences.GetEntryValue <bool>(Pref_CategoryName, nameof(Pref_DebugOutput)); }
public override void OnApplicationStart() { ClassInjector.RegisterTypeInIl2Cpp <BoneDeleteHandler>(); var category = MelonPreferences.CreateCategory("Turbones"); var enableCollisionChecks = category.CreateEntry("OptimizedCollisionChecks", true, "Enable optimized collision checks"); var enableUpdate = category.CreateEntry("OptimizedUpdate", true, "Enable optimized simulation"); var updateMultiThread = category.CreateEntry("OptimizedMultiThread", false, "Enable multithreading (placebo!)"); var threadCount = category.CreateEntry("DynamicBoneThreads", Math.Max(1, Environment.ProcessorCount / 2 - 1), "Thread count (placebo!)", dont_save_default: true); var dllName = "JigglyRustSolver.dll"; try { using var resourceStream = Assembly.GetExecutingAssembly() .GetManifestResourceStream(typeof(TurbonesMod), dllName); using var fileStream = File.Open("VRChat_Data/Plugins/" + dllName, FileMode.Create, FileAccess.Write); resourceStream.CopyTo(fileStream); } catch (IOException ex) { MelonLogger.Warning("Failed to write native dll; will attempt loading it anyway. This is normal if you're running multiple instances of VRChat"); MelonDebug.Msg(ex.ToString()); } if (!JigglySolverApi.Initialize("VRChat_Data/Plugins/" + dllName)) { MelonLogger.Error("Error initializing native library; mod won't work"); return; } ourDynBoneCollideEntryPoint = Marshal.ReadIntPtr((IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod( typeof(DynamicBoneCollider).GetMethod(nameof(DynamicBoneCollider .Method_Public_Void_byref_Vector3_Single_0))).GetValue(null)); ourDynBoneUpdateEntryPoint = Marshal.ReadIntPtr((IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod( typeof(DynamicBone).GetMethod(nameof(DynamicBone .Method_Private_Void_Single_Boolean_0))).GetValue(null)); var isCollidePatched = false; unsafe void PatchCollide() { if (isCollidePatched) { return; fixed(IntPtr *a = &ourDynBoneCollideEntryPoint) MelonUtils.NativeHookAttach((IntPtr)a, JigglySolverApi.LibDynBoneCollideEntryPoint); MelonLogger.Msg("Patched DynamicBone Collide"); isCollidePatched = true; } unsafe void UnpatchCollide() { if (!isCollidePatched) { return; fixed(IntPtr *a = &ourDynBoneCollideEntryPoint) MelonUtils.NativeHookDetach((IntPtr)a, JigglySolverApi.LibDynBoneCollideEntryPoint); MelonLogger.Msg("Unpatched DynamicBone Collide"); isCollidePatched = false; } unsafe void RepatchUpdate(bool useFast, bool useMt) { // TODO: re-enable multithreading if it ever gets useful/stable useMt = false; if (ourLastPatchPointer != IntPtr.Zero) { fixed(IntPtr *a = &ourDynBoneUpdateEntryPoint) MelonUtils.NativeHookDetach((IntPtr)a, ourLastPatchPointer); MelonLogger.Msg("Unpatched DynamicBone Update"); ourLastPatchPointer = IntPtr.Zero; } if (!CheckWasSuccessful) return; } if (useFast) { ourLastPatchPointer = useMt ? JigglySolverApi.LibDynBoneUpdateMultiThreaded : JigglySolverApi.LibDynBoneUpdateSingleThreaded; fixed(IntPtr *a = &ourDynBoneUpdateEntryPoint) MelonUtils.NativeHookAttach((IntPtr)a, ourLastPatchPointer); MelonLogger.Msg($"Patched DynamicBone Update (multithreaded: {useMt})"); } else { ourLastPatchPointer = JigglySolverApi.DynamicBoneUpdateNotifyPatch; fixed(IntPtr *a = &ourDynBoneUpdateEntryPoint) MelonUtils.NativeHookAttach((IntPtr)a, ourLastPatchPointer); JigglySolverApi.SetOriginalBoneUpdateDelegate(ourDynBoneUpdateEntryPoint); MelonLogger.Msg($"Patched DynamicBone Update (notify)"); } } CheckDummyThree(); enableCollisionChecks.OnValueChanged += (_, v) => { if (v) PatchCollide(); }
public IEnumerator InitializeUI() { MelonLogger.Msg("Initializing DiscordMute UI..."); var parentObject = QuickMenu.Find("Container").Find("Window").transform; var originalMic = parentObject.Find("MicButton").gameObject; DiscordButton = UnityEngine.Object.Instantiate(originalMic, originalMic.transform); DiscordButton.name = "DiscordButton"; DiscordButton.transform.SetParent(parentObject); DiscordButton.SetActive(true); DiscordButton.transform.localPosition += new Vector3(30, 97, 0); MelonLogger.Msg("Initializing Bind Manager"); BindManager.Initialize(); void ShowBindManager() { BindManager.Show("Press your mute key in keyboard", new Action <List <Keys> >(selectedKeys => { string stringKeys = ""; if (selectedKeys.Count > 0) { stringKeys = string.Join(",", selectedKeys); } MelonPreferences.SetEntryValue("DiscordMute", nameof(MuteKey), stringKeys); MelonPreferences.Save(); }), null); } ExpansionKitApi.GetExpandedMenu(ExpandedMenu.SettingsMenu).AddSimpleButton("Discord Bind", () => ShowBindManager()); UnityEngine.Object.Destroy(DiscordButton.GetComponent <MicToggle>()); UnityEngine.Object.Destroy(DiscordButton.GetComponent <Toggle>()); yield return(null); // Wait object destroy var tooltip = DiscordButton.GetComponent <UiToggleTooltip>(); tooltip.field_Public_String_0 = "Discord"; tooltip.field_Public_String_1 = "Discord"; var toggle = DiscordButton.AddComponent <Toggle>(); yield return(null); // Wait component toggle.onValueChanged.RemoveAllListeners(); toggle.isOn = true; toggle.onValueChanged.AddListener(new Action <bool>(value => { if (!string.IsNullOrEmpty(MuteKey)) { List <Keys> selectedKeys = new List <Keys>(); if (!string.IsNullOrEmpty(MuteKey)) { string[] stringKeys = MuteKey.Split(','); foreach (var stringKey in stringKeys) { selectedKeys.Add((Keys)Enum.Parse(typeof(Keys), stringKey)); } } // Hold and Release the selected keys foreach (var key in selectedKeys) { HoldKey(key); } foreach (var key in selectedKeys) { ReleaseKey(key); } } else { ShowBindManager(); } })); yield break; }
public override void OnPreferencesSaved() { MuteKey = MelonPreferences.GetEntryValue <string>("DiscordMute", nameof(MuteKey)); }
/* * public static ModifierParams.BopMode bopModeParams; * private static string bopModeTitle = "[Header]Bop Mode"; * private static bool bopModeEnabled; * private static float bopModeDuration; * private static float bopModeCooldown; */ public static void RegisterConfig() { MelonPreferences.CreateEntry(Category, nameof(enableTwitchModifiers), true, "Enables Twitch Modifiers."); MelonPreferences.CreateEntry(Category, nameof(showOnScoreOverlay), true, "Shows active modifiers and cooldowns on Score Overlay (requries Score Overlay by octo)."); MelonPreferences.CreateEntry(Category, nameof(enableCountdown), true, "Enables Countdown before activating a modifier."); MelonPreferences.CreateEntry(Category, nameof(useChannelPoints), false, "Requires viewers to redeem channel points to use modifiers."); MelonPreferences.CreateEntry(Category, nameof(allowScoreDisablingMods), true, "Turning this off disables some modifiers that prevent you from submitting scores to the leaderboards."); MelonPreferences.CreateEntry(Category, nameof(cooldownBetweenModifiers), 2f, "Cooldown before another modifier can be activated.[0, 20, 1, 2]"); MelonPreferences.CreateEntry(Category, nameof(maxActiveModifiers), 5, "How many modifiers can be active at once.[1, 10, 1, 5]"); MelonPreferences.CreateEntry(Category, nameof(showModStatus), true, "Shows time left for on active modifier ingame."); MelonPreferences.CreateEntry(Category, nameof(disableForOst), true, "Disables Twitch Modifiers during OST songs."); MelonPreferences.CreateEntry(Category, nameof(speedTilte), "", "[Header]Speed"); MelonPreferences.CreateEntry(Category, nameof(speedEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(speedDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(speedCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(minSpeed), .5f, "Minimum amount of speed [0.1, 1, 0.1, 0.5]{P}"); MelonPreferences.CreateEntry(Category, nameof(maxSpeed), 1.5f, "Maximum amount of speed [1, 3, 0.1, 1.5]{P}"); MelonPreferences.CreateEntry(Category, nameof(aimTitle), "", "[Header]Aim Assist"); MelonPreferences.CreateEntry(Category, nameof(aimAssistEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(aimAssistDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(aimAssistCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(minAimAssist), 0f, "Minimum amount of Aim Assist [0, 1, 0.1, 0]{P}"); MelonPreferences.CreateEntry(Category, nameof(psyTitle), "", "[Header]Psychedelia"); MelonPreferences.CreateEntry(Category, nameof(psychedeliaEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(psychedeliaDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(psychedeliaCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(minPsychedeliaSpeed), 1f, "Minimum amount of speed [0.1, 1, 0.1, 0.5]{P}"); MelonPreferences.CreateEntry(Category, nameof(maxPsychedeliaSpeed), 10f, "Maximum amount of speed [1, 30, 1, 10]{P}"); MelonPreferences.CreateEntry(Category, nameof(minesTitle), "", "[Header]Mines"); MelonPreferences.CreateEntry(Category, nameof(minesEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(minesDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(minesCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(wobbleTitle), "", "[Header]Wobble"); MelonPreferences.CreateEntry(Category, nameof(wobbleEnabled), true, "Enables this modifier and all of it's modes."); MelonPreferences.CreateEntry(Category, nameof(wombleEnabled), true, "Womble is wobble with speed arguments."); MelonPreferences.CreateEntry(Category, nameof(woobleEnabled), true, "A slightly more retarded wobble."); MelonPreferences.CreateEntry(Category, nameof(wroblEnabled), true, "Wobble gone full retard."); MelonPreferences.CreateEntry(Category, nameof(wobbleDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(wobbleCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(wobbleMinSpeed), .5f, "Minimum amount of speed [0.5, 1, 0.1, 0.5]{P}"); MelonPreferences.CreateEntry(Category, nameof(wobbleMaxSpeed), 1.5f, "Maximum amount of speed [1, 2, 1, 1.5]{P}"); MelonPreferences.CreateEntry(Category, nameof(invisGunsTitle), "", "[Header]Invisible Guns"); MelonPreferences.CreateEntry(Category, nameof(invisibleGunsEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(invisibleGunsDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(invisibleGunsCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(particlesTitle), "", "[Header]Particles"); MelonPreferences.CreateEntry(Category, nameof(particlesEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(particlesDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(particlesCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(minParticles), 0f, "Minimum amount of particles [0, 1, 0.1, 0]{P}"); MelonPreferences.CreateEntry(Category, nameof(maxParticles), 10f, "Maximum amount of particles [1, 50, 1, 10]{P}"); MelonPreferences.CreateEntry(Category, nameof(zOffsetTitle), "", "[Header]zOffset"); MelonPreferences.CreateEntry(Category, nameof(zoffsetEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(zoffsetDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(zoffsetCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(minZoffset), -.5f, "Minimum amount of zOffset [-0.5, 0, 0.1, -0.5]"); MelonPreferences.CreateEntry(Category, nameof(maxZoffset), 3f, "Maximum amount of zOffset [0, 5, 0.1, 3]"); MelonPreferences.CreateEntry(Category, nameof(betterMeleesTitle), "", "[Header]Better Melees"); MelonPreferences.CreateEntry(Category, nameof(betterMeleesEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(betterMeleesDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(betterMeleesCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(randomoffsetTitle), "", "[Header]Random Offset"); MelonPreferences.CreateEntry(Category, nameof(randomOffsetEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(randomOffsetDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(randomOffsetCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(minRandomOffsetX), -1.5f, "Minimum offset on X-Axis.[-2.5, 0, 0.1, -1.5]{P}"); MelonPreferences.CreateEntry(Category, nameof(maxRandomOffsetX), 1.5f, "Maximum offset on X-Axis.[0, 2.5, 0.1, 1.5]{P}"); MelonPreferences.CreateEntry(Category, nameof(minRandomOffsetY), -1.5f, "Minimum offset on Y-Axis.[-2.5, 0, 0.1, -1.5]{P}"); MelonPreferences.CreateEntry(Category, nameof(maxRandomOffsetY), 1.5f, "Maximum offset on Y-Axis.[0, 2.5, 0.1, 1.5]{P}"); MelonPreferences.CreateEntry(Category, nameof(scaleTitle), "", "[Header]Scale"); MelonPreferences.CreateEntry(Category, nameof(scaleEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(scaleDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(scaleCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(minScale), .5f, "Minimum scale.[0.1, 1, 0.1, 0.5]{P}"); MelonPreferences.CreateEntry(Category, nameof(maxScale), 3f, "Maximum scale.[1, 3, 0.1, 3]{P}"); MelonPreferences.CreateEntry(Category, nameof(randomColorsTitle), "", "[Header]Random Colors"); MelonPreferences.CreateEntry(Category, nameof(randomColorsEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(randomColorsDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(randomColorsCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(colorSwapTitle), "", "[Header]Color Swap"); MelonPreferences.CreateEntry(Category, nameof(colorSwapEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(colorSwapDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(colorSwapCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(streamModeTitle), "", "[Header]Stream Mode"); MelonPreferences.CreateEntry(Category, nameof(streamModeEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(streamModeDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(streamModeCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(maxStreamSpeed), 16, "Maximum interval (note value).[4, 32, 2, 16]"); MelonPreferences.CreateEntry(Category, nameof(hiddenTelegraphsTitle), "", "[Header]Hidden Telegraphs"); MelonPreferences.CreateEntry(Category, nameof(hiddenTelegraphsEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(hiddenTelegraphsDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(hiddenTelegraphsCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(unifyColorsTitle), "", "[Header]Unify Colors"); MelonPreferences.CreateEntry(Category, nameof(unifyColorsEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(unifyColorsDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(unifyColorsCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); /*MelonPreferences.CreateEntry(Category, nameof(timingAttackTitle), "", timingAttackTitle); * MelonPreferences.CreateEntry(Category, nameof(timingAttackEnabled), true, "Enables this modifier."); * MelonPreferences.CreateEntry(Category, nameof(timingAttackDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); * MelonPreferences.CreateEntry(Category, nameof(timingAttackCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 60, 1, 20]"); * * MelonPreferences.CreateEntry(Category, nameof(nukeTitle), "", nukeTitle); * MelonPreferences.CreateEntry(Category, nameof(nukeEnabled), true, "Enables this modifier."); * MelonPreferences.CreateEntry(Category, nameof(nukeDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); * MelonPreferences.CreateEntry(Category, nameof(nukeCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 600, 10, 120]");*/ MelonPreferences.CreateEntry(Category, nameof(stutterChainTitle), "", "[Header]Stutter Chains"); MelonPreferences.CreateEntry(Category, nameof(stutterChainsEnabled), true, "Enables this modifier."); MelonPreferences.CreateEntry(Category, nameof(stutterChainsDuration), 20f, "Duration of this modifier. [10, 60, 1, 20]"); MelonPreferences.CreateEntry(Category, nameof(stutterChainsCooldown), 20f, "Cooldown before this modifier can be activated again. [0, 600, 10, 120]"); MelonPreferences.CreateEntry(Category, nameof(stutterChainsMin), .5f, "Minimum Stutter Rotation.[1, 50, 1, 1]{P}"); MelonPreferences.CreateEntry(Category, nameof(stutterChainsMax), 3f, "Maximum Stutter Rotation.[6, 100, 1, 100]{P}"); OnPreferencesSaved(); }
public override void OnGUI() { if (CheatToggles.guiEnabled) { if (initializedScene > 1) { if (GUI.Toggle(new Rect(500f, 2f, 150f, 20f), CheatToggles.guiGhost, "Ghost GUI") != CheatToggles.guiGhost) { CheatToggles.guiGhost = !CheatToggles.guiGhost; CheatToggles.guiGhostTroll = false; CheatToggles.guiESP = false; CheatToggles.guiHelper = false; CheatToggles.guiHelperInfo = false; CheatToggles.guiTroll = false; CheatToggles.guiDebug = false; CheatToggles.guiTest = false; CheatToggles.guiFeatureCollection = false; } if (CheatToggles.guiGhost == true) { if (GUI.Toggle(new Rect(650f, 2f, 150f, 20f), CheatToggles.enableEspGhost, "Ghost ESP") != CheatToggles.enableEspGhost) { CheatToggles.enableEspGhost = !CheatToggles.enableEspGhost; Debug.Msg("ESP: Toggled " + (CheatToggles.enableEspGhost ? "On" : "Off"), 1); } } if (GUI.Toggle(new Rect(500f, 22f, 150f, 20f), CheatToggles.guiESP, "ESP GUI") != CheatToggles.guiESP) { CheatToggles.guiESP = !CheatToggles.guiESP; CheatToggles.guiGhost = false; CheatToggles.guiGhostTroll = false; CheatToggles.guiHelper = false; CheatToggles.guiHelperInfo = false; CheatToggles.guiTroll = false; CheatToggles.guiDebug = false; CheatToggles.guiTest = false; CheatToggles.guiFeatureCollection = false; } if (CheatToggles.guiESP == true) { if (GUI.Toggle(new Rect(650f, 2f, 150f, 20f), CheatToggles.enableEspGhost, "Ghost ESP") != CheatToggles.enableEspGhost) { CheatToggles.enableEspGhost = !CheatToggles.enableEspGhost; Debug.Msg("Ghost ESP: Toggled " + (CheatToggles.enableEspGhost ? "On" : "Off"), 1); } if (GUI.Toggle(new Rect(650f, 22f, 150f, 20f), CheatToggles.enableEspGhostVisible, "Ghost Visible") != CheatToggles.enableEspGhostVisible) { CheatToggles.enableEspGhostVisible = !CheatToggles.enableEspGhostVisible; Debug.Msg("Ghost Visible: Toggled " + (CheatToggles.enableEspGhostVisible ? "On" : "Off"), 1); } if (GUI.Toggle(new Rect(650f, 42f, 150f, 20f), CheatToggles.enableEspGhostBone, "Ghost Bone ESP") != CheatToggles.enableEspGhostBone) { CheatToggles.enableEspGhostBone = !CheatToggles.enableEspGhostBone; Debug.Msg("Ghost Bone ESP: Toggled " + (CheatToggles.enableEspGhostBone ? "On" : "Off"), 1); } if (GUI.Toggle(new Rect(650f, 62f, 150f, 20f), CheatToggles.enableEspGhostFinger, "Ghost Bone Finger ESP") != CheatToggles.enableEspGhostFinger) { CheatToggles.enableEspGhostFinger = !CheatToggles.enableEspGhostFinger; Debug.Msg("Ghost Bone Finger ESP: Toggled " + (CheatToggles.enableEspGhostFinger ? "On" : "Off"), 1); } if (GUI.Toggle(new Rect(650f, 82f, 150f, 20f), CheatToggles.enableEspPlayer, "Player ESP") != CheatToggles.enableEspPlayer) { CheatToggles.enableEspPlayer = !CheatToggles.enableEspPlayer; Debug.Msg("Player ESP: Toggled " + (CheatToggles.enableEspPlayer ? "On" : "Off"), 1); } if (GUI.Toggle(new Rect(650f, 102f, 150f, 20f), CheatToggles.enableEspPlayerBone, "Player Bone ESP") != CheatToggles.enableEspPlayerBone) { CheatToggles.enableEspPlayerBone = !CheatToggles.enableEspPlayerBone; Debug.Msg("Player Bone ESP: Toggled " + (CheatToggles.enableEspPlayerBone ? "On" : "Off"), 1); } if (GUI.Toggle(new Rect(650f, 122f, 150f, 20f), CheatToggles.enableEspBone, "Bone ESP") != CheatToggles.enableEspBone) { CheatToggles.enableEspBone = !CheatToggles.enableEspBone; Debug.Msg("Bone ESP: Toggled " + (CheatToggles.enableEspBone ? "On" : "Off"), 1); } if (GUI.Toggle(new Rect(650f, 142f, 150f, 20f), CheatToggles.enableEspOuija, "Cursed Items ESP") != CheatToggles.enableEspOuija) { CheatToggles.enableEspOuija = !CheatToggles.enableEspOuija; Debug.Msg("Cursed Items ESP: Toggled " + (CheatToggles.enableEspOuija ? "On" : "Off"), 1); } if (GUI.Toggle(new Rect(650f, 162f, 150f, 20f), CheatToggles.enableEspFuseBox, "FuseBox ESP") != CheatToggles.enableEspFuseBox) { CheatToggles.enableEspFuseBox = !CheatToggles.enableEspFuseBox; Debug.Msg("FuseBox ESP: Toggled " + (CheatToggles.enableEspFuseBox ? "On" : "Off"), 1); } if (GUI.Toggle(new Rect(650f, 182f, 150f, 20f), CheatToggles.enableEspEmf, "Emf ESP") != CheatToggles.enableEspEmf) { CheatToggles.enableEspEmf = !CheatToggles.enableEspEmf; Debug.Msg("Emf ESP: Toggled " + (CheatToggles.enableEspEmf ? "On" : "Off"), 1); } } if (GUI.Toggle(new Rect(500f, 42f, 150f, 20f), CheatToggles.guiHelper, "Helper GUI") != CheatToggles.guiHelper) { CheatToggles.guiHelper = !CheatToggles.guiHelper; CheatToggles.guiGhost = false; CheatToggles.guiGhostTroll = false; CheatToggles.guiESP = false; CheatToggles.guiHelperInfo = false; CheatToggles.guiTroll = false; CheatToggles.guiDebug = false; CheatToggles.guiTest = false; CheatToggles.guiFeatureCollection = false; } if (CheatToggles.guiHelper == true) { if (GUI.Toggle(new Rect(650f, 2f, 150f, 20f), CheatToggles.guiHelperInfo, "Basic Info") != CheatToggles.guiHelperInfo) { CheatToggles.guiHelperInfo = !CheatToggles.guiHelperInfo; } if (CheatToggles.guiHelperInfo == true) { if (GUI.Toggle(new Rect(800f, 2f, 150f, 20f), CheatToggles.enableBIGhost, "Ghost Info") != CheatToggles.enableBIGhost) { CheatToggles.enableBIGhost = !CheatToggles.enableBIGhost; Debug.Msg("Ghost Info: Toggled " + (CheatToggles.enableBIGhost ? "On" : "Off"), 1); } if (GUI.Toggle(new Rect(800f, 22f, 150f, 20f), CheatToggles.enableBIMissions, "Missions Info") != CheatToggles.enableBIMissions) { CheatToggles.enableBIMissions = !CheatToggles.enableBIMissions; Debug.Msg("Missions Info: Toggled " + (CheatToggles.enableBIMissions ? "On" : "Off"), 1); } if (GUI.Toggle(new Rect(800f, 42f, 150f, 20f), CheatToggles.enableBIPlayer, "Player Info") != CheatToggles.enableBIPlayer) { CheatToggles.enableBIPlayer = !CheatToggles.enableBIPlayer; Debug.Msg("Player Info: Toggled " + (CheatToggles.enableBIPlayer ? "On" : "Off"), 1); } } if (GUI.Toggle(new Rect(650f, 22f, 150f, 20f), CheatToggles.enableFullbright, "Enable Fullbright") != CheatToggles.enableFullbright) { CheatToggles.enableFullbright = !CheatToggles.enableFullbright; Debug.Msg("Fullbright: Toggled " + (CheatToggles.enableFullbright ? "On" : "Off"), 1); if (CheatToggles.enableFullbright) { Fullbright.Enable(); } else { Fullbright.Disable(); } } if (GUI.Toggle(new Rect(650f, 62f, 150f, 20f), CheatToggles.enableInfStamina, "Infinite Stamina") != CheatToggles.enableInfStamina) { CheatToggles.enableInfStamina = !CheatToggles.enableInfStamina; Debug.Msg("Infinite Stamina: Toggled " + (CheatToggles.enableInfStamina ? "On" : "Off"), 1); } } if (GUI.Toggle(new Rect(500f, 62f, 150f, 20f), CheatToggles.guiTroll, "Troll GUI") != CheatToggles.guiTroll) { CheatToggles.guiTroll = !CheatToggles.guiTroll; CheatToggles.guiGhost = false; CheatToggles.guiGhostTroll = false; CheatToggles.guiESP = false; CheatToggles.guiHelper = false; CheatToggles.guiHelperInfo = false; CheatToggles.guiDebug = false; CheatToggles.guiTest = false; CheatToggles.guiFeatureCollection = false; } if (GUI.Toggle(new Rect(500f, 82f, 150f, 20f), CheatToggles.guiDebug, "Debug GUI") != CheatToggles.guiDebug) { CheatToggles.guiDebug = !CheatToggles.guiDebug; CheatToggles.guiGhost = false; CheatToggles.guiGhostTroll = false; CheatToggles.guiESP = false; CheatToggles.guiHelper = false; CheatToggles.guiHelperInfo = false; CheatToggles.guiTroll = false; CheatToggles.guiTest = false; CheatToggles.guiFeatureCollection = false; } if (CheatToggles.guiDebug == true) { if (GUI.Toggle(new Rect(650f, 2f, 150f, 20f), CheatToggles.enableDebug, "Enable Debug") != CheatToggles.enableDebug) { CheatToggles.enableDebug = !CheatToggles.enableDebug; Debug.Msg("Debug: Toggled " + (CheatToggles.enableDebug ? "On" : "Off"), 1); MelonPreferences.SetEntryValue <bool>("Settings", "DebugEnabled", CheatToggles.enableDebug); } if (GUI.Toggle(new Rect(650f, 22f, 150f, 20f), Debug.debugMode1, "Debug Mode 1") != Debug.debugMode1) { Debug.debugMode1 = !Debug.debugMode1; Debug.Msg("Debug Mode 1: Toggled " + (Debug.debugMode1 ? "On" : "Off"), 1); MelonPreferences.SetEntryValue <bool>("Settings", "DebugM1Enabled", Debug.debugMode1); } if (GUI.Toggle(new Rect(650f, 42f, 150f, 20f), Debug.debugMode2, "Debug Mode 2") != Debug.debugMode2) { Debug.debugMode2 = !Debug.debugMode2; Debug.Msg("Debug Mode 2: Toggled " + (Debug.debugMode2 ? "On" : "Off"), 1); MelonPreferences.SetEntryValue <bool>("Settings", "DebugM2Enabled", Debug.debugMode2); } if (GUI.Toggle(new Rect(650f, 62f, 150f, 20f), Debug.debugMode3, "Debug Mode 3") != Debug.debugMode3) { Debug.debugMode3 = !Debug.debugMode3; Debug.Msg("Debug Mode 3: Toggled " + (Debug.debugMode3 ? "On" : "Off"), 1); MelonPreferences.SetEntryValue <bool>("Settings", "DebugM3Enabled", Debug.debugMode3); } } if (GUI.Toggle(new Rect(500f, 102f, 150f, 20f), CheatToggles.guiTest, "New Features") != CheatToggles.guiTest) { CheatToggles.guiTest = !CheatToggles.guiTest; CheatToggles.guiGhost = false; CheatToggles.guiGhostTroll = false; CheatToggles.guiESP = false; CheatToggles.guiHelper = false; CheatToggles.guiHelperInfo = false; CheatToggles.guiTroll = false; CheatToggles.guiDebug = false; CheatToggles.guiFeatureCollection = false; } if (CheatToggles.guiTest == true) { if (GUI.Button(new Rect(650f, 82f, 150f, 20f), "Disable All Features") && levelController != null) { DisableAll(); Debug.Msg("Disable All", 1); } } if (GUI.Toggle(new Rect(500f, 122f, 150f, 20f), CheatToggles.guiFeatureCollection, "Feature Coll. GUI") != CheatToggles.guiFeatureCollection) { CheatToggles.guiFeatureCollection = !CheatToggles.guiFeatureCollection; CheatToggles.guiGhost = false; CheatToggles.guiGhostTroll = false; CheatToggles.guiESP = false; CheatToggles.guiHelper = false; CheatToggles.guiHelperInfo = false; CheatToggles.guiTroll = false; CheatToggles.guiDebug = false; CheatToggles.guiTest = false; } } else { if (initializedScene == 1) { if (GUI.Toggle(new Rect(350f, 2f, 150f, 20f), CheatToggles.guiDebug, "Debug GUI") != CheatToggles.guiDebug) { CheatToggles.guiDebug = !CheatToggles.guiDebug; CheatToggles.guiGhost = false; CheatToggles.guiGhostTroll = false; CheatToggles.guiESP = false; CheatToggles.guiHelper = false; CheatToggles.guiHelperInfo = false; CheatToggles.guiTroll = false; CheatToggles.guiTest = false; CheatToggles.guiFeatureCollection = false; } if (CheatToggles.guiDebug == true) { if (GUI.Toggle(new Rect(370f, 22f, 150f, 20f), CheatToggles.enableDebug, "Enable Debug") != CheatToggles.enableDebug) { CheatToggles.enableDebug = !CheatToggles.enableDebug; Debug.Msg("Debug: Toggled " + (CheatToggles.enableDebug ? "On" : "Off"), 1); MelonPreferences.SetEntryValue <bool>("Settings", "DebugEnabled", CheatToggles.enableDebug); } if (GUI.Toggle(new Rect(370f, 42f, 150f, 20f), Debug.debugMode1, "Debug Mode 1") != Debug.debugMode1) { Debug.debugMode1 = !Debug.debugMode1; Debug.Msg("Debug Mode 1: Toggled " + (Debug.debugMode1 ? "On" : "Off"), 1); MelonPreferences.SetEntryValue <bool>("Settings", "DebugM1Enabled", Debug.debugMode1); } if (GUI.Toggle(new Rect(370f, 62f, 150f, 20f), Debug.debugMode2, "Debug Mode 2") != Debug.debugMode2) { Debug.debugMode2 = !Debug.debugMode2; Debug.Msg("Debug Mode 2: Toggled " + (Debug.debugMode2 ? "On" : "Off"), 1); MelonPreferences.SetEntryValue <bool>("Settings", "DebugM2Enabled", Debug.debugMode2); } if (GUI.Toggle(new Rect(370f, 82f, 150f, 20f), Debug.debugMode3, "Debug Mode 3") != Debug.debugMode3) { Debug.debugMode3 = !Debug.debugMode3; Debug.Msg("Debug Mode 3: Toggled " + (Debug.debugMode3 ? "On" : "Off"), 1); MelonPreferences.SetEntryValue <bool>("Settings", "DebugM3Enabled", Debug.debugMode3); } } GUI.SetNextControlName("changeName"); playerName = GUI.TextArea(new Rect(650f, 2f, 150f, 20f), playerName); if (GUI.Button(new Rect(800f, 2f, 150f, 20f), "Change Name")) { GUI.FocusControl("changeName"); ChangeNickname(playerName); } } } } if (CheatToggles.enableEspGhost || CheatToggles.enableEspGhostVisible || CheatToggles.enableEspGhostBone || CheatToggles.enableEspPlayer || CheatToggles.enableEspBone || CheatToggles.enableEspOuija || CheatToggles.enableEspEmf || CheatToggles.enableEspFuseBox) { ESP.Enable(); } if (CheatToggles.enableBIGhost || CheatToggles.enableBIMissions || CheatToggles.enableBIPlayer) { GUI.Label(new Rect(0f, 0f, 500f, 160f), "", "box"); } if (CheatToggles.enableBIGhost) { BasicInformations.EnableGhost(); GUI.Label(new Rect(10f, 2f, 300f, 50f), "<color=#00FF00><b>Ghost Name:</b> " + (ghostNameAge ?? "") + "</color>"); GUI.Label(new Rect(10f, 17f, 300f, 50f), "<color=#00FF00><b>Ghost Type:</b> " + (ghostType ?? "") + "</color>"); GUI.Label(new Rect(10f, 47f, 400f, 50f), "<color=#00FF00><b>Evidence:</b> " + (evidence ?? "") + "</color>"); GUI.Label(new Rect(10f, 32f, 300f, 50f), "<color=#00FF00><b>Ghost State:</b> " + (ghostState ?? "") + "</color>"); GUI.Label(new Rect(10f, 62f, 400f, 50f), "<color=#00FF00><b>Responds to:</b> " + (ghostIsShy ?? "") + "</color>"); } else { if (initializedScene > 1) { BasicInformations.DisableGhost(); } } if (CheatToggles.enableBIMissions) { BasicInformations.EnableMissions(); } if (CheatToggles.enableBIPlayer) { BasicInformations.EnablePlayer(); GUI.Label(new Rect(10f, 77f, 300f, 50f), "<color=#00FF00><b>My Sanity:</b> " + (myPlayerSanity ?? "N/A") + "</color>"); } if (CheatToggles.enableInfStamina) { myPlayer.field_Public_PlayerStamina_0.field_Protected_Boolean_1 = false; myPlayer.field_Public_PlayerStamina_0.field_Protected_Single_1 = 3; } }
public override void VRChat_OnUiManagerInit() { if (subMenu != "UIExpansionKit") { ButtonAPI.CustomTransform = GameObject.Find("/UserInterface/QuickMenu/" + subMenu).transform; ButtonAPI.CreateButton(ButtonAPI.ButtonType.Default, "Vibrator\nController", "Vibrator Controller Settings", buttonX - 4, 3 - buttonY, null, delegate(bool a) { ButtonAPI.EnterSubMenu(ButtonAPI.MakeEmptyPage("SubMenu_1")); }, Color.white, Color.magenta, null, true, false, false, false, null, true); } //Back LockButtonUI = ButtonAPI.CreateButton(ButtonAPI.ButtonType.Default, "Back", "Exit this menu", ButtonAPI.HorizontalPosition.RightOfMenu, ButtonAPI.VerticalPosition.BottomButton, ButtonAPI.MakeEmptyPage("SubMenu_1").transform, delegate(bool a) { if (subMenu == "UIExpansionKit") { ButtonAPI.EnterSubMenu(GameObject.Find("/UserInterface/QuickMenu/ShortcutMenu")); } else { ButtonAPI.EnterSubMenu(GameObject.Find("/UserInterface/QuickMenu/" + subMenu)); } }, Color.yellow, Color.magenta, null, true, false, false, false, null, true); //Lock button LockButtonUI = ButtonAPI.CreateButton(ButtonAPI.ButtonType.Default, "Lock Speed\nButton", "Click than press button on controller to set button to lock vibraton speed (click twice to disable)", ButtonAPI.HorizontalPosition.FirstButtonPos, ButtonAPI.VerticalPosition.TopButton, ButtonAPI.MakeEmptyPage("SubMenu_1").transform, delegate(bool a) { if (findButton == "lockButton") { lockButton = KeyCode.None; findButton = null; LockKeyBind.SetText(""); LockButtonUI.SetText("Lock Speed\nButton"); MelonPreferences.SetEntryValue(vibratorController.Identifier, "lockButton", lockButton.GetHashCode()); return; } findButton = "lockButton"; LockButtonUI.SetText("Press Now"); }, Color.white, Color.magenta, null, true, false, false, false, null, true); LockKeyBind = ButtonAPI.CreateButton(ButtonAPI.ButtonType.Default, "", "Lock Speed Keybind", ButtonAPI.HorizontalPosition.FirstButtonPos, ButtonAPI.VerticalPosition.SecondButton, ButtonAPI.MakeEmptyPage("SubMenu_1").transform, delegate(bool a) { }, Color.white, Color.grey, null, false, false, false, false, null, false); LockKeyBind.SetInteractivity(false); if (lockButton != 0) { LockKeyBind.SetText(lockButton.ToString()); } //Hold button HoldButtonUI = ButtonAPI.CreateButton(ButtonAPI.ButtonType.Default, "Hold\nButton", "Click than press button on controller to set button to hold to use toy (click twice to disable)", ButtonAPI.HorizontalPosition.SecondButtonPos, ButtonAPI.VerticalPosition.TopButton, ButtonAPI.MakeEmptyPage("SubMenu_1").transform, delegate(bool a) { if (findButton == "holdButton") { holdButton = KeyCode.None; findButton = null; HoldKeyBind.SetText(""); HoldButtonUI.SetText("Hold\nButton"); MelonPreferences.SetEntryValue(vibratorController.Identifier, "lockButton", holdButton.GetHashCode()); return; } findButton = "holdButton"; HoldButtonUI.SetText("Press Now"); }, Color.white, Color.magenta, null, true, false, false, false, null, true); HoldKeyBind = ButtonAPI.CreateButton(ButtonAPI.ButtonType.Default, "", "Hold Keybind", ButtonAPI.HorizontalPosition.SecondButtonPos, ButtonAPI.VerticalPosition.SecondButton, ButtonAPI.MakeEmptyPage("SubMenu_1").transform, delegate(bool a) { }, Color.white, Color.grey, null, false, false, false, false, null, false); HoldKeyBind.SetInteractivity(false); if (holdButton != 0) { HoldKeyBind.SetText(holdButton.ToString()); } //Add toy addButtonUI = ButtonAPI.CreateButton(ButtonAPI.ButtonType.Default, "Add\nToy", "Click to pair with a friend's toy", ButtonAPI.HorizontalPosition.ThirdButtonPos, ButtonAPI.VerticalPosition.TopButton, ButtonAPI.MakeEmptyPage("SubMenu_1").transform, delegate(bool a) { InputPopup("", delegate(string text) { if (text.Length != 4) { addButtonUI.SetText("Add\nToys\n<color=#FF0000>Invalid Code</color>"); } else { Client.send("join " + text); } }); }, Color.white, Color.magenta, null, true, false, false, false, null, true); //How to use ButtonAPI.CreateButton(ButtonAPI.ButtonType.Default, "How To Use", "Opens instructions to use", ButtonAPI.HorizontalPosition.ThirdButtonPos, ButtonAPI.VerticalPosition.SecondButton, ButtonAPI.MakeEmptyPage("SubMenu_1").transform, delegate(bool a) { System.Diagnostics.Process.Start("https://github.com/markviews/VRChatVibratorController"); }, Color.white, Color.grey, null, false, false, false, false, null, false); quickMenu = GameObject.Find("UserInterface/QuickMenu/QuickMenu_NewElements"); menuContent = GameObject.Find("UserInterface/MenuContent/Backdrop/Backdrop"); }
public override void Init() { prefCategory = MelonPreferences.CreateCategory(CTG_NAME, $"{CTG_NAME} Settings", false, true); }
public static bool IsCameraExpandoStartsCollapsed() => MelonPreferences.GetEntryValue <bool>(KitCategory, CameraExpandoStartsCollapsed);
public override void OnPreferencesSaved() { rotationValue = MelonPreferences.GetEntryValue <float>(ModCategory, RotationValuePref); highPrecisionRotationValue = MelonPreferences.GetEntryValue <float>(ModCategory, HighPrecisionRotationValuePref); resetRotationOnSceneChange = MelonPreferences.GetEntryValue <bool>(ModCategory, ResetRotationOnSceneChangePref); }
public override void Init() { QuickMenuFromSocialButton = MelonPreferences.CreateEntry("UserInfoExtensionsSettings", nameof(QuickMenuFromSocialButton), false, "Show \"To Quick Menu\" button"); UserInfoExtensionsMod.userDetailsMenu.AddSimpleButton("To Quick Menu", ToQuickMenu, new Action <GameObject>((gameObject) => { quickMenuFromSocialButtonGameObject = gameObject; gameObject.SetActive(QuickMenuFromSocialButton.Value); })); UserInfoExtensionsMod.menu.AddSimpleButton("To Quick Menu", ToQuickMenu); }
public override void OnApplicationStart() { Utilities.LoggerInstance = LoggerInstance; advInvPreferencesCategory = MelonPreferences.CreateCategory("AdvancedInvites", "Advanced Invites"); advInvPreferencesCategory.CreateEntry("DeleteNotifications", InviteHandler.DeleteNotifications, "Delete Notification After Successful Use"); advInvPreferencesCategory.CreateEntry("BlacklistEnabled", blacklistEnabled, "Blacklist System"); advInvPreferencesCategory.CreateEntry("WhitelistEnabled", whitelistEnabled, "Whitelist System"); advInvPreferencesCategory.CreateEntry("NotificationVolume", .8f, "Notification Volume"); advInvPreferencesCategory.CreateEntry("JoinMeNotifyRequest", joinMeNotifyRequest, "Join Me Req Notification Sound"); advInvPreferencesCategory.CreateEntry("IgnoreBusyStatus", ignoreBusyStatus, "Ignore Busy Status"); advInvPreferencesCategory.CreateEntry("InviteSoundEnabled", true, "Invite Sound"); advInvPreferencesCategory.CreateEntry("InviteRequestSoundEnabled", true, "Invite-Request Sound"); advInvPreferencesCategory.CreateEntry("VoteToKickSoundEnabled", false, "Vote-Kick Sound", true); advInvPreferencesCategory.CreateEntry("FriendRequestSoundEnabled", false, "Friend-Request Sound", true); OnPreferencesLoaded(); Localization.Load(); #if DEBUG DebugTesting.Test(); try { MethodInfo sendNotificationMethod = typeof(NotificationManager).GetMethod( nameof(NotificationManager.Method_Public_Void_String_String_String_String_NotificationDetails_ArrayOf_Byte_0), BindingFlags.Public | BindingFlags.Instance); HarmonyInstance.Patch( sendNotificationMethod, new HarmonyMethod(typeof(AdvancedInviteSystem).GetMethod(nameof(SendNotificationPatch), BindingFlags.NonPublic | BindingFlags.Static))); } catch (Exception e) { Utilities.LoggerInstance.Error("Error Patching SendNotification: " + e.Message); } #endif try { // Appears to be NotificationManager.Method_Private_Void_Notification_1 MethodInfo acceptNotificationMethod = typeof(NotificationManager).GetMethods(BindingFlags.Public | BindingFlags.Instance).Single( m => m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(Notification) && m.Name.IndexOf("PDM", StringComparison.OrdinalIgnoreCase) == -1 && m.XRefScanFor("AcceptNotification for notification:") && m.XRefScanFor("Could not accept notification because notification details is null")); acceptNotificationDelegate = Patch <AcceptNotificationDelegate>(acceptNotificationMethod, GetDetour(nameof(AcceptNotificationPatch))); } catch (Exception e) { Utilities.LoggerInstance.Error("Error Patching AcceptNotification: " + e.Message); } try { //Appears to be NotificationManager.Method_Private_String_Notification_1 MethodInfo addNotificationMethod = typeof(NotificationManager.ObjectNPrivateSealedNoVoBonoNo0).GetMethods(BindingFlags.Public | BindingFlags.Instance).Single( m => m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(Notification) && m.Name.IndexOf("addNotification", StringComparison.OrdinalIgnoreCase) >= 0); addNotificationDelegate = Patch <AddNotificationDelegate>(addNotificationMethod, GetDetour(nameof(AddNotificationPatch))); } catch (Exception e) { Utilities.LoggerInstance.Error("Error Patching AddNotification: " + e.Message); } try { // Faded to and joined and initialized room MethodInfo fadeMethod = typeof(VRCUiManager).GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).First( m => m.Name.StartsWith("Method_Public_Void_String_Single_Action_") && m.Name.IndexOf("PDM", StringComparison.OrdinalIgnoreCase) == -1 && m.GetParameters().Length == 3); origFadeTo = Patch <FadeTo>(fadeMethod, GetDetour(nameof(FadeToPatch))); } catch (Exception e) { Utilities.LoggerInstance.Error("Error Patching FadeTo: " + e.Message); } UserPermissionHandler.LoadSettings(); WorldPermissionHandler.LoadSettings(); UiButtons.Initialize(); SoundPlayer.Initialize(); }
public static void InitUI(bool firstInit = false) { SetBadGoDisabler(GameObject.Find("UserInterface/QuickMenu/ShortcutMenu/UserIconCameraButton"), !MelonPreferences.GetEntryValue <bool>(BuildInfo.Name, VRCPlusPet.mlCfgNameHideIconCameraButton)); GameObject.Find("UserInterface/QuickMenu/ShortcutMenu/UserIconButton")?.SetActive(!MelonPreferences.GetEntryValue <bool>(BuildInfo.Name, VRCPlusPet.mlCfgNameHideUserIconsButton)); GameObject.Find("UserInterface/MenuContent/Screens/UserInfo/User Panel/Supporter")?.SetActiveRecursively(!MelonPreferences.GetEntryValue <bool>(BuildInfo.Name, VRCPlusPet.mlCfgNameHideSocialSupporterButton)); bool fakeVRCP = MelonPreferences.GetEntryValue <bool>(BuildInfo.Name, VRCPlusPet.mlCfgNameFakeVRCP); bool hideUserIconTab = MelonPreferences.GetEntryValue <bool>(BuildInfo.Name, VRCPlusPet.mlCfgNameHideUserIconTab); bool hideVRCPTab = MelonPreferences.GetEntryValue <bool>(BuildInfo.Name, VRCPlusPet.mlCfgNameHideVRCPTab); if (firstInit || VRCPlusPet.cachedCfgFakeVRCP != fakeVRCP || VRCPlusPet.cachedCfgHideUserIconTab != hideUserIconTab || VRCPlusPet.cachedCfgHideVRCPTab != hideVRCPTab) { VRCPlusPet.cachedCfgFakeVRCP = fakeVRCP; VRCPlusPet.cachedCfgHideUserIconTab = hideUserIconTab; VRCPlusPet.cachedCfgHideVRCPTab = hideVRCPTab; Transform tabsTransform = GameObject.Find("UserInterface/MenuContent/Backdrop/Header/Tabs/ViewPort/Content").transform; for (int i = 0; i < tabsTransform.childCount; i++) { Transform childTransform = tabsTransform.GetChild(i); string childName = childTransform.name; if (childName != "Search") { if (childName == "VRC+PageTab") { childTransform.gameObject.SetActive(!hideVRCPTab); } else { LayoutElement childLayoutElement = childTransform.GetComponent <LayoutElement>(); if (childName == "UserIconTab") { SetBadGoDisabler(childLayoutElement.gameObject, !hideUserIconTab); } else { if (hideUserIconTab) { if (!originalSizes.ContainsKey(childName)) { originalSizes.Add(childName, childLayoutElement.preferredWidth); } childLayoutElement.preferredWidth = 250f; } else { childLayoutElement.preferredWidth = originalSizes.GetValueSafe(childName); } } } } } } }
public static bool IsCategoriesStartCollapsed() => MelonPreferences.GetEntryValue <bool>(KitCategory, CategoriesStartCollapsed);
public override void VRChat_OnUiManagerInit() { BindManager.Initialize(); void ShowBindManager() { BindManager.Show("Press your mute key in keyboard", new Action <List <Keys> >(selectedKeys => { string stringKeys = ""; if (selectedKeys.Count > 0) { stringKeys = string.Join(",", selectedKeys); } MelonPreferences.SetEntryValue("DiscordMute", nameof(MuteKey), stringKeys); MelonPreferences.Save(); }), null); } ExpansionKitApi.GetExpandedMenu(ExpandedMenu.SettingsMenu).AddSimpleButton("Discord Bind", () => ShowBindManager()); var originalMic = GameObject.Find("/UserInterface/QuickMenu/MicControls"); DiscordButton = GameObject.Instantiate(originalMic, originalMic.transform); DiscordButton.name = "Discord"; DiscordButton.SetActive(true); DiscordButton.transform.localPosition -= new Vector3(420, 7); DiscordButton.GetComponentInChildren <Text>().text = "Discord"; var button = DiscordButton.GetComponentInChildren <Button>(); button.onClick = new Button.ButtonClickedEvent(); button.onClick.AddListener(new Action(() => { bool isEnabled = !GameObject.Find("/UserInterface/QuickMenu/MicControls/Discord/MicButton/MicEnabled").activeSelf; GameObject.Find("/UserInterface/QuickMenu/MicControls/Discord/MicButton/MicEnabled").gameObject.SetActive(isEnabled); GameObject.Find("/UserInterface/QuickMenu/MicControls/Discord/MicButton/MicDisabled").gameObject.SetActive(!isEnabled); if (!string.IsNullOrEmpty(MuteKey)) { List <Keys> selectedKeys = new List <Keys>(); if (!string.IsNullOrEmpty(MuteKey)) { string[] stringKeys = MuteKey.Split(','); foreach (var stringKey in stringKeys) { selectedKeys.Add((Keys)Enum.Parse(typeof(Keys), stringKey)); } } // Hold and Release the selected keys foreach (var key in selectedKeys) { HoldKey(key); } foreach (var key in selectedKeys) { ReleaseKey(key); } } else { ShowBindManager(); } })); }
public override void OnApplicationStart() { var pluginsPath = MelonUtils.GetGameDataDirectory() + "/Plugins"; var dllName = ShaderFilterApi.DLLName + ".dll"; try { using var resourceStream = Assembly.GetExecutingAssembly() .GetManifestResourceStream(typeof(TrueShaderAntiCrashMod), dllName); using var fileStream = File.Open(pluginsPath + "/" + dllName, FileMode.Create, FileAccess.Write); resourceStream.CopyTo(fileStream); } catch (IOException ex) { MelonLogger.Warning("Failed to write native unity plugin; will attempt loading it anyway. This is normal if you're running multiple instances of VRChat"); MelonDebug.Msg(ex.ToString()); } var process = Process.GetCurrentProcess(); foreach (ProcessModule module in process.Modules) { if (!module.FileName.Contains("UnityPlayer")) { continue; } var loadLibraryAddress = module.BaseAddress + 0x819130; var dg = Marshal.GetDelegateForFunctionPointer <FindAndLoadUnityPlugin>(loadLibraryAddress); var strPtr = Marshal.StringToHGlobalAnsi(ShaderFilterApi.DLLName); dg(strPtr, out var loaded); if (loaded == IntPtr.Zero) { MelonLogger.Error("Module load failed"); return; } ShaderFilterApi.Init(loaded); Marshal.FreeHGlobal(strPtr); break; } var category = MelonPreferences.CreateCategory("True Shader Anticrash"); var loopsEnabled = (MelonPreferences_Entry <bool>)category.CreateEntry("LimitLoops", true, "Limit loops"); var geometryEnabled = (MelonPreferences_Entry <bool>)category.CreateEntry("LimitGeometry", true, "Limit geometry shaders"); var tessEnabled = (MelonPreferences_Entry <bool>)category.CreateEntry("LimitTesselation", true, "Limit tesselation"); MelonPreferences_Entry <bool> enabledInPublicsOnly = null; IEnumerator WaitForRoomManagerAndUpdate() { while (RoomManager.field_Internal_Static_ApiWorldInstance_0 == null) { yield return(null); } UpdateLimiters(); } void UpdateLimiters() { if (enabledInPublicsOnly.Value) { var room = RoomManager.field_Internal_Static_ApiWorldInstance_0; if (room == null) { MelonCoroutines.Start(WaitForRoomManagerAndUpdate()); return; } if (room.GetAccessType() != ApiWorldInstance.AccessType.Public) { ShaderFilterApi.SetFilteringState(false, false, false); return; } } ShaderFilterApi.SetFilteringState(loopsEnabled.Value, geometryEnabled.Value, tessEnabled.Value); } loopsEnabled.OnValueChanged += (_, value) => UpdateLimiters(); geometryEnabled.OnValueChanged += (_, value) => UpdateLimiters(); tessEnabled.OnValueChanged += (_, value) => UpdateLimiters(); var maxLoopIterations = (MelonPreferences_Entry <int>)category.CreateEntry("MaxLoopIterations", 128, "Max loop iterations"); maxLoopIterations.OnValueChanged += (_, value) => ShaderFilterApi.SetLoopLimit(value); var maxGeometry = (MelonPreferences_Entry <int>)category.CreateEntry("MaxGeometryOutputs", 60, "Max geometry shader outputs"); maxGeometry.OnValueChanged += (_, value) => ShaderFilterApi.SetLoopLimit(value); var maxTess = (MelonPreferences_Entry <float>)category.CreateEntry("MaxTesselation", 5f, "Max tesselation power"); maxTess.OnValueChanged += (_, value) => ShaderFilterApi.SetMaxTesselationPower(value); var enabledForWorlds = (MelonPreferences_Entry <bool>)category.CreateEntry("DisableDuringWorldLoad", true, "Try to avoid affecting world shaders"); enabledInPublicsOnly = (MelonPreferences_Entry <bool>)category.CreateEntry("EnabledInPublicsOnly", false, "Only enabled in public instances"); SceneManager.add_sceneLoaded(new Action <Scene, LoadSceneMode>((sc, _) => { if (sc.buildIndex == -1) { UpdateLimiters(); } })); SceneManager.add_sceneUnloaded(new Action <Scene>(_ => { if (enabledForWorlds.Value) { ShaderFilterApi.SetFilteringState(false, false, false); } })); UpdateLimiters(); ShaderFilterApi.SetMaxTesselationPower(maxTess.Value); ShaderFilterApi.SetLoopLimit(maxLoopIterations.Value); ShaderFilterApi.SetGeometryLimit(maxGeometry.Value); if (MelonHandler.Mods.Any(it => it.Assembly.GetName().Name == "UIExpansionKit" && it.Assembly.GetName().Version >= new Version(0, 2, 4))) { AddNewUixProperties(category.Identifier); } }
public static void Init() { category = MelonPreferences.CreateCategory("InstanceHistory Config"); useUIX = (MelonPreferences_Entry <bool>)category.CreateEntry("UseUIX", false, "Should use UIX instead of regular buttons"); }
public static bool HasKey(string section, string name) => MelonPreferences.HasEntry(section, name);
private static void CreateCategoryPage(MelonPreferences_Category category) { WipeScroller(); displayState = DisplayState.Prefs; var categoryHeader = modMenuOM.AddHeader(0, category.DisplayName); modMenuOM.scrollable.AddRow(categoryHeader); int buttonIndex = 0; Il2CppGeneric.List <GameObject> row = new Il2CppGeneric.List <GameObject>(); foreach (var pref in category.Entries) { switch (pref.BoxedValue) { case int value: MinMaxStepDefaultInt rangesInt = ParseMinMaxStepInt(pref.DisplayName); if (rangesInt.Equals(default(MinMaxStepDefaultInt))) { break; } var intSlider = modMenuOM.AddSlider(buttonIndex % 2, AddWhitespace(pref.Identifier), null, new Action <float>((amount) => { int currentVal = MelonPreferences.GetEntryValue <int>(pref.Category.Identifier, pref.Identifier); int increment = (int)amount * rangesInt.step; int newVal = currentVal + increment; if (newVal > rangesInt.max) { MelonPreferences.SetEntryValue(pref.Category.Identifier, pref.Identifier, rangesInt.max); } else if (newVal < rangesInt.min) { MelonPreferences.SetEntryValue(pref.Category.Identifier, pref.Identifier, rangesInt.min); } else { MelonPreferences.SetEntryValue(pref.Category.Identifier, pref.Identifier, newVal); } }), new Func <float>(() => { return(MelonPreferences.GetEntryValue <int>(pref.Category.Identifier, pref.Identifier)); }), new Action(() => { MelonPreferences.SetEntryValue(pref.Category.Identifier, pref.Identifier, rangesInt.prefDefault); }), RemoveTags(pref.DisplayName), new Func <float, string>((amount) => { return(amount.ToString()); })); buttonIndex++; row.Add(intSlider.gameObject); break; case bool value: var checkbox = modMenuOM.AddButton(buttonIndex % 2, AddWhitespace(pref.Identifier), new Action(() => { bool currentVal = MelonPreferences.GetEntryValue <bool>(pref.Category.Identifier, pref.Identifier); MelonPreferences.SetEntryValue(pref.Category.Identifier, pref.Identifier, !currentVal); }), new Func <bool>(() => { return(MelonPreferences.GetEntryValue <bool>(pref.Category.Identifier, pref.Identifier)); }), pref.DisplayName); row.Add(checkbox.gameObject); buttonIndex++; break; case float value: MinMaxStepDefault rangesFloat = ParseMinMaxStep(pref.DisplayName); if (rangesFloat.Equals(default(MinMaxStepDefault))) { break; } var customSpecifier = GetFormatSpecifier(pref.DisplayName); if (customSpecifier == "") { customSpecifier = "N2"; //Default to N2 if specifier is missing } var floatSlider = modMenuOM.AddSlider(buttonIndex % 2, AddWhitespace(pref.Identifier), "N2", new Action <float>((amount) => { float currentVal = MelonPreferences.GetEntryValue <float>(pref.Category.Identifier, pref.Identifier); float increment = rangesFloat.step * amount; //(amount * Mathf.Floor(currentVal * 10f)); float newVal = currentVal + increment; if (newVal > rangesFloat.max) { MelonPreferences.SetEntryValue(pref.Category.Identifier, pref.Identifier, rangesFloat.max); } else if (newVal < rangesFloat.min) { MelonPreferences.SetEntryValue(pref.Category.Identifier, pref.Identifier, rangesFloat.min); } else { MelonPreferences.SetEntryValue(pref.Category.Identifier, pref.Identifier, currentVal + increment); } }), new Func <float>(() => { return(MelonPreferences.GetEntryValue <float>(pref.Category.Identifier, pref.Identifier)); }), new Action(() => { MelonPreferences.SetEntryValue(pref.Category.Identifier, pref.Identifier, rangesFloat.prefDefault); }), RemoveTags(pref.DisplayName), new Func <float, string>((amount) => { return(amount.ToString(customSpecifier)); })); row.Add(floatSlider.gameObject); buttonIndex++; break; case string value: if (pref.DisplayName.ToLower().Contains("[header]")) { if (row.Count == 1) { modMenuOM.scrollable.AddRow(row[0]); row.Clear(); } var header = modMenuOM.AddHeader(0, RemoveTags(pref.DisplayName)); modMenuOM.scrollable.AddRow(header); buttonIndex = 0; } break; default: break; } if (row.Count == 2) { //This is the dumbest code I've ever wrote. Il2CppGeneric.List <GameObject> tempRow = new Il2CppGeneric.List <GameObject>(); tempRow.Add(row[0]); tempRow.Add(row[1]); modMenuOM.scrollable.AddRow(tempRow); row.Clear(); } else if (buttonIndex == category.Entries.Count && buttonIndex % 2 == 1) // This might be obsolete { modMenuOM.scrollable.AddRow(row[0]); row.Clear(); } } }