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()); } }
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); }
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); }
// 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"); }
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. }
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); }
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; } }
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); } }
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); } } }
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); }
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"); } }
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"); }
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; } }
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); }
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"); }