static public void ResetGame(PauseScreenController pauseScreen, bool AskConfirmation, Booth.QuickRestart parent, bool startNewGame) { if (AskConfirmation) { if (SimpleDialogBox.instancesList.Count > 0) { // Don't create more than one window. return; } SimpleDialogBox confirmation = SimpleDialogBox.Create(); confirmation.headerToken = new SimpleDialogBox.TokenParamsPair("Are you sure?"); String description = "Are you sure you want to reset this run?"; if (pauseScreen is null) { description += " Use info screen button (usually tab/select) to move cursor."; } confirmation.descriptionToken = new SimpleDialogBox.TokenParamsPair(description); confirmation.AddActionButton(() => { ActuallyResetGame(pauseScreen, parent, startNewGame); }, "Yes"); confirmation.AddCancelButton("Cancel"); } else { // Avoid duplicate code but allow the dialog shenanigans ActuallyResetGame(pauseScreen, parent, startNewGame); } }
// Token: 0x06001887 RID: 6279 RVA: 0x00069BC4 File Offset: 0x00067DC4 public static void IssueQuitCommand(Action action) { if (!QuitConfirmationHelper.IsQuitConfirmationRequired()) { action(); return; } QuitConfirmationHelper.NetworkStatus networkStatus; if (NetworkUser.readOnlyInstancesList.Count <= NetworkUser.readOnlyLocalPlayersList.Count) { networkStatus = QuitConfirmationHelper.NetworkStatus.SinglePlayer; } else if (NetworkServer.active) { networkStatus = QuitConfirmationHelper.NetworkStatus.Host; } else { networkStatus = QuitConfirmationHelper.NetworkStatus.Client; } string token; switch (networkStatus) { case QuitConfirmationHelper.NetworkStatus.None: token = ""; break; case QuitConfirmationHelper.NetworkStatus.SinglePlayer: token = "QUIT_RUN_CONFIRM_DIALOG_BODY_SINGLEPLAYER"; break; case QuitConfirmationHelper.NetworkStatus.Client: token = "QUIT_RUN_CONFIRM_DIALOG_BODY_CLIENT"; break; case QuitConfirmationHelper.NetworkStatus.Host: token = "QUIT_RUN_CONFIRM_DIALOG_BODY_HOST"; break; default: throw new ArgumentOutOfRangeException(); } SimpleDialogBox simpleDialogBox = SimpleDialogBox.Create(null); simpleDialogBox.headerToken = new SimpleDialogBox.TokenParamsPair("QUIT_RUN_CONFIRM_DIALOG_TITLE", Array.Empty <object>()); simpleDialogBox.descriptionToken = new SimpleDialogBox.TokenParamsPair(token, Array.Empty <object>()); simpleDialogBox.AddActionButton(new UnityAction(action.Invoke), "DIALOG_OPTION_YES", Array.Empty <object>()); simpleDialogBox.AddCancelButton("CANCEL", Array.Empty <object>()); }
public SaveButton(string name, SaveData save) : base(name) { if (save == null) { throw new Exception($"Error loading save data for savegame '{name}'"); } this.name = name; this.time = save.time; container = new GameObject("Container"); container.AddComponent <RectTransform>().localScale = Vector3.one; container.AddComponent <HorizontalLayoutGroup>().childForceExpandWidth = false; container.AddComponent <LayoutElement>(); gameObject.transform.SetParent(container.transform); gameObject.GetComponent <LayoutElement>().flexibleWidth = 1.0f; GameObject timeTextObject = new GameObject("Time Text"); timeTextObject.transform.SetParent(gameObject.transform); GameObject statTextObject = new GameObject("Game Stats"); statTextObject.transform.SetParent(gameObject.transform); // Position the time in the top right with a slight offset RectTransform timeRect = timeTextObject.AddComponent <RectTransform>(); timeRect.anchorMin = new Vector2(0, 1); timeRect.anchorMax = new Vector2(0, 1); timeRect.pivot = new Vector2(0, 1); timeRect.anchoredPosition = new Vector2(10, -10); //Position stats in the top right RectTransform statRect = statTextObject.AddComponent <RectTransform>(); statRect.anchorMin = new Vector2(1, 1); statRect.anchorMax = new Vector2(1, 1); statRect.pivot = new Vector2(1, 1); statRect.anchoredPosition = new Vector2(-10, -10); string date = DateTimeOffset.FromUnixTimeMilliseconds(time).Add(TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow)).ToString(); // Format the time text and align it properly HGTextMeshProUGUI timeText = timeTextObject.AddComponent <HGTextMeshProUGUI>(); timeText.text = "Created\n" + date.Substring(0, date.IndexOfAny(new char[] { '+', '-' })); timeText.color = Color.white; timeText.enableWordWrapping = false; timeText.alignment = TextAlignmentOptions.TopLeft; timeText.fontSize = 22; HGTextMeshProUGUI statText = statTextObject.AddComponent <HGTextMeshProUGUI>(); statText.text = $"{save.run.stageClearCount} stages cleared\n" + $"{difficulties[save.run.difficulty]} difficulty\n" + $"{TimeSpan.FromSeconds(save.run.fixedTime).ToString("mm':'ss")} time\n" + $"{SavedGames.levelNames[save.run.sceneName] ?? save.run.sceneName}"; statText.color = Color.white; statText.enableWordWrapping = false; statText.alignment = TextAlignmentOptions.TopRight; statText.fontSize = 22; if (File.Exists($"{SavedGames.directory}{name}.png")) { GameObject screenshot = new GameObject("Screenshot"); screenshot.transform.SetParent(container.transform); screenshot.AddComponent <LayoutElement>().preferredWidth = 355; screenshot.GetComponent <LayoutElement>().flexibleWidth = 0; screenshot.transform.SetAsFirstSibling(); Texture2D image = new Texture2D(2, 2); image.LoadImage(File.ReadAllBytes($"{SavedGames.directory}{name}.png")); screenshot.AddComponent <Image>().sprite = Sprite.Create(image, new Rect(0, 0, image.width, image.height), new Vector2(0, 0)); } ModButton deleteButton = new ModButton("Delete"); deleteButton.gameObject.transform.SetParent(container.transform); deleteButton.gameObject.GetComponent <LayoutElement>().preferredWidth = 200; deleteButton.gameObject.GetComponent <LayoutElement>().flexibleWidth = 0; deleteButton.gameObject.transform.SetAsLastSibling(); deleteButton.customButtonTransition.onClick.AddListener(() => { SimpleDialogBox box = SimpleDialogBox.Create(); box.headerLabel.text = "Delete save '" + name + "'"; box.descriptionLabel.text = "Once you delete this save, the run will no longer be recoverable. Are you sure?"; box.AddActionButton(() => { File.Delete($"{SavedGames.directory}{name}.json"); UnityEngine.Object.Destroy(container.gameObject); SavedGames.saveButtons.Remove(this); }, "Delete"); box.AddCancelButton("Cancel"); }); GameObject iconContainer = new GameObject("Icon container"); iconContainer.transform.SetParent(gameObject.transform); RectTransform iconContainerRect = iconContainer.AddComponent <RectTransform>(); iconContainerRect.anchorMin = new Vector2(0, 0); iconContainerRect.anchorMax = new Vector2(1, 0); iconContainerRect.pivot = new Vector2(0, 0); iconContainerRect.anchoredPosition = new Vector2(10, 3); iconContainer.AddComponent <HorizontalLayoutGroup>().childForceExpandWidth = false; foreach (PlayerData pd in save.players) { GameObject bodyPrefab = BodyCatalog.FindBodyPrefab(pd.characterBodyName); Texture texture = bodyPrefab.GetComponent <CharacterBody>().portraitIcon; GameObject icon = new GameObject("Icon"); icon.transform.SetParent(iconContainer.transform); icon.AddComponent <RectTransform>().anchorMin = new Vector2(0, 0); icon.GetComponent <RectTransform>().anchorMax = new Vector2(0, 0); icon.GetComponent <RectTransform>().pivot = new Vector2(0, 0); icon.AddComponent <RawImage>().texture = texture; icon.GetComponent <RawImage>().gameObject.AddComponent <AspectRatioFitter>().aspectMode = AspectRatioFitter.AspectMode.WidthControlsHeight; icon.GetComponent <RawImage>().gameObject.GetComponent <AspectRatioFitter>().aspectRatio = 1; icon.AddComponent <LayoutElement>().flexibleWidth = 0; icon.GetComponent <LayoutElement>().preferredWidth = 60; } // Modify colors to make the button look more like a button you shouldn't press unless you're sure ColorBlock colors = deleteButton.gameObject.GetComponent <CustomButtonTransition>().colors; colors.normalColor = new Color32(244, 67, 54, 255); colors.highlightedColor = new Color32(239, 83, 80, 187); colors.pressedColor = new Color32(211, 47, 47, 255); deleteButton.gameObject.GetComponent <CustomButtonTransition>().colors = colors; }
public void Awake() { Debug.Log("SavedGames - Original by morris1927"); //Singleton used for hacky crap :) if (instance == null) { instance = this; } else { Destroy(this); } loadKey = Config.Wrap <int>( "Keybinds", "LoadKey", null, (int)KeyCode.F5); saveKey = Config.Wrap <int>( "Keybinds", "SaveKey", null, (int)KeyCode.F8); //Register our Commands On.RoR2.Console.Awake += (orig, self) => { Generic.CommandHelper.RegisterCommands(self); orig(self); }; //Stop the scene loading objects so we can load our own On.RoR2.SceneDirector.PopulateScene += (orig, self) => { if (!loadingScene) { orig(self); } loadingScene = false; }; //Removing targetGraphic null error On.RoR2.UI.CustomButtonTransition.DoStateTransition += (orig, self, state, instant) => { if (self.targetGraphic != null) { orig(self, state, instant); } }; //Removing targetGraphic null error On.RoR2.UI.CustomScrollbar.DoStateTransition += (orig, self, state, instant) => { if (self.targetGraphic != null) { orig(self, state, instant); } }; //Setup "Load Game" Main Menu button and loading menu On.RoR2.UI.MainMenu.MainMenuController.Start += (orig, self) => { ModButton button = new ModButton("Load Game"); Transform buttonTransform = button.gameObject.transform; buttonTransform.SetParent(self.titleMenuScreen.transform.GetChild(2).transform); buttonTransform.SetSiblingIndex(1); Color32 c = button.baseImage.color; c.a = 73; button.baseImage.color = c; button.rectTransform.localScale = Vector3.one; button.rectTransform.sizeDelta = new Vector2(320, 48); button.buttonSkinController.useRecommendedAlignment = false; button.tmpText.alignment = TextAlignmentOptions.Left; button.tmpText.rectTransform.sizeDelta = new Vector2(-24, -8); GameObject submenuPrefab = new GameObject("Load Game"); GameObject scaledSpace = new GameObject("Scaled Space"); RectTransform scaledRect = scaledSpace.AddComponent <RectTransform>(); scaledRect.anchorMin = new Vector2(0.05f, 0.05f); scaledRect.anchorMax = new Vector2(0.95f, 0.95f); scaledRect.offsetMax = new Vector2(0, 0); scaledRect.offsetMin = new Vector2(0, 0); scaledSpace.transform.SetParent(submenuPrefab.transform); ModPanel topPanel = new ModPanel(); topPanel.gameObject.AddComponent <HorizontalLayoutGroup>(); topPanel.gameObject.transform.SetParent(scaledSpace.transform); topPanel.rectTransform.anchorMin = new Vector2(0, 1); topPanel.rectTransform.anchorMax = new Vector2(1, 1); topPanel.rectTransform.sizeDelta = new Vector2(0, 96); topPanel.rectTransform.pivot = new Vector2(0.5f, 1); ModButton backButton = new ModButton("Back"); backButton.gameObject.transform.SetParent(scaledSpace.transform); backButton.customButtonTransition.onClick.AddListener(delegate() { self.SetDesiredMenuScreen(self.titleMenuScreen); }); //ModButton loadButton = new ModButton("Load"); //loadButton.gameObject.transform.SetParent(scaledSpace.transform); //loadButton.customButtonTransition.onClick.AddListener(delegate () { }); ModSubMenu saveMenu = new ModSubMenu("Load Menu", self, submenuPrefab); submenuPrefab.transform.SetParent(saveMenu.subMenuObject.transform); ModScrollBar sb = new ModScrollBar(); sb.gameObject.transform.SetParent(scaledSpace.transform); submenuPrefab.SetActive(false); GameObject contentObject = new GameObject("Content"); contentObject.transform.SetParent(sb.viewportObject.transform); contentObject.AddComponent <CanvasRenderer>(); ModButton sortButton1 = new ModButton("Sort by date"); sortButton1.gameObject.transform.SetParent(topPanel.gameObject.transform); sortButton1.customButtonTransition.onClick.AddListener(delegate() { sortDir = sort == 0 ? !sortDir : true; sort = 0; SortSaves(); }); sortButton1.rectTransform.anchorMin = new Vector2(0, 0.5f); sortButton1.rectTransform.anchorMax = new Vector2(0, 0.5f); sortButton1.rectTransform.pivot = new Vector2(0, 0.5f); sortButton1.rectTransform.anchoredPosition = new Vector2(20, 0); ModButton sortButton2 = new ModButton("Sort by name"); sortButton2.gameObject.transform.SetParent(topPanel.gameObject.transform); sortButton2.customButtonTransition.onClick.AddListener(delegate() { sortDir = sort == 1 ? !sortDir : true; sort = 1; SortSaves(); }); sortButton2.rectTransform.anchorMin = new Vector2(0, 0.5f); sortButton2.rectTransform.anchorMax = new Vector2(0, 0.5f); sortButton2.rectTransform.pivot = new Vector2(0, 0.5f); sortButton2.rectTransform.anchoredPosition = new Vector2(20, 0); instance.StartCoroutine(SetupUI(delegate() { backButton.rectTransform.anchoredPosition = new Vector2(0, 0); backButton.rectTransform.anchorMin = new Vector2(0, 0); backButton.rectTransform.anchorMax = new Vector2(0, 0); backButton.rectTransform.sizeDelta = new Vector2(200, 50); backButton.rectTransform.pivot = new Vector2(0, 0); //loadButton.rectTransform.anchorMin = new Vector2(1, 0); //loadButton.rectTransform.anchorMax = new Vector2(1, 0); //loadButton.rectTransform.sizeDelta = new Vector2(200, 50); //loadButton.rectTransform.pivot = new Vector2(1, 0); RectTransform contentRect = contentObject.AddComponent <RectTransform>(); contentRect.sizeDelta = new Vector2(100, 300); sb.scrollRect.content = contentRect; sb.customScrollbar.direction = Scrollbar.Direction.BottomToTop; sb.scrollRect.movementType = ScrollRect.MovementType.Clamped; sb.rectTransform.anchorMin = new Vector2(0, 0); sb.rectTransform.anchorMax = new Vector2(1, 1); sb.rectTransform.sizeDelta = new Vector2(-60, -200); sb.rectTransform.anchoredPosition = new Vector2(0, 0); sb.gameObject.GetComponent <Image>().color = new Color32(16, 16, 16, 150); sb.gameObject.GetComponent <Image>().sprite = Generic.FindResource <Sprite>("texUIHighlightHeader"); sb.gameObject.GetComponent <Image>().color = new Color32(14, 14, 14, 150); sb.gameObject.GetComponent <Image>().type = Image.Type.Sliced; sb.customScrollbar.GetComponent <RectTransform>().anchorMin = new Vector2(0, 0); sb.customScrollbar.GetComponent <RectTransform>().anchorMax = new Vector2(1, 1); sb.customScrollbar.GetComponent <RectTransform>().sizeDelta = new Vector2(20, 0); sb.handleAreaObject.GetComponent <RectTransform>().anchorMin = new Vector2(1, 0); sb.handleAreaObject.GetComponent <RectTransform>().anchorMax = new Vector2(1, 1); sb.handleAreaObject.GetComponent <RectTransform>().sizeDelta = new Vector2(10, 0); sb.handleAreaObject.GetComponent <RectTransform>().pivot = new Vector2(0, 1); sb.handleAreaObject.GetComponent <Image>().sprite = Generic.FindResource <Sprite>("texUICleanButton"); sb.handleAreaObject.GetComponent <Image>().color = new Color32(44, 44, 44, 150); sb.handleAreaObject.GetComponent <Image>().type = Image.Type.Sliced; sb.handleObject.GetComponent <RectTransform>().sizeDelta = new Vector2(20, 0); sb.handleObject.GetComponent <Image>().sprite = Generic.FindResource <Sprite>("texUICleanButton"); sb.handleObject.GetComponent <Image>().type = Image.Type.Sliced; sb.handleOutlineObject.GetComponent <Image>().enabled = false; sb.viewportObject.GetComponent <RectTransform>().anchorMin = new Vector2(0, 0); sb.viewportObject.GetComponent <RectTransform>().anchorMax = new Vector2(1, 1); sb.viewportObject.GetComponent <RectTransform>().sizeDelta = new Vector2(0, 0); contentObject.GetComponent <RectTransform>().anchorMin = new Vector2(0, 0); contentObject.GetComponent <RectTransform>().anchorMax = new Vector2(1, 1); contentObject.GetComponent <RectTransform>().pivot = new Vector2(1, 1); contentObject.GetComponent <RectTransform>().sizeDelta = new Vector2(0, 0); VerticalLayoutGroup contentLayoutGroup = contentObject.AddComponent <VerticalLayoutGroup>(); ContentSizeFitter contentSizeFitter = contentObject.AddComponent <ContentSizeFitter>(); contentSizeFitter.verticalFit = ContentSizeFitter.FitMode.MinSize; if (Directory.Exists(directory)) { saveButtons.Clear(); foreach (var file in Directory.GetFiles(directory, "*.json")) { FileStream saveFile = File.Open(file, FileMode.Open, FileAccess.ReadWrite); string fileName = saveFile.Name.Replace(directory, "") .Replace(".json", ""); SaveData data; using (var sr = new StreamReader(saveFile)) { data = TinyJson.JSONParser.FromJson <SaveData>(sr.ReadToEnd()); } SaveButton fileSelectButton = new SaveButton(fileName, data); fileSelectButton.customButtonTransition.onClick.AddListener(delegate() { RoR2.Console.instance.SubmitCmd(null, $"load {fileName}"); }); fileSelectButton.container.GetComponent <LayoutElement>().minHeight = 200; fileSelectButton.container.transform.SetParent(contentObject.transform); saveButtons.Add(fileSelectButton); saveFile.Close(); } SortSaves(); } })); button.customButtonTransition.onClick.AddListener(delegate() { self.SetDesiredMenuScreen(saveMenu.submenuMainMenuScreen); submenuPrefab.SetActive(true); }); orig(self); }; //Add save button to pause screen On.RoR2.UI.PauseScreenController.Awake += (orig, self) => { StartCoroutine(CaptureScreen(self)); ModButton button = new ModButton("Save"); GameObject buttonObject = button.gameObject; buttonObject.transform.SetParent(self.mainPanel.GetChild(0)); buttonObject.transform.SetSiblingIndex(1); buttonObject.GetComponent <RectTransform>().localScale = Vector3.one; buttonObject.GetComponent <RectTransform>().sizeDelta = new Vector2(320, 48); ModInputField inputField = new ModInputField(); GameObject inputObject = inputField.gameObject; inputObject.transform.SetParent(self.mainPanel.GetChild(0)); inputObject.transform.SetSiblingIndex(1); inputField.tmpInputField.text = lastSelected; RectTransform inputRect = inputField.rectTransform; inputRect.sizeDelta = new Vector2(320, 48); inputRect.localScale = new Vector3(1, 1, 1); CustomButtonTransition buttonEvents = buttonObject.GetComponent <CustomButtonTransition>(); buttonEvents.onClick.AddListener(delegate { string saveName = inputField.tmpInputField.text; if (File.Exists($"{directory}{saveName}.json")) { SimpleDialogBox box = SimpleDialogBox.Create(); box.headerLabel.text = "Overwrite save?"; box.descriptionLabel.text = "There's already save with that name, are you sure you wish to overwrite it?"; box.AddActionButton(() => { RoR2.Console.instance.SubmitCmd(null, $"save {saveName}"); }, "Overwrite"); box.AddCancelButton("Cancel"); } else { RoR2.Console.instance.SubmitCmd(null, $"save {saveName}"); } }); orig(self); }; }