public IEnumerator DoOnLevelStart() { yield return(new WaitUntil(() => standardLevelGameplayManager.GetField <StandardLevelGameplayManager.GameState>("_gameState") == StandardLevelGameplayManager.GameState.Playing)); yield return(new WaitUntil(() => Resources.FindObjectsOfTypeAll <GameEnergyCounter>().Any())); gameSongController = standardLevelGameplayManager.GetField <GameSongController>("_gameSongController"); gameEnergyCounter = Resources.FindObjectsOfTypeAll <GameEnergyCounter>().First(); //Prevent the gameEnergyCounter from invoking death by obstacle _oldObstacleEnergyDrainPerSecond = gameEnergyCounter.GetField <float>("_obstacleEnergyDrainPerSecond"); gameEnergyCounter.SetField("_obstacleEnergyDrainPerSecond", 0f); //Unhook the functions in the energy counter that watch note events, so we can peek inside the process beatmapObjectManager = gameEnergyCounter.GetField <BeatmapObjectManager>("_beatmapObjectManager"); beatmapObjectManager.noteWasMissedEvent -= gameEnergyCounter.HandleNoteWasMissedEvent; beatmapObjectManager.noteWasMissedEvent += beatmapObjectManager_noteWasMissedEvent; beatmapObjectManager.noteWasCutEvent -= gameEnergyCounter.HandleNoteWasCutEvent; beatmapObjectManager.noteWasCutEvent += beatmapObjectManager_noteWasCutEvent; //Unhook the level end event so we can reset everything before the level ends gameSongController.songDidFinishEvent -= standardLevelGameplayManager.HandleSongDidFinish; gameSongController.songDidFinishEvent += gameSongController_songDidFinishEvent; }
private void SceneManagerOnActiveSceneChanged(Scene arg0, Scene scene) { if (scene.buildIndex == 1) { if (SettingsObject == null) { var volumeSettings = Resources.FindObjectsOfTypeAll <VolumeSettingsController>().FirstOrDefault(); volumeSettings.gameObject.SetActive(false); SettingsObject = Object.Instantiate(volumeSettings.gameObject); SettingsObject.SetActive(false); volumeSettings.gameObject.SetActive(true); var volume = SettingsObject.GetComponent <VolumeSettingsController>(); ReflectionUtil.CopyComponent(volume, typeof(SimpleSettingsController), typeof(SpeedSettingsController), SettingsObject); Object.DestroyImmediate(volume); SettingsObject.GetComponentInChildren <TMP_Text>().text = "SPEED"; Object.DontDestroyOnLoad(SettingsObject); } } else { if (_mainGameSceneSetupData == null) { _mainGameSceneSetupData = Resources.FindObjectsOfTypeAll <MainGameSceneSetupData>().FirstOrDefault(); } if (_mainGameSceneSetupData == null || scene.buildIndex != 4) { return; } if (_lastLevelId != _mainGameSceneSetupData.levelId && !string.IsNullOrEmpty(_lastLevelId)) { TimeScale = 1; _lastLevelId = _mainGameSceneSetupData.levelId; } _lastLevelId = _mainGameSceneSetupData.levelId; _audioTimeSync = Resources.FindObjectsOfTypeAll <AudioTimeSyncController>().FirstOrDefault(); _audioTimeSync.forcedAudioSync = true; _songAudio = ReflectionUtil.GetPrivateField <AudioSource>(_audioTimeSync, "_audioSource"); Enabled = _mainGameSceneSetupData.gameplayOptions.noEnergy; var noteCutSoundEffectManager = Resources.FindObjectsOfTypeAll <NoteCutSoundEffectManager>().FirstOrDefault(); var noteCutSoundEffect = ReflectionUtil.GetPrivateField <NoteCutSoundEffect>(noteCutSoundEffectManager, "_noteCutSoundEffectPrefab"); _noteCutAudioSource = ReflectionUtil.GetPrivateField <AudioSource>(noteCutSoundEffect, "_audioSource"); var canvas = Resources.FindObjectsOfTypeAll <HorizontalLayoutGroup>().FirstOrDefault(x => x.name == "Buttons") .transform.parent; canvas.gameObject.AddComponent <SpeedSettingsCreator>(); TimeScale = TimeScale; gameSongController = Resources.FindObjectsOfTypeAll <GameSongController>().FirstOrDefault(); songObjectSpawnController = Resources.FindObjectsOfTypeAll <SongObjectSpawnController>().FirstOrDefault(); scoreController = Resources.FindObjectsOfTypeAll <ScoreController>().FirstOrDefault <ScoreController>(); scoresDict = new Dictionary <int, ScoreListItem>(); } }
public void OnActiveSceneChanged(Scene arg0, Scene scene) { _energyCounter = UnityEngine.Object.FindObjectOfType <GameEnergyCounter>(); _songController = UnityEngine.Object.FindObjectOfType <GameSongController>(); _gameplayManager = UnityEngine.Object.FindObjectOfType <GameplayManager>(); if (_energyCounter != null) { _oldEnergy = _energyCounter.energy; } }
public void Start() { // The goal now is to find the clip this scene will be playing. // For this, we find the single root gameObject (which is the gameObject // to which we are attached), // then we get its GameSongController to find the audio clip, // and its FlyingTextSpawner to display the lyrics. textSpawner = gameObject.GetComponentInChildren <FlyingTextSpawner>(); songController = gameObject.GetComponentInChildren <GameSongController>(); if (textSpawner == null || songController == null) { return; } audioClip = (AudioClip)SongFileField.GetValue(songController); // Clip found, now select the first song that has the same clip (using reference comparison). levelData = (from world in PersistentSingleton <GameDataModel> .instance.gameStaticData.worldsData from levelStaticData in world.levelsData from difficultyLevel in levelStaticData.difficultyLevels where ReferenceEquals(difficultyLevel.audioClip, audioClip) select levelStaticData).FirstOrDefault(); if (levelData == null) { Debug.Log("Corresponding song not found."); return; } // We found the matching song, we can get started. Debug.Log($"Corresponding song data found: {levelData.songName} by {levelData.authorName}."); // When this coroutine ends, it will call the given callback with a list // of all the subtitles we found, and allow us to react. // If no subs are found, the callback is not called. StartCoroutine(LyricsFetcher.GetLyrics(levelData.songName, levelData.authorName, subs => { SpawnText("Lyrics found", 3f); StartCoroutine(DisplayLyrics(subs)); })); }
public void Construct(PluginConfig config, Submission submission, AudioTimeSyncController audioTimeSyncController, BeatmapLevelsModel beatmapLevelsModel, GameplayCoreSceneSetupData gameplayCoreSceneSetupData, GameSongController gameSongController) { _config = config; _submission = submission; _audioTimeSyncController = audioTimeSyncController; _beatmapLevelsModel = beatmapLevelsModel; _gameplayCoreSceneSetupData = gameplayCoreSceneSetupData; _gameSongController = gameSongController; _random = new System.Random(); IBeatmapLevelPack beatmapLevelPack = _beatmapLevelsModel.GetLevelPackForLevelId(_gameplayCoreSceneSetupData.difficultyBeatmap.level.levelID); _previewBeatmapLevels = beatmapLevelPack.beatmapLevelCollection.beatmapLevels; }
private IEnumerator WaitForLoad() { bool loaded = false; while (!loaded) { songController = Resources.FindObjectsOfTypeAll <GameSongController>().FirstOrDefault(); if (songController == null) { Plugin.Log("Music Volume songController is null!", Plugin.LogLevel.DebugOnly); yield return(new WaitForSeconds(0.01f)); } else { Plugin.Log("Music Volume found songController!", Plugin.LogLevel.DebugOnly); loaded = true; } } LoadingDidFinishEvent(); }
public IEnumerator Start() { // The goal now is to find the clip this scene will be playing. // For this, we find the single root gameObject (which is the gameObject // to which we are attached), // then we get its GameSongController to find the audio clip, // and its FlyingTextSpawner to display the lyrics. if (Settings.VerboseLogging) { Debug.Log("[Beat Singer] Attached to scene."); Debug.Log($"[Beat Singer] Lyrics are enabled: {Settings.DisplayLyrics}."); } textSpawner = FindObjectOfType <FlyingTextSpawner>(); songController = FindObjectOfType <GameSongController>(); var sceneSetup = FindObjectOfType <GameplayCoreSceneSetup>(); if (songController == null || sceneSetup == null) { yield break; } if (textSpawner == null) { var installer = FindObjectOfType <EffectPoolsInstaller>(); var container = (Zenject.DiContainer)ContainerField.GetValue(installer); textSpawner = container.InstantiateComponentOnNewGameObject <FlyingTextSpawner>(); } var sceneSetupData = (GameplayCoreSceneSetupData)SceneSetupDataField.GetValue(sceneSetup); if (sceneSetupData == null) { yield break; } audio = (AudioTimeSyncController)AudioTimeSyncField.GetValue(songController); IBeatmapLevel level = sceneSetupData.difficultyBeatmap.level; List <Subtitle> subtitles = new List <Subtitle>(); Debug.Log($"[Beat Singer] Corresponding song data found: {level.songName} by {level.songAuthorName} ({(level.songSubName != null ? level.songSubName : "No sub-name")})."); if (LyricsFetcher.GetLocalLyrics(sceneSetupData.difficultyBeatmap.level.levelID, subtitles)) { Debug.Log("[Beat Singer] Found local lyrics."); Debug.Log($"[Beat Singer] These lyrics can be uploaded online using the ID: \"{level.GetLyricsHash()}\"."); // Lyrics found locally, continue with them. SpawnText("Lyrics found locally", 3f); } else { Debug.Log("[Beat Singer] Did not find local lyrics, trying online lyrics..."); // When this coroutine ends, it will call the given callback with a list // of all the subtitles we found, and allow us to react. // If no subs are found, the callback is not called. yield return(StartCoroutine(LyricsFetcher.GetOnlineLyrics(level, subtitles))); if (subtitles.Count != 0) { goto FoundOnlineLyrics; } yield return(StartCoroutine(LyricsFetcher.GetMusixmatchLyrics(level.songName, level.songAuthorName, subtitles))); if (subtitles.Count != 0) { goto FoundOnlineLyrics; } yield return(StartCoroutine(LyricsFetcher.GetMusixmatchLyrics(level.songName, level.songSubName, subtitles))); if (subtitles.Count != 0) { goto FoundOnlineLyrics; } yield break; FoundOnlineLyrics: SpawnText("Lyrics found online", 3f); } StartCoroutine(DisplayLyrics(subtitles)); }
public IEnumerator Start() { // The goal now is to find the clip this scene will be playing. // For this, we find the single root gameObject (which is the gameObject // to which we are attached), // then we get its GameSongController to find the audio clip, // and its FlyingTextSpawner to display the lyrics. textSpawner = FindObjectOfType <FlyingTextSpawner>(); songController = FindObjectOfType <GameSongController>(); if (textSpawner == null || songController == null) { yield break; } MainGameSceneSetup sceneSetup = FindObjectOfType <MainGameSceneSetup>(); if (sceneSetup == null) { yield break; } MainGameSceneSetupData sceneSetupData = SetupDataField.GetValue(sceneSetup) as MainGameSceneSetupData; if (sceneSetupData == null) { yield break; } List <Subtitle> subtitles = new List <Subtitle>(); if (LyricsFetcher.GetLocalLyrics(sceneSetupData.difficultyLevel.level.levelID, subtitles)) { // Lyrics found locally, continue with them. SpawnText("Lyrics found locally", 3f); } else { // Clip found, now select the first song that has the same clip (using reference comparison). IStandardLevel level = sceneSetupData.difficultyLevel.level; // We found the matching song, we can get started. Debug.Log($"Corresponding song data found: {level.songName} by {level.songAuthorName}."); // When this coroutine ends, it will call the given callback with a list // of all the subtitles we found, and allow us to react. // If no subs are found, the callback is not called. yield return(StartCoroutine(LyricsFetcher.GetOnlineLyrics(level.songName, level.songAuthorName, subtitles))); if (subtitles.Count == 0) { yield break; } SpawnText("Lyrics found online", 3f); } StartCoroutine(DisplayLyrics(subtitles)); }
private void SceneManagerOnActiveSceneChanged(Scene arg0, Scene scene) { try { this._playerController = FindObjectOfType <PlayerController>(); if (scene.buildIndex == 1) { IsLeftSaberOn = true; if (_beatmapObjectSpawnController != null) { _beatmapObjectSpawnController.noteWasCutEvent -= this.HandleNoteWasCutEvent; } if (_mainSettingsModel != null && stored) { StartCoroutine(RestoreNoEnergy()); } } if (scene.buildIndex == 5) { var _mainGameSceneSetup = FindObjectOfType <MainGameSceneSetup>(); this._gameSongController = FindObjectOfType <GameSongController>(); this._noteCutEffectSpawner = FindObjectOfType <NoteCutEffectSpawner>(); this._beatmapObjectSpawnController = FindObjectOfType <BeatmapObjectSpawnController>(); _noteCutHapticEffect = ReflectionUtil.GetPrivateField <NoteCutHapticEffect>(_noteCutEffectSpawner, "_noteCutHapticEffect"); _hapticFeedbackController = ReflectionUtil.GetPrivateField <HapticFeedbackController>(_noteCutHapticEffect, "_hapticFeedbackController"); _mainSettingsModel = ReflectionUtil.GetPrivateField <MainSettingsModel>(_hapticFeedbackController, "_mainSettingsModel"); _mainSettingsModel.controllersRumbleEnabled = true; this._mainGameSceneSetupData = ReflectionUtil.GetPrivateField <MainGameSceneSetupData>(_mainGameSceneSetup, "_mainGameSceneSetupData"); if (!stored) { storedNoEnergy = _mainGameSceneSetupData.gameplayOptions.noEnergy; } stored = true; if (_mainGameSceneSetupData.gameplayMode == GameplayMode.SoloNoArrows) { BeatmapDataModel _beatmapDataModel = ReflectionUtil.GetPrivateField <BeatmapDataModel>(_mainGameSceneSetup, "_beatmapDataModel"); BeatmapData beatmapData = CreateTransformedBeatmapData(_mainGameSceneSetupData.difficultyLevel.beatmapData, _mainGameSceneSetupData.gameplayOptions, _mainGameSceneSetupData.gameplayMode); if (beatmapData != null) { _beatmapDataModel.beatmapData = beatmapData; ReflectionUtil.SetPrivateField(_mainGameSceneSetup, "_beatmapDataModel", _beatmapDataModel); } if (Plugin.IsOneColorModeOn) { _mainGameSceneSetupData.gameplayOptions.noEnergy = true; _sabers = FindObjectsOfType <Saber>(); Saber targetSaber = (Plugin.IsColorRed) ? _playerController.leftSaber : _playerController.rightSaber; Saber otherSaber = (Plugin.IsColorRed) ? _playerController.rightSaber : _playerController.leftSaber; if (targetSaber == null || otherSaber == null) { return; } var targetCopy = Instantiate(targetSaber.gameObject); Saber newSaber = targetCopy.GetComponent <Saber>(); targetCopy.transform.parent = targetSaber.transform.parent; targetCopy.transform.localPosition = Vector3.zero; targetCopy.transform.localRotation = Quaternion.identity; targetSaber.transform.parent = otherSaber.transform.parent; targetSaber.transform.localPosition = Vector3.zero; targetSaber.transform.localRotation = Quaternion.identity; otherSaber.gameObject.SetActive(false); if (Plugin.IsColorRed) { ReflectionUtil.SetPrivateField(_playerController, "_rightSaber", targetSaber); ReflectionUtil.SetPrivateField(_playerController, "_leftSaber", newSaber); } else { ReflectionUtil.SetPrivateField(_playerController, "_leftSaber", targetSaber); ReflectionUtil.SetPrivateField(_playerController, "_rightSaber", newSaber); } _playerController.leftSaber.gameObject.SetActive(IsLeftSaberOn); if (_beatmapObjectSpawnController != null) { _beatmapObjectSpawnController.noteWasCutEvent += this.HandleNoteWasCutEvent; } } } } } catch (Exception ex) { Console.WriteLine(ex.Message + "\n" + ex.StackTrace); } }
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; } }
private void OnSceneLoaded(Scene newScene, LoadSceneMode mode) { var gameStatus = statusManager.gameStatus; gameStatus.scene = newScene.name; if (newScene.name == "Menu") { // Menu headInObstacle = false; // TODO: get the current song, mode and mods while in menu gameStatus.ResetMapInfo(); gameStatus.ResetPerformance(); statusManager.EmitStatusUpdate(ChangedProperties.AllButNoteCut, "menu"); } else if (newScene.name == "StandardLevel") { // In game mainSetupData = Resources.FindObjectsOfTypeAll <MainGameSceneSetupData>().FirstOrDefault(); if (mainSetupData == null) { Console.WriteLine("[HTTP Status] Couldn't find MainGameSceneSetupData"); return; } gamePauseManager = Resources.FindObjectsOfTypeAll <GamePauseManager>().FirstOrDefault(); if (gamePauseManager == null) { Console.WriteLine("[HTTP Status] Couldn't find GamePauseManager"); return; } scoreController = Resources.FindObjectsOfTypeAll <ScoreController>().FirstOrDefault(); if (scoreController == null) { Console.WriteLine("[HTTP Status] Couldn't find ScoreController"); return; } gameplayManager = Resources.FindObjectsOfTypeAll <GameplayManager>().FirstOrDefault(); if (gameplayManager == null) { Console.WriteLine("[HTTP Status] Couldn't find GameplayManager"); return; } beatmapObjectCallbackController = Resources.FindObjectsOfTypeAll <BeatmapObjectCallbackController>().FirstOrDefault(); if (beatmapObjectCallbackController == null) { Console.WriteLine("[HTTP Status] Couldn't find BeatmapObjectCallbackController"); return; } GameSongController gameSongController = (GameSongController)gameSongControllerField.GetValue(gameplayManager); audioTimeSyncController = (AudioTimeSyncController)audioTimeSyncControllerField.GetValue(gameSongController); playerHeadAndObstacleInteraction = (PlayerHeadAndObstacleInteraction)playerHeadAndObstacleInteractionField.GetValue(scoreController); // 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; var diff = mainSetupData.difficultyLevel; var level = diff.level; gameStatus.mode = mainSetupData.gameplayMode.ToString(); gameStatus.songName = level.songName; gameStatus.songSubName = level.songSubName; gameStatus.songAuthorName = level.songAuthorName; gameStatus.songBPM = level.beatsPerMinute; gameStatus.songTimeOffset = (long)(level.songTimeOffset * 1000f); gameStatus.length = (long)(level.audioClip.length * 1000f); gameStatus.start = GetCurrentTime(); gameStatus.paused = 0; gameStatus.difficulty = diff.difficulty.Name(); gameStatus.notesCount = diff.beatmapData.notesCount; gameStatus.obstaclesCount = diff.beatmapData.obstaclesCount; gameStatus.maxScore = ScoreController.MaxScoreForNumberOfNotes(diff.beatmapData.notesCount); try { // From https://support.unity3d.com/hc/en-us/articles/206486626-How-can-I-get-pixels-from-unreadable-textures- var texture = level.coverImage.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(); // TODO: obstaclesOption can be All, FullHeightOnly or None. Reflect that? gameStatus.modObstacles = mainSetupData.gameplayOptions.obstaclesOption.ToString(); gameStatus.modNoEnergy = mainSetupData.gameplayOptions.noEnergy; gameStatus.modMirror = mainSetupData.gameplayOptions.mirror; statusManager.EmitStatusUpdate(ChangedProperties.AllButNoteCut, "songStart"); } else { statusManager.EmitStatusUpdate(ChangedProperties.AllButNoteCut, "scene"); } }
private void ReceivedFromServer(string[] _data) { lastCommands.Clear(); foreach (string data in _data) { try { ServerCommand command = JsonUtility.FromJson <ServerCommand>(data); lastCommands.Add(command); if (command.commandType == ServerCommandType.SetPlayerInfos) { if (command.scoreboardScoreFormat != null) { scoreboardScoreFormat = command.scoreboardScoreFormat; } _playerInfos.Clear(); foreach (string playerStr in command.playerInfos) { PlayerInfo player = JsonUtility.FromJson <PlayerInfo>(playerStr); if (!String.IsNullOrEmpty(player.playerAvatar) && Config.Instance.ShowAvatarsInGame) { byte[] avatar = Convert.FromBase64String(player.playerAvatar); player.rightHandPos = Serialization.ToVector3(avatar.Take(12).ToArray()); player.leftHandPos = Serialization.ToVector3(avatar.Skip(12).Take(12).ToArray()); player.headPos = Serialization.ToVector3(avatar.Skip(24).Take(12).ToArray()); player.rightHandRot = Serialization.ToQuaternion(avatar.Skip(36).Take(16).ToArray()); player.leftHandRot = Serialization.ToQuaternion(avatar.Skip(52).Take(16).ToArray()); player.headRot = Serialization.ToQuaternion(avatar.Skip(68).Take(16).ToArray()); } _playerInfos.Add(player); } localPlayerIndex = FindIndexInList(_playerInfos, localPlayerInfo); if (Config.Instance.ShowAvatarsInGame) { try { if (_avatars.Count > _playerInfos.Count) { List <AvatarController> avatarsToRemove = new List <AvatarController>(); for (int i = _playerInfos.Count; i < _avatars.Count; i++) { avatarsToRemove.Add(_avatars[i]); } foreach (AvatarController avatar in avatarsToRemove) { _avatars.Remove(avatar); Destroy(avatar.gameObject); } } else if (_avatars.Count < _playerInfos.Count) { for (int i = 0; i < (_playerInfos.Count - _avatars.Count); i++) { _avatars.Add(new GameObject("Avatar").AddComponent <AvatarController>()); } } List <PlayerInfo> _playerInfosByID = _playerInfos.OrderBy(x => x.playerId).ToList(); for (int i = 0; i < _playerInfos.Count; i++) { _avatars[i].SetPlayerInfo(_playerInfosByID[i], (i - FindIndexInList(_playerInfosByID, localPlayerInfo)) * 3f, localPlayerInfo.Equals(_playerInfosByID[i])); } } catch (Exception e) { Console.WriteLine($"AVATARS EXCEPTION: {e}"); } } if (_playerInfos.Count <= 5) { for (int i = 0; i < _playerInfos.Count; i++) { scoreDisplays[i].UpdatePlayerInfo(_playerInfos[i], FindIndexInList(_playerInfos, _playerInfos[i])); } for (int i = _playerInfos.Count; i < scoreDisplays.Count; i++) { scoreDisplays[i].UpdatePlayerInfo(null, 0); } } else { if (localPlayerIndex < 3) { for (int i = 0; i < 5; i++) { scoreDisplays[i].UpdatePlayerInfo(_playerInfos[i], FindIndexInList(_playerInfos, _playerInfos[i])); } } else if (localPlayerIndex > _playerInfos.Count - 3) { for (int i = _playerInfos.Count - 5; i < _playerInfos.Count; i++) { scoreDisplays[i - (_playerInfos.Count - 5)].UpdatePlayerInfo(_playerInfos[i], FindIndexInList(_playerInfos, _playerInfos[i])); } } else { for (int i = localPlayerIndex - 2; i < localPlayerIndex + 3; i++) { scoreDisplays[i - (localPlayerIndex - 2)].UpdatePlayerInfo(_playerInfos[i], FindIndexInList(_playerInfos, _playerInfos[i])); } } } if (PlayerInfosReceived != null) { PlayerInfosReceived.Invoke(_playerInfos); } } else if (command.commandType == ServerCommandType.Kicked) { Console.WriteLine($"You were kicked! Reason: {command.kickReason}"); GameSongController controller = Resources.FindObjectsOfTypeAll <GameSongController>().FirstOrDefault(); ReflectionUtil.SetPrivateField(controller, "_songDidFinish", true); controller.SendSongDidFinishEvent(); } } catch (Exception e) { Console.WriteLine("EXCEPTION ON RECEIVED: " + e); } } StartCoroutine(ReceiveFromServerCoroutine()); }
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"); }
public EndlessGameInstaller(GameSongController gameSongController) { _gameSongController = gameSongController; }