Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of HonestMainMenu v1.0.0
HonestMainMenu.Il2Cpp.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using HarmonyLib; using HonestMainMenu; using HonestMainMenu.Models; using HonestMainMenu.Services; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.Networking; using Il2CppScheduleOne.Persistence; using Il2CppScheduleOne.UI.Input; using Il2CppScheduleOne.UI.MainMenu; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppTMPro; using MelonLoader; using UnityEngine; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: ComVisible(true)] [assembly: Guid("F2F8CCDD-DA07-47DF-9247-39B991BE39E3")] [assembly: MelonInfo(typeof(Main), "Honest Main Menu", "1.0.0", "Roach_ (Adrian Nicolae)", "https://github.com/RoachxD/ScheduleOne.HonestMainMenu/releases/latest")] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: MelonColor(255, 97, 100, 62)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("Roach_")] [assembly: AssemblyConfiguration("Release_Il2Cpp")] [assembly: AssemblyCopyright("Copyright © 2025 Roach_ (Adrian Nicolae)")] [assembly: AssemblyDescription("A MelonLoader mod for Schedule I that adds a true continue button to the main menu.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("HonestMainMenu.Il2Cpp")] [assembly: AssemblyTitle("HonestMainMenu.Il2Cpp")] [assembly: NeutralResourcesLanguage("en-GB")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace HonestMainMenu { public class Main : MelonMod { public override void OnInitializeMelon() { string text = "IL2CPP"; Melon<Main>.Logger.Msg("Honest Main Menu (" + text + ") initializing.."); try { ((MelonBase)this).HarmonyInstance.PatchAll(Assembly.GetExecutingAssembly()); IEnumerable<string> values = from p in ((MelonBase)this).HarmonyInstance.GetPatchedMethods() select p.DeclaringType.FullName + "." + p.Name; string text2 = string.Join(", ", values); Melon<Main>.Logger.Msg("Honest Main Menu initialized successfully!"); Melon<Main>.Logger.Msg("Harmony patches successfully applied: " + text2 + "."); } catch (Exception ex) { Melon<Main>.Logger.Error("Failed to apply Harmony patches: " + ex.Message); Melon<Main>.Logger.Error((object)ex); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (!sceneName.Equals("Menu", StringComparison.OrdinalIgnoreCase)) { MenuReactivity.Stop(); return; } Melon<Main>.Logger.Msg("Main menu scene ('Menu') loaded. Attempting UI modifications.."); GameObject val = GameObject.Find("MainMenu"); if ((Object)(object)val == (Object)null) { Melon<Main>.Logger.Error("Could not find main menu root object 'MainMenu'. Aborting UI modifications."); return; } Transform transform = val.transform; BackButtonPromptSetup.Apply(transform); MenuButtons menuButtons = MenuSetup.Build(transform); if (menuButtons != null) { MelonCoroutines.Start(MenuReactivity.Run(menuButtons)); ContinueScreenSetup.Apply(transform); Melon<Main>.Logger.Msg("Honest Main Menu UI modifications applied successfully."); } } } public static class UIConstants { public const string MenuSceneName = "Menu"; public const string MainMenuObjectName = "MainMenu"; public const string MenuButtonsParentPath = "Home/Bank"; public const string ContinueObjectNameAndLabel = "Continue"; public const string LoadGameObjectName = "LoadGame"; public const string InputPromptObjectName = "InputPrompt (Back)"; public const string LoadGameLabel = "Load Game"; public const string RmbPromptBindingKey = "rightButton"; public const string TitleObjectName = "Title"; } public static class UIHelper { public static void SetText(this GameObject gameObject, string text) { if (!((Object)(object)gameObject == (Object)null)) { TextMeshProUGUI componentInChildren = gameObject.GetComponentInChildren<TextMeshProUGUI>(true); if (!((Object)(object)componentInChildren == (Object)null)) { ((TMP_Text)componentInChildren).text = text; } } } } } namespace HonestMainMenu.Services { internal static class BackButtonPromptSetup { public static void Apply(Transform menuRoot) { if (TryGetInputPrompt(menuRoot, out var promptComponent, out var ownerObject)) { bool actionsModified; List<InputActionReference> filteredInputActions = GetFilteredInputActions(promptComponent.Actions, "rightButton", out actionsModified); if (actionsModified) { ApplyActionsToPrompt(promptComponent, filteredInputActions, ownerObject); } } } private static bool TryGetInputPrompt(Transform mainMenuRoot, out InputPrompt promptComponent, out GameObject ownerObject) { promptComponent = null; Transform obj = mainMenuRoot.Find("InputPrompt (Back)"); ownerObject = ((obj != null) ? ((Component)obj).gameObject : null); if ((Object)(object)ownerObject == (Object)null) { Melon<Main>.Logger.Warning("Could not find InputPrompt owner GameObject at 'InputPrompt (Back)'."); return false; } promptComponent = ownerObject.GetComponent<InputPrompt>(); if ((Object)(object)promptComponent == (Object)null) { Melon<Main>.Logger.Warning("Could not find 'ScheduleOne.UI.Input.InputPrompt' component on 'InputPrompt (Back)'. Make sure the type name is correct."); return false; } return true; } private static List<InputActionReference> GetFilteredInputActions(List<InputActionReference> currentActions, string bindingKeyToRemove, out bool actionsModified) { actionsModified = false; List<InputActionReference> list = new List<InputActionReference>(); Enumerator<InputActionReference> enumerator = currentActions.GetEnumerator(); string text = default(string); string value = default(string); while (enumerator.MoveNext()) { InputActionReference current = enumerator.Current; if ((Object)(object)current == (Object)null || current.action == null) { list.Add(current); continue; } InputActionRebindingExtensions.GetBindingDisplayString(current.action, 0, ref text, ref value, (DisplayStringOptions)0); if (bindingKeyToRemove.Equals(value, StringComparison.OrdinalIgnoreCase)) { actionsModified = true; } else { list.Add(current); } } return list; } private static void ApplyActionsToPrompt(InputPrompt promptComponent, List<InputActionReference> newActions, GameObject promptOwnerObject) { promptComponent.Actions.Clear(); foreach (InputActionReference newAction in newActions) { promptComponent.Actions.Add(newAction); } if (promptOwnerObject.activeInHierarchy) { promptOwnerObject.SetActive(false); promptOwnerObject.SetActive(true); } } } internal static class ContinueScreenSetup { public static void Apply(Transform mainMenuRoot) { Transform val = mainMenuRoot.Find("Continue"); if ((Object)(object)val == (Object)null) { Melon<Main>.Logger.Error("Could not find 'MainMenu/Continue' screen object. Aborting screen configuration."); return; } ((Object)((Component)val).gameObject).name = "LoadGame"; Transform val2 = val.Find("Title"); if ((Object)(object)val2 == (Object)null) { Melon<Main>.Logger.Error($"Could not find '{"Title"}' child GameObject under '{((Object)val).name}'. " + "The screen title text will not be updated."); } else { ((Component)val2).gameObject.SetText("Load Game"); } } } internal static class MenuReactivity { private static UnityAction _onSaveInfoLoaded; public static IEnumerator Run(MenuButtons menuButtons) { yield return (object)new WaitUntil(Func<bool>.op_Implicit((Func<bool>)(() => (Object)(object)Singleton<LoadManager>.Instance != (Object)null))); if (LoadManager.LastPlayedGame != null) { UpdateContinueButtonInteractableState(menuButtons); yield break; } _onSaveInfoLoaded = UnityAction.op_Implicit((Action)delegate { Melon<Main>.Logger.Msg("LoadManager.OnSaveInfoLoaded event triggered, updating buttons interactable states."); UpdateContinueButtonInteractableState(menuButtons); }); Singleton<LoadManager>.Instance.onSaveInfoLoaded.AddListener(_onSaveInfoLoaded); } public static void Stop() { if (!((Delegate)(object)_onSaveInfoLoaded == (Delegate)null)) { Singleton<LoadManager>.Instance.onSaveInfoLoaded.RemoveListener(_onSaveInfoLoaded); _onSaveInfoLoaded = null; } } private static void UpdateContinueButtonInteractableState(MenuButtons menuButtons) { ((UnityEvent)menuButtons.ContinueButton.onClick).AddListener(UnityAction.op_Implicit((Action)PerformNewContinueAction)); ((Selectable)menuButtons.ContinueButton).interactable = true; ((Selectable)menuButtons.LoadGameButton).interactable = true; } private static void PerformNewContinueAction() { if (!Singleton<Lobby>.Instance.IsHost) { Singleton<MainMenuPopup>.Instance.Open("Cannot Continue", "You must be the host in order to be able to continue a game.", true); } else { Singleton<LoadManager>.Instance.StartGame(LoadManager.LastPlayedGame, false); } } } internal static class MenuSetup { public static MenuButtons Build(Transform menuRoot) { Transform val = menuRoot.Find("Home/Bank"); if ((Object)(object)val == (Object)null) { Melon<Main>.Logger.Error("Could not find menu buttons parent object at 'MainMenu/Home/Bank', aborting UI modifications!"); return null; } Transform val2 = val.Find("Continue"); if ((Object)(object)val2 == (Object)null) { Melon<Main>.Logger.Error("Could not find the original 'Continue' button object, aborting UI modifications!"); return null; } MenuButtons menuButtons = new MenuButtons { ContinueButton = CreateAndConfigureNewContinueButton(((Component)val2).gameObject), LoadGameButton = null }; if ((Object)(object)menuButtons.ContinueButton == (Object)null) { Melon<Main>.Logger.Error("Failed to create and configure the new 'Continue' button, aborting UI modifications!"); return null; } menuButtons.LoadGameButton = ConfigureLoadGameButton(((Component)val2).gameObject); if ((Object)(object)menuButtons.LoadGameButton == (Object)null) { Melon<Main>.Logger.Error("Failed to configure the 'LoadGame' button, aborting UI modifications!"); return null; } ((Selectable)menuButtons.ContinueButton).interactable = false; ((Selectable)menuButtons.LoadGameButton).interactable = false; PositionButtonsAndOffsetSiblings(menuButtons); return menuButtons; } private static Button ConfigureLoadGameButton(GameObject buttonObject) { Button component = buttonObject.GetComponent<Button>(); if ((Object)(object)component == (Object)null) { return null; } ((Object)buttonObject).name = "LoadGame"; buttonObject.SetText("Load Game"); return component; } private static Button CreateAndConfigureNewContinueButton(GameObject buttonObject) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown GameObject val = Object.Instantiate<GameObject>(buttonObject, buttonObject.transform.parent); ((Object)val).name = "Continue"; val.SetText("Continue"); Button component = val.GetComponent<Button>(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val); return null; } component.onClick = new ButtonClickedEvent(); return component; } private static void PositionButtonsAndOffsetSiblings(MenuButtons menuButtons) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) RectTransform component = ((Component)menuButtons.LoadGameButton).gameObject.GetComponent<RectTransform>(); RectTransform component2 = ((Component)menuButtons.ContinueButton).gameObject.GetComponent<RectTransform>(); Transform parent = ((Component)menuButtons.LoadGameButton).gameObject.transform.parent; if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)parent == (Object)null) { Melon<Main>.Logger.Error("Could not get RectTransforms or parent for positioning. Destroying new button."); Object.Destroy((Object)(object)((Component)menuButtons.ContinueButton).gameObject); return; } Vector2 anchoredPosition = component.anchoredPosition; int siblingIndex = ((Component)menuButtons.LoadGameButton).gameObject.transform.GetSiblingIndex(); component2.anchoredPosition = anchoredPosition; ((Component)menuButtons.ContinueButton).gameObject.transform.SetSiblingIndex(siblingIndex); float x = component2.anchoredPosition.x; float y = component2.anchoredPosition.y; Rect rect = component2.rect; component.anchoredPosition = new Vector2(x, y - ((Rect)(ref rect)).height); ((Component)menuButtons.LoadGameButton).gameObject.transform.SetSiblingIndex(siblingIndex + 1); for (int i = siblingIndex + 2; i < parent.childCount; i++) { RectTransform component3 = ((Component)parent.GetChild(i)).GetComponent<RectTransform>(); if (component3 != null) { float x2 = component3.anchoredPosition.x; float y2 = component3.anchoredPosition.y; rect = component2.rect; component3.anchoredPosition = new Vector2(x2, y2 - ((Rect)(ref rect)).height); } } Melon<Main>.Logger.Msg("Positioned new 'Continue' at original spot, shifted 'LoadGame' (Load Game) below it, and offset subsequent buttons."); } } } namespace HonestMainMenu.Patches { [HarmonyPatch(typeof(SceneManager), "LoadScene", new Type[] { typeof(string) })] public static class SceneManagerLoadScenePatch { private static string _lastSceneName = string.Empty; private static bool Prefix(string sceneName) { if (!string.IsNullOrEmpty(_lastSceneName) && (_lastSceneName.Equals(sceneName, StringComparison.OrdinalIgnoreCase) || _lastSceneName.Equals("Assets/Scenes/" + sceneName + ".unity", StringComparison.OrdinalIgnoreCase))) { return false; } _lastSceneName = sceneName; return true; } } } namespace HonestMainMenu.Models { internal class MenuButtons { public Button ContinueButton { get; set; } public Button LoadGameButton { get; set; } } }
HonestMainMenu.Mono.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using HarmonyLib; using HonestMainMenu; using HonestMainMenu.Models; using HonestMainMenu.Services; using MelonLoader; using ScheduleOne.DevUtilities; using ScheduleOne.Networking; using ScheduleOne.Persistence; using ScheduleOne.UI.Input; using ScheduleOne.UI.MainMenu; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: ComVisible(true)] [assembly: Guid("F2F8CCDD-DA07-47DF-9247-39B991BE39E3")] [assembly: MelonInfo(typeof(Main), "Honest Main Menu", "1.0.0", "Roach_ (Adrian Nicolae)", "https://github.com/RoachxD/ScheduleOne.HonestMainMenu/releases/latest")] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: MelonColor(255, 97, 100, 62)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("Roach_")] [assembly: AssemblyConfiguration("Release_Mono")] [assembly: AssemblyCopyright("Copyright © 2025 Roach_ (Adrian Nicolae)")] [assembly: AssemblyDescription("A MelonLoader mod for Schedule I that adds a true continue button to the main menu.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("HonestMainMenu.Mono")] [assembly: AssemblyTitle("HonestMainMenu.Mono")] [assembly: NeutralResourcesLanguage("en-GB")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace HonestMainMenu { public class Main : MelonMod { public override void OnInitializeMelon() { string text = "Mono"; Melon<Main>.Logger.Msg("Honest Main Menu (" + text + ") initializing.."); try { ((MelonBase)this).HarmonyInstance.PatchAll(Assembly.GetExecutingAssembly()); IEnumerable<string> values = from p in ((MelonBase)this).HarmonyInstance.GetPatchedMethods() select p.DeclaringType.FullName + "." + p.Name; string text2 = string.Join(", ", values); Melon<Main>.Logger.Msg("Honest Main Menu initialized successfully!"); Melon<Main>.Logger.Msg("Harmony patches successfully applied: " + text2 + "."); } catch (Exception ex) { Melon<Main>.Logger.Error("Failed to apply Harmony patches: " + ex.Message); Melon<Main>.Logger.Error((object)ex); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (!sceneName.Equals("Menu", StringComparison.OrdinalIgnoreCase)) { MenuReactivity.Stop(); return; } Melon<Main>.Logger.Msg("Main menu scene ('Menu') loaded. Attempting UI modifications.."); GameObject val = GameObject.Find("MainMenu"); if ((Object)(object)val == (Object)null) { Melon<Main>.Logger.Error("Could not find main menu root object 'MainMenu'. Aborting UI modifications."); return; } Transform transform = val.transform; BackButtonPromptSetup.Apply(transform); MenuButtons menuButtons = MenuSetup.Build(transform); if (menuButtons != null) { MelonCoroutines.Start(MenuReactivity.Run(menuButtons)); ContinueScreenSetup.Apply(transform); Melon<Main>.Logger.Msg("Honest Main Menu UI modifications applied successfully."); } } } public static class UIConstants { public const string MenuSceneName = "Menu"; public const string MainMenuObjectName = "MainMenu"; public const string MenuButtonsParentPath = "Home/Bank"; public const string ContinueObjectNameAndLabel = "Continue"; public const string LoadGameObjectName = "LoadGame"; public const string InputPromptObjectName = "InputPrompt (Back)"; public const string LoadGameLabel = "Load Game"; public const string RmbPromptBindingKey = "rightButton"; public const string TitleObjectName = "Title"; } public static class UIHelper { public static void SetText(this GameObject gameObject, string text) { if (!((Object)(object)gameObject == (Object)null)) { TextMeshProUGUI componentInChildren = gameObject.GetComponentInChildren<TextMeshProUGUI>(true); if (!((Object)(object)componentInChildren == (Object)null)) { ((TMP_Text)componentInChildren).text = text; } } } } } namespace HonestMainMenu.Services { internal static class BackButtonPromptSetup { public static void Apply(Transform menuRoot) { if (TryGetInputPrompt(menuRoot, out var promptComponent, out var ownerObject)) { bool actionsModified; List<InputActionReference> filteredInputActions = GetFilteredInputActions(promptComponent.Actions, "rightButton", out actionsModified); if (actionsModified) { ApplyActionsToPrompt(promptComponent, filteredInputActions, ownerObject); } } } private static bool TryGetInputPrompt(Transform mainMenuRoot, out InputPrompt promptComponent, out GameObject ownerObject) { promptComponent = null; Transform obj = mainMenuRoot.Find("InputPrompt (Back)"); ownerObject = ((obj != null) ? ((Component)obj).gameObject : null); if ((Object)(object)ownerObject == (Object)null) { Melon<Main>.Logger.Warning("Could not find InputPrompt owner GameObject at 'InputPrompt (Back)'."); return false; } promptComponent = ownerObject.GetComponent<InputPrompt>(); if ((Object)(object)promptComponent == (Object)null) { Melon<Main>.Logger.Warning("Could not find 'ScheduleOne.UI.Input.InputPrompt' component on 'InputPrompt (Back)'. Make sure the type name is correct."); return false; } return true; } private static List<InputActionReference> GetFilteredInputActions(List<InputActionReference> currentActions, string bindingKeyToRemove, out bool actionsModified) { actionsModified = false; List<InputActionReference> list = new List<InputActionReference>(); string text = default(string); string value = default(string); foreach (InputActionReference currentAction in currentActions) { if ((Object)(object)currentAction == (Object)null || currentAction.action == null) { list.Add(currentAction); continue; } InputActionRebindingExtensions.GetBindingDisplayString(currentAction.action, 0, ref text, ref value, (DisplayStringOptions)0); if (bindingKeyToRemove.Equals(value, StringComparison.OrdinalIgnoreCase)) { actionsModified = true; } else { list.Add(currentAction); } } return list; } private static void ApplyActionsToPrompt(InputPrompt promptComponent, List<InputActionReference> newActions, GameObject promptOwnerObject) { promptComponent.Actions.Clear(); promptComponent.Actions.AddRange(newActions); if (promptOwnerObject.activeInHierarchy) { promptOwnerObject.SetActive(false); promptOwnerObject.SetActive(true); } } } internal static class ContinueScreenSetup { public static void Apply(Transform mainMenuRoot) { Transform val = mainMenuRoot.Find("Continue"); if ((Object)(object)val == (Object)null) { Melon<Main>.Logger.Error("Could not find 'MainMenu/Continue' screen object. Aborting screen configuration."); return; } ((Object)((Component)val).gameObject).name = "LoadGame"; Transform val2 = val.Find("Title"); if ((Object)(object)val2 == (Object)null) { Melon<Main>.Logger.Error("Could not find 'Title' child GameObject under '" + ((Object)val).name + "'. The screen title text will not be updated."); } else { ((Component)val2).gameObject.SetText("Load Game"); } } } internal static class MenuReactivity { private static UnityAction _onSaveInfoLoaded; public static IEnumerator Run(MenuButtons menuButtons) { yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)Singleton<LoadManager>.Instance != (Object)null)); if (LoadManager.LastPlayedGame != null) { UpdateContinueButtonInteractableState(menuButtons); yield break; } _onSaveInfoLoaded = (UnityAction)delegate { Melon<Main>.Logger.Msg("LoadManager.OnSaveInfoLoaded event triggered, updating buttons interactable states."); UpdateContinueButtonInteractableState(menuButtons); }; Singleton<LoadManager>.Instance.onSaveInfoLoaded.AddListener(_onSaveInfoLoaded); } public static void Stop() { if (_onSaveInfoLoaded != null) { Singleton<LoadManager>.Instance.onSaveInfoLoaded.RemoveListener(_onSaveInfoLoaded); _onSaveInfoLoaded = null; } } private static void UpdateContinueButtonInteractableState(MenuButtons menuButtons) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown ((UnityEvent)menuButtons.ContinueButton.onClick).AddListener(new UnityAction(PerformNewContinueAction)); ((Selectable)menuButtons.ContinueButton).interactable = true; ((Selectable)menuButtons.LoadGameButton).interactable = true; } private static void PerformNewContinueAction() { if (!Singleton<Lobby>.Instance.IsHost) { Singleton<MainMenuPopup>.Instance.Open("Cannot Continue", "You must be the host in order to be able to continue a game.", true); } else { Singleton<LoadManager>.Instance.StartGame(LoadManager.LastPlayedGame, false); } } } internal static class MenuSetup { public static MenuButtons Build(Transform menuRoot) { Transform val = menuRoot.Find("Home/Bank"); if ((Object)(object)val == (Object)null) { Melon<Main>.Logger.Error("Could not find menu buttons parent object at 'MainMenu/Home/Bank', aborting UI modifications!"); return null; } Transform val2 = val.Find("Continue"); if ((Object)(object)val2 == (Object)null) { Melon<Main>.Logger.Error("Could not find the original 'Continue' button object, aborting UI modifications!"); return null; } MenuButtons menuButtons = new MenuButtons { ContinueButton = CreateAndConfigureNewContinueButton(((Component)val2).gameObject), LoadGameButton = null }; if ((Object)(object)menuButtons.ContinueButton == (Object)null) { Melon<Main>.Logger.Error("Failed to create and configure the new 'Continue' button, aborting UI modifications!"); return null; } menuButtons.LoadGameButton = ConfigureLoadGameButton(((Component)val2).gameObject); if ((Object)(object)menuButtons.LoadGameButton == (Object)null) { Melon<Main>.Logger.Error("Failed to configure the 'LoadGame' button, aborting UI modifications!"); return null; } ((Selectable)menuButtons.ContinueButton).interactable = false; ((Selectable)menuButtons.LoadGameButton).interactable = false; PositionButtonsAndOffsetSiblings(menuButtons); return menuButtons; } private static Button ConfigureLoadGameButton(GameObject buttonObject) { Button component = buttonObject.GetComponent<Button>(); if ((Object)(object)component == (Object)null) { return null; } ((Object)buttonObject).name = "LoadGame"; buttonObject.SetText("Load Game"); return component; } private static Button CreateAndConfigureNewContinueButton(GameObject buttonObject) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown GameObject val = Object.Instantiate<GameObject>(buttonObject, buttonObject.transform.parent); ((Object)val).name = "Continue"; val.SetText("Continue"); Button component = val.GetComponent<Button>(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val); return null; } component.onClick = new ButtonClickedEvent(); return component; } private static void PositionButtonsAndOffsetSiblings(MenuButtons menuButtons) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) RectTransform component = ((Component)menuButtons.LoadGameButton).gameObject.GetComponent<RectTransform>(); RectTransform component2 = ((Component)menuButtons.ContinueButton).gameObject.GetComponent<RectTransform>(); Transform parent = ((Component)menuButtons.LoadGameButton).gameObject.transform.parent; if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)parent == (Object)null) { Melon<Main>.Logger.Error("Could not get RectTransforms or parent for positioning. Destroying new button."); Object.Destroy((Object)(object)((Component)menuButtons.ContinueButton).gameObject); return; } Vector2 anchoredPosition = component.anchoredPosition; int siblingIndex = ((Component)menuButtons.LoadGameButton).gameObject.transform.GetSiblingIndex(); component2.anchoredPosition = anchoredPosition; ((Component)menuButtons.ContinueButton).gameObject.transform.SetSiblingIndex(siblingIndex); float x = component2.anchoredPosition.x; float y = component2.anchoredPosition.y; Rect rect = component2.rect; component.anchoredPosition = new Vector2(x, y - ((Rect)(ref rect)).height); ((Component)menuButtons.LoadGameButton).gameObject.transform.SetSiblingIndex(siblingIndex + 1); for (int i = siblingIndex + 2; i < parent.childCount; i++) { RectTransform component3 = ((Component)parent.GetChild(i)).GetComponent<RectTransform>(); if (component3 != null) { float x2 = component3.anchoredPosition.x; float y2 = component3.anchoredPosition.y; rect = component2.rect; component3.anchoredPosition = new Vector2(x2, y2 - ((Rect)(ref rect)).height); } } Melon<Main>.Logger.Msg("Positioned new 'Continue' at original spot, shifted 'LoadGame' (Load Game) below it, and offset subsequent buttons."); } } } namespace HonestMainMenu.Patches { [HarmonyPatch(typeof(SceneManager), "LoadScene", new Type[] { typeof(string) })] public static class SceneManagerLoadScenePatch { private static string _lastSceneName = string.Empty; private static bool Prefix(string sceneName) { if (!string.IsNullOrEmpty(_lastSceneName) && (_lastSceneName.Equals(sceneName, StringComparison.OrdinalIgnoreCase) || _lastSceneName.Equals("Assets/Scenes/" + sceneName + ".unity", StringComparison.OrdinalIgnoreCase))) { return false; } _lastSceneName = sceneName; return true; } } } namespace HonestMainMenu.Models { internal class MenuButtons { public Button ContinueButton { get; set; } public Button LoadGameButton { get; set; } } }