Esempio n. 1
0
 public LevelOptionsInfo(BeatmapDifficulty difficulty, GameplayModifiers modifiers, string characteristicName)
 {
     this.difficulty         = difficulty;
     this.modifiers          = new GameplayModifiersStruct(modifiers);
     this.characteristicName = characteristicName;
 }
Esempio n. 2
0
        private void CleanUpSong()
        {
            statusManager.gameStatus.ResetMapInfo();
            statusManager.gameStatus.ResetPerformance();

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

            // Clear note id mappings.
            noteToIdMapping = null;

            if (pauseController != null)
            {
                pauseController.didPauseEvent  -= OnGamePause;
                pauseController.didResumeEvent -= OnGameResume;
                pauseController = null;
            }

            if (scoreController != null)
            {
                scoreController.noteWasCutEvent          -= OnNoteWasCut;
                scoreController.noteWasMissedEvent       -= OnNoteWasMissed;
                scoreController.scoreDidChangeEvent      -= OnScoreDidChange;
                scoreController.comboDidChangeEvent      -= OnComboDidChange;
                scoreController.multiplierDidChangeEvent -= OnMultiplierDidChange;
                scoreController = null;
            }

            if (gameplayManager != null)
            {
                if (gameplayManager is ILevelEndActions levelEndActions)
                {
                    // event Action levelFailedEvent;
                    levelEndActions.levelFailedEvent += OnLevelFailed;
                }
                gameplayManager = null;
            }

            if (beatmapObjectCallbackController != null)
            {
                beatmapObjectCallbackController.beatmapEventDidTriggerEvent -= OnBeatmapEventDidTrigger;
                beatmapObjectCallbackController = null;
            }

            if (gameplayModifiersSO != null)
            {
                gameplayModifiersSO = null;
            }

            if (audioTimeSyncController != null)
            {
                audioTimeSyncController = null;
            }

            if (playerHeadAndObstacleInteraction != null)
            {
                playerHeadAndObstacleInteraction = null;
            }

            if (gameSongController != null)
            {
                gameSongController.songDidFinishEvent -= OnLevelFinished;
                gameSongController = null;
            }

            if (gameEnergyCounter != null)
            {
                gameEnergyCounter.gameEnergyDidReach0Event -= OnEnergyDidReach0Event;
                gameEnergyCounter = null;
            }

            if (gameplayCoreSceneSetupData != null)
            {
                gameplayCoreSceneSetupData = null;
            }

            if (gameplayModifiers != null)
            {
                gameplayModifiers = null;
            }
        }
Esempio n. 3
0
        private void Client_PacketRecieved(Packet packet)
        {
            if (packet.Type == PacketType.PlaySong)
            {
                PlaySong playSong = packet.SpecificPacket as PlaySong;

                var desiredLevel          = Plugin.masterLevelList.First(x => x.levelID == playSong.levelId);
                var desiredCharacteristic = desiredLevel.beatmapCharacteristics.First(x => x.serializedName == playSong.characteristic.SerializedName);
                var desiredDifficulty     = (BeatmapDifficulty)playSong.difficulty;

                var playerSpecificSettings = new PlayerSpecificSettings();
                playerSpecificSettings.advancedHud    = playSong.playerSettings.advancedHud;
                playerSpecificSettings.leftHanded     = playSong.playerSettings.leftHanded;
                playerSpecificSettings.noTextsAndHuds = playSong.playerSettings.noTextsAndHuds;
                playerSpecificSettings.reduceDebris   = playSong.playerSettings.reduceDebris;
                playerSpecificSettings.staticLights   = playSong.playerSettings.staticLights;

                var gameplayModifiers = new GameplayModifiers();
                gameplayModifiers.batteryEnergy      = playSong.gameplayModifiers.batteryEnergy;
                gameplayModifiers.disappearingArrows = playSong.gameplayModifiers.disappearingArrows;
                gameplayModifiers.failOnSaberClash   = playSong.gameplayModifiers.failOnSaberClash;
                gameplayModifiers.fastNotes          = playSong.gameplayModifiers.fastNotes;
                gameplayModifiers.ghostNotes         = playSong.gameplayModifiers.ghostNotes;
                gameplayModifiers.instaFail          = playSong.gameplayModifiers.instaFail;
                gameplayModifiers.noBombs            = playSong.gameplayModifiers.noBombs;
                gameplayModifiers.noFail             = playSong.gameplayModifiers.noFail;
                gameplayModifiers.noObstacles        = playSong.gameplayModifiers.noObstacles;
                gameplayModifiers.songSpeed          = (GameplayModifiers.SongSpeed)playSong.gameplayModifiers.songSpeed;

                SaberUtilities.PlaySong(desiredLevel, desiredCharacteristic, desiredDifficulty, gameplayModifiers, playerSpecificSettings);
            }
            else if (packet.Type == PacketType.LoadSong)
            {
                LoadSong loadSong = packet.SpecificPacket as LoadSong;

                Action <IBeatmapLevel> SongLoaded = (loadedLevel) =>
                {
                    var loadedSong   = new LoadedSong();
                    var beatmapLevel = new PreviewBeatmapLevel();
                    beatmapLevel.Characteristics = loadedLevel.beatmapCharacteristics.ToList().Select(x => {
                        var characteristic            = new Characteristic();
                        characteristic.SerializedName = x.serializedName;
                        characteristic.difficulties   =
                            loadedLevel.beatmapLevelData.difficultyBeatmapSets
                            .First(y => y.beatmapCharacteristic.serializedName == x.serializedName)
                            .difficultyBeatmaps.Select(y => (Characteristic.BeatmapDifficulty)y.difficulty).ToArray();

                        return(characteristic);
                    }).ToArray();

                    beatmapLevel.LevelId = loadedLevel.levelID;
                    beatmapLevel.Name    = loadedLevel.songName;
                    beatmapLevel.Loaded  = true;

                    loadedSong.level = beatmapLevel;

                    client.Send(new Packet(loadedSong).ToBytes());
                };

                LoadSong(loadSong.levelId, SongLoaded);
            }
            else if (packet.Type == PacketType.Command)
            {
                Command command = packet.SpecificPacket as Command;
                if (command.commandType == Command.CommandType.ReturnToMenu)
                {
                    SaberUtilities.ReturnToMenu();
                }
            }
        }
 static void Prefix(MissionLevelScenesTransitionSetupDataSO __instance, IDifficultyBeatmap difficultyBeatmap, MissionObjective[] missionObjectives, GameplayModifiers gameplayModifiers, PlayerSpecificSettings playerSpecificSettings)
 {
     Plugin.LevelData.GameplayCoreSceneSetupData = new GameplayCoreSceneSetupData(difficultyBeatmap, gameplayModifiers, playerSpecificSettings, PracticeSettings.defaultPracticeSettings, false);
     Plugin.LevelData.IsSet     = true;
     __instance.didFinishEvent -= __instance_didFinishEvent;
     __instance.didFinishEvent += __instance_didFinishEvent;
 }
        //private BeatmapObjectCallbackController beatmapObjectCallbackController;

        public void SceneManagerOnActiveSceneChanged(Scene oldScene, Scene newScene)
        {
            if (newScene.name == "GameCore")
            {
                gameStatus = new GameStatus();

                levelSceneSetupData = FindFirstOrDefault <StandardLevelSceneSetupDataSO>();
                //gamePauseManager = FindFirstOrDefault<GamePauseManager>();
                scoreController         = FindFirstOrDefault <ScoreController>();
                gameplayModifiersSO     = FindFirstOrDefault <GameplayModifiersModelSO>();
                audioTimeSyncController = FindFirstOrDefault <AudioTimeSyncController>();
                //playerHeadAndObstacleInteraction = FindFirstOrDefault<PlayerHeadAndObstacleInteraction>();
                gameEnergyCounter = FindFirstOrDefault <GameEnergyCounter>();
                gameplayManager   = FindFirstOrDefault <StandardLevelGameplayManager>();
                //beatmapObjectCallbackController = FindFirstOrDefault<BeatmapObjectCallbackController>();

                // 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> // 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  = levelSceneSetupData.difficultyBeatmap;
                IBeatmapLevel      level = diff.level;

                GameplayModifiers      gameplayModifiers = levelSceneSetupData.gameplayCoreSetupData.gameplayModifiers;
                PlayerSpecificSettings playerSettings    = levelSceneSetupData.gameplayCoreSetupData.playerSpecificSettings;
                PracticeSettings       practiceSettings  = levelSceneSetupData.gameplayCoreSetupData.practiceSettings;

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

                var songInfo = FindLevelInfancyWay(levelSceneSetupData.difficultyBeatmap.level.levelID);


                gameStatus.songHash        = level.levelID.Substring(0, Math.Max(0, level.levelID.IndexOf('∎')));
                gameStatus.songBeatSaverID = songInfo == null ? null : ParseIdFromSongPath(songInfo);
                gameStatus.songFilePath    = songInfo?.path;
                gameStatus.songName        = level.songName;
                gameStatus.songSubName     = level.songSubName;
                gameStatus.songAuthorName  = level.songAuthorName;
                gameStatus.songBPM         = level.beatsPerMinute;
                gameStatus.noteJumpSpeed   = diff.noteJumpMovementSpeed;
                gameStatus.songTimeOffset  = (long)(level.songTimeOffset * 1000f / songSpeedMul);
                gameStatus.length          = (long)(level.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.maxScore         = ScoreController.GetScoreForGameplayModifiersScoreMultiplier(ScoreController.MaxScoreForNumberOfNotes(diff.beatmapData.notesCount), modifierMultiplier);
                gameStatus.maxPossibleScore = ScoreController.MaxScoreForNumberOfNotes(diff.beatmapData.notesCount);
                gameStatus.maxRank          = RankModel.MaxRankForGameplayModifiers(gameplayModifiers, gameplayModifiersSO).ToString();

                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.modFailOnSaberClash   = gameplayModifiers.failOnSaberClash;
                gameStatus.modStrictAngles       = gameplayModifiers.strictAngles;
            }
        }
Esempio n. 6
0
        // Yoinked from TournamentAssistant
        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)
                    );
            };
            BeatmapLevelsModel beatmapLevelsModel = Resources.FindObjectsOfTypeAll <BeatmapLevelsModel>().FirstOrDefault();
            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);
            }
        }
Esempio n. 7
0
        static void Postfix(MissionLevelScenesTransitionSetupDataSO __instance, IPreviewBeatmapLevel previewBeatmapLevel, string missionId, IDifficultyBeatmap difficultyBeatmap, MissionObjective[] missionObjectives, ColorScheme overrideColorScheme, GameplayModifiers gameplayModifiers, PlayerSpecificSettings playerSpecificSettings, string backButtonText)
        {
            EnvironmentInfoSO environmentInfoSO = difficultyBeatmap.GetEnvironmentInfo();

            ScoreSubmission._wasDisabled  = false;
            ScoreSubmission.LastDisablers = Array.Empty <string>();
            Plugin.LevelData.GameplayCoreSceneSetupData = new GameplayCoreSceneSetupData(difficultyBeatmap, previewBeatmapLevel, gameplayModifiers, playerSpecificSettings, PracticeSettings.defaultPracticeSettings, false, environmentInfoSO, overrideColorScheme);
            Plugin.LevelData.IsSet = true;
            Plugin.LevelData.Mode  = Mode.Mission;
            Utilities.Logger.log.Debug("Level Data set");
            __instance.didFinishEvent -= __instance_didFinishEvent;
            __instance.didFinishEvent += __instance_didFinishEvent;
        }
        public override void HandleMenuRpcManagerSelectedGameplayModifiers(string userId, GameplayModifiers gameplayModifiers)
        {
            ExtendedPlayer?player = _playerManager.GetExtendedPlayer(userId);

            if (player != null)
            {
                player.lastModifiers = gameplayModifiers;
            }
            base.HandleMenuRpcManagerSelectedGameplayModifiers(userId, gameplayModifiers);
            if (userId == hostUserId && MPState.FreeModEnabled)
            {
                GameplayModifiers localModifiers = GetPlayerGameplayModifiers(localUserId);
                if (localModifiers.songSpeed != gameplayModifiers.songSpeed)
                {
                    base.SetLocalPlayerGameplayModifiers(localModifiers.CopyWith(songSpeed: gameplayModifiers.songSpeed));
                }
            }
        }
        static void Prefix(string gameMode, IDifficultyBeatmap difficultyBeatmap, OverrideEnvironmentSettings overrideEnvironmentSettings, ref ColorScheme overrideColorScheme, GameplayModifiers gameplayModifiers, PlayerSpecificSettings playerSpecificSettings, PracticeSettings practiceSettings, string backButtonText, bool useTestNoteCutSoundEffects, Action beforeSceneSwitchCallback, Action <DiContainer> afterSceneSwitchCallback, Action <StandardLevelScenesTransitionSetupDataSO, LevelCompletionResults> levelFinishedCallback)
        {
            Plugin.Log.Info($"Starting ({difficultyBeatmap.GetType().FullName}) {difficultyBeatmap.SerializedName()} {gameMode} {difficultyBeatmap.difficulty} {difficultyBeatmap.level.songName}");

            string startingGameModeName = difficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName;

            if (startingGameModeName == GameModeHelper.GENERATED_360DEGREE_MODE || startingGameModeName == GameModeHelper.GENERATED_90DEGREE_MODE)
            {
                Plugin.Log.Info($"Generating rotation events for {startingGameModeName}...");

                // Colors are not copied from standard mode for some reason? Enforce it here
                var mapCustomColors = difficultyBeatmap.level.environmentInfo?.colorScheme?.colorScheme;
                if (mapCustomColors != null && overrideColorScheme == null)
                {
                    Plugin.Log.Info($"Overriding custom colors with {mapCustomColors.environmentColor0} {mapCustomColors.environmentColor1}");
                    overrideColorScheme = mapCustomColors;
                }

                if (!generated.Contains(difficultyBeatmap))
                {
                    generated.Add(difficultyBeatmap);
                    Generator360 gen = new Generator360();
                    gen.WallGenerator = Config.Instance.EnableWallGenerator;
                    gen.OnlyOneSaber  = Config.Instance.OnlyOneSaber;

                    if (startingGameModeName == GameModeHelper.GENERATED_90DEGREE_MODE)
                    {
                        gen.LimitRotations      = Config.Instance.LimitRotations90;
                        gen.BottleneckRotations = Config.Instance.LimitRotations90 / 2;
                    }
                    else if (startingGameModeName == GameModeHelper.GENERATED_360DEGREE_MODE)
                    {
                        gen.LimitRotations      = Config.Instance.LimitRotations360;
                        gen.BottleneckRotations = Config.Instance.LimitRotations360 / 2;
                    }

                    gen.Generate(difficultyBeatmap);
                }
                else
                {
                    Plugin.Log.Info("Already generated rotation events");
                }
            }
        }
Esempio n. 10
0
        public void SongFinished(StandardLevelScenesTransitionSetupDataSO sender, LevelCompletionResults levelCompletionResults, IDifficultyBeatmap difficultyBeatmap, GameplayModifiers gameplayModifiers, bool practice)
        {
            if (Client.Instance.InRadioMode)
            {
                PluginUI.instance.radioFlowCoordinator.lastDifficulty = difficultyBeatmap;
                PluginUI.instance.radioFlowCoordinator.lastResults    = levelCompletionResults;
            }

            if (Config.Instance.SpectatorMode || Client.disableScoreSubmission || ScoreSubmission.Disabled || ScoreSubmission.ProlongedDisabled)
            {
                return;
            }

            PlayerDataModelSO _playerDataModel = Resources.FindObjectsOfTypeAll <PlayerDataModelSO>().First();

            _playerDataModel.currentLocalPlayer.playerAllOverallStatsData.soloFreePlayOverallStatsData.UpdateWithLevelCompletionResults(levelCompletionResults);
            _playerDataModel.Save();
            if (levelCompletionResults.levelEndStateType != LevelCompletionResults.LevelEndStateType.Failed && levelCompletionResults.levelEndStateType != LevelCompletionResults.LevelEndStateType.Cleared)
            {
                return;
            }

            PlayerDataModelSO.LocalPlayer currentLocalPlayer = _playerDataModel.currentLocalPlayer;
            bool                    cleared               = levelCompletionResults.levelEndStateType == LevelCompletionResults.LevelEndStateType.Cleared;
            string                  levelID               = difficultyBeatmap.level.levelID;
            BeatmapDifficulty       difficulty            = difficultyBeatmap.difficulty;
            BeatmapCharacteristicSO beatmapCharacteristic = difficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic;
            PlayerLevelStatsData    playerLevelStatsData  = currentLocalPlayer.GetPlayerLevelStatsData(levelID, difficulty, beatmapCharacteristic);
            bool                    newHighScore          = playerLevelStatsData.highScore < levelCompletionResults.score;

            playerLevelStatsData.IncreaseNumberOfGameplays();
            if (cleared)
            {
                playerLevelStatsData.UpdateScoreData(levelCompletionResults.score, levelCompletionResults.maxCombo, levelCompletionResults.fullCombo, levelCompletionResults.rank);
                Resources.FindObjectsOfTypeAll <PlatformLeaderboardsModel>().First().AddScore(difficultyBeatmap, levelCompletionResults.unmodifiedScore, gameplayModifiers);
            }
        }
Esempio n. 11
0
        private void SongDetail_didPressPlayButtonEvent(IBeatmapLevel level, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty)
        {
            _lastPlayedBeatmapLevel   = level;
            _lastPlayedCharacteristic = characteristic;
            _lastPlayedDifficulty     = difficulty;

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

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

            var songSpeed = GameplayModifiers.SongSpeed.Normal;

            if (_currentParameters.GameplayModifiers.Options.HasFlag(GameOptions.SlowSong))
            {
                songSpeed = GameplayModifiers.SongSpeed.Slower;
            }
            if (_currentParameters.GameplayModifiers.Options.HasFlag(GameOptions.FastSong))
            {
                songSpeed = GameplayModifiers.SongSpeed.Faster;
            }
            if (_currentParameters.GameplayModifiers.Options.HasFlag(GameOptions.SuperFastSong))
            {
                songSpeed = GameplayModifiers.SongSpeed.SuperFast;
            }

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

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

            //Disable scores if we need to
            if (((QualifierEvent.EventSettings)Event.Flags).HasFlag(QualifierEvent.EventSettings.DisableScoresaberSubmission))
            {
                BS_Utils.Gameplay.ScoreSubmission.DisableSubmission(SharedConstructs.Name);
            }

            SongUtils.PlaySong(level, characteristic, difficulty, playerData.overrideEnvironmentSettings, colorScheme, gameplayModifiers, playerSettings, SongFinished);
        }
Esempio n. 12
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(
                    "Solo",
                    loadedLevel.beatmapLevelData.GetDifficultyBeatmap(characteristic, difficulty),
                    loadedLevel,
                    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("_coverImage", level.GetField <Sprite>("_coverImage"));
                    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})");
            }
        }
Esempio n. 13
0
        public void StartLevel(BeatmapLevelSO song, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, GameplayModifiers modifiers)
        {
            if (Connected && NetworkClient != null)
            {
#if DEBUG
                Misc.Logger.Info("Starting level...");
#endif
                NetOutgoingMessage outMsg = NetworkClient.CreateMessage();
                outMsg.Write((byte)CommandType.StartLevel);

                new StartLevelInfo(difficulty, modifiers, characteristic.serializedName).AddToMessage(outMsg);
                SongInfo selectedSong = new SongInfo(song);
                selectedSong.songDuration = selectedSong.songDuration / modifiers.songSpeedMul;
                selectedSong.AddToMessage(outMsg);

                NetworkClient.SendMessage(outMsg, NetDeliveryMethod.ReliableOrdered, 0);
            }
        }
Esempio n. 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!");
            }
        }
Esempio n. 15
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)
        {
            base.Client_PlaySong(desiredLevel, desiredCharacteristic, desiredDifficulty, gameplayModifiers, playerSpecificSettings, overrideEnvironmentSettings, colorScheme, useFloatingScoreboard, useSync, disablePause);

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

            //Reset score
            (Plugin.client.SelfObject as Player).Score    = 0;
            (Plugin.client.SelfObject as Player).Accuracy = 0;
            var playerUpdate = new Event
            {
                Type          = Event.Types.EventType.PlayerUpdated,
                ChangedObject = Google.Protobuf.WellKnownTypes.Any.Pack(Plugin.client.SelfObject as IMessage)
            };

            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);
            });
        }
        private void PacketReceived(NetIncomingMessage msg)
        {
            CommandType commandType = (CommandType)msg.ReadByte();

            if (!joined)
            {
                if (commandType == CommandType.JoinRoom)
                {
                    switch (msg.ReadByte())
                    {
                    case 0:
                    {
                        Client.Instance.playerInfo.playerState = PlayerState.DownloadingSongs;
                        Client.Instance.RequestRoomInfo();
                        Client.Instance.SendPlayerInfo();
                        joined = true;
                        InGameOnlineController.Instance.needToSendUpdates = true;
                    }
                    break;

                    case 1:
                    {
                        _roomNavigationController.DisplayError("Unable to join room!\nRoom not found");
                    }
                    break;

                    case 2:
                    {
                        _roomNavigationController.DisplayError("Unable to join room!\nIncorrect password");
                    }
                    break;

                    case 3:
                    {
                        _roomNavigationController.DisplayError("Unable to join room!\nToo much players");
                    }
                    break;

                    default:
                    {
                        _roomNavigationController.DisplayError("Unable to join room!\nUnknown error");
                    }
                    break;
                    }
                }
            }
            else
            {
                try
                {
                    switch (commandType)
                    {
                    case CommandType.GetRoomInfo:
                    {
                        Client.Instance.playerInfo.playerState = PlayerState.Room;

                        roomInfo = new RoomInfo(msg);

                        Client.Instance.isHost = Client.Instance.playerInfo.Equals(roomInfo.roomHost);

                        UpdateUI(roomInfo.roomState);
                    }
                    break;

                    case CommandType.SetSelectedSong:
                    {
                        if (msg.LengthBytes < 16)
                        {
                            roomInfo.roomState    = RoomState.SelectingSong;
                            roomInfo.selectedSong = null;

                            PreviewPlayer.CrossfadeToDefault();

                            UpdateUI(roomInfo.roomState);

                            if (songToDownload != null)
                            {
                                songToDownload.songQueueState          = SongQueueState.Error;
                                Client.Instance.playerInfo.playerState = PlayerState.Room;
                            }
                        }
                        else
                        {
                            roomInfo.roomState = RoomState.Preparing;
                            SongInfo selectedSong = new SongInfo(msg);
                            roomInfo.selectedSong = selectedSong;

                            if (songToDownload != null)
                            {
                                songToDownload.songQueueState = SongQueueState.Error;
                            }

                            UpdateUI(roomInfo.roomState);
                        }
                    }
                    break;

                    case CommandType.TransferHost:
                    {
                        roomInfo.roomHost      = new PlayerInfo(msg);
                        Client.Instance.isHost = Client.Instance.playerInfo.Equals(roomInfo.roomHost);

                        if (Client.Instance.playerInfo.playerState == PlayerState.DownloadingSongs)
                        {
                            return;
                        }

                        UpdateUI(roomInfo.roomState);
                    }
                    break;

                    case CommandType.StartLevel:
                    {
                        if (Client.Instance.playerInfo.playerState == PlayerState.DownloadingSongs)
                        {
                            return;
                        }

                        lastSelectedSong = "";

                        Client.Instance.playerInfo.playerComboBlocks = 0;
                        Client.Instance.playerInfo.playerCutBlocks   = 0;
                        Client.Instance.playerInfo.playerEnergy      = 0f;
                        Client.Instance.playerInfo.playerScore       = 0;

                        byte     difficulty = msg.ReadByte();
                        SongInfo songInfo   = new SongInfo(msg);

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

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

                            if (Config.Instance.SpectatorMode)
                            {
                                Client.Instance.playerInfo.playerState = PlayerState.Spectating;
                                gameplayModifiers.noFail = true;
                            }
                            else
                            {
                                Client.Instance.playerInfo.playerState = PlayerState.Game;
                                gameplayModifiers.noFail = roomInfo.noFail;
                            }

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

                            roomInfo.roomState = RoomState.InGame;

                            Client.Instance.MessageReceived -= PacketReceived;

                            LevelSO            level             = _levelCollection.levels.First(x => x.levelID.StartsWith(songInfo.levelId));
                            IDifficultyBeatmap difficultyBeatmap = level.GetDifficultyBeatmap((BeatmapDifficulty)difficulty);

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

                            Client.Instance.MessageReceived -= PacketReceived;
                            menuSceneSetupData.StartStandardLevel(difficultyBeatmap, gameplayModifiers, playerSettings, null, null, (StandardLevelSceneSetupDataSO sender, LevelCompletionResults levelCompletionResults) => { InGameOnlineController.Instance.SongFinished(sender, levelCompletionResults, difficultyBeatmap, gameplayModifiers, false); });
                            return;
                        }
                        else
                        {
                            Logger.Error("SceneSetupData is null!");
                        }
                    }
                    break;

                    case CommandType.LeaveRoom:
                    {
                        LeaveRoom();
                    }
                    break;

                    case CommandType.UpdatePlayerInfo:
                    {
                        if (roomInfo != null)
                        {
                            if (roomInfo.roomState != RoomState.SelectingSong)
                            {
                                float currentTime = msg.ReadFloat();
                                float totalTime   = msg.ReadFloat();

                                int playersCount = msg.ReadInt32();

                                List <PlayerInfo> playerInfos = new List <PlayerInfo>();
                                for (int j = 0; j < playersCount; j++)
                                {
                                    try
                                    {
                                        playerInfos.Add(new PlayerInfo(msg));
                                    }
                                    catch (Exception e)
                                    {
#if DEBUG
                                        Misc.Logger.Exception($"Unable to parse PlayerInfo! Excpetion: {e}");
#endif
                                    }
                                }

                                switch (roomInfo.roomState)
                                {
                                case RoomState.InGame:
                                    playerInfos = playerInfos.Where(x => x.playerScore > 0 && x.playerState == PlayerState.Game).ToList();
                                    UpdateLeaderboard(playerInfos, currentTime, totalTime, false);
                                    break;

                                case RoomState.Results:
                                    playerInfos = playerInfos.Where(x => x.playerScore > 0 && (x.playerState == PlayerState.Game || x.playerState == PlayerState.Room)).ToList();
                                    UpdateLeaderboard(playerInfos, currentTime, totalTime, true);
                                    break;

                                case RoomState.Preparing:
                                    _roomManagementViewController.UpdatePlayerList(playerInfos);
                                    break;
                                }
                            }
                        }
                    }
                    break;

                    case CommandType.PlayerReady:
                    {
                        int playersReady = msg.ReadInt32();
                        int playersTotal = msg.ReadInt32();

                        if (roomInfo.roomState == RoomState.Preparing && _difficultySelectionViewController != null)
                        {
                            _difficultySelectionViewController.SetPlayersReady(playersReady, playersTotal);
                        }
                    }
                    break;

                    case CommandType.Disconnect:
                    {
                        InGameOnlineController.Instance.needToSendUpdates = false;
                        if (msg.LengthBytes > 3)
                        {
                            string reason = msg.ReadString();

                            PopAllViewControllers(_roomNavigationController);
                            InGameOnlineController.Instance.DestroyAvatars();
                            PreviewPlayer.CrossfadeToDefault();
                            joined           = false;
                            lastSelectedSong = "";

                            _roomNavigationController.DisplayError(reason);
                        }
                        else
                        {
                            _roomNavigationController.DisplayError("ServerHub refused connection!");
                        }
                    }
                    break;
                    }
                }catch (Exception e)
                {
                    Logger.Exception("Unable to parse packet!");
                    if (msg != null)
                    {
                        Logger.Exception($"Packet={commandType}, DataLength={msg.LengthBytes}");
                    }
                    Logger.Exception(e.ToString());
                }
            }
        }
        public void StartLevel(IPreviewBeatmapLevel song, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, GameplayModifiers modifiers)
        {
            if (connected && networkClient != null)
            {
                Plugin.log.Debug("Starting level...");

                NetOutgoingMessage outMsg = networkClient.CreateMessage();
                outMsg.Write((byte)CommandType.StartLevel);

                new LevelOptionsInfo(difficulty, modifiers, characteristic.serializedName).AddToMessage(outMsg);
                SongInfo selectedSong = new SongInfo(song);
                selectedSong.songDuration = selectedSong.songDuration / modifiers.songSpeedMul;
                selectedSong.AddToMessage(outMsg);

                networkClient.SendMessage(outMsg, NetDeliveryMethod.ReliableOrdered, 0);
            }
        }
Esempio n. 18
0
        private static void StartLevel(IBeatmapLevel beatmapLevel, CustomPreviewBeatmapLevel beatmap, BeatmapDifficulty difficulty)
        {
            Logger.log.Info("Starting level");

            MenuTransitionsHelper menuSceneSetupData = Resources.FindObjectsOfTypeAll <MenuTransitionsHelper>().FirstOrDefault();
            PlayerData            playerSettings     = Resources.FindObjectsOfTypeAll <PlayerDataModel>().FirstOrDefault().playerData;

            var gamePlayModifiers = new GameplayModifiers();

            gamePlayModifiers.IsWithoutModifiers();

            IBeatmapLevel           level           = beatmapLevel;
            BeatmapCharacteristicSO characteristics = beatmap.previewDifficultyBeatmapSets[0].beatmapCharacteristic;
            IDifficultyBeatmap      levelDifficulty = BeatmapLevelDataExtensions.GetDifficultyBeatmap(level.beatmapLevelData, characteristics, difficulty);



            menuSceneSetupData.StartStandardLevel(
                "Random",
                levelDifficulty,
                playerSettings.overrideEnvironmentSettings.overrideEnvironments ? playerSettings.overrideEnvironmentSettings : null,
                playerSettings.colorSchemesSettings.overrideDefaultColors ? playerSettings.colorSchemesSettings.GetSelectedColorScheme() : null,
                gamePlayModifiers,
                playerSettings.playerSpecificSettings,
                playerSettings.practiceSettings,
                "Exit",
                false,
                () => { },
                (StandardLevelScenesTransitionSetupDataSO sceneTransition, LevelCompletionResults results) =>
            {
                bool newHighScore = false;

                var mainFlowCoordinator       = Resources.FindObjectsOfTypeAll <MainFlowCoordinator>().First();
                RandomSongMenu randomSongMenu = BeatSaberUI.CreateFlowCoordinator <RandomSongMenu>();

                if (results.levelEndAction == LevelCompletionResults.LevelEndAction.Restart)
                {
                    Logger.log.Info("Restarting level");
                    return;
                }

                switch (results.levelEndStateType)
                {
                case LevelCompletionResults.LevelEndStateType.None:
                    break;

                case LevelCompletionResults.LevelEndStateType.Cleared:
                    UploadScore(levelDifficulty, results, out newHighScore);
                    randomSongMenu.Show(beatmap, difficulty, levelDifficulty, results, newHighScore);
                    Logger.log.Info("Showing menu");
                    break;

                case LevelCompletionResults.LevelEndStateType.Failed:
                    Logger.log.Info("Showing menu");
                    randomSongMenu.Show(beatmap, difficulty, levelDifficulty, results, newHighScore);
                    break;

                default:
                    break;
                }
            });
        }
Esempio n. 19
0
 public GameplayModifiersWrapper(GameplayModifiers modifiers)
 {
     _modifiers = modifiers;
 }
Esempio n. 20
0
        public static void HandleSongSelected(IPreviewBeatmapLevel previewBeatmapLevel, BeatmapDifficulty beatmapDifficulty,
                                              BeatmapCharacteristicSO beatmapCharacteristic, GameplayModifiers gameplayModifiers)
        {
            if (!MpLobbyConnectionTypePatch.IsPartyHost)
            {
                return;
            }

            _level      = previewBeatmapLevel;
            _difficulty = beatmapDifficulty;

            HandleUpdate();
        }
Esempio n. 21
0
        public 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";

                gamePause       = FindFirstOrDefault <GamePause>();
                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>();

                if (gameplayManager.GetType() == typeof(StandardLevelGameplayManager))
                {
                    Plugin.log.Info("Standard Level loaded");
                    standardLevelGameplayManager = FindFirstOrDefault <StandardLevelGameplayManager>();
                    // public event Action StandardLevelGameplayManager#levelFailedEvent;
                    standardLevelGameplayManager.levelFailedEvent += OnLevelFailed;
                    // public event Action StandardLevelGameplayManager#levelFinishedEvent;
                    standardLevelGameplayManager.levelFinishedEvent += OnLevelFinished;
                }
                else if (gameplayManager.GetType() == typeof(MissionLevelGameplayManager))
                {
                    Plugin.log.Info("Mission Level loaded");
                    missionLevelGameplayManager = FindFirstOrDefault <MissionLevelGameplayManager>();
                    // public event Action StandardLevelGameplayManager#levelFailedEvent;
                    missionLevelGameplayManager.levelFailedEvent += OnLevelFailed;
                    // public event Action StandardLevelGameplayManager#levelFinishedEvent;
                    missionLevelGameplayManager.levelFinishedEvent += OnLevelFinished;
                }

                gameplayCoreSceneSetupData = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData;

                // Register event listeners
                // public event Action GamePause#didPauseEvent;
                gamePause.didPauseEvent += OnGamePause;
                // public event Action GamePause#didResumeEvent;
                gamePause.didResumeEvent += 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;
                // 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;
                // 13 is a magical number for the length of "custom_level_"
                gameStatus.songHash       = level.levelID.StartsWith("custom_level_") && !level.levelID.EndsWith(" WIP") ? level.levelID.Substring(13) : 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.notesCount      = diff.beatmapData.notesCount;
                gameStatus.bombsCount      = diff.beatmapData.bombsCount;
                gameStatus.obstaclesCount  = diff.beatmapData.obstaclesCount;
                gameStatus.environmentName = level.environmentInfo.sceneInfo.sceneName;

                gameStatus.maxScore = gameplayModifiersSO.MaxModifiedScoreForMaxRawScore(ScoreModel.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.playerHeight = playerSettings.playerHeight;
                gameStatus.sfxVolume    = playerSettings.sfxVolume;
                gameStatus.reduceDebris = playerSettings.reduceDebris;
                gameStatus.noHUD        = playerSettings.noTextsAndHuds;
                gameStatus.advancedHUD  = playerSettings.advancedHud;
                gameStatus.autoRestart  = playerSettings.autoRestart;

                statusManager.EmitStatusUpdate(ChangedProperties.AllButNoteCut, "songStart");
            }
        }
 protected virtual void Client_PlaySong(IPreviewBeatmapLevel level, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, GameplayModifiers gameOptions, PlayerSpecificSettings playerOptions, OverrideEnvironmentSettings environmentSettings, ColorScheme colors, bool floatingScoreboard, bool streamSync, bool disablePause)
 {
 }
 static void Prefix(StandardLevelScenesTransitionSetupDataSO __instance, IDifficultyBeatmap difficultyBeatmap, 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;
 }
Esempio n. 24
0
        protected override void Client_PacketRecieved(Packet packet)
        {
            base.Client_PacketRecieved(packet);

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

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

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

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

                var gameplayModifiers = new GameplayModifiers();
                gameplayModifiers.batteryEnergy      = playSong.GameplayModifiers.Options.HasFlag(GameOptions.BatteryEnergy);
                gameplayModifiers.disappearingArrows = playSong.GameplayModifiers.Options.HasFlag(GameOptions.DisappearingArrows);
                gameplayModifiers.failOnSaberClash   = playSong.GameplayModifiers.Options.HasFlag(GameOptions.FailOnClash);
                gameplayModifiers.fastNotes          = playSong.GameplayModifiers.Options.HasFlag(GameOptions.FastNotes);
                gameplayModifiers.ghostNotes         = playSong.GameplayModifiers.Options.HasFlag(GameOptions.GhostNotes);
                gameplayModifiers.instaFail          = playSong.GameplayModifiers.Options.HasFlag(GameOptions.InstaFail);
                gameplayModifiers.noBombs            = playSong.GameplayModifiers.Options.HasFlag(GameOptions.NoBombs);
                gameplayModifiers.noFail             = playSong.GameplayModifiers.Options.HasFlag(GameOptions.NoFail);
                gameplayModifiers.noObstacles        = playSong.GameplayModifiers.Options.HasFlag(GameOptions.NoObstacles);
                gameplayModifiers.noArrows           = playSong.GameplayModifiers.Options.HasFlag(GameOptions.NoArrows);

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

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

                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);

                    Logger.Debug($"SENT DOWNLOADED SIGNAL {(playerUpdate.ChangedObject as Player).DownloadState}");
                };

                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 <bool> loadSongAction = (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));

                                Logger.Debug($"SENT DOWNLOADED SIGNAL {(playerUpdated.ChangedObject as Player).DownloadState}");
                            }
                        };

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

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

                        Logger.Debug($"SENT DOWNLOAD SIGNAL {(playerUpdate.ChangedObject as Player).DownloadState}");

                        SongDownloader.DownloadSong(loadSong.LevelId, songDownloaded: loadSongAction, downloadProgressChanged: (progress) => Logger.Debug($"DOWNLOAD PROGRESS: {progress}"));
                    }
                }
            }
            else if (packet.Type == PacketType.File)
            {
                File file = packet.SpecificPacket as File;
                if (file.Intention == File.Intentions.SetPngToShowWhenTriggered)
                {
                    var pngBytes = file.Compressed ? CompressionUtils.Decompress(file.Data) : file.Data;
                    ScreenOverlay.Instance.SetPngBytes(pngBytes);
                }
                else if (file.Intention == 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
                }));
            }
        }
Esempio n. 25
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);
                practiceSettings.songSpeedMul = modifiers.songSpeedMul;

                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), false, () => {}, (StandardLevelScenesTransitionSetupDataSO sender, LevelCompletionResults levelCompletionResults) => { InGameOnlineController.Instance.SongFinished(sender, levelCompletionResults, difficultyBeatmap, modifiers, (practiceSettings != null)); });
                return;
            }
            else
            {
                Misc.Logger.Error("SceneSetupData is null!");
            }
        }
Esempio n. 26
0
 public static bool HasPositiveModifiers(GameplayModifiers modifiers)
 {
     return(modifiers.disappearingArrows ||
            modifiers.ghostNotes ||
            modifiers.songSpeed == GameplayModifiers.SongSpeed.Faster);
 }
Esempio n. 27
0
        public async void HandleSongStart()
        {
            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 = FindFirstOrDefault <ScoreController>();
            gameplayManager = FindFirstOrDefaultOptional <StandardLevelGameplayManager>() as MonoBehaviour ?? FindFirstOrDefaultOptional <MissionLevelGameplayManager>();
            beatmapObjectCallbackController  = FindFirstOrDefault <BeatmapObjectCallbackController>();
            gameplayModifiersSO              = FindFirstOrDefault <GameplayModifiersModelSO>();
            audioTimeSyncController          = FindFirstOrDefault <AudioTimeSyncController>();
            playerHeadAndObstacleInteraction = (PlayerHeadAndObstacleInteraction)scoreControllerHeadAndObstacleInteractionField.GetValue(scoreController);
            gameSongController = FindFirstOrDefault <GameSongController>();
            gameEnergyCounter  = FindFirstOrDefault <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 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;
            // 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;
            gameStatus.mode      = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData.difficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName;

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

            float songSpeedMul = gameplayModifiers.songSpeedMul;

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

            // Generate NoteData to id mappings for backwards compatiblity with <1.12.1
            noteToIdMapping = new NoteData[diff.beatmapData.cuttableNotesType + diff.beatmapData.bombsCount];
            lastNoteId      = 0;

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

            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;
            // 13 is "custom_level_" and 40 is the magic number for the length of the SHA-1 hash
            gameStatus.songHash       = level.levelID.StartsWith("custom_level_") && !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.notesCount      = diff.beatmapData.cuttableNotesType;
            gameStatus.bombsCount      = diff.beatmapData.bombsCount;
            gameStatus.obstaclesCount  = diff.beatmapData.obstaclesCount;
            gameStatus.environmentName = level.environmentInfo.sceneInfo.sceneName;

            try {
                // From https://support.unity3d.com/hc/en-us/articles/206486626-How-can-I-get-pixels-from-unreadable-textures-
                var texture   = (await level.GetCoverImageAsync(CancellationToken.None)).texture;
                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();

            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.staticLights = playerSettings.staticLights;
            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;

            statusManager.EmitStatusUpdate(ChangedProperties.AllButNoteCut, "songStart");
        }
Esempio n. 28
0
 public static float GetModifiedAcc(float accuracy, GameplayModifiersModelSO modifiersModel, GameplayModifiers modifiers)
 {
     return(modifiersModel.GetTotalMultiplier(modifiers) * accuracy);
 }
Esempio n. 29
0
        static bool Prefix(ref string userId, ref BeatmapIdentifierNetSerializable beatmapId, ref GameplayModifiers gameplayModifiers, ref float startTime, LobbyGameStateController __instance)
        {
            Plugin.Log?.Debug($"LobbyGameStateController.HandleMenuRpcManagerStartedLevel");

            if (SongCore.Loader.GetLevelById(beatmapId.levelID) != null)
            {
                Plugin.Log?.Debug($"Level is loaded.");
            }
            LobbyGameStateController = __instance;
            LastUserId = userId;
            return(true);
        }
 public CustomGameplayModifiers(GameplayModifiers gameplayModifiers) :
     base(gameplayModifiers.demoNoFail, gameplayModifiers.demoNoObstacles, gameplayModifiers.energyType, gameplayModifiers.noFail, gameplayModifiers.instaFail,
          gameplayModifiers.failOnSaberClash, gameplayModifiers.enabledObstacleType, gameplayModifiers.noBombs, gameplayModifiers.fastNotes,
          gameplayModifiers.strictAngles, gameplayModifiers.disappearingArrows, gameplayModifiers.songSpeed, gameplayModifiers.noArrows, gameplayModifiers.ghostNotes)
 {
 }