protected override void DidActivate(bool firstActivation, ActivationType activationType) { if (activationType == ActivationType.AddedToHierarchy) { title = Plugin.Name; navigationController = BeatSaberUI.CreateViewController <GenericNavigationController>(); navigationController.didFinishEvent += (_) => mainFlowCoordinator.InvokeMethod("DismissFlowCoordinator", this, null, false); if (soloFreePlayFlowCoordinator == null) { soloFreePlayFlowCoordinator = Resources.FindObjectsOfTypeAll <SoloFreePlayFlowCoordinator>().First(); } if (_alwaysOwnedContent == null) { _alwaysOwnedContent = Resources.FindObjectsOfTypeAll <AlwaysOwnedContentSO>().First(); } if (_primaryLevelCollection == null) { _primaryLevelCollection = _alwaysOwnedContent.alwaysOwnedPacks.First(x => x.packID == "OstVol1").beatmapLevelCollection as BeatmapLevelCollectionSO; } if (_secondaryLevelCollection == null) { _secondaryLevelCollection = _alwaysOwnedContent.alwaysOwnedPacks.First(x => x.packID == "OstVol2").beatmapLevelCollection as BeatmapLevelCollectionSO; } if (_tertiaryLevelCollection == null) { _tertiaryLevelCollection = _alwaysOwnedContent.alwaysOwnedPacks.First(x => x.packID == "OstVol3").beatmapLevelCollection as BeatmapLevelCollectionSO; } if (_extrasLevelCollection == null) { _extrasLevelCollection = _alwaysOwnedContent.alwaysOwnedPacks.First(x => x.packID == "Extras").beatmapLevelCollection as BeatmapLevelCollectionSO; } if (beatmapLevelPackCollection == null) { beatmapLevelPackCollection = soloFreePlayFlowCoordinator.GetField <IBeatmapLevelPackCollection>("_levelPackCollection"); } if (centerViewController == null) { centerViewController = BeatSaberUI.CreateViewController <CenterViewController>(); centerViewController.GenerateButtonPressed += () => { centerViewController.SetUIType(CenterViewController.UIType.ProgressBar); GeneratePlaylistWithMinTime(centerViewController.GetTimeValue(), centerViewController.UseOnlyPreferredDifficulty ? centerViewController.PreferredDifficulty : (BeatmapDifficulty?)null, async(playlist) => { var duration = 0f; foreach (var song in playlist) { duration += song.songDuration; Logger.Debug($"PLAYLIST ITEM: {song.songName} ({song.songDuration})"); } Logger.Debug($"TOTAL DURATION: {duration}"); centerViewController.SetUIType(CenterViewController.UIType.GenerationButton); //Launch first level Config.Enabled = true; Plugin.instance.loadedLevels = new Queue <IPreviewBeatmapLevel>(playlist); //Ensure the first level is an IBeatmapLevel var firstBeatmapLevel = Plugin.instance.loadedLevels.First(); if (firstBeatmapLevel is CustomPreviewBeatmapLevel) { var result = await SongHelpers.GetLevelFromPreview(firstBeatmapLevel); if (result != null && !(result?.isError == true)) { firstBeatmapLevel = result?.beatmapLevel; } } var firstMap = SongHelpers.GetClosestDifficultyPreferLower(firstBeatmapLevel as IBeatmapLevel, centerViewController.PreferredDifficulty); SongStitcher.songSwitched -= SongSwitched; SongStitcher.songSwitched += SongSwitched; var playerDataModel = Resources.FindObjectsOfTypeAll <PlayerDataModelSO>().First(); MenuTransitionsHelperSO menuTransitionHelper = Resources.FindObjectsOfTypeAll <MenuTransitionsHelperSO>().FirstOrDefault(); menuTransitionHelper.StartStandardLevel(firstMap, null, null, playerDataModel.playerData.gameplayModifiers, playerDataModel.playerData.playerSpecificSettings, null, "Menu", false, null, SongFinished); }); }; } ProvideInitialViewControllers(navigationController); SetViewControllersToNavigationConctroller(navigationController, new VRUIViewController[] { centerViewController }); } }
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 GeneratePlaylistWithMinTime(float minTime, BeatmapDifficulty?difficulty = null, Action <List <IPreviewBeatmapLevel> > playlistLoaded = null) { var totalDuration = 0f; var pickFrom = new List <IPreviewBeatmapLevel>(); foreach (var pack in beatmapLevelPackCollection.beatmapLevelPacks) { pickFrom = pickFrom.Union(pack.beatmapLevelCollection.beatmapLevels).ToList(); } var ret = new List <IPreviewBeatmapLevel>(); Action addAnotherSong = null; addAnotherSong = async() => { var currentIndex = rand.Next(0, pickFrom.Count); var currentLevel = pickFrom.ElementAt(currentIndex); pickFrom.RemoveAt(currentIndex); Action <IBeatmapLevel> SongLoaded = (loadedLevel) => { //If a difficulty was specified, we'll only pick songs that have that difficulty //NOTE: We can't filter out maps during the union because this beatmap data might not //be populated until the level is loaded if (difficulty == null || loadedLevel.beatmapLevelData.difficultyBeatmapSets.Any(x => x.difficultyBeatmaps.Any(y => y.difficulty == difficulty))) { Logger.Debug($"ADDED: {loadedLevel.songName} ({loadedLevel.songDuration}) (Total time: {totalDuration})"); totalDuration += loadedLevel.beatmapLevelData.audioClip.length; ret.Add(loadedLevel); centerViewController.SetProgress(totalDuration / minTime); } if (totalDuration < minTime && pickFrom.Count > 0) { addAnotherSong(); } else { playlistLoaded(ret); } }; if ((currentLevel is PreviewBeatmapLevelSO && await SongHelpers.HasDLCLevel(currentLevel.levelID)) || currentLevel is CustomPreviewBeatmapLevel) { Logger.Debug("Loading DLC/Custom level..."); var result = await SongHelpers.GetLevelFromPreview(currentLevel); if (result != null && !(result?.isError == true)) { SongLoaded(result?.beatmapLevel); } } else if (currentLevel is BeatmapLevelSO) { Logger.Debug("Reading OST data without songloader..."); SongLoaded(currentLevel as IBeatmapLevel); } else { Logger.Debug($"Skipping unowned DLC ({currentLevel.songName})"); if (pickFrom.Count > 0) { addAnotherSong(); } else { playlistLoaded(ret); } } }; addAnotherSong(); }