public LTUI(Config config, StandardLevelDetailViewController standardLevelDetailViewController) { Y2Pos = -100f; _config = config; _standardLevelDetailViewController = standardLevelDetailViewController; _detailView = standardLevelDetailViewController.GetField <StandardLevelDetailView, StandardLevelDetailViewController>("_standardLevelDetailView"); }
/// <summary> /// Constructor. Acquire all necessary BeatSaberUi elements. /// </summary> /// <param name="flowCoordinator"></param> public BeatSaberUIController(LevelSelectionFlowCoordinator flowCoordinator) { Logger.Debug("Collecting all BeatSaberUI Elements..."); LevelSelectionFlowCoordinator = flowCoordinator; // gather flow coordinator elements LevelSelectionNavigationController = LevelSelectionFlowCoordinator.GetField <LevelSelectionNavigationController, LevelSelectionFlowCoordinator>("levelSelectionNavigationController"); Logger.Debug("Acquired LevelSelectionNavigationController [{0}]", LevelSelectionNavigationController.GetInstanceID()); LevelFilteringNavigationController = LevelSelectionNavigationController.GetField <LevelFilteringNavigationController, LevelSelectionNavigationController>("_levelFilteringNavigationController"); Logger.Debug("Acquired LevelFilteringNavigationController [{0}]", LevelFilteringNavigationController.GetInstanceID()); LevelCollectionNavigationController = LevelSelectionNavigationController.GetField <LevelCollectionNavigationController, LevelSelectionNavigationController>("_levelCollectionNavigationController"); Logger.Debug("Acquired LevelCollectionNavigationController [{0}]", LevelCollectionNavigationController.GetInstanceID()); LevelCollectionViewController = LevelCollectionNavigationController.GetField <LevelCollectionViewController, LevelCollectionNavigationController>("_levelCollectionViewController"); Logger.Debug("Acquired LevelPackLevelsViewController [{0}]", LevelCollectionViewController.GetInstanceID()); LevelDetailViewController = LevelCollectionNavigationController.GetField <StandardLevelDetailViewController, LevelCollectionNavigationController>("_levelDetailViewController"); Logger.Debug("Acquired StandardLevelDetailViewController [{0}]", LevelDetailViewController.GetInstanceID()); LevelCollectionTableView = this.LevelCollectionViewController.GetField <LevelCollectionTableView, LevelCollectionViewController>("_levelCollectionTableView"); Logger.Debug("Acquired LevelPackLevelsTableView [{0}]", LevelCollectionTableView.GetInstanceID()); StandardLevelDetailView = LevelDetailViewController.GetField <StandardLevelDetailView, StandardLevelDetailViewController>("_standardLevelDetailView"); Logger.Debug("Acquired StandardLevelDetailView [{0}]", StandardLevelDetailView.GetInstanceID()); BeatmapCharacteristicSelectionViewController = StandardLevelDetailView.GetField <BeatmapCharacteristicSegmentedControlController, StandardLevelDetailView>("_beatmapCharacteristicSegmentedControlController"); Logger.Debug("Acquired BeatmapCharacteristicSegmentedControlController [{0}]", BeatmapCharacteristicSelectionViewController.GetInstanceID()); LevelDifficultyViewController = StandardLevelDetailView.GetField <BeatmapDifficultySegmentedControlController, StandardLevelDetailView>("_beatmapDifficultySegmentedControlController"); Logger.Debug("Acquired BeatmapDifficultySegmentedControlController [{0}]", LevelDifficultyViewController.GetInstanceID()); LevelCollectionTableViewTransform = LevelCollectionTableView.transform as RectTransform; Logger.Debug("Acquired TableViewRectTransform from LevelPackLevelsTableView [{0}]", LevelCollectionTableViewTransform.GetInstanceID()); AnnotatedBeatmapLevelCollectionsViewController = LevelFilteringNavigationController.GetField <AnnotatedBeatmapLevelCollectionsViewController, LevelFilteringNavigationController>("_annotatedBeatmapLevelCollectionsViewController"); Logger.Debug("Acquired AnnotatedBeatmapLevelCollectionsViewController from LevelFilteringNavigationController [{0}]", AnnotatedBeatmapLevelCollectionsViewController.GetInstanceID()); TableView tableView = LevelCollectionTableView.GetField <TableView, LevelCollectionTableView>("_tableView"); ScrollView scrollView = tableView.GetField <ScrollView, TableView>("_scrollView"); TableViewPageUpButton = scrollView.GetField <Button, ScrollView>("_pageUpButton"); TableViewPageDownButton = scrollView.GetField <Button, ScrollView>("_pageDownButton"); Logger.Debug("Acquired Page Up and Down buttons..."); ActionButtons = StandardLevelDetailView.GetComponentsInChildren <RectTransform>().First(x => x.name == "ActionButtons"); Logger.Debug("Acquired ActionButtons [{0}]", ActionButtons.GetInstanceID()); ScreenSystem = Resources.FindObjectsOfTypeAll <ScreenSystem>().Last(); Logger.Debug("Acquired ScreenSystem [{0}]", ScreenSystem.GetInstanceID()); SimpleDialogPromptViewControllerPrefab = Resources.FindObjectsOfTypeAll <SimpleDialogPromptViewController>().Last(); Logger.Debug("Acquired SimpleDialogPromptViewControllerPrefab [{0}]", SimpleDialogPromptViewControllerPrefab.GetInstanceID()); BeatmapLevelsModel = Resources.FindObjectsOfTypeAll <BeatmapLevelsModel>().Last(); Logger.Debug("Acquired BeatmapLevelsModel [{0}]", BeatmapLevelsModel); }
public LTUI(Config config, StandardLevelDetailViewController standardLevelDetailViewController) { Y2Pos = -100f; _config = config; _standardLevelDetailViewController = standardLevelDetailViewController; _detailView = standardLevelDetailViewController.GetField <StandardLevelDetailView, StandardLevelDetailViewController>("_standardLevelDetailView"); _beatmapCharacteristicSegmentedControlController = _detailView.GetField <BeatmapCharacteristicSegmentedControlController, StandardLevelDetailView>("_beatmapCharacteristicSegmentedControlController"); }
public override void Instantiate() { //We have to find our own target //TODO: Clean up time complexity issue. This is called for each new option StandardLevelDetailViewController _sldvc = Resources.FindObjectsOfTypeAll <StandardLevelDetailViewController>().First(); GameplayOptionsViewController _govc = _sldvc.GetField <GameplayOptionsViewController>("_gameplayOptionsViewController"); RectTransform container = (RectTransform)_govc.transform.Find("Switches").Find("Container"); var volumeSettings = Resources.FindObjectsOfTypeAll <VolumeSettingsController>().FirstOrDefault(); gameObject = UnityEngine.Object.Instantiate(volumeSettings.gameObject, container); gameObject.name = optionName; gameObject.GetComponentInChildren <TMP_Text>().text = optionName; //Slim down the toggle option so it fits in the space we have before the divider (gameObject.transform as RectTransform).sizeDelta = new Vector2(50, (gameObject.transform as RectTransform).sizeDelta.y); //This magical nonsense is courtesy of Taz and his SettingsUI class VolumeSettingsController volume = gameObject.GetComponent <VolumeSettingsController>(); ListViewController newListSettingsController = (ListViewController)ReflectionUtil.CopyComponent(volume, typeof(ListSettingsController), typeof(ListViewController), gameObject); UnityEngine.Object.DestroyImmediate(volume); newListSettingsController.values = _options.Keys.ToList(); newListSettingsController.SetValue = OnChange; newListSettingsController.GetValue = () => { if (GetValue != null) { return(GetValue.Invoke()); } return(_options.Keys.ElementAt(0)); }; newListSettingsController.GetTextForValue = (v) => { if (_options.ContainsKey(v)) { return(_options[v]); } return("UNKNOWN"); }; //Initialize the controller, as if we had just opened the settings menu newListSettingsController.Init(); gameObject.SetActive(false); }
void Constractor(GameplaySetupViewController container, PlayerDataModel model, StandardLevelDetailViewController standard) { this.CreateParams(); this.gameplaySetupViewController = container; this.playerDataModel = model; var detailview = standard.GetField <StandardLevelDetailView, StandardLevelDetailViewController>("_standardLevelDetailView"); this._actionButton = detailview.actionButton; if (this._actionButton is NoTransitionsButton noTransitionsButton) { foreach (var bg in noTransitionsButton.gameObject.GetComponentsInChildren <ImageView>()) { if (bg.name == "BG") { bg.SetField("_gradient", false); this._defaultColor = bg.color; } } } this.playerSettingsPanelController = this.gameplaySetupViewController.GetField <PlayerSettingsPanelController, GameplaySetupViewController>("_playerSettingsPanelController"); }
public override void Instantiate() { //We have to find our own target //TODO: Clean up time complexity issue. This is called for each new option StandardLevelDetailViewController _sldvc = Resources.FindObjectsOfTypeAll <StandardLevelDetailViewController>().First(); GameplayOptionsViewController _govc = _sldvc.GetField <GameplayOptionsViewController>("_gameplayOptionsViewController"); RectTransform container = (RectTransform)_govc.transform.Find("Switches").Find("Container"); //TODO: Can probably slim this down a bit gameObject = UnityEngine.Object.Instantiate(container.Find("NoEnergy").gameObject, container); gameObject.GetComponentInChildren <TextMeshProUGUI>().text = optionName; gameObject.name = optionName; gameObject.layer = container.gameObject.layer; gameObject.transform.parent = container; gameObject.transform.localPosition = Vector3.zero; gameObject.transform.localScale = Vector3.one; gameObject.transform.rotation = Quaternion.identity; gameObject.SetActive(false); //All options start disabled gameObject.GetComponentInChildren <HMUI.Toggle>().isOn = GetValue; gameObject.GetComponentInChildren <HMUI.Toggle>().didSwitchEvent += (_, e) => { OnToggle?.Invoke(e); }; }
public void Update() { if (gamePauseManager.pause) { return; //Don't do anything if we're paused } //if (audioTimeSyncController.songTime > 10f && playlist.Count > 0 && !_loadingSong) if (audioTimeSyncController.songTime >= audioTimeSyncController.songLength - 0.3f && playlist.Count > 0 && !_loadingSong) { Logger.Debug("Switching song..."); audioTimeSyncController.StopSong(); //If we don't, there's a chance the song would progress to `songLength - 0.2f` and the base game would finish the game scene Logger.Debug($"Current song: {gameplayCoreSceneSetupData.difficultyBeatmap.level.songName}"); //Clear out old data from objects that would have ideally been recreated ClearOldData(); //Set up new song var gameplayModifiers = gameplayCoreSceneSetupData.gameplayModifiers; var playerSpecificSettings = gameplayCoreSceneSetupData.playerSpecificSettings; float songSpeedMul = gameplayModifiers.songSpeedMul; var level = playlist.Dequeue(); //Load song if it's a custom level if (level is CustomPreviewBeatmapLevel) { var task = Task.Run(async() => await SongHelpers.GetLevelFromPreview(level)); task.Wait(); var result = task.Result; if (result != null && !(result?.isError == true)) { level = result?.beatmapLevel; } } Logger.Debug($"New song: {level.songName}"); var oldMap = gameplayCoreSceneSetupData.difficultyBeatmap; Logger.Debug($"Getting closest difficulty to {gameplayCoreSceneSetupData.difficultyBeatmap.difficulty} with characteristic {gameplayCoreSceneSetupData.difficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic}..."); IDifficultyBeatmap map = SongHelpers.GetClosestDifficultyPreferLower(level as IBeatmapLevel, (BeatmapDifficulty)preferredDifficulty, gameplayCoreSceneSetupData.difficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic); Logger.Debug($"Got: {map.difficulty} ({map.parentDifficultyBeatmapSet.beatmapCharacteristic})"); gameplayCoreSceneSetupData.SetField("_difficultyBeatmap", map); BeatmapData beatmapData = BeatDataTransformHelper.CreateTransformedBeatmapData(map.beatmapData, gameplayModifiers, gameplayCoreSceneSetupData.practiceSettings, gameplayCoreSceneSetupData.playerSpecificSettings); beatmapDataModel.beatmapData = beatmapData; //If this is the last song, set up the viewcontrollers in a way that the proper data is displayed after the song var currentPack = levelDetailViewController.GetField <IBeatmapLevelPack>("_pack"); var currentPlayer = levelDetailViewController.GetField <PlayerData>("_playerData"); var currentShowPlayerStats = levelDetailViewController.GetField <bool>("_showPlayerStats"); levelDetailViewController.SetData(currentPack, map.level, currentPlayer, currentShowPlayerStats); audioTimeSyncController.Init(map.level.beatmapLevelData.audioClip, 0f, map.level.songTimeOffset, songSpeedMul); beatmapObjectSpawnController.Init(level.beatsPerMinute, beatmapData.beatmapLinesData.Length, gameplayModifiers.fastNotes ? 20f : (map.noteJumpMovementSpeed == 0 ? map.difficulty.NoteJumpMovementSpeed() : map.noteJumpMovementSpeed), map.noteJumpStartBeatOffset, gameplayModifiers.disappearingArrows, gameplayModifiers.ghostNotes); pauseMenuManager.Init(map.level.songName, map.level.songSubName, map.difficulty.Name()); //Deal with characteristic issues Saber.SaberType saberType; if (gameplayCoreSceneSetup.UseOneSaberOnly(map.parentDifficultyBeatmapSet.beatmapCharacteristic, playerSpecificSettings, out saberType)) { gameplayCoreSceneSetup.GetField <PlayerController>("_playerController").AllowOnlyOneSaber(saberType); } else { gameplayCoreSceneSetup .GetField <PlayerController>("_playerController") .GetField <SaberManager>("_saberManager") .SetField("_allowOnlyOneSaber", false); } Logger.Debug("Starting new song..."); audioTimeSyncController.StartSong(); Logger.Debug("Song started!"); songSwitched?.Invoke(oldMap, map); _loadingSong = false; } //else if (audioTimeSyncController.songTime > 10f && (playlist == null || playlist.Count <= 0) && !_loadingSong) else if (audioTimeSyncController.songTime >= audioTimeSyncController.songLength - 0.3f && (playlist == null || playlist.Count <= 0)) { _loadingSong = true; //Only show the following log message once Logger.Debug($"Would have switched songs, but playlist was null ({playlist == null}) or empty ({playlist?.Count <= 0})"); } }
private void AddMenuOption() { Transform dropdownTemplate = _gameplaySetupViewController.transform.Find("EnvironmentOverrideSettings/Settings/Elements/NormalLevels"); Transform otherSettingsContent = _settingsNavigationController.transform.Find("OtherSettings/Content"); if (!dropdownTemplate) { Plugin.Log.Error("Dropdown template not found!"); return; } if (!otherSettingsContent) { Plugin.Log.Error("OtherSettings/Content not found!"); return; } GameObject gameObject = _container.InstantiatePrefab(dropdownTemplate.gameObject, otherSettingsContent); gameObject.name = "LanguageSetting"; RectTransform rectTransform = gameObject.GetComponent <RectTransform>(); rectTransform.offsetMin = new Vector2(0, -14.2f); rectTransform.offsetMax = new Vector2(0, -7.2f); LocalizedTextMeshProUGUI label = gameObject.transform.Find("Label").GetComponent <LocalizedTextMeshProUGUI>(); label.Key = "SETTINGS_LANGUAGE"; _container.InstantiateComponent <LanguageSetting>(gameObject); Plugin.Log.Debug("Created language setting"); var textGameObject = new GameObject("SiraLocalizerContributorsText"); _credits = textGameObject.AddComponent <CurvedTextMeshPro>(); var textRectTransform = (RectTransform)textGameObject.transform; textRectTransform.SetParent(otherSettingsContent, false); textRectTransform.offsetMin = new Vector2(-45f, -7.4f); textRectTransform.offsetMax = new Vector2(45f, -7.4f); _credits.alignment = TextAlignmentOptions.TopLeft; _credits.lineSpacing = -35f; _credits.fontSize = 3f; _credits.fontStyle = FontStyles.Italic; _credits.gameObject.SetActive(false); foreach (var lang in Localization.Instance.SupportedLanguages) { if (lang == Language.English) { continue; } var contributors = Localization.Get("LANGUAGE_CONTRIBUTORS", lang); var name = Localization.Get("MENU_LANGUAGE_THIS", lang); if (!string.IsNullOrEmpty(contributors)) { _credits.text += $"<b>{name}</b> <color=#bababa>{contributors}</color>\n"; } } _creditsToggle = _container.InstantiatePrefabForComponent <Button>(_standardLevelDetailViewController.GetField <StandardLevelDetailView, StandardLevelDetailViewController>("_standardLevelDetailView").practiceButton); _creditsToggle.name = "LocalizationCreditsButton"; UnityEngine.Object.Destroy(_creditsToggle.transform.Find("Content").GetComponent <LayoutElement>()); _creditsToggle.gameObject.transform.SetParent(otherSettingsContent, false); var rect = (_creditsToggle.transform as RectTransform); rect.localPosition = new Vector3(-5f, -11f, 0f); ContentSizeFitter buttonSizeFitter = _creditsToggle.gameObject.AddComponent <ContentSizeFitter>(); buttonSizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; buttonSizeFitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize; LocalizedTextMeshProUGUI localizer = _creditsToggle.GetComponentInChildren <LocalizedTextMeshProUGUI>(true); localizer.Key = "CREDITS_TITLE"; _creditsToggle.onClick.AddListener(ToggleCredits); }
protected override void DidActivate(bool firstActivation, bool addedToHierarchy, bool screenSystemEnabling) { if (firstActivation) { //Set up UI SetTitle("Game Room", ViewController.AnimationType.None); showBackButton = true; _playerDataModel = Resources.FindObjectsOfTypeAll <PlayerDataModel>().First(); _menuLightsManager = Resources.FindObjectsOfTypeAll <MenuLightsManager>().First(); _soloFreePlayFlowCoordinator = Resources.FindObjectsOfTypeAll <SoloFreePlayFlowCoordinator>().First(); _standardLevelDetailViewController = Resources.FindObjectsOfTypeAll <StandardLevelDetailViewController>().First(); _standardLevelDetailView = _standardLevelDetailViewController.GetField <StandardLevelDetailView, StandardLevelDetailViewController>("_standardLevelDetailView"); _resultsViewController = Resources.FindObjectsOfTypeAll <ResultsViewController>().First(); _scoreLights = _soloFreePlayFlowCoordinator.GetField <MenuLightsPresetSO>("_resultsClearedLightsPreset"); _defaultLights = _soloFreePlayFlowCoordinator.GetField <MenuLightsPresetSO>("_defaultLightsPreset"); _songSelection = BeatSaberUI.CreateViewController <SongSelection>(); _songSelection.SongSelected += SongSelection_SongSelected; _splashScreen = BeatSaberUI.CreateViewController <SplashScreen>(); _songDetail = BeatSaberUI.CreateViewController <SongDetail>(); _songDetail.PlayPressed += SongDetail_didPressPlayButtonEvent; _songDetail.DifficultyBeatmapChanged += SongDetail_didChangeDifficultyBeatmapEvent; _playerList = BeatSaberUI.CreateViewController <PlayerList>(); } if (addedToHierarchy) { TournamentMode = Match == null; if (TournamentMode) { _splashScreen.StatusText = $"Connecting to \"{Host.Name}\"..."; ProvideInitialViewControllers(_splashScreen); } else { //If we're not in tournament mode, then a client connection has already been made //by the room selection screen, so we can just assume Plugin.client isn't null //NOTE: This is *such* a hack. Oh my god. isHost = Match.Leader == Plugin.client.Self; _songSelection.SetSongs(SongUtils.masterLevelList); _playerList.Players = Match.Players; _splashScreen.StatusText = "Waiting for the host to select a song..."; if (isHost) { ProvideInitialViewControllers(_songSelection, _playerList); } else { ProvideInitialViewControllers(_splashScreen, _playerList); } } } //The ancestor sets up the server event listeners //It would be possible to recieve an event that does a ui update after this call //and before the rest of the ui is set up, if we did this at the top. //So, we do it last base.DidActivate(firstActivation, addedToHierarchy, screenSystemEnabling); }
public static void Build() { //Grab necessary references StandardLevelDetailViewController _sldvc = Resources.FindObjectsOfTypeAll <StandardLevelDetailViewController>().First(); GameplayOptionsViewController _govc = _sldvc.GetField <GameplayOptionsViewController>("_gameplayOptionsViewController"); //Get reference to the switch container RectTransform container = (RectTransform)_govc.transform.Find("Switches").Find("Container"); container.sizeDelta = new Vector2(container.sizeDelta.x, container.sizeDelta.y + 7f); //Grow container so it aligns properly with text //Get references to the original switches, so we can later duplicate then destroy them Transform noEnergyOriginal = container.Find("NoEnergy"); Transform noObstaclesOriginal = container.Find("NoObstacles"); Transform mirrorOriginal = container.Find("Mirror"); Transform staticLightsOriginal = container.Find("StaticLights"); //Get references to other UI elements we need to hide //Transform divider = (RectTransform)_govc.transform.Find("Switches").Find("Separator"); //Transform defaults = (RectTransform)_govc.transform.Find("Switches").Find("DefaultsButton"); //Future duplicated switches Transform noEnergy = null; Transform noObstacles = null; Transform mirror = null; Transform staticLights = null; //Future down button Button _pageDownButton = null; //Create up button Button _pageUpButton = Instantiate(Resources.FindObjectsOfTypeAll <Button>().First(x => (x.name == "PageUpButton")), container); _pageUpButton.transform.parent = container; _pageUpButton.transform.localScale = Vector3.one; (_pageUpButton.transform as RectTransform).sizeDelta = new Vector2((_pageUpButton.transform.parent as RectTransform).sizeDelta.x, 3.5f); _pageUpButton.onClick.AddListener(delegate() { Instance.ChangePage(--Instance._listIndex, container, noEnergy, noObstacles, mirror, staticLights); //Nice responsive scroll buttons if (Instance._listIndex <= 0) { _pageUpButton.interactable = false; } if (Instance.customOptions.Count > 0) { _pageDownButton.interactable = true; } }); _pageUpButton.interactable = false; //Duplicate and delete default toggles so that the up button is on the top noEnergy = Instantiate(noEnergyOriginal, container); noObstacles = Instantiate(noObstaclesOriginal, container); mirror = Instantiate(mirrorOriginal, container); staticLights = Instantiate(staticLightsOriginal, container); //Create custom options foreach (object option in Instance.customOptions) { //Due to possible "different" types (due to cross-plugin support), we need to do this through reflection option.InvokeMethod("Instantiate"); } //Destroy original toggles and set their corresponding references to the new toggles DestroyImmediate(noEnergyOriginal.gameObject); DestroyImmediate(noObstaclesOriginal.gameObject); DestroyImmediate(mirrorOriginal.gameObject); DestroyImmediate(staticLightsOriginal.gameObject); _govc.SetField("_noEnergyToggle", noEnergy.gameObject.GetComponentInChildren <HMUI.Toggle>()); _govc.SetField("_noObstaclesToggle", noObstacles.gameObject.GetComponentInChildren <HMUI.Toggle>()); _govc.SetField("_mirrorToggle", mirror.gameObject.GetComponentInChildren <HMUI.Toggle>()); _govc.SetField("_staticLightsToggle", staticLights.gameObject.GetComponentInChildren <HMUI.Toggle>()); //Create down button _pageDownButton = Instantiate(Resources.FindObjectsOfTypeAll <Button>().First(x => (x.name == "PageDownButton")), container); _pageDownButton.transform.parent = container; _pageDownButton.transform.localScale = Vector3.one; (_pageDownButton.transform as RectTransform).sizeDelta = new Vector2((_pageDownButton.transform.parent as RectTransform).sizeDelta.x, (_pageDownButton.transform as RectTransform).sizeDelta.y); _pageDownButton.onClick.AddListener(delegate() { Instance.ChangePage(++Instance._listIndex, container, noEnergy, noObstacles, mirror, staticLights); //Nice responsive scroll buttons if (Instance._listIndex >= 0) { _pageUpButton.interactable = true; } if (((Instance.customOptions.Count + 4 - 1) / 4) - Instance._listIndex <= 0) { _pageDownButton.interactable = false; } }); _pageDownButton.interactable = Instance.customOptions.Count > 0; //Unfortunately, due to weird object creation for versioning, this doesn't always //happen when the scene changes Instance._listIndex = 0; }