Пример #1
0
 private BeatmapData CreateTransformedBeatmapData(BeatmapData beatmapData, PlayerSpecificSettings playerSettings, BaseGameModeType baseGameMode)
 {
     try {
         if (beatmapData == null)
         {
             throw new Exception("Null beatmapData");
         }
         if (ChromaConfig.CustomMapCheckingEnabled)
         {
             /*if (ModeActive(ChromaMode.DOUBLES_DOTS) || ModeActive(ChromaMode.DOUBLES_MONO) || ModeActive(ChromaMode.DOUBLES_REMOVED) || ModeActive(ChromaMode.INVERT_COLOUR) || ModeActive(ChromaMode.MIRROR_DIRECTION) || ModeActive(ChromaMode.MIRROR_POSITION) || ModeActive(ChromaMode.MONOCHROME) || ModeActive(ChromaMode.NO_ARROWS) || ModeActive(ChromaMode.RANDOM_COLOURS_CHROMA) || ModeActive(ChromaMode.RANDOM_COLOURS_INTENSE) || ModeActive(ChromaMode.RANDOM_COLOURS_ORIGINAL) || ModeActive(ChromaMode.RANDOM_COLOURS_TRUE)) {*/
             ChromaLogger.Log("Attempting map modification...");
             //return ChromaToggle.Beatmap.Z_MapModifier.CreateTransformedData(beatmapData, modes);
             ChromaBehaviour chroma        = this;
             CustomBeatmap   customBeatmap = ChromaMapModifier.CreateTransformedData(beatmapData, ref chroma, ref playerSettings, ref baseGameMode, ref songBPM);
             if (customBeatmap == null)
             {
                 ChromaLogger.Log("Major error sir, beatmap data failed!", ChromaLogger.Level.WARNING);
                 return(beatmapData);
             }
             else
             {
                 return(customBeatmap.BeatmapData);
             }
         }
     } catch (Exception e) {
         ChromaLogger.Log("Error creating transformed map data...");
         ChromaLogger.Log(e, ChromaLogger.Level.ERROR);
     }
     return(beatmapData);
 }
Пример #2
0
        private void playButton_Click(object sender, EventArgs e)
        {
            if (songListView.SelectedItems.Count > 0 && difficultyDropdown.SelectedIndex >= 0)
            {
                var playerSettings = new PlayerSpecificSettings();
                playerSettings.leftHanded     = mirrorCheckbox.Checked;
                playerSettings.staticLights   = staticLightsCheckbox.Checked;
                playerSettings.noTextsAndHuds = noHudCheckbox.Checked;
                playerSettings.advancedHud    = advancedHudCheckbox.Checked;
                playerSettings.reduceDebris   = reduceDebrisCheckbox.Checked;

                var modifiers = new GameplayModifiers();
                modifiers.noFail           = noFailCheckbox.Checked;
                modifiers.noBombs          = noBombsCheckbox.Checked;
                modifiers.noObstacles      = noWallsCheckbox.Checked;
                modifiers.instaFail        = instaFailCheckbox.Checked && !modifiers.noFail;
                modifiers.failOnSaberClash = failOnClashCheckbox.Checked;
                modifiers.batteryEnergy    = batteryEnergyCheckbox.Checked && !modifiers.noFail && !modifiers.instaFail;
                modifiers.fastNotes        = fastNotesCheckbox.Checked;
                modifiers.songSpeed        = fastSongCheckbox.Checked ?
                                             GameplayModifiers.SongSpeed.Faster :
                                             slowSongCheckbox.Checked ?
                                             GameplayModifiers.SongSpeed.Slower :
                                             GameplayModifiers.SongSpeed.Normal;
                modifiers.disappearingArrows = disappearingArrowsCheckbox.Checked && !ghostNotesCheckbox.Checked;
                modifiers.ghostNotes         = ghostNotesCheckbox.Checked;

                var characteristic = currentSelection.beatmapCharacteristics.First(x => x.serializedName == characteristicDropdown.SelectedItem as string);
                SaberUtilities.PlaySong(currentSelection, characteristic, (BeatmapDifficulty)difficultyDropdown.SelectedItem, modifiers, playerSettings);
            }
        }
Пример #3
0
        public void StartLevel(BeatmapLevelSO level, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, GameplayModifiers modifiers, float startTime = 0f)
        {
            Client.Instance.playerInfo.playerComboBlocks = 0;
            Client.Instance.playerInfo.playerCutBlocks   = 0;
            Client.Instance.playerInfo.playerTotalBlocks = 0;
            Client.Instance.playerInfo.playerEnergy      = 0f;
            Client.Instance.playerInfo.playerScore       = 0;

            MenuTransitionsHelperSO menuSceneSetupData = Resources.FindObjectsOfTypeAll <MenuTransitionsHelperSO>().FirstOrDefault();

            if (_playerManagementViewController != null)
            {
                _playerManagementViewController.SetGameplayModifiers(modifiers);
            }

            if (menuSceneSetupData != null)
            {
                if (Config.Instance.SpectatorMode)
                {
                    Client.Instance.playerInfo.playerState = PlayerState.Spectating;
                    modifiers.noFail = true;
                }
                else
                {
                    Client.Instance.playerInfo.playerState = PlayerState.Game;
                }

                PlayerSpecificSettings playerSettings = Resources.FindObjectsOfTypeAll <PlayerDataModelSO>().FirstOrDefault().currentLocalPlayer.playerSpecificSettings;

                roomInfo.roomState = RoomState.InGame;

                IDifficultyBeatmap difficultyBeatmap = level.GetDifficultyBeatmap(characteristic, difficulty, true);

#if DEBUG
                Logger.Info($"Starting song: name={level.songName}, levelId={level.levelID}, difficulty={difficulty}");
#endif

                Client.Instance.MessageReceived -= PacketReceived;

                try
                {
                    BS_Utils.Gameplay.Gamemode.NextLevelIsIsolated("Beat Saber Multiplayer");
                }
                catch
                {
                }

                PracticeSettings practiceSettings = new PracticeSettings(PracticeSettings.defaultPracticeSettings);
                practiceSettings.startSongTime = startTime + 1.5f;
                practiceSettings.songSpeedMul  = modifiers.songSpeedMul;

                menuSceneSetupData.StartStandardLevel(difficultyBeatmap, modifiers, playerSettings, (startTime > 1f ? practiceSettings : null), false, () => {}, (StandardLevelScenesTransitionSetupDataSO sender, LevelCompletionResults levelCompletionResults) => { InGameOnlineController.Instance.SongFinished(sender, levelCompletionResults, difficultyBeatmap, modifiers, false); });
                return;
            }
            else
            {
                Logger.Error("SceneSetupData is null!");
            }
        }
Пример #4
0
        private static void OnPlayerHeightChanged(PlayerSpecificSettings __instance)
        {
            float playerHeight = __instance.playerHeight;

            _logger.Info("Player height changed to " + playerHeight);

            playerHeightChanged?.Invoke(playerHeight);
        }
Пример #5
0
 internal static void Postfix(PlayerData __instance)
 {
     playerSetting = __instance.playerSpecificSettings;
     if (!MultiplayerSession.ConnectedMultiplay)
     {
         CameraUtilities.SetAllCameraCulling();
     }
 }
Пример #6
0
 static void Prefix(StandardLevelScenesTransitionSetupDataSO __instance, IDifficultyBeatmap difficultyBeatmap, OverrideEnvironmentSettings overrideEnvironmentSettings, ColorScheme overrideColorScheme,
                    GameplayModifiers gameplayModifiers, PlayerSpecificSettings playerSpecificSettings, PracticeSettings practiceSettings, string backButtonText, bool useTestNoteCutSoundEffects)
 {
     Plugin.LevelData.GameplayCoreSceneSetupData = new GameplayCoreSceneSetupData(difficultyBeatmap, gameplayModifiers, playerSpecificSettings, practiceSettings, useTestNoteCutSoundEffects);
     Plugin.LevelData.IsSet     = true;
     __instance.didFinishEvent -= __instance_didFinishEvent;
     __instance.didFinishEvent += __instance_didFinishEvent;
 }
        /// <summary>
        /// Update the local player's height based on the head's current position. Similar to <see cref="PlayerHeightSettingsController.AutoSetHeight"/>
        /// </summary>
        public void UpdatePlayerHeight()
        {
            _vrPlatformHelper.GetNodePose(UnityEngine.XR.XRNode.Head, 0, out Vector3 position, out _);

            PlayerSpecificSettings currentSettings = _playerDataModel.playerData.playerSpecificSettings;
            float height = position.y + roomCenter.y + MainSettingsModelSO.kHeadPosToPlayerHeightOffset;

            _playerDataModel.playerData.SetPlayerSpecificSettings(currentSettings.CopyWith(null, height, false));
        }
Пример #8
0
 static void Prefix(StandardLevelScenesTransitionSetupDataSO __instance, IDifficultyBeatmap difficultyBeatmap,
                    GameplayModifiers gameplayModifiers, PlayerSpecificSettings playerSpecificSettings, PracticeSettings practiceSettings, string backButtonText, bool useTestNoteCutSoundEffects)
 {
     ScoreSubmission._wasDisabled  = false;
     ScoreSubmission.LastDisablers = Array.Empty <string>();
     Plugin.LevelData.GameplayCoreSceneSetupData = new GameplayCoreSceneSetupData(difficultyBeatmap, gameplayModifiers, playerSpecificSettings, practiceSettings, useTestNoteCutSoundEffects);
     Plugin.LevelData.IsSet     = true;
     __instance.didFinishEvent -= __instance_didFinishEvent;
     __instance.didFinishEvent += __instance_didFinishEvent;
 }
Пример #9
0
        public static bool ShouldSkip(PlayerSpecificSettings specificSettings, DiContainer container)
        {
            HUDConfigModel      hudConfig = container.Resolve <HUDConfigModel>();
            ProgressConfigModel progress  = container.Resolve <ProgressConfigModel>();
            ScoreConfigModel    score     = container.Resolve <ScoreConfigModel>();
            bool result = specificSettings.noTextsAndHuds && !(
                (progress.Enabled && progress.Mode == ProgressMode.BaseGame && CheckIgnoreOption(hudConfig, progress)) ||
                (score.Enabled && CheckIgnoreOption(hudConfig, score)));

            IsOverridingBaseGameHUD = specificSettings.noTextsAndHuds && !result;
            return(result);
        }
Пример #10
0
        public void StartLevel(IBeatmapLevel level, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, GameplayModifiers modifiers, float startTime = 0f)
        {
            Client.Instance.playerInfo.updateInfo.playerComboBlocks  = 0;
            Client.Instance.playerInfo.updateInfo.playerCutBlocks    = 0;
            Client.Instance.playerInfo.updateInfo.playerTotalBlocks  = 0;
            Client.Instance.playerInfo.updateInfo.playerEnergy       = 0f;
            Client.Instance.playerInfo.updateInfo.playerScore        = 0;
            Client.Instance.playerInfo.updateInfo.playerLevelOptions = new LevelOptionsInfo(difficulty, modifiers, characteristic.serializedName);

            MenuTransitionsHelperSO menuSceneSetupData = Resources.FindObjectsOfTypeAll <MenuTransitionsHelperSO>().FirstOrDefault();

            if (_playerManagementViewController != null)
            {
                _playerManagementViewController.SetGameplayModifiers(modifiers);
            }

            if (menuSceneSetupData != null)
            {
                Client.Instance.playerInfo.updateInfo.playerState = Config.Instance.SpectatorMode ? PlayerState.Spectating : PlayerState.Game;

                PlayerSpecificSettings playerSettings = Resources.FindObjectsOfTypeAll <PlayerDataModelSO>().FirstOrDefault().playerData.playerSpecificSettings;

                roomInfo.roomState = RoomState.InGame;

                IDifficultyBeatmap difficultyBeatmap = level.GetDifficultyBeatmap(characteristic, difficulty, false);

                Plugin.log.Debug($"Starting song: name={level.songName}, levelId={level.levelID}, difficulty={difficulty}");

                Client.Instance.MessageReceived -= PacketReceived;

                try
                {
                    BS_Utils.Gameplay.Gamemode.NextLevelIsIsolated("Beat Saber Multiplayer");
                }
                catch
                {
                }

                PracticeSettings practiceSettings = new PracticeSettings(PracticeSettings.defaultPracticeSettings);
                practiceSettings.startSongTime = startTime + 1.5f;
                practiceSettings.songSpeedMul  = modifiers.songSpeedMul;
                practiceSettings.startInAdvanceAndClearNotes = true;

                menuSceneSetupData.StartStandardLevel(difficultyBeatmap, new OverrideEnvironmentSettings()
                {
                    overrideEnvironments = false
                }, null, modifiers, playerSettings, (startTime > 1f ? practiceSettings : null), "Lobby", false, () => { }, (StandardLevelScenesTransitionSetupDataSO sender, LevelCompletionResults levelCompletionResults) => { InGameOnlineController.Instance.SongFinished(levelCompletionResults, difficultyBeatmap, modifiers, startTime > 1f); });
            }
            else
            {
                Plugin.log.Error("SceneSetupData is null!");
            }
        }
Пример #11
0
        private static PlayerOptions GetOptions(PlayerSpecificSettings settings)
        {
            int val = 0;

            val |= settings.leftHanded ? 1 : 0;
            val |= settings.environmentEffectsFilterPreset == EnvironmentEffectsFilterPreset.NoEffects ? 2 : 0;
            val |= settings.noTextsAndHuds ? 4 : 0;
            val |= settings.advancedHud ? 8 : 0;
            val |= settings.reduceDebris ? 16 : 0;
            val |= settings.automaticPlayerHeight ? 32 : 0;
            val |= settings.noFailEffects ? 64 : 0;
            val |= settings.autoRestart ? 128 : 0;
            val |= settings.hideNoteSpawnEffect ? 256 : 0;
            val |= settings.adaptiveSfx ? 512 : 0;
            return((PlayerOptions)val);
        }
Пример #12
0
        public void StartLevel(BeatmapLevelSO level, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, GameplayModifiers modifiers, float startTime = 0f)
        {
            Client.Instance.playerInfo.playerComboBlocks = 0;
            Client.Instance.playerInfo.playerCutBlocks   = 0;
            Client.Instance.playerInfo.playerEnergy      = 0f;
            Client.Instance.playerInfo.playerScore       = 0;

            MenuTransitionsHelperSO menuSceneSetupData = Resources.FindObjectsOfTypeAll <MenuTransitionsHelperSO>().FirstOrDefault();

            if (menuSceneSetupData != null)
            {
                PlayerSpecificSettings playerSettings = Resources.FindObjectsOfTypeAll <PlayerDataModelSO>().FirstOrDefault().currentLocalPlayer.playerSpecificSettings;

                channelInfo.state = ChannelState.InGame;
                Client.Instance.playerInfo.playerState = PlayerState.Game;

                IDifficultyBeatmap difficultyBeatmap = level.GetDifficultyBeatmap(characteristic, difficulty, false);

#if DEBUG
                Misc.Logger.Info($"Starting song: name={level.songName}, levelId={level.levelID}, difficulty={difficulty}");
#endif

                PracticeSettings practiceSettings = new PracticeSettings(PracticeSettings.defaultPracticeSettings);

                if (startTime > 1.5f)
                {
                    practiceSettings.startSongTime = startTime + 1.5f;
                }

                Client.Instance.MessageReceived -= MessageReceived;

                try
                {
                    BS_Utils.Gameplay.Gamemode.NextLevelIsIsolated("Beat Saber Multiplayer");
                }
                catch
                {
                }

                menuSceneSetupData.StartStandardLevel(difficultyBeatmap, modifiers, playerSettings, (startTime > 1.5f ? practiceSettings : null), null, (StandardLevelScenesTransitionSetupDataSO sender, LevelCompletionResults levelCompletionResults) => { InGameOnlineController.Instance.SongFinished(sender, levelCompletionResults, difficultyBeatmap, modifiers, (practiceSettings != null)); });
                return;
            }
            else
            {
                Misc.Logger.Error("SceneSetupData is null!");
            }
        }
        static bool Prefix(Action beforeSceneSwitchCallback, CampaignFlowCoordinator __instance, MissionSelectionNavigationController ____missionSelectionNavigationController, MenuTransitionsHelper ____menuTransitionsHelper, PlayerDataModel ____playerDataModel)
        {
            if (____missionSelectionNavigationController.selectedMissionNode.missionData is CustomMissionDataSO)
            {
                CustomMissionDataSO missionData = ____missionSelectionNavigationController.selectedMissionNode.missionData as CustomMissionDataSO;

                IDifficultyBeatmap     difficultyBeatmap      = BeatmapLevelDataExtensions.GetDifficultyBeatmap(Loader.BeatmapLevelsModelSO.GetBeatmapLevelIfLoaded(missionData.customLevel.levelID).beatmapLevelData, missionData.beatmapCharacteristic, missionData.beatmapDifficulty);
                GameplayModifiers      gameplayModifiers      = missionData.gameplayModifiers;
                MissionObjective[]     missionObjectives      = missionData.missionObjectives;
                PlayerSpecificSettings playerSpecificSettings = ____playerDataModel.playerData.playerSpecificSettings;
                ColorSchemesSettings   colorSchemesSettings   = ____playerDataModel.playerData.colorSchemesSettings;
                ColorScheme            overrideColorScheme    = colorSchemesSettings.overrideDefaultColors ? colorSchemesSettings.GetSelectedColorScheme() : null;
                ____menuTransitionsHelper.StartMissionLevel("", difficultyBeatmap, overrideColorScheme, gameplayModifiers, missionObjectives, playerSpecificSettings, beforeSceneSwitchCallback, __instance.HandleMissionLevelSceneDidFinish);
                return(false);
            }
            return(true);
        }
Пример #14
0
        public void StartLevel(IBeatmapLevel level, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, GameplayModifiers modifiers, float startTime = 0f)
        {
            Client.Instance.playerInfo.updateInfo.playerComboBlocks = 0;
            Client.Instance.playerInfo.updateInfo.playerCutBlocks   = 0;
            Client.Instance.playerInfo.updateInfo.playerEnergy      = 0f;
            Client.Instance.playerInfo.updateInfo.playerScore       = 0;

            MenuTransitionsHelperSO menuSceneSetupData = Resources.FindObjectsOfTypeAll <MenuTransitionsHelperSO>().FirstOrDefault();

            if (menuSceneSetupData != null)
            {
                PlayerData             playerData     = Resources.FindObjectsOfTypeAll <PlayerDataModelSO>().FirstOrDefault().playerData;
                PlayerSpecificSettings playerSettings = playerData.playerSpecificSettings;

                channelInfo.state = ChannelState.InGame;
                Client.Instance.playerInfo.updateInfo.playerState = PlayerState.Game;

                IDifficultyBeatmap difficultyBeatmap = level.GetDifficultyBeatmap(characteristic, difficulty, false);

#if DEBUG
                Plugin.log.Info($"Starting song: name={level.songName}, levelId={level.levelID}, difficulty={difficulty}");
#endif

                PracticeSettings practiceSettings = new PracticeSettings(PracticeSettings.defaultPracticeSettings);

                practiceSettings.startSongTime = startTime + 1.5f;
                practiceSettings.songSpeedMul  = modifiers.songSpeedMul;
                practiceSettings.startInAdvanceAndClearNotes = true;

                Client.Instance.MessageReceived -= MessageReceived;

                try
                {
                    BS_Utils.Gameplay.Gamemode.NextLevelIsIsolated("Beat Saber Multiplayer");
                }
                catch
                {
                }
                OverrideEnvironmentSettings overrideEnvironmentSettings = new OverrideEnvironmentSettings();
                menuSceneSetupData.StartStandardLevel(difficultyBeatmap, overrideEnvironmentSettings, playerData.colorSchemesSettings.GetSelectedColorScheme(), modifiers, playerSettings, (startTime > 1f ? practiceSettings : null), "Lobby", false, () => {}, (StandardLevelScenesTransitionSetupDataSO sender, LevelCompletionResults levelCompletionResults) => { InGameOnlineController.Instance.SongFinished(sender, levelCompletionResults, difficultyBeatmap, modifiers, (startTime > 1f)); });
            }
            else
            {
                Plugin.log.Error("SceneSetupData is null!");
            }
        }
Пример #15
0
        static void Prefix(StandardLevelScenesTransitionSetupDataSO __instance, string gameMode, IDifficultyBeatmap difficultyBeatmap, OverrideEnvironmentSettings overrideEnvironmentSettings,
                           GameplayModifiers gameplayModifiers, PlayerSpecificSettings playerSpecificSettings, PracticeSettings practiceSettings, string backButtonText, bool useTestNoteCutSoundEffects)
        {
            EnvironmentInfoSO environmentInfoSO = difficultyBeatmap.GetEnvironmentInfo();

            if (overrideEnvironmentSettings != null && overrideEnvironmentSettings.overrideEnvironments)
            {
                environmentInfoSO = overrideEnvironmentSettings.GetOverrideEnvironmentInfoForType(environmentInfoSO.environmentType);
            }

            ScoreSubmission._wasDisabled  = false;
            ScoreSubmission.LastDisablers = Array.Empty <string>();
            Plugin.LevelData.GameplayCoreSceneSetupData = new GameplayCoreSceneSetupData(difficultyBeatmap, gameplayModifiers, playerSpecificSettings, practiceSettings, useTestNoteCutSoundEffects, environmentInfoSO);
            Plugin.LevelData.IsSet = true;
            Plugin.LevelData.Mode  = Mode.Standard;
            Utilities.Logger.log.Debug("Level Data set");
            __instance.didFinishEvent -= __instance_didFinishEvent;
            __instance.didFinishEvent += __instance_didFinishEvent;
        }
        public void StartLevel(LevelSO level, BeatmapDifficulty difficulty, float startTime = 0f)
        {
            Client.Instance.playerInfo.playerComboBlocks = 0;
            Client.Instance.playerInfo.playerCutBlocks   = 0;
            Client.Instance.playerInfo.playerEnergy      = 0f;
            Client.Instance.playerInfo.playerScore       = 0;

            MenuSceneSetupDataSO menuSceneSetupData = Resources.FindObjectsOfTypeAll <MenuSceneSetupDataSO>().FirstOrDefault();

            if (menuSceneSetupData != null)
            {
                GameplayModifiers gameplayModifiers = new GameplayModifiers();

                gameplayModifiers.noFail = true;

                PlayerSpecificSettings playerSettings = Resources.FindObjectsOfTypeAll <PlayerDataModelSO>().FirstOrDefault().currentLocalPlayer.playerSpecificSettings;

                channelInfo.state = ChannelState.InGame;
                Client.Instance.playerInfo.playerState = PlayerState.Game;

                IDifficultyBeatmap difficultyBeatmap = level.GetDifficultyBeatmap(difficulty);

                if (difficultyBeatmap == null)
                {
                    difficultyBeatmap = level.GetDifficultyBeatmap(GetClosestDifficulty(level, difficulty));
                }

                Misc.Logger.Info($"Starting song: name={level.songName}, levelId={level.levelID}, difficulty={difficulty}");

                PracticeSettings practiceSettings = new PracticeSettings(PracticeSettings.defaultPracticeSettings);
                practiceSettings.startSongTime = startTime + 1.5f;

                Client.Instance.MessageReceived -= MessageReceived;
                menuSceneSetupData.StartStandardLevel(difficultyBeatmap, gameplayModifiers, playerSettings, (startTime > 1f ? practiceSettings : null), null, (StandardLevelSceneSetupDataSO sender, LevelCompletionResults levelCompletionResults) => { InGameOnlineController.Instance.SongFinished(sender, levelCompletionResults, difficultyBeatmap, gameplayModifiers, (practiceSettings != null)); });
                return;
            }
            else
            {
                Misc.Logger.Error("SceneSetupData is null!");
            }
        }
Пример #17
0
        private void PlaySong(Song song)
        {
            MenuTransitionsHelper menuTransitionHelper = Resources.FindObjectsOfTypeAll <MenuTransitionsHelper>().FirstOrDefault();
            var playerSettings = _playerDataModel.playerData.playerSpecificSettings;

            //Override defaults if we have forced options enabled
            if (song.PlayerOptions != PlayerOptions.None)
            {
                playerSettings                = new PlayerSpecificSettings();
                playerSettings.leftHanded     = song.PlayerOptions.HasFlag(PlayerOptions.Mirror);
                playerSettings.staticLights   = song.PlayerOptions.HasFlag(PlayerOptions.StaticLights);
                playerSettings.noTextsAndHuds = song.PlayerOptions.HasFlag(PlayerOptions.NoHud);
                playerSettings.advancedHud    = song.PlayerOptions.HasFlag(PlayerOptions.AdvancedHud);
                playerSettings.reduceDebris   = song.PlayerOptions.HasFlag(PlayerOptions.ReduceDebris);
            }

            GameplayModifiers gameplayModifiers = new GameplayModifiers();

            gameplayModifiers.noFail      = song.GameOptions.HasFlag(GameOptions.NoFail);
            gameplayModifiers.noBombs     = song.GameOptions.HasFlag(GameOptions.NoBombs);
            gameplayModifiers.noObstacles = song.GameOptions.HasFlag(GameOptions.NoObstacles);
            if (song.GameOptions.HasFlag(GameOptions.SlowSong))
            {
                gameplayModifiers.songSpeed = GameplayModifiers.SongSpeed.Slower;
            }
            else if (song.GameOptions.HasFlag(GameOptions.FastSong))
            {
                gameplayModifiers.songSpeed = GameplayModifiers.SongSpeed.Faster;
            }

            gameplayModifiers.instaFail          = song.GameOptions.HasFlag(GameOptions.InstaFail);
            gameplayModifiers.failOnSaberClash   = song.GameOptions.HasFlag(GameOptions.FailOnClash);
            gameplayModifiers.batteryEnergy      = song.GameOptions.HasFlag(GameOptions.BatteryEnergy);
            gameplayModifiers.fastNotes          = song.GameOptions.HasFlag(GameOptions.FastNotes);
            gameplayModifiers.disappearingArrows = song.GameOptions.HasFlag(GameOptions.DisappearingArrows);
            gameplayModifiers.ghostNotes         = song.GameOptions.HasFlag(GameOptions.GhostNotes);

            var colorSchemeSettings = _playerDataModel.playerData.colorSchemesSettings;

            SongUtils.PlaySong(song.PreviewBeatmap, song.Beatmap.parentDifficultyBeatmapSet.beatmapCharacteristic, song.Beatmap.difficulty, _playerDataModel.playerData.overrideEnvironmentSettings, colorSchemeSettings.GetColorSchemeForId(colorSchemeSettings.selectedColorSchemeId), gameplayModifiers, playerSettings, SongFinished);
        }
Пример #18
0
        private static void Postfix(IDifficultyBeatmap difficultyBeatmap, PlayerSpecificSettings playerSpecificSettings)
        {
            if (difficultyBeatmap.beatmapData is CustomBeatmapData customBeatmapData)
            {
                IEnumerable <string> requirements = ((List <object>)Trees.at(customBeatmapData.beatmapCustomData, "_requirements"))?.Cast <string>();
                bool noodleRequirement            = requirements?.Contains(CAPABILITY) ?? false;
                NoodleController.ToggleNoodlePatches(noodleRequirement);

                // Reset tracks when entering game scene
                Dictionary <string, Track> tracks = Trees.at(customBeatmapData.customData, "tracks");
                if (tracks != null)
                {
                    foreach (KeyValuePair <string, Track> track in tracks)
                    {
                        track.Value.ResetVariables();
                    }
                }
            }

            NoodleController.LeftHandedMode = playerSpecificSettings.leftHanded;
        }
Пример #19
0
        private void playButton_Click(object sender, EventArgs e)
        {
            if (songListView.SelectedItems.Count > 0 && difficultyDropdown.SelectedIndex >= 0)
            {
                var playerSettings = new PlayerSpecificSettings();
                playerSettings.leftHanded     = mirrorCheckbox.Checked;
                playerSettings.staticLights   = staticLightsCheckbox.Checked;
                playerSettings.noTextsAndHuds = noHudCheckbox.Checked;
                playerSettings.advancedHud    = advancedHudCheckbox.Checked;
                playerSettings.reduceDebris   = reduceDebrisCheckbox.Checked;

                var modifiers = new GameplayModifiers();
                modifiers.noFail           = noFailCheckbox.Checked;
                modifiers.noBombs          = noBombsCheckbox.Checked;
                modifiers.noObstacles      = noWallsCheckbox.Checked;
                modifiers.instaFail        = instaFailCheckbox.Checked && !modifiers.noFail;
                modifiers.failOnSaberClash = failOnClashCheckbox.Checked;
                modifiers.batteryEnergy    = batteryEnergyCheckbox.Checked && !modifiers.noFail && !modifiers.instaFail;
                modifiers.fastNotes        = fastNotesCheckbox.Checked;
                modifiers.songSpeed        = fastSongCheckbox.Checked ?
                                             GameplayModifiers.SongSpeed.Faster :
                                             slowSongCheckbox.Checked ?
                                             GameplayModifiers.SongSpeed.Slower :
                                             GameplayModifiers.SongSpeed.Normal;
                modifiers.disappearingArrows = disappearingArrowsCheckbox.Checked && !ghostNotesCheckbox.Checked;
                modifiers.ghostNotes         = ghostNotesCheckbox.Checked;

                var characteristic = currentSelection.Characteristics.First(x => x.SerializedName == characteristicDropdown.SelectedItem as string);

                var playSong = new PlaySong();
                playSong.characteristic = new Characteristic();
                playSong.characteristic.SerializedName = characteristic.SerializedName;
                playSong.difficulty        = (Characteristic.BeatmapDifficulty)Enum.Parse(typeof(Characteristic.BeatmapDifficulty), difficultyDropdown.SelectedItem.ToString());
                playSong.gameplayModifiers = modifiers;
                playSong.playerSettings    = playerSettings;
                playSong.levelId           = currentSelection.LevelId;

                server.Send(new Packet(playSong).ToBytes());
            }
        }
Пример #20
0
        public static void StartSong(IBeatmapLevel level, byte difficulty, GameplayModifiers gameplayModifiers, PracticeSettings practiceSettings = null)
        {
            if (InSong || level == null || gameplayModifiers == null)
            {
                return;
            }
            try
            {
                MenuTransitionsHelperSO menuSceneSetupData = Resources.FindObjectsOfTypeAll <MenuTransitionsHelperSO>().FirstOrDefault();
                if (menuSceneSetupData != null)
                {
                    PlayerSpecificSettings playerSettings = Resources.FindObjectsOfTypeAll <PlayerDataModelSO>().FirstOrDefault().currentLocalPlayer.playerSpecificSettings;
                    _gameplayModifiers = gameplayModifiers;
                    _difficultyBeatmap = null;
                    foreach (IDifficultyBeatmap difficultyBeatmap in level.beatmapLevelData.difficultyBeatmapSets[0].difficultyBeatmaps)
                    {
                        if (difficultyBeatmap.difficultyRank == difficulty)
                        {
                            _difficultyBeatmap = difficultyBeatmap;
                            break;
                        }
                    }

                    if (_difficultyBeatmap == null)
                    {
                        throw new Exception("IDifficultyBeatmap not found");
                    }

                    Data.Logger.Debug($"Starting song: name={level.songName}, levelId={level.levelID}, difficulty={_difficultyBeatmap.difficulty}");
                    InSong = true;
                    Controllers.PlayerController.Instance._playerInfo.SongFailed = false;
                    Controllers.PlayerController.Instance._playerInfo.InSong     = true;
                    menuSceneSetupData.StartStandardLevel(_difficultyBeatmap, gameplayModifiers, playerSettings, practiceSettings, null, new Action <StandardLevelScenesTransitionSetupDataSO, LevelCompletionResults>(FinishSong));
                }
            } catch (Exception e)
            {
                Data.Logger.Error(e);
            }
        }
Пример #21
0
            public static void Postfix(IDifficultyBeatmap difficultyBeatmap, PlayerSpecificSettings playerSpecificSettings, ref ColorScheme overrideColorScheme)
            {
                loadedLights    = false;
                loadError       = false;
                playerLaserErr  = false;
                ringErr         = false;
                isInMultiplayer = true;
                Plugin.Log.Info("In multiplayer.");

                EnvironmentEffectsFilterPreset defaultPreset = playerSpecificSettings.environmentEffectsFilterDefaultPreset;
                EnvironmentEffectsFilterPreset ePlusPreset   = playerSpecificSettings.environmentEffectsFilterExpertPlusPreset;

                if (difficultyBeatmap.difficulty == BeatmapDifficulty.ExpertPlus && ePlusPreset == EnvironmentEffectsFilterPreset.NoEffects)
                {
                    staticLights = true;
                }
                else if (difficultyBeatmap.difficulty != BeatmapDifficulty.ExpertPlus && defaultPreset == EnvironmentEffectsFilterPreset.NoEffects)
                {
                    staticLights = true;
                }
                else
                {
                    staticLights = false;
                }

                EnvironmentInfoSO eiso = difficultyBeatmap.GetEnvironmentInfo();

                colours = overrideColorScheme ?? new ColorScheme(eiso.colorScheme);
                BoostColour b        = Plugin.Boost;
                ColorScheme mapColor = new ColorScheme("CustomColourScheme", "CustomColourScheme", false, colours.saberAColor, colours.saberBColor, colours.environmentColor0, colours.environmentColor1, true, new Color(b.r0, b.g0, b.b0), new Color(b.r1, b.g1, b.b1), colours.obstaclesColor);

                overrideColorScheme = mapColor;
                colours             = mapColor;
                colour0             = colours.environmentColor0;
                colour1             = colours.environmentColor1;
                ringErr             = false;
            }
Пример #22
0
        public static void StartSong(LevelSO level, byte difficulty, GameplayModifiers gameplayModifiers)
        {
            if (InSong || level == null || gameplayModifiers == null)
            {
                return;
            }
            try
            {
                MenuSceneSetupDataSO menuSceneSetupData = Resources.FindObjectsOfTypeAll <MenuSceneSetupDataSO>().FirstOrDefault();
                if (menuSceneSetupData != null)
                {
                    PlayerSpecificSettings playerSettings = Resources.FindObjectsOfTypeAll <PlayerDataModelSO>().FirstOrDefault().currentLocalPlayer.playerSpecificSettings;
                    _gameplayModifiers = gameplayModifiers;
                    _difficultyBeatmap = level.GetDifficultyBeatmap((BeatmapDifficulty)difficulty);

                    Data.Logger.Debug($"Starting song: name={level.songName}, levelId={level.levelID}, difficulty={_difficultyBeatmap.difficulty}");
                    InSong = true;
                    menuSceneSetupData.StartStandardLevel(_difficultyBeatmap, gameplayModifiers, playerSettings, null, null, new Action <StandardLevelSceneSetupDataSO, LevelCompletionResults>(FinishSong));
                }
            } catch (Exception e)
            {
                Data.Logger.Error(e);
            }
        }
Пример #23
0
        private void OnActiveSceneChanged(Scene oldScene, Scene newScene)
        {
            GameStatus gameStatus = statusManager.gameStatus;

            gameStatus.scene = newScene.name;

            if (newScene.name == "MenuCore")
            {
                // Menu
                gameStatus.scene = "Menu";

                Gamemode.Init();

                // TODO: get the current song, mode and mods while in menu
                gameStatus.ResetMapInfo();

                gameStatus.ResetPerformance();

                // Release references for AfterCutScoreBuffers that don't resolve due to player leaving the map before finishing.
                noteCutMapping.Clear();

                statusManager.EmitStatusUpdate(ChangedProperties.AllButNoteCut, "menu");
            }
            else if (newScene.name == "GameCore")
            {
                // In game
                gameStatus.scene = "Song";

                gamePauseManager = FindFirstOrDefault <GamePauseManager>();
                scoreController  = FindFirstOrDefault <ScoreController>();
                gameplayManager  = Resources.FindObjectsOfTypeAll <StandardLevelGameplayManager>().FirstOrDefault() as MonoBehaviour ?? Resources.FindObjectsOfTypeAll <MissionLevelGameplayManager>().FirstOrDefault();
                beatmapObjectCallbackController  = FindFirstOrDefault <BeatmapObjectCallbackController>();
                gameplayModifiersSO              = FindFirstOrDefault <GameplayModifiersModelSO>();
                audioTimeSyncController          = FindFirstOrDefault <AudioTimeSyncController>();
                playerHeadAndObstacleInteraction = FindFirstOrDefault <PlayerHeadAndObstacleInteraction>();
                gameEnergyCounter = FindFirstOrDefault <GameEnergyCounter>();

                gameplayCoreSceneSetupData = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData;

                // Register event listeners
                // private GameEvent GamePauseManager#_gameDidPauseSignal
                AddSubscriber(gamePauseManager, "_gameDidPauseSignal", OnGamePause);
                // private GameEvent GamePauseManager#_gameDidResumeSignal
                AddSubscriber(gamePauseManager, "_gameDidResumeSignal", OnGameResume);
                // public ScoreController#noteWasCutEvent<NoteData, NoteCutInfo, int multiplier> // called after AfterCutScoreBuffer is created
                scoreController.noteWasCutEvent += OnNoteWasCut;
                // public ScoreController#noteWasMissedEvent<NoteData, int multiplier>
                scoreController.noteWasMissedEvent += OnNoteWasMissed;
                // public ScoreController#scoreDidChangeEvent<int, int> // score
                scoreController.scoreDidChangeEvent += OnScoreDidChange;
                // public ScoreController#comboDidChangeEvent<int> // combo
                scoreController.comboDidChangeEvent += OnComboDidChange;
                // public ScoreController#multiplierDidChangeEvent<int, float> // multiplier, progress [0..1]
                scoreController.multiplierDidChangeEvent += OnMultiplierDidChange;
                // private GameEvent GameplayManager#_levelFinishedSignal
                AddSubscriber(gameplayManager, "_levelFinishedSignal", OnLevelFinished);
                // private GameEvent GameplayManager#_levelFailedSignal
                AddSubscriber(gameplayManager, "_levelFailedSignal", OnLevelFailed);
                // public event Action<BeatmapEventData> BeatmapObjectCallbackController#beatmapEventDidTriggerEvent
                beatmapObjectCallbackController.beatmapEventDidTriggerEvent += OnBeatmapEventDidTrigger;

                IDifficultyBeatmap diff  = gameplayCoreSceneSetupData.difficultyBeatmap;
                IBeatmapLevel      level = diff.level;

                gameStatus.partyMode = Gamemode.IsPartyActive;
                gameStatus.mode      = Gamemode.GameMode;

                gameplayModifiers = gameplayCoreSceneSetupData.gameplayModifiers;
                PlayerSpecificSettings playerSettings   = gameplayCoreSceneSetupData.playerSpecificSettings;
                PracticeSettings       practiceSettings = gameplayCoreSceneSetupData.practiceSettings;

                float songSpeedMul = gameplayModifiers.songSpeedMul;
                if (practiceSettings != null)
                {
                    songSpeedMul = practiceSettings.songSpeedMul;
                }
                float modifierMultiplier = gameplayModifiersSO.GetTotalMultiplier(gameplayModifiers);

                gameStatus.songName        = level.songName;
                gameStatus.songSubName     = level.songSubName;
                gameStatus.songAuthorName  = level.songAuthorName;
                gameStatus.levelAuthorName = level.levelAuthorName;
                gameStatus.songBPM         = level.beatsPerMinute;
                gameStatus.noteJumpSpeed   = diff.noteJumpMovementSpeed;
                gameStatus.songHash        = level.levelID.Substring(0, Math.Min(32, level.levelID.Length));
                gameStatus.songTimeOffset  = (long)(level.songTimeOffset * 1000f / songSpeedMul);
                gameStatus.length          = (long)(level.beatmapLevelData.audioClip.length * 1000f / songSpeedMul);
                gameStatus.start           = GetCurrentTime() - (long)(audioTimeSyncController.songTime * 1000f / songSpeedMul);
                if (practiceSettings != null)
                {
                    gameStatus.start -= (long)(practiceSettings.startSongTime * 1000f / songSpeedMul);
                }
                gameStatus.paused          = 0;
                gameStatus.difficulty      = diff.difficulty.Name();
                gameStatus.notesCount      = diff.beatmapData.notesCount;
                gameStatus.bombsCount      = diff.beatmapData.bombsCount;
                gameStatus.obstaclesCount  = diff.beatmapData.obstaclesCount;
                gameStatus.environmentName = level.environmentSceneInfo.sceneName;

                gameStatus.maxScore = ScoreController.MaxModifiedScoreForMaxRawScore(ScoreController.MaxRawScoreForNumberOfNotes(diff.beatmapData.notesCount), gameplayModifiers, gameplayModifiersSO);
                gameStatus.maxRank  = RankModel.MaxRankForGameplayModifiers(gameplayModifiers, gameplayModifiersSO).ToString();

                try {
                    // From https://support.unity3d.com/hc/en-us/articles/206486626-How-can-I-get-pixels-from-unreadable-textures-
                    var texture   = level.GetCoverImageTexture2DAsync(CancellationToken.None).Result;
                    var active    = RenderTexture.active;
                    var temporary = RenderTexture.GetTemporary(
                        texture.width,
                        texture.height,
                        0,
                        RenderTextureFormat.Default,
                        RenderTextureReadWrite.Linear
                        );

                    Graphics.Blit(texture, temporary);
                    RenderTexture.active = temporary;

                    var cover = new Texture2D(texture.width, texture.height);
                    cover.ReadPixels(new Rect(0, 0, temporary.width, temporary.height), 0, 0);
                    cover.Apply();

                    RenderTexture.active = active;
                    RenderTexture.ReleaseTemporary(temporary);

                    gameStatus.songCover = System.Convert.ToBase64String(
                        ImageConversion.EncodeToPNG(cover)
                        );
                } catch {
                    gameStatus.songCover = null;
                }

                gameStatus.ResetPerformance();

                gameStatus.modifierMultiplier  = modifierMultiplier;
                gameStatus.songSpeedMultiplier = songSpeedMul;
                gameStatus.batteryLives        = gameEnergyCounter.batteryLives;

                gameStatus.modObstacles          = gameplayModifiers.enabledObstacleType.ToString();
                gameStatus.modInstaFail          = gameplayModifiers.instaFail;
                gameStatus.modNoFail             = gameplayModifiers.noFail;
                gameStatus.modBatteryEnergy      = gameplayModifiers.batteryEnergy;
                gameStatus.modDisappearingArrows = gameplayModifiers.disappearingArrows;
                gameStatus.modNoBombs            = gameplayModifiers.noBombs;
                gameStatus.modSongSpeed          = gameplayModifiers.songSpeed.ToString();
                gameStatus.modNoArrows           = gameplayModifiers.noArrows;
                gameStatus.modGhostNotes         = gameplayModifiers.ghostNotes;
                gameStatus.modFailOnSaberClash   = gameplayModifiers.failOnSaberClash;
                gameStatus.modStrictAngles       = gameplayModifiers.strictAngles;
                gameStatus.modFastNotes          = gameplayModifiers.fastNotes;

                gameStatus.staticLights = playerSettings.staticLights;
                gameStatus.leftHanded   = playerSettings.leftHanded;
                gameStatus.swapColors   = playerSettings.swapColors;
                gameStatus.playerHeight = playerSettings.playerHeight;
                gameStatus.disableSFX   = playerSettings.disableSFX;
                gameStatus.noHUD        = playerSettings.noTextsAndHuds;
                gameStatus.advancedHUD  = playerSettings.advancedHud;

                statusManager.EmitStatusUpdate(ChangedProperties.AllButNoteCut, "songStart");
            }
        }
Пример #24
0
        protected override void Client_PlaySong(IPreviewBeatmapLevel desiredLevel, BeatmapCharacteristicSO desiredCharacteristic, BeatmapDifficulty desiredDifficulty, GameplayModifiers gameplayModifiers, PlayerSpecificSettings playerSpecificSettings, OverrideEnvironmentSettings overrideEnvironmentSettings, ColorScheme colorScheme, bool useFloatingScoreboard = false, bool useSync = false, bool disablePause = false, bool disableFail = false)
        {
            base.Client_PlaySong(desiredLevel, desiredCharacteristic, desiredDifficulty, gameplayModifiers, playerSpecificSettings, overrideEnvironmentSettings, colorScheme, useFloatingScoreboard, useSync, disablePause, disableFail);

            //Set up per-play settings
            Plugin.UseSync = useSync;
            Plugin.UseFloatingScoreboard = useFloatingScoreboard;
            Plugin.DisablePause          = disablePause;
            Plugin.DisableFail           = disableFail;

            //Reset score
            (Plugin.client.Self as Player).Score    = 0;
            (Plugin.client.Self as Player).Accuracy = 0;
            var playerUpdate = new Event();

            playerUpdate.Type          = Event.EventType.PlayerUpdated;
            playerUpdate.ChangedObject = Plugin.client.Self;
            Plugin.client.Send(new Packet(playerUpdate));

            UnityMainThreadDispatcher.Instance().Enqueue(() =>
            {
                //If the player is still on the results screen, go ahead and boot them out
                if (_resultsViewController.isInViewControllerHierarchy)
                {
                    resultsViewController_continueButtonPressedEvent(null);
                }

                SongUtils.PlaySong(desiredLevel, desiredCharacteristic, desiredDifficulty, overrideEnvironmentSettings, colorScheme, gameplayModifiers, playerSpecificSettings, SongFinished);
            });
        }
Пример #25
0
 private static void Postfix(IDifficultyBeatmap difficultyBeatmap, PlayerSpecificSettings playerSpecificSettings)
 {
     SceneTransitionHelper.Patch(difficultyBeatmap, playerSpecificSettings);
 }
Пример #26
0
        public static async void PlaySong(IPreviewBeatmapLevel level, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, GameplayModifiers gameplayModifiers = null, PlayerSpecificSettings playerSettings = null)
        {
            Action <IBeatmapLevel> SongLoaded = (loadedLevel) =>
            {
                MenuTransitionsHelperSO _menuSceneSetupData = Resources.FindObjectsOfTypeAll <MenuTransitionsHelperSO>().First();
                _menuSceneSetupData.StartStandardLevel(
                    loadedLevel.beatmapLevelData.GetDifficultyBeatmap(characteristic, difficulty),
                    null,
                    null,
                    gameplayModifiers ?? new GameplayModifiers(),
                    playerSettings ?? new PlayerSpecificSettings(),
                    null,
                    "Menu",
                    false,
                    null,
                    null
                    );
            };

            if ((level is PreviewBeatmapLevelSO && await HasDLCLevel(level.levelID)) ||
                level is CustomPreviewBeatmapLevel)
            {
                Logger.Debug("Loading DLC/Custom level...");
                var result = await GetLevelFromPreview(level);

                if (result != null && !(result?.isError == true))
                {
                    SongLoaded(result?.beatmapLevel);
                }
            }
            else if (level is BeatmapLevelSO)
            {
                Logger.Debug("Reading OST data without songloader...");
                SongLoaded(level as IBeatmapLevel);
            }
            else
            {
                Logger.Debug($"Skipping unowned DLC ({level.songName})");
            }
        }
Пример #27
0
        public static async void PlaySong(IPreviewBeatmapLevel level, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, OverrideEnvironmentSettings overrideEnvironmentSettings = null, ColorScheme colorScheme = null, GameplayModifiers gameplayModifiers = null, PlayerSpecificSettings playerSettings = null, Action <StandardLevelScenesTransitionSetupDataSO, LevelCompletionResults> songFinishedCallback = null)
        {
            Action <IBeatmapLevel> SongLoaded = (loadedLevel) =>
            {
                MenuTransitionsHelper _menuSceneSetupData = Resources.FindObjectsOfTypeAll <MenuTransitionsHelper>().First();
                _menuSceneSetupData.StartStandardLevel(
                    loadedLevel.beatmapLevelData.GetDifficultyBeatmap(characteristic, difficulty),
                    overrideEnvironmentSettings,
                    colorScheme,
                    gameplayModifiers ?? new GameplayModifiers(),
                    playerSettings ?? new PlayerSpecificSettings(),
                    null,
                    "Menu",
                    false,
                    null,
                    (standardLevelScenesTransitionSetupData, results) => songFinishedCallback?.Invoke(standardLevelScenesTransitionSetupData, results)
                    );
            };

            if ((level is PreviewBeatmapLevelSO && await HasDLCLevel(level.levelID)) ||
                level is CustomPreviewBeatmapLevel)
            {
                Logger.Debug("Loading DLC/Custom level...");
                var result = await GetLevelFromPreview(level);

                if (result != null && !(result?.isError == true))
                {
                    //HTTPstatus requires cover texture to be applied in here, and due to a fluke
                    //of beat saber, it's not applied when the level is loaded, but it *is*
                    //applied to the previewlevel it's loaded from
                    var loadedLevel = result?.beatmapLevel;
                    loadedLevel.SetField("_coverImageTexture2D", level.GetField <Texture2D>("_coverImageTexture2D"));
                    SongLoaded(loadedLevel);
                }
            }
            else if (level is BeatmapLevelSO)
            {
                Logger.Debug("Reading OST data without songloader...");
                SongLoaded(level as IBeatmapLevel);
            }
            else
            {
                Logger.Debug($"Skipping unowned DLC ({level.songName})");
            }
        }
Пример #28
0
        public async void HandleSongStart()
        {
            // Check if level data is actually available in BS_Utils before proceeding further. It isn't available in the tutorial
            if (!BS_Utils.Plugin.LevelData.IsSet)
            {
                Plugin.log.Debug("BS_Utils level data is not present. Probably due to the tutorial being active.");
                return;
            }

            GameStatus gameStatus = statusManager.gameStatus;

            // Check for multiplayer early to abort if needed: gameplay controllers don't exist in multiplayer until later
            multiplayerSessionManager = FindFirstOrDefaultOptional <MultiplayerSessionManager>();
            multiplayerController     = FindFirstOrDefaultOptional <MultiplayerController>();

            if (multiplayerSessionManager && multiplayerController)
            {
                Plugin.log.Debug("Multiplayer Level loaded");

                // public event Action<DisconnectedReason> MultiplayerSessionManager#disconnectedEvent;
                multiplayerSessionManager.disconnectedEvent += OnMultiplayerDisconnected;

                // public event Action<State> MultiplayerController#stateChangedEvent;
                multiplayerController.stateChangedEvent += OnMultiplayerStateChanged;

                // Do nothing until the next state change to Gameplay.
                if (multiplayerController.state != MultiplayerController.State.Gameplay)
                {
                    return;
                }

                multiplayerLocalActivePlayerFacade = FindFirstOrDefaultOptional <MultiplayerLocalActivePlayerFacade>();

                if (multiplayerLocalActivePlayerFacade != null)
                {
                    multiplayerLocalActivePlayerFacade.playerDidFinishEvent += OnMultiplayerLevelFinished;
                }
            }
            else if (!doDelayedSongStart)
            {
                doDelayedSongStart = true;

                return;
            }

            // `wants_to_play_next_level` is set for players who don't want to play the song aka want to spectate aka are not "active". `isSpectating` is apparently not spectating.
            gameStatus.scene       = multiplayerSessionManager.isSpectating || !multiplayerSessionManager.LocalPlayerHasState(NetworkConstants.wantsToPlayNextLevel) ? "Spectator" : "Song";
            gameStatus.multiplayer = multiplayerSessionManager.isConnectingOrConnected;

            pauseController                  = FindFirstOrDefaultOptional <PauseController>();
            scoreController                  = FindWithMultiplayerFix <ScoreController>();
            beatmapObjectManager             = (BeatmapObjectManager)scoreControllerBeatmapObjectManagerField.GetValue(scoreController);
            gameplayManager                  = FindFirstOrDefaultOptional <StandardLevelGameplayManager>() as MonoBehaviour ?? FindFirstOrDefaultOptional <MissionLevelGameplayManager>();
            beatmapObjectCallbackController  = FindWithMultiplayerFix <BeatmapObjectCallbackController>();
            gameplayModifiersSO              = FindFirstOrDefault <GameplayModifiersModelSO>();
            audioTimeSyncController          = FindWithMultiplayerFix <AudioTimeSyncController>();
            playerHeadAndObstacleInteraction = (PlayerHeadAndObstacleInteraction)scoreControllerHeadAndObstacleInteractionField.GetValue(scoreController);
            gameSongController               = FindWithMultiplayerFix <GameSongController>();
            gameEnergyCounter                = FindWithMultiplayerFix <GameEnergyCounter>();

            if (multiplayerController)
            {
                // NOOP
            }
            else if (gameplayManager is StandardLevelGameplayManager)
            {
                Plugin.log.Debug("Standard Level loaded");
            }
            else if (gameplayManager is MissionLevelGameplayManager)
            {
                Plugin.log.Debug("Mission Level loaded");
            }

            gameplayCoreSceneSetupData = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData;

            // Register event listeners
            // PauseController doesn't exist in multiplayer
            if (pauseController != null)
            {
                // public event Action PauseController#didPauseEvent;
                pauseController.didPauseEvent += OnGamePause;
                // public event Action PauseController#didResumeEvent;
                pauseController.didResumeEvent += OnGameResume;
            }
            // public ScoreController#noteWasCutEvent<NoteData, NoteCutInfo, int multiplier> // called after CutScoreBuffer is created
            scoreController.noteWasCutEvent += OnNoteWasCut;
            // public ScoreController#noteWasMissedEvent<NoteData, int multiplier>
            scoreController.noteWasMissedEvent += OnNoteWasMissed;
            // public ScoreController#scoreDidChangeEvent<int, int> // score
            scoreController.scoreDidChangeEvent += OnScoreDidChange;
            // public ScoreController#comboDidChangeEvent<int> // combo
            scoreController.comboDidChangeEvent += OnComboDidChange;
            // public ScoreController#multiplierDidChangeEvent<int, float> // multiplier, progress [0..1]
            scoreController.multiplierDidChangeEvent += OnMultiplierDidChange;

            beatmapObjectManager.noteWasSpawnedEvent += OnNoteWasSpawned;
            // public event Action<BeatmapEventData> BeatmapObjectCallbackController#beatmapEventDidTriggerEvent
            beatmapObjectCallbackController.beatmapEventDidTriggerEvent += OnBeatmapEventDidTrigger;
            // public event Action GameSongController#songDidFinishEvent;
            gameSongController.songDidFinishEvent += OnLevelFinished;
            // public event Action GameEnergyCounter#gameEnergyDidReach0Event;
            gameEnergyCounter.gameEnergyDidReach0Event += OnEnergyDidReach0Event;
            if (gameplayManager is ILevelEndActions levelEndActions)
            {
                // event Action levelFailedEvent;
                levelEndActions.levelFailedEvent += OnLevelFailed;
            }

            IDifficultyBeatmap diff  = gameplayCoreSceneSetupData.difficultyBeatmap;
            IBeatmapLevel      level = diff.level;

            gameStatus.partyMode = Gamemode.IsPartyActive;

            gameplayModifiers         = gameplayCoreSceneSetupData.gameplayModifiers;
            gameplayModiferParamsList = gameplayModifiersSO.CreateModifierParamsList(gameplayModifiers);

            PlayerSpecificSettings playerSettings   = gameplayCoreSceneSetupData.playerSpecificSettings;
            PracticeSettings       practiceSettings = gameplayCoreSceneSetupData.practiceSettings;

            float songSpeedMul = gameplayModifiers.songSpeedMul;

            if (practiceSettings != null)
            {
                songSpeedMul = practiceSettings.songSpeedMul;
            }

            int beatmapObjectId    = 0;
            var beatmapObjectsData = diff.beatmapData.beatmapObjectsData;

            // Generate NoteData to id mappings for backwards compatiblity with <1.12.1
            noteToIdMapping = new NoteData[beatmapObjectsData.Count(obj => obj is NoteData)];
            lastNoteId      = 0;

            foreach (BeatmapObjectData beatmapObjectData in beatmapObjectsData)
            {
                if (beatmapObjectData is NoteData noteData)
                {
                    noteToIdMapping[beatmapObjectId++] = noteData;
                }
            }

            gameStatus.songName                = level.songName;
            gameStatus.songSubName             = level.songSubName;
            gameStatus.songAuthorName          = level.songAuthorName;
            gameStatus.levelAuthorName         = level.levelAuthorName;
            gameStatus.songBPM                 = level.beatsPerMinute;
            gameStatus.noteJumpSpeed           = diff.noteJumpMovementSpeed;
            gameStatus.noteJumpStartBeatOffset = diff.noteJumpStartBeatOffset;
            // 13 is "custom_level_" and 40 is the magic number for the length of the SHA-1 hash
            gameStatus.songHash       = Regex.IsMatch(level.levelID, "^custom_level_[0-9A-F]{40}", RegexOptions.IgnoreCase) && !level.levelID.EndsWith(" WIP") ? level.levelID.Substring(13, 40) : null;
            gameStatus.levelId        = level.levelID;
            gameStatus.songTimeOffset = (long)(level.songTimeOffset * 1000f / songSpeedMul);
            gameStatus.length         = (long)(level.beatmapLevelData.audioClip.length * 1000f / songSpeedMul);
            gameStatus.start          = GetCurrentTime() - (long)(audioTimeSyncController.songTime * 1000f / songSpeedMul);
            if (practiceSettings != null)
            {
                gameStatus.start -= (long)(practiceSettings.startSongTime * 1000f / songSpeedMul);
            }
            gameStatus.paused          = 0;
            gameStatus.difficulty      = diff.difficulty.Name();
            gameStatus.difficultyEnum  = Enum.GetName(typeof(BeatmapDifficulty), diff.difficulty);
            gameStatus.characteristic  = diff.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName;
            gameStatus.notesCount      = diff.beatmapData.cuttableNotesCount;
            gameStatus.bombsCount      = diff.beatmapData.bombsCount;
            gameStatus.obstaclesCount  = diff.beatmapData.obstaclesCount;
            gameStatus.environmentName = level.environmentInfo.sceneInfo.sceneName;

            ColorScheme colorScheme = gameplayCoreSceneSetupData.colorScheme ?? new ColorScheme(gameplayCoreSceneSetupData.environmentInfo.colorScheme);

            gameStatus.colorSaberA       = colorScheme.saberAColor;
            gameStatus.colorSaberB       = colorScheme.saberBColor;
            gameStatus.colorEnvironment0 = colorScheme.environmentColor0;
            gameStatus.colorEnvironment1 = colorScheme.environmentColor1;
            if (colorScheme.supportsEnvironmentColorBoost)
            {
                gameStatus.colorEnvironmentBoost0 = colorScheme.environmentColor0Boost;
                gameStatus.colorEnvironmentBoost1 = colorScheme.environmentColor1Boost;
            }
            gameStatus.colorObstacle = colorScheme.obstaclesColor;

            try {
                // From https://support.unity3d.com/hc/en-us/articles/206486626-How-can-I-get-pixels-from-unreadable-textures-
                // Modified to correctly handle texture atlases. Fixes #82.
                var active = RenderTexture.active;

                var sprite = await level.GetCoverImageAsync(CancellationToken.None);

                var texture   = sprite.texture;
                var temporary = RenderTexture.GetTemporary(texture.width, texture.height, 0, RenderTextureFormat.Default, RenderTextureReadWrite.Linear);

                Graphics.Blit(texture, temporary);
                RenderTexture.active = temporary;

                var spriteRect = sprite.rect;
                var uv         = sprite.uv[0];

                var cover = new Texture2D((int)spriteRect.width, (int)spriteRect.height);
                // Unity sucks. The coordinates of the sprite on its texture atlas are only accessible through the Sprite.uv property since rect always returns `x=0,y=0`, so we need to convert them back into texture space.
                cover.ReadPixels(new Rect(
                                     uv.x * texture.width,
                                     texture.height - uv.y * texture.height,
                                     spriteRect.width,
                                     spriteRect.height
                                     ), 0, 0);
                cover.Apply();

                RenderTexture.active = active;
                RenderTexture.ReleaseTemporary(temporary);

                gameStatus.songCover = System.Convert.ToBase64String(ImageConversion.EncodeToPNG(cover));
            } catch {
                gameStatus.songCover = null;
            }

            gameStatus.ResetPerformance();

            UpdateModMultiplier();

            gameStatus.songSpeedMultiplier = songSpeedMul;
            gameStatus.batteryLives        = gameEnergyCounter.batteryLives;

            gameStatus.modObstacles          = gameplayModifiers.enabledObstacleType.ToString();
            gameStatus.modInstaFail          = gameplayModifiers.instaFail;
            gameStatus.modNoFail             = gameplayModifiers.noFailOn0Energy;
            gameStatus.modBatteryEnergy      = gameplayModifiers.energyType == GameplayModifiers.EnergyType.Battery;
            gameStatus.modDisappearingArrows = gameplayModifiers.disappearingArrows;
            gameStatus.modNoBombs            = gameplayModifiers.noBombs;
            gameStatus.modSongSpeed          = gameplayModifiers.songSpeed.ToString();
            gameStatus.modNoArrows           = gameplayModifiers.noArrows;
            gameStatus.modGhostNotes         = gameplayModifiers.ghostNotes;
            gameStatus.modFailOnSaberClash   = gameplayModifiers.failOnSaberClash;
            gameStatus.modStrictAngles       = gameplayModifiers.strictAngles;
            gameStatus.modFastNotes          = gameplayModifiers.fastNotes;
            gameStatus.modSmallNotes         = gameplayModifiers.smallCubes;
            gameStatus.modProMode            = gameplayModifiers.proMode;
            gameStatus.modZenMode            = gameplayModifiers.zenMode;

            var environmentEffectsFilterPreset = diff.difficulty == BeatmapDifficulty.ExpertPlus ? playerSettings.environmentEffectsFilterExpertPlusPreset : playerSettings.environmentEffectsFilterDefaultPreset;

            // Backwards compatibility for <1.13.4
            gameStatus.staticLights           = environmentEffectsFilterPreset != EnvironmentEffectsFilterPreset.AllEffects;
            gameStatus.leftHanded             = playerSettings.leftHanded;
            gameStatus.playerHeight           = playerSettings.playerHeight;
            gameStatus.sfxVolume              = playerSettings.sfxVolume;
            gameStatus.reduceDebris           = playerSettings.reduceDebris;
            gameStatus.noHUD                  = playerSettings.noTextsAndHuds;
            gameStatus.advancedHUD            = playerSettings.advancedHud;
            gameStatus.autoRestart            = playerSettings.autoRestart;
            gameStatus.saberTrailIntensity    = playerSettings.saberTrailIntensity;
            gameStatus.environmentEffects     = environmentEffectsFilterPreset.ToString();
            gameStatus.hideNoteSpawningEffect = playerSettings.hideNoteSpawnEffect;

            statusManager.EmitStatusUpdate(ChangedProperties.AllButNoteCut, "songStart");
        }
        protected override void Client_PacketReceived(Packet packet)
        {
            base.Client_PacketReceived(packet);

            if (packet.Type == PacketType.PlaySong)
            {
                PlaySong playSong = packet.SpecificPacket as PlaySong;

                var desiredLevel          = SongUtils.masterLevelList.First(x => x.levelID == playSong.GameplayParameters.Beatmap.LevelId);
                var desiredCharacteristic = desiredLevel.previewDifficultyBeatmapSets.FirstOrDefault(x => x.beatmapCharacteristic.serializedName == playSong.GameplayParameters.Beatmap.Characteristic.SerializedName).beatmapCharacteristic ?? desiredLevel.previewDifficultyBeatmapSets.First().beatmapCharacteristic;
                var desiredDifficulty     = (BeatmapDifficulty)playSong.GameplayParameters.Beatmap.Difficulty;

                var playerData     = Resources.FindObjectsOfTypeAll <PlayerDataModel>().First().playerData;
                var playerSettings = playerData.playerSpecificSettings;

                //Override defaults if we have forced options enabled
                if (playSong.GameplayParameters.PlayerSettings.Options != PlayerOptions.None)
                {
                    playerSettings = new PlayerSpecificSettings(
                        playSong.GameplayParameters.PlayerSettings.Options.HasFlag(PlayerOptions.StaticLights),
                        playSong.GameplayParameters.PlayerSettings.Options.HasFlag(PlayerOptions.LeftHanded),
                        playSong.GameplayParameters.PlayerSettings.PlayerHeight,
                        playSong.GameplayParameters.PlayerSettings.Options.HasFlag(PlayerOptions.AutoPlayerHeight),
                        playSong.GameplayParameters.PlayerSettings.SfxVolume,
                        playSong.GameplayParameters.PlayerSettings.Options.HasFlag(PlayerOptions.ReduceDebris),
                        playSong.GameplayParameters.PlayerSettings.Options.HasFlag(PlayerOptions.NoHud),
                        playSong.GameplayParameters.PlayerSettings.Options.HasFlag(PlayerOptions.NoFailEffects),
                        playSong.GameplayParameters.PlayerSettings.Options.HasFlag(PlayerOptions.AdvancedHud),
                        playSong.GameplayParameters.PlayerSettings.Options.HasFlag(PlayerOptions.AutoRestart),
                        playSong.GameplayParameters.PlayerSettings.SaberTrailIntensity,
                        playSong.GameplayParameters.PlayerSettings.NoteJumpStartBeatOffset,
                        playSong.GameplayParameters.PlayerSettings.Options.HasFlag(PlayerOptions.HideNoteSpawnEffect),
                        playSong.GameplayParameters.PlayerSettings.Options.HasFlag(PlayerOptions.AdaptiveSfx)
                        );
                }

                var songSpeed = GameplayModifiers.SongSpeed.Normal;
                if (playSong.GameplayParameters.GameplayModifiers.Options.HasFlag(GameOptions.SlowSong))
                {
                    songSpeed = GameplayModifiers.SongSpeed.Slower;
                }
                if (playSong.GameplayParameters.GameplayModifiers.Options.HasFlag(GameOptions.FastSong))
                {
                    songSpeed = GameplayModifiers.SongSpeed.Faster;
                }

                var gameplayModifiers = new GameplayModifiers(
                    playSong.GameplayParameters.GameplayModifiers.Options.HasFlag(GameOptions.DemoNoFail),
                    playSong.GameplayParameters.GameplayModifiers.Options.HasFlag(GameOptions.DemoNoObstacles),
                    playSong.GameplayParameters.GameplayModifiers.Options.HasFlag(GameOptions.BatteryEnergy) ? GameplayModifiers.EnergyType.Battery : GameplayModifiers.EnergyType.Bar,
                    playSong.GameplayParameters.GameplayModifiers.Options.HasFlag(GameOptions.NoFail),
                    playSong.GameplayParameters.GameplayModifiers.Options.HasFlag(GameOptions.InstaFail),
                    playSong.GameplayParameters.GameplayModifiers.Options.HasFlag(GameOptions.FailOnClash),
                    playSong.GameplayParameters.GameplayModifiers.Options.HasFlag(GameOptions.NoObstacles) ? GameplayModifiers.EnabledObstacleType.NoObstacles : GameplayModifiers.EnabledObstacleType.All,
                    playSong.GameplayParameters.GameplayModifiers.Options.HasFlag(GameOptions.NoBombs),
                    playSong.GameplayParameters.GameplayModifiers.Options.HasFlag(GameOptions.FastNotes),
                    playSong.GameplayParameters.GameplayModifiers.Options.HasFlag(GameOptions.StrictAngles),
                    playSong.GameplayParameters.GameplayModifiers.Options.HasFlag(GameOptions.DisappearingArrows),
                    songSpeed,
                    playSong.GameplayParameters.GameplayModifiers.Options.HasFlag(GameOptions.NoArrows),
                    playSong.GameplayParameters.GameplayModifiers.Options.HasFlag(GameOptions.GhostNotes)
                    );

                var colorScheme = playerData.colorSchemesSettings.overrideDefaultColors ? playerData.colorSchemesSettings.GetSelectedColorScheme() : null;

                //Disable score submission if nofail is on. This is specifically for Hidden Sabers, though it may stay longer
                if (playSong.DisableScoresaberSubmission)
                {
                    BS_Utils.Gameplay.ScoreSubmission.DisableSubmission(SharedConstructs.Name);
                }
                if (playSong.ShowNormalNotesOnStream)
                {
                    var customNotes = IPA.Loader.PluginManager.GetPluginFromId("CustomNotes");
                    if (customNotes != null)
                    {
                        EnableHMDOnly();
                    }
                }

                PlaySong?.Invoke(desiredLevel, desiredCharacteristic, desiredDifficulty, gameplayModifiers, playerSettings, playerData.overrideEnvironmentSettings, colorScheme, playSong.FloatingScoreboard, playSong.StreamSync, playSong.DisablePause, playSong.DisableFail);
            }
            else if (packet.Type == PacketType.Command)
            {
                Command command = packet.SpecificPacket as Command;
                if (command.CommandType == Command.CommandTypes.ReturnToMenu)
                {
                    if (SyncHandler.Instance != null)
                    {
                        ScreenOverlay.Instance.Clear();
                    }
                    if ((Self as Player).PlayState == Player.PlayStates.InGame)
                    {
                        PlayerUtils.ReturnToMenu();
                    }
                }
                else if (command.CommandType == Command.CommandTypes.ScreenOverlay_ShowPng)
                {
                    ScreenOverlay.Instance.ShowPng();
                }
                else if (command.CommandType == Command.CommandTypes.DelayTest_Finish)
                {
                    UnityMainThreadDispatcher.Instance().Enqueue(() => {
                        ScreenOverlay.Instance.Clear();
                        SyncHandler.Instance.Resume();
                        SyncHandler.Destroy();
                    });
                }
            }
            else if (packet.Type == PacketType.LoadSong)
            {
                LoadSong loadSong = packet.SpecificPacket as LoadSong;

                Action <IBeatmapLevel> SongLoaded = (loadedLevel) =>
                {
                    //Send updated download status
                    (Self as Player).DownloadState = Player.DownloadStates.Downloaded;

                    var playerUpdate = new Event();
                    playerUpdate.Type          = Event.EventType.PlayerUpdated;
                    playerUpdate.ChangedObject = Self;
                    Send(new Packet(playerUpdate));

                    //Notify any listeners of the client that a song has been loaded
                    LoadedSong?.Invoke(loadedLevel);
                };

                if (OstHelper.IsOst(loadSong.LevelId))
                {
                    SongLoaded?.Invoke(SongUtils.masterLevelList.First(x => x.levelID == loadSong.LevelId) as BeatmapLevelSO);
                }
                else
                {
                    if (SongUtils.masterLevelList.Any(x => x.levelID == loadSong.LevelId))
                    {
                        SongUtils.LoadSong(loadSong.LevelId, SongLoaded);
                    }
                    else
                    {
                        Action <string, bool> loadSongAction = (hash, succeeded) =>
                        {
                            if (succeeded)
                            {
                                SongUtils.LoadSong(loadSong.LevelId, SongLoaded);
                            }
                            else
                            {
                                (Self as Player).DownloadState = Player.DownloadStates.DownloadError;

                                var playerUpdated = new Event();
                                playerUpdated.Type          = Event.EventType.PlayerUpdated;
                                playerUpdated.ChangedObject = Self;

                                Send(new Packet(playerUpdated));
                            }
                        };

                        (Self as Player).DownloadState = Player.DownloadStates.Downloading;

                        var playerUpdate = new Event();
                        playerUpdate.Type          = Event.EventType.PlayerUpdated;
                        playerUpdate.ChangedObject = Self;
                        Send(new Packet(playerUpdate));

                        SongDownloader.DownloadSong(loadSong.LevelId, songDownloaded: loadSongAction, downloadProgressChanged: (hash, progress) => Logger.Debug($"DOWNLOAD PROGRESS ({hash}): {progress}"), customHostUrl: loadSong.CustomHostUrl);
                    }
                }
            }
            else if (packet.Type == PacketType.File)
            {
                File file = packet.SpecificPacket as File;
                if (file.Intent == File.Intentions.SetPngToShowWhenTriggered)
                {
                    var pngBytes = file.Compressed ? CompressionUtils.Decompress(file.Data) : file.Data;
                    ScreenOverlay.Instance.SetPngBytes(pngBytes);
                }
                else if (file.Intent == File.Intentions.ShowPngImmediately)
                {
                    var pngBytes = file.Compressed ? CompressionUtils.Decompress(file.Data) : file.Data;
                    ScreenOverlay.Instance.SetPngBytes(pngBytes);
                    ScreenOverlay.Instance.ShowPng();
                }

                Send(packet.From, new Packet(new Acknowledgement()
                {
                    PacketId = packet.Id,
                    Type     = Acknowledgement.AcknowledgementType.FileDownloaded
                }));
            }
        }
Пример #30
0
        void SelectAndLoadSong(string name, string difficulty)
        {
            //try
            //{
            //    mainMenuViewController.HandleMenuButton(MainMenuViewController.MenuButton.SoloFreePlay);
            //}
            //catch (Exception e)
            //{

            //}
            //try
            //{
            //    soloModeSelectionViewController.HandleMenuButton(SoloModeSelectionViewController.MenuType.FreePlayMode);
            //}
            //catch (Exception e)
            //{

            //}
            LevelCollectionSO _levelCollection = SongLoader.CustomLevelCollectionSO;
            LevelSO           level            = _levelCollection.GetLevelsWithBeatmapCharacteristic(Resources.FindObjectsOfTypeAll <BeatmapCharacteristicSO>().First(x => x.characteristicName == "Standard")).First(x => x.songName == name);

            //level = listViewController.GetPrivateField<IBeatmapLevel[]>("_levels").Where(x => x.songName == name)// && x.songAuthorName == author && x.songSubName == subname)
            //    .ToList().ElementAt(0);



            Console.WriteLine("Song found:" + level.songName);

            difficultyLevel = level.GetDifficultyBeatmap(_difficulties[difficulty]);
            //////////////////////////////////////////////////////////////////
            //            THING TO GET SONG BY JUST STARTING IT             //
            //////////////////////////////////////////////////////////////////
            GameplayModifiers gameplayModifiers = new GameplayModifiers();

            gameplayModifiers.ResetToDefault();
            gameplayModifiers.noFail = true;
            PlayerSpecificSettings playerSettings = Resources.FindObjectsOfTypeAll <PlayerDataModelSO>().FirstOrDefault().currentLocalPlayer.playerSpecificSettings;

            var practiceSettings = new PracticeSettings(PracticeSettings.defaultPracticeSettings);

            practiceSettings.startSongTime = time;
            practiceSettings.songSpeedMul  = playbackSpeed;

            MenuSceneSetupDataSO menu   = Resources.FindObjectsOfTypeAll <MenuSceneSetupDataSO>().First();
            SongLoader           loader = Resources.FindObjectsOfTypeAll <SongLoader>().First();

            loader.LoadAudioClipForLevel((CustomLevel)level, delegate(CustomLevel customLevel)
            {
                menu.StartStandardLevel(difficultyLevel, gameplayModifiers, playerSettings, practiceSettings, null, null);
            });

            ///////////////////////////////////////////////////////////////////
            //          THING TO GET SONG BY NAVIGATING THROUGH MENUS        //
            ///////////////////////////////////////////////////////////////////
            //MenuSceneSetupDataSO menu = Resources.FindObjectsOfTypeAll<MenuSceneSetupDataSO>().First();

            //soloFreePlayFlowCoordinator.HandleLevelListViewControllerDidSelectLevel(listViewController, level);
            //levelListView.SelectAndScrollToLevel(level.levelID);
            //int row = levelListView.RowNumberForLevelID(level.levelID);
            //levelListView.HandleDidSelectRowEvent(levelListView.GetPrivateField<TableView>("_tableView"), row);
            //try
            //{

            //    DifficultyTableView difficultyTableView = beatmapDifficultyViewController.GetPrivateField<DifficultyTableView>("_difficultyTableView");
            //    TableView tableView = difficultyTableView.GetPrivateField<TableView>("_tableView");
            //    difficultyTableView.HandleDidSelectRowEvent(tableView, 0);
            //    tableView.SelectRow(0);
            //    difficultyTableView.SelectRow(difficultyLevel, false);
            //    soloFreePlayFlowCoordinator.HandleDifficultyViewControllerDidSelectDifficulty(beatmapDifficultyViewController, difficultyLevel);

            //    practiceController.Init(level, new PracticeSettings());

            //    GameplayModifiers gameplayModifiers = new GameplayModifiers();
            //    gameplayModifiers.ResetToDefault();
            //    gameplayModifiers.noFail = true;

            //    gameplaySetupViewController.SetData(gameplaySetupViewController.playerSettings, gameplayModifiers);
            //    soloFreePlayFlowCoordinator.HandleLevelDetailViewControllerDidPressPracticeButton(detailViewController);
            //    Console.WriteLine("loading " + difficultyLevel.level.songName);
            //    detailViewController.PracticeButtonPressed();

            //    if (!autoPlayBuffer && time > 2)
            //    {   // pause on start
            //        practiceController.HandleSongStartScrollbarOnValueChanged(time - 2);
            //    }
            //    else
            //    {   // autoplay or negative time will f**k it up
            //        practiceController.HandleSongStartScrollbarOnValueChanged(time);
            //    }
            //    Console.WriteLine("Starting song at: " + practiceController.GetPrivateField<PracticeSettings>("_practiceSettings").startSongTime);
            //    practiceController.PlayButtonPressed();
            //    soloFreePlayFlowCoordinator.HandlePracticeViewControllerDidPressPlayButton();
            //}
            //catch (Exception e)
            //{
            //    Console.WriteLine(e);
            //    //Console.WriteLine(e.StackTrace);
            //}
            //finally
            //{
            //    Console.WriteLine("[Mediocre Loader] Finally");
            //}

            //mainGameSceneSetupData.TransitionToScene(0.7f);
        }