/// <summary> /// Create a button at the specified position, assign it to a parent <c>Component</c> and return it. /// </summary> /// <param name="parent">The buttons's supposed parent.</param> /// <param name="name">The Unity name of the button.</param> /// <param name="label">The button's text.</param> /// <param name="x">The x-position of the button, relative to the container's upper left corner.</param> /// <param name="y">The y-position of the button, relative to the container's upper left corner.</param> /// <param name="width">The width of the button. 200-300 seem like decent values.</param> /// <param name="height">The height of the button. 60 seems to be the "standard" value.</param> /// <returns>The created button.</returns> public static GameUISelectableButton AddButtonToComponent(Component parent, string name, string label, float x, float y, float width, float height) { GameUISelectableButton button = GameObject.Instantiate(buttonTemplate, parent.transform); button.name = name; (button.transform as RectTransform).offsetMin = new Vector2(x, -y - height); (button.transform as RectTransform).offsetMax = new Vector2(x + width, -y); button.GetComponentInChildren <TextMeshProUGUI>().text = label; return(button); }
/// <summary> /// Initalize a bunch of UI element templates: a dialog, a button, a dropdown menu, a slider, a toggle button and /// a label. /// </summary> /// <remarks> /// This method needs to be called before trying to instantiate any UI elements with <c>CreateCustomXXX</c> /// methods, otherwise those will throw unchecked NullPointerExceptions (I should probably handle those better). /// Currently, this is achieved by the <see cref="InitCustomUIElementsPatch"/>. Also, once it has been called, /// another call to this method has no effect. /// </remarks> /// <param name="settingsScreen">The settings screen. Using this to store the dialog template so that it doesn't /// get unloaded. There's probably a less hacky way to do this.</param> /// <param name="dialog">The dialog to be used as a template.</param> /// <param name="settingsDialog">The Settings Dialog, used to get a variety of UI elements.</param> public static void InitalizeTemplates(SettingsScreen settingsScreen, ScreenDialog dialog, SettingsDialog settingsDialog) { // This only needs to run once. if (!AreTemplatesInitalized()) { initalized = true; // Just store a bunch of UI elements from the settings screen as templates. They will always be loaded, // so we don't have to care about manipulating them in any way yet. buttonTemplate = Traverse.Create(settingsDialog).Field("keyMappingButton").GetValue <GameUISelectableButton>(); dropdownTemplate = Traverse.Create(settingsDialog).Field("gameSpeedDropdown").GetValue <GameUISelectableDropdown>();; toggleTemplate = Traverse.Create(settingsDialog).Field("googlyEyesToggle").GetValue <GameUISelectableToggle>(); sliderTemplate = Traverse.Create(Traverse.Create(settingsDialog).Field("scrollSensitivityControl").GetValue <ScrollSensitivityControl>()).Field("slider").GetValue <SelectableSliderHelper>(); // There don't seem to be any labels that are assigned to explicit fields, which kinda makes sense, so we'll have to search for one. // This unfortunately breaks pretty easily as shown by the latest update of the game, so I guess we need a long term solution. labelTemplate = settingsDialog.transform.Find("Content/Content/Audio Section/Global volume control").GetComponentInChildren <TextMeshProUGUI>(); // Print warnings if any initalization has been unsuccessful. if (buttonTemplate == null) { AdvancedRunHistory.Log("Button template is null.", LogLevel.Warning); } if (dropdownTemplate == null) { AdvancedRunHistory.Log("Dropdown template is null.", LogLevel.Warning); } if (toggleTemplate == null) { AdvancedRunHistory.Log("Toggle template is null.", LogLevel.Warning); } if (sliderTemplate == null) { AdvancedRunHistory.Log("Slider template is null.", LogLevel.Warning); } if (labelTemplate == null) { AdvancedRunHistory.Log("Label template is null.", LogLevel.Warning); } // We actually neeed to instantiate a copy of the dialog template right now, as the Patch Notes dialog will // unload as soon as you leave the Main Menu screen. Also, we can remove its contents while we're at it. dialogTemplate = GameObject.Instantiate(dialog, settingsScreen.transform); foreach (Transform child in dialogTemplate.transform.Find("Content")) { GameObject.Destroy(child.gameObject); } if (dialogTemplate == null) { AdvancedRunHistory.Log("Dialog template is null.", LogLevel.Warning); } } }
//--------------------------------------------------------------------- // Create the restart battle button //--------------------------------------------------------------------- /// <summary> /// Copy the "end turn" button and modify it to be the "restart battle" button. /// </summary> public static void Create(BattleHud battleHud) { // Don't create button if we're doing a hell rush if (Traverse.Create(Traverse.Create(battleHud).Field("combatManager").GetValue <CombatManager>()).Field("saveManager").GetValue <SaveManager>().IsBattleMode()) { return; } // Get BattleHud private fields EndTurnUI endTurnButton = Traverse.Create(battleHud).Field("endTurnButton").GetValue <EndTurnUI>(); EnergyUI energyUI = Traverse.Create(battleHud).Field("energyUI").GetValue <EnergyUI>(); CardPileCountUI deckUI = Traverse.Create(battleHud).Field("deckUI").GetValue <CardPileCountUI>(); // Copy end turn game object GameObject buttonRoot = GameObject.Instantiate(endTurnButton.gameObject, energyUI.transform.parent) as GameObject; buttonRoot.name = "RestartBattleButton"; // Delete unwanted game objects and components DeleteUnwanted(buttonRoot); // Set position to in the corner next to the ember RectTransform transRoot = buttonRoot.transform as RectTransform; RectTransform transEmber = energyUI.transform as RectTransform; transRoot.anchorMin = transEmber.anchorMin; transRoot.anchorMax = transEmber.anchorMax; transRoot.anchoredPosition = transEmber.anchoredPosition; transRoot.sizeDelta = transEmber.sizeDelta; buttonRoot.transform.position = new Vector3( Mathf.LerpUnclamped(deckUI.transform.position.x, energyUI.transform.position.x, 1.75f), Mathf.LerpUnclamped(deckUI.transform.position.y, energyUI.transform.position.y, -0.1f), buttonRoot.transform.position.z); // Make it a bit smaller than the "End Turn" button buttonRoot.transform.localScale = new Vector3(.6f, .6f, buttonRoot.transform.localScale.z); // Clear shortcut key so "End Turn" keyboard shortcut doesn't trigger restart battle GameUISelectableButton restartBattleButton = buttonRoot.GetComponent <GameUISelectableButton>(); Traverse.Create(restartBattleButton).Field("inputType").SetValue((int)InputManager.Controls.NONE); // Set button text to "Restart Battle" TextMeshProUGUI textMeshPro = buttonRoot.GetComponentInChildren <TextMeshProUGUI>(); textMeshPro.text = "Restart Battle"; // Add RestartBattleButton to handle the button click restartBattleButton.gameObject.AddComponent <RestartBattleButton>(); }
static void Postfix(ref GameUISelectableButton ___multiplayerButton, ref List <GameUISelectableButton> ___menuButtons) { ___menuButtons.Remove(___multiplayerButton); ___multiplayerButton.enabled = false; }
private void Start() { _battleHud = GetComponentInParent <BattleHud>(); _restartBattleButton = GetComponent <GameUISelectableButton>(); UISignals.GameUITriggered.AddListener(OnGameUITriggered); }