Ejemplo n.º 1
0
        private void Init(CountersData data)
        {
            _scoreController = data.ScoreController;
            PlayerDataModelSO player = data.PlayerData;

            gameplayModsModel = data.ModifiersData;
            gameplayMods      = data.PlayerData.playerData.gameplayModifiers;
            IDifficultyBeatmap beatmap = data.GCSSD.difficultyBeatmap;

            stats = player.playerData.GetPlayerLevelStatsData(
                beatmap.level.levelID, beatmap.difficulty, beatmap.parentDifficultyBeatmapSet.beatmapCharacteristic);
            int maxRawScore = ScoreController.MaxRawScoreForNumberOfNotes(beatmap.beatmapData.notesCount);

            _maxPossibleScore = Mathf.RoundToInt(maxRawScore * gameplayModsModel.GetTotalMultiplier(gameplayMods));
            beginningPB       = stats.highScore / (float)_maxPossibleScore;
            highScore         = stats.highScore;

            Vector3 position = CountersController.DeterminePosition(gameObject, settings.Position, settings.Distance);

            TextHelper.CreateText(out _PbTrackerText, position);
            _PbTrackerText.fontSize  = settings.TextSize;
            _PbTrackerText.color     = Color.white;
            _PbTrackerText.alignment = TextAlignmentOptions.Center;

            _scoreController.scoreDidChangeEvent += UpdateScore;

            SetPersonalBest(beginningPB);

            if (settings.UnderScore)
            {
                StartCoroutine(WaitForScoreCounter());
            }
        }
Ejemplo n.º 2
0
        public override void CounterInit()
        {
            modifiersModel = SCGameplayModsModel(ref scoreController);
            IDifficultyBeatmap beatmap = data.difficultyBeatmap;
            int maxRawScore            = ScoreModel.MaxRawScoreForNumberOfNotes(noteCountProcessor.NoteCount);

            maxPossibleScore = ScoreModel.GetModifiedScoreForGameplayModifiersScoreMultiplier(maxRawScore,
                                                                                              modifiersModel.GetTotalMultiplier(data.gameplayModifiers));
            stats     = playerDataModel.playerData.GetPlayerLevelStatsData(beatmap);
            highScore = stats.highScore;

            if (scoreConfig.Enabled && Settings.UnderScore)
            {
                HUDCanvas scoreCanvas = CanvasUtility.GetCanvasSettingsFromID(scoreConfig.CanvasID);
                counter = CanvasUtility.CreateTextFromSettings(scoreConfig, SCORE_COUNTER_OFFSET * (3f / scoreCanvas.PositionScale));
            }
            else
            {
                counter = CanvasUtility.CreateTextFromSettings(Settings);
            }
            counter.alignment = TextAlignmentOptions.Top;
            counter.fontSize  = Settings.TextSize;

            pbRatio = (float)highScore / maxPossibleScore;

            SetPersonalBest((float)highScore / maxPossibleScore);
            ScoreUpdated(0);
        }
Ejemplo n.º 3
0
        public override void CounterInit()
        {
            ColorUtility.TryParseHtmlString("#FFA500", out orange);

            modifiersModel = SCGameplayModsModel(ref scoreController);
            IDifficultyBeatmap beatmap = data.difficultyBeatmap;
            int maxRawScore            = ScoreModel.MaxRawScoreForNumberOfNotes(beatmap.beatmapData.notesCount);

            maxPossibleScore = ScoreModel.GetModifiedScoreForGameplayModifiersScoreMultiplier(maxRawScore,
                                                                                              modifiersModel.GetTotalMultiplier(data.gameplayModifiers));
            stats     = playerDataModel.playerData.GetPlayerLevelStatsData(beatmap);
            highScore = stats.highScore;

            if (scoreConfig.Enabled && Settings.UnderScore)
            {
                counter = CanvasUtility.CreateTextFromSettings(scoreConfig, SCORE_COUNTER_OFFSET);
            }
            else
            {
                counter = CanvasUtility.CreateTextFromSettings(Settings);
            }
            counter.alignment = TextAlignmentOptions.Top;
            counter.fontSize  = Settings.TextSize;

            SetPersonalBest((float)highScore / maxPossibleScore);
        }
Ejemplo n.º 4
0
        // Currently only used for modifiers, but could be useful for anything requiring level selection to be loaded
        internal void OnFirstLoad()
        {
            // Modifiers
            var gameplayModifiersPanelController = Resources.FindObjectsOfTypeAll <GameplayModifiersPanelController>().FirstOrDefault();

            _modifiersModel = Resources.FindObjectsOfTypeAll <GameplayModifiersModelSO>().First();
            _modifiers      = gameplayModifiersPanelController.GetPrivateField <GameplayModifiers>("_gameplayModifiers");
        }
Ejemplo n.º 5
0
 public CountersData()
 {
     ScoreController         = Resources.FindObjectsOfTypeAll <ScoreController>().First();
     PlayerController        = Resources.FindObjectsOfTypeAll <PlayerController>().First();
     AudioTimeSyncController = Resources.FindObjectsOfTypeAll <AudioTimeSyncController>().First();
     PlayerData    = Resources.FindObjectsOfTypeAll <PlayerDataModelSO>().First();
     ModifiersData = Resources.FindObjectsOfTypeAll <GameplayModifiersModelSO>().First();
     GCSSD         = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData; //By the time all of these load, so should GCSSD.
 }
Ejemplo n.º 6
0
 public CountersData()
 {
     BOM                     = Resources.FindObjectsOfTypeAll <BeatmapObjectManager>().First();
     ScoreController         = Resources.FindObjectsOfTypeAll <ScoreController>().First();
     PlayerController        = Resources.FindObjectsOfTypeAll <PlayerController>().First();
     AudioTimeSyncController = Resources.FindObjectsOfTypeAll <AudioTimeSyncController>().First();
     PlayerData              = Resources.FindObjectsOfTypeAll <PlayerDataModel>().First();
     ModifiersData           = Resources.FindObjectsOfTypeAll <GameplayModifiersModelSO>().First();
     GCSSD                   = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData; //By the time all of these load, so should GCSSD.
     Is360Or90Level          = Resources.FindObjectsOfTypeAll <FlyingGameHUDRotation>().Any(x => x.isActiveAndEnabled);
 }
Ejemplo n.º 7
0
        IEnumerator InitControllers()
        {
            yield return(new WaitUntil(delegate() { return FindObjectOfType <ScoreController>() != null && FindObjectOfType <GameEnergyCounter>() != null; }));

            StandardLevelGameplayManager _gameManager = Resources.FindObjectsOfTypeAll <StandardLevelGameplayManager>().First();

            _gameplayModifiersSO = Resources.FindObjectsOfTypeAll <GameplayModifiersModelSO>().FirstOrDefault();

            if (_gameManager != null)
            {
                try
                {
                    if (ReflectionUtil.GetPrivateField <IPauseTrigger>(_gameManager, "_pauseTrigger") != null)
                    {
                        ReflectionUtil.GetPrivateField <IPauseTrigger>(_gameManager, "_pauseTrigger").pauseTriggeredEvent -= _gameManager.HandlePauseTriggered;
                        ReflectionUtil.GetPrivateField <IPauseTrigger>(_gameManager, "_pauseTrigger").pauseTriggeredEvent += ShowPauseMenu;
                    }

                    if (ReflectionUtil.GetPrivateField <VRPlatformHelper>(_gameManager, "_vrPlatformHelper") != null)
                    {
                        ReflectionUtil.GetPrivateField <VRPlatformHelper>(_gameManager, "_vrPlatformHelper").inputFocusWasCapturedEvent -= _gameManager.HandleInputFocusWasCaptured;
                        ReflectionUtil.GetPrivateField <VRPlatformHelper>(_gameManager, "_vrPlatformHelper").inputFocusWasCapturedEvent += ShowPauseMenu;
                    }
                }
                catch (Exception e)
                {
                    Data.Logger.Error(e.ToString());
                }
            }

            _scoreController  = FindObjectOfType <ScoreController>();
            _energyController = FindObjectOfType <GameEnergyCounter>();

            if (_scoreController != null)
            {
                _scoreController.scoreDidChangeEvent += ScoreChanged;
                _scoreController.noteWasCutEvent     += NoteWasCutEvent;
                _scoreController.comboDidChangeEvent += ComboDidChangeEvent;
                _scoreController.noteWasMissedEvent  += NoteWasMissedEvent;
            }

            if (_energyController != null)
            {
                _energyController.gameEnergyDidChangeEvent += EnergyDidChangeEvent;
            }

            _pauseMenuManager = FindObjectsOfType <PauseMenuManager>().First();

            if (_pauseMenuManager != null)
            {
                _pauseMenuManager.GetPrivateField <Button>("_restartButton").interactable = false;
            }
        }
Ejemplo n.º 8
0
        public SongData()
        {
            try
            {
                BOSC            = Resources.FindObjectsOfTypeAll <BeatmapObjectSpawnController>().First();
                GCSSD           = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData;
                modifierData    = Resources.FindObjectsOfTypeAll <GameplayModifiersModelSO>().First();
                playerData      = Resources.FindObjectsOfTypeAll <PlayerDataModel>().First();
                scoreController = Resources.FindObjectsOfTypeAll <ScoreController>().First();
            } catch (Exception)
            {
                Logger.log.Error("SongData couldn't be created. Did you start the tutorial ?");
                return;
            }

            if (UserIDFix.UserIDIsReady)
            {
                playerID = UserIDFix.UserID;
            }
            else
            {
                UserIDFix.UserIDReady += SetUserID;
            }

            songID         = GCSSD.difficultyBeatmap.level.levelID.Replace("custom_level_", "").Split('_')[0];
            songDifficulty = GCSSD.difficultyBeatmap.difficulty.ToString().ToLower();
            gameMode       = GCSSD.difficultyBeatmap.level.beatmapLevelData.difficultyBeatmapSets[0].beatmapCharacteristic.serializedName;

            songDifficultyRank = GCSSD.difficultyBeatmap.difficultyRank;
            songName           = GCSSD.difficultyBeatmap.level.songName;
            songArtist         = GCSSD.difficultyBeatmap.level.songAuthorName;
            songMapper         = GCSSD.difficultyBeatmap.level.levelAuthorName;

            WaitForAudioTimeSyncController();

            if (GCSSD.practiceSettings != null)
            {
                songDataType  = SongDataType.practice;
                songSpeed     = GCSSD.practiceSettings.songSpeedMul;
                songStartTime = GCSSD.practiceSettings.startSongTime;
            }
            else
            {
                songDataType = SongDataType.replay;                         // We set it as a replay by default, then set it as a pass if IsNotAReplay() is called
                scoreController.scoreDidChangeEvent += IsNotAReplay;
            }

            dataCollector = new DataCollector();
            dataCollector.RegisterCollector(this);
        }
        protected override void DidActivate(bool firstActivation, bool addedToHierarchy, bool screenSystemEnabling)
        {
            if (firstActivation)
            {
                SetTitle("Custom Campaigns");
                showBackButton = true;

                _campaignFlowCoordinator           = Resources.FindObjectsOfTypeAll <CampaignFlowCoordinator>().First();
                _missionMapAnimationController     = Resources.FindObjectsOfTypeAll <MissionMapAnimationController>().First();
                _missionNodesManager               = Resources.FindObjectsOfTypeAll <MissionNodesManager>().First();
                _missionStagesManager              = Resources.FindObjectsOfTypeAll <MissionStagesManager>().First();
                _missionConnectionsGenerator       = Resources.FindObjectsOfTypeAll <MissionConnectionsGenerator>().First();
                _missionSelectionMapViewController = Resources.FindObjectsOfTypeAll <MissionSelectionMapViewController>().First();
                _missionNodeSelectionManager       = Resources.FindObjectsOfTypeAll <MissionNodeSelectionManager>().First();
                _missionLevelDetailViewController  = Resources.FindObjectsOfTypeAll <MissionLevelDetailViewController>().First();
                _missionResultsViewController      = Resources.FindObjectsOfTypeAll <MissionResultsViewController>().First();

                _playButton    = _missionLevelDetailViewController.GetPrivateField <Button>("_playButton");
                _mapScrollView = _missionSelectionMapViewController.GetPrivateField <ScrollView>("_mapScrollView");
                _mapScrollViewItemsVisibilityController = _mapScrollView.GetComponent <ScrollViewItemsVisibilityController>();
                _backgroundImage = _mapScrollView.GetComponentsInChildren <Image>().First(x => x.name == "Map");
                _missionSelectionNavigationController = _campaignFlowCoordinator.GetPrivateField <MissionSelectionNavigationController>("_missionSelectionNavigationController");
                _gameplayModifierInfoListItemsList    = _missionLevelDetailViewController.GetPrivateField <GameplayModifierInfoListItemsList>("_gameplayModifierInfoListItemsList");
                _modifiersPanelGO       = _missionLevelDetailViewController.GetPrivateField <GameObject>("_modifiersPanelGO");
                _gameplayModifiersModel = _missionLevelDetailViewController.GetPrivateField <GameplayModifiersModelSO>("_gameplayModifiersModel");

                BSMLParser.instance.Parse(Utilities.GetResourceContent(Assembly.GetExecutingAssembly(), "BeatSaberCustomCampaigns.Views.challenge-detail.bsml"), _missionLevelDetailViewController.gameObject, this);

                _campaignProgressModel = _campaignFlowCoordinator.GetPrivateField <CampaignProgressModel>("_campaignProgressModel");

                _campaignListViewController                  = BeatSaberUI.CreateViewController <CampaignListViewController>();
                _campaignDetailViewController                = BeatSaberUI.CreateViewController <CampaignDetailViewController>();
                _campaignTotalLeaderboardViewController      = BeatSaberUI.CreateViewController <CampaignTotalLeaderboardViewController>();
                _campaignListNavigationController            = BeatSaberUI.CreateViewController <NavigationController>();
                _campaignListViewController.clickedCampaign += ShowDetails;
                _campaignDetailViewController.clickedPlay   += OpenCampaign;

                _campaignChallengeLeaderbaordViewController = BeatSaberUI.CreateViewController <CampaignChallengeLeaderboardViewController>();
                _unlockedItemsViewController = BeatSaberUI.CreateViewController <UnlockedItemsViewController>();
            }
            if (addedToHierarchy)
            {
                SetBaseCampaignEnabled(false);

                SetViewControllerToNavigationController(_campaignListNavigationController, _campaignListViewController);
                ProvideInitialViewControllers(_campaignListNavigationController);
            }
        }
Ejemplo n.º 10
0
        public void SetGameplayModifiers(GameplayModifiers modifiers)
        {
            if (_modifiersPanel != null)
            {
                _modifiersPanel.Init(modifiers);

                GameplayModifiersModelSO modifiersModel = Resources.FindObjectsOfTypeAll <GameplayModifiersModelSO>().First();

                var modifiersParams = modifiersModel.GetModifierParams(modifiers);

                foreach (GameplayModifierToggle gameplayModifierToggle in _modifiersPanel.GetPrivateField <GameplayModifierToggle[]>("_gameplayModifierToggles"))
                {
                    gameplayModifierToggle.toggle.isOn = modifiersParams.Contains(gameplayModifierToggle.gameplayModifier);
                }
            }
        }
Ejemplo n.º 11
0
        public static float CalculateMultiplier(GameplayModifiersModelSO gameplayModifiersModelSO, GameplayModifiers gameplayModifiers)
        {
            List <GameplayModifierParamsSO> modifierParams = gameplayModifiersModelSO.CreateModifierParamsList(gameplayModifiers);
            float multiplier = gameplayModifiersModelSO.GetTotalMultiplier(modifierParams, 1f);

            // ScoreSaber weights these multipliers differently
            if (gameplayModifiers.disappearingArrows)
            {
                multiplier += (DA_SS - DA_ORIGINAL);
            }
            if (gameplayModifiers.ghostNotes)
            {
                multiplier += (GN_SS - GN_ORIGINAL);
            }
            if (gameplayModifiers.songSpeed.Equals(GameplayModifiers.SongSpeed.Faster))
            {
                multiplier += (FS_SS - FS_ORIGINAL);
            }
            return(multiplier);
        }
 static bool Prefix(MissionLevelDetailViewController __instance, MissionNode ____missionNode, TextMeshProUGUI ____missionText, TextMeshProUGUI ____songNameText, TextMeshProUGUI ____difficultyText, TextMeshProUGUI ____characteristicsText, ObjectiveListItemsList ____objectiveListItems, GameplayModifiersModelSO ____gameplayModifiersModel, GameObject ____modifiersPanelGO, GameplayModifierInfoListItemsList ____gameplayModifierInfoListItemsList)
 {
     if (____missionNode.missionData is CustomMissionDataSO)
     {
         CustomMissionDataSO       missionData = (____missionNode.missionData as CustomMissionDataSO);
         CustomPreviewBeatmapLevel level       = missionData.customLevel;
         ____missionText.text = Localization.Get("CAMPAIGN_MISSION") + " " + ____missionNode.formattedMissionNodeName;
         if (level == null)
         {
             ____songNameText.text        = string.Format(Localization.Get("CAMPAIGN_SONG"), "SONG NOT FOUND");
             ____difficultyText.text      = string.Format(Localization.Get("CAMPAIGN_DIFFICULTY"), "NOT FOUND");
             ____characteristicsText.text = string.Format(Localization.Get("CAMPAIGN_TYPE"), "NOT FOUND");
         }
         else
         {
             ____songNameText.text        = string.Format(Localization.Get("CAMPAIGN_SONG"), level.songName);
             ____difficultyText.text      = string.Format(Localization.Get("CAMPAIGN_DIFFICULTY"), BeatmapDifficultyMethods.Name(missionData.beatmapDifficulty));
             ____characteristicsText.text = string.Format(Localization.Get("CAMPAIGN_TYPE"), Localization.Get(missionData.beatmapCharacteristic.characteristicNameLocalizationKey));
         }
         MissionObjective[] missionObjectives = missionData.missionObjectives;
         ____objectiveListItems.SetData((missionObjectives.Length == 0) ? 1 : missionObjectives.Length, delegate(int idx, ObjectiveListItem objectiveListItem)
         {
             if (idx == 0 && missionObjectives.Length == 0)
             {
                 objectiveListItem.title         = Localization.Get("CAMPAIGN_FINISH_LEVEL");
                 objectiveListItem.conditionText = "";
                 objectiveListItem.hideCondition = true;
             }
             else
             {
                 MissionObjective missionObjective = missionObjectives[idx];
                 if (missionObjective.type.noConditionValue)
                 {
                     objectiveListItem.title         = missionObjective.type.objectiveNameLocalized.Replace(" ", "\n");
                     objectiveListItem.hideCondition = true;
                 }
                 else
                 {
                     objectiveListItem.title         = missionObjective.type.objectiveNameLocalized;
                     objectiveListItem.hideCondition = false;
                     ObjectiveValueFormatterSO objectiveValueFormater = missionObjective.type.objectiveValueFormater;
                     objectiveListItem.conditionText = $"{MissionDataExtensions.Name(missionObjective.referenceValueComparisonType)} {objectiveValueFormater.FormatValue(missionObjective.referenceValue)}";
                 }
             }
         });
         List <GameplayModifierParamsSO> modifierParamsList = ____gameplayModifiersModel.GetModifierParams(missionData.gameplayModifiers);
         ____modifiersPanelGO.SetActive(modifierParamsList.Count > 0);
         ____gameplayModifierInfoListItemsList.SetData(modifierParamsList.Count, delegate(int idx, GameplayModifierInfoListItem gameplayModifierInfoListItem)
         {
             GameplayModifierParamsSO gameplayModifierParamsSO = modifierParamsList[idx];
             gameplayModifierInfoListItem.modifierIcon         = gameplayModifierParamsSO.icon;
             gameplayModifierInfoListItem.modifierName         = Localization.Get(gameplayModifierParamsSO.modifierNameLocalizationKey);
             gameplayModifierInfoListItem.modifierDescription  = Localization.Get(gameplayModifierParamsSO.descriptionLocalizationKey);
             gameplayModifierInfoListItem.showSeparator        = (idx != modifierParamsList.Count - 1);
         });
         return(false);
     }
     return(true);
 }
Ejemplo n.º 13
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");
            }
        }
Ejemplo n.º 14
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");
        }
Ejemplo n.º 15
0
        private void CleanUpSong()
        {
            statusManager.gameStatus.ResetMapInfo();
            statusManager.gameStatus.ResetPerformance();

            noteControllerMapping.Clear();

            // Release references for AfterCutScoreBuffers that don't resolve due to player leaving the map before finishing.
            foreach (var noteCutItem in noteCutMapping)
            {
                // CutScoreBuffers are pooled. Remove the event listener just in case it never fires the event.
                noteCutItem.Key.didFinishEvent.Remove(this);
            }
            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 (beatmapObjectManager != null)
            {
                beatmapObjectManager.noteWasSpawnedEvent -= OnNoteWasSpawned;
                beatmapObjectManager = 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;
            }

            if (gameplayModiferParamsList != null)
            {
                gameplayModiferParamsList = null;
            }
        }
Ejemplo n.º 16
0
 public static float GetModifiedAcc(float accuracy, GameplayModifiersModelSO modifiersModel, GameplayModifiers modifiers)
 {
     return(modifiersModel.GetTotalMultiplier(modifiers) * accuracy);
 }
        //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;
            }
        }
 static bool Prefix(MissionLevelDetailViewController __instance, MissionNode ____missionNode, LevelBar ____levelBar, ObjectiveListItemsList ____objectiveListItems, GameplayModifiersModelSO ____gameplayModifiersModel, GameObject ____modifiersPanelGO, GameplayModifierInfoListItemsList ____gameplayModifierInfoListItemsList)
 {
     if (____missionNode.missionData is CustomMissionDataSO)
     {
         CustomMissionDataSO       missionData = (____missionNode.missionData as CustomMissionDataSO);
         CustomPreviewBeatmapLevel level       = missionData.customLevel;
         if (level == null)
         {
             // TODO: Localization?
             ____levelBar.GetPrivateField <TextMeshProUGUI>("_songNameText").text   = "SONG NOT FOUND";
             ____levelBar.GetPrivateField <TextMeshProUGUI>("_difficultyText").text = "SONG NOT FOUND";
             ____levelBar.GetPrivateField <TextMeshProUGUI>("_authorNameText").text = "SONG NOT FOUND";
         }
         else
         {
             ____levelBar.Setup(level, missionData.beatmapCharacteristic, missionData.beatmapDifficulty);
         }
         MissionObjective[] missionObjectives = missionData.missionObjectives;
         ____objectiveListItems.SetData((missionObjectives.Length == 0) ? 1 : missionObjectives.Length, delegate(int idx, ObjectiveListItem objectiveListItem)
         {
             if (idx == 0 && missionObjectives.Length == 0)
             {
                 objectiveListItem.title         = Localization.Get("CAMPAIGN_FINISH_LEVEL");
                 objectiveListItem.conditionText = "";
                 objectiveListItem.hideCondition = true;
             }
             else
             {
                 MissionObjective missionObjective = missionObjectives[idx];
                 if (missionObjective.type.noConditionValue)
                 {
                     objectiveListItem.title         = missionObjective.type.objectiveNameLocalized.Replace(" ", "\n");
                     objectiveListItem.hideCondition = true;
                 }
                 else
                 {
                     objectiveListItem.title         = missionObjective.type.objectiveNameLocalized;
                     objectiveListItem.hideCondition = false;
                     ObjectiveValueFormatterSO objectiveValueFormater = missionObjective.type.objectiveValueFormater;
                     objectiveListItem.conditionText = $"{MissionDataExtensions.Name(missionObjective.referenceValueComparisonType)} {objectiveValueFormater.FormatValue(missionObjective.referenceValue)}";
                 }
             }
         });
         List <GameplayModifierParamsSO> modifierParamsList = ____gameplayModifiersModel.GetModifierParams(missionData.gameplayModifiers);
         ____modifiersPanelGO.SetActive(modifierParamsList.Count > 0);
         ____gameplayModifierInfoListItemsList.SetData(modifierParamsList.Count, delegate(int idx, GameplayModifierInfoListItem gameplayModifierInfoListItem)
         {
             GameplayModifierParamsSO gameplayModifierParamsSO = modifierParamsList[idx];
             gameplayModifierInfoListItem.modifierIcon         = gameplayModifierParamsSO.icon;
             gameplayModifierInfoListItem.hoverHintText        = Localization.Get(gameplayModifierParamsSO.modifierNameLocalizationKey) + " - " + Localization.Get(gameplayModifierParamsSO.descriptionLocalizationKey);
         });
         return(false);
     }
     return(true);
 }
Ejemplo n.º 19
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");
        }