예제 #1
0
        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;
        }
예제 #2
0
        internal override void Init(CountersData data, Vector3 position)
        {
            beatmapObjectManager = data.BOM;
            TextHelper.CreateText(out missedText, position - new Vector3(0, 0.4f, 0));
            missedText.text      = "0";
            missedText.fontSize  = 4;
            missedText.color     = Color.white;
            missedText.alignment = TextAlignmentOptions.Center;

            GameObject labelGO = new GameObject("Counters+ | Missed Label");

            labelGO.transform.parent = transform;
            TextHelper.CreateText(out label, position);
            label.text      = "Misses";
            label.fontSize  = 3;
            label.color     = Color.white;
            label.alignment = TextAlignmentOptions.Center;

            if (settings.CustomMissTextIntegration && PluginUtility.IsPluginPresent("CustomMissText"))
            {
                UpdateCustomMissText();
            }
            else if (!PluginUtility.IsPluginPresent("CustomMissText"))
            {
                settings.CustomMissTextIntegration = false;
                settings.Save();
            }

            if (beatmapObjectManager != null)
            {
                beatmapObjectManager.noteWasMissedEvent += OnNoteMiss;
                beatmapObjectManager.noteWasCutEvent    += OnNoteCut;
            }
        }
예제 #3
0
        internal override void Init(CountersData data, Vector3 position)
        {
            beatmapObjectManager = data.BOM;
            beatmapObjectManager.noteWasCutEvent    += OnNoteCut;
            beatmapObjectManager.noteWasMissedEvent += OnNoteMiss;
            notesLeft = data.GCSSD.difficultyBeatmap.beatmapData.notesCount;
            TextHelper.CreateText(out counter, position - new Vector3(0, 0.4f, 0));
            counter.text      = $"Notes Remaining {notesLeft}";
            counter.fontSize  = 3f;
            counter.color     = Color.white;
            counter.alignment = TextAlignmentOptions.Center;

            if (settings.LabelAboveCount)
            {
                counter.fontSize = 4;
                counter.text     = notesLeft.ToString();
                GameObject labelGO = new GameObject("Counters+ | Notes Left Label");
                labelGO.transform.parent = transform;
                TextHelper.CreateText(out TMP_Text label, position);
                label.text      = "Notes Remaining";
                label.fontSize  = 3;
                label.color     = Color.white;
                label.alignment = TextAlignmentOptions.Center;
            }
        }
예제 #4
0
        internal static IEnumerator DelayedStart(BeatmapObjectSpawnController beatmapObjectSpawnController)
        {
            yield return(new WaitForEndOfFrame());

            BeatmapObjectSpawnController = beatmapObjectSpawnController;

            // prone to breaking if anything else implements these interfaces
            BeatmapObjectManager            beatmapObjectManager = _beatmapObjectSpawnAccessor(ref beatmapObjectSpawnController) as BeatmapObjectManager;
            BeatmapObjectCallbackController coreSetup            = _callbackControllerAccessor(ref beatmapObjectSpawnController) as BeatmapObjectCallbackController;

            IAudioTimeSource = _audioTimeSourceAccessor(ref coreSetup);
            IReadonlyBeatmapData beatmapData = _beatmapDataAccessor(ref coreSetup);

            beatmapObjectManager.noteWasCutEvent -= NoteColorizer.ColorizeSaber;
            beatmapObjectManager.noteWasCutEvent += NoteColorizer.ColorizeSaber;

            if (Harmony.HasAnyPatches(HARMONYID))
            {
                if (beatmapData is CustomBeatmapData customBeatmap)
                {
                    if (ChromaConfig.Instance.EnvironmentEnhancementsEnabled)
                    {
                        EnvironmentEnhancementManager.Init(customBeatmap, beatmapObjectSpawnController.noteLinesDistance);
                    }
                }

                // please let me kill legacy
                LegacyLightHelper.Activate(beatmapData.beatmapEventsData);
            }
        }
예제 #5
0
        private void gameSongController_songDidFinishEvent()
        {
            //Reset the gameEnergyCounter death by obstacle value
            _oldObstacleEnergyDrainPerSecond = gameEnergyCounter.GetField <float>("_obstacleEnergyDrainPerSecond");
            gameEnergyCounter.SetField("_obstacleEnergyDrainPerSecond", 0f);

            //Rehook the functions in the energy counter that watch note events
            beatmapObjectManager = gameEnergyCounter.GetField <BeatmapObjectManager>("_beatmapObjectManager");

            beatmapObjectManager.noteWasMissedEvent += gameEnergyCounter.HandleNoteWasMissedEvent;
            beatmapObjectManager.noteWasMissedEvent -= beatmapObjectManager_noteWasMissedEvent;

            beatmapObjectManager.noteWasCutEvent += gameEnergyCounter.HandleNoteWasCutEvent;
            beatmapObjectManager.noteWasCutEvent -= beatmapObjectManager_noteWasCutEvent;

            //Rehook the level end event
            gameSongController.songDidFinishEvent += standardLevelGameplayManager.HandleSongDidFinish;
            gameSongController.songDidFinishEvent -= gameSongController_songDidFinishEvent;

            if (_wouldHaveFailed)
            {
                standardLevelGameplayManager.HandleGameEnergyDidReach0();
            }
            standardLevelGameplayManager.HandleSongDidFinish();
        }
 public NsvController(BeatmapObjectManager beatmapObjectManager, Factories.NsvBlockFactory blockFactory, SiraLog logger)
 {
     _config = PluginConfig.Instance;
     _logger = logger;
     _beatmapObjectManager = beatmapObjectManager;
     _slicedBlockPool      = new NsvSlicedBlock[MaxItems];
     _blockFactory         = blockFactory;
 }
        private static bool GetHiddenForType(BeatmapObjectManager beatmapObjectManager)
        {
            if (beatmapObjectManager is BasicBeatmapObjectManager)
            {
                return(true);
            }

            return(beatmapObjectManager.spawnHidden);
        }
예제 #8
0
        public void GetControllers()
        {
            DismissGraph(null);
            levelOk                      = false;
            averageHitValue              = 0.0f;
            averageHitValueSize          = 0;
            secondaryAverageHitValue     = 0.0f;
            secondaryAverageHitValueSize = 0;
            energyList.Clear();
            secondaryEnergyList.Clear();
            misses.Clear();

            if (PluginConfig.Instance.mode == PluginConfig.MeasurementMode.Energy)
            {
                energyList.Add(new Pair <float, float>(0.0f, 0.5f));
            }
            if (PluginConfig.Instance.secondaryMode == PluginConfig.MeasurementMode.Energy)
            {
                secondaryEnergyList.Add(new Pair <float, float>(0.0f, 0.5f));
            }

            scoreController = Resources.FindObjectsOfTypeAll <ScoreController>().LastOrDefault();
            ComboUIController comboUIController = Resources.FindObjectsOfTypeAll <ComboUIController>().LastOrDefault();

            energyCounter   = Resources.FindObjectsOfTypeAll <GameEnergyCounter>().LastOrDefault();
            rankCounter     = Resources.FindObjectsOfTypeAll <RelativeScoreAndImmediateRankCounter>().LastOrDefault();
            audioController = Resources.FindObjectsOfTypeAll <AudioTimeSyncController>().LastOrDefault();
            endActions      = Resources.FindObjectsOfTypeAll <StandardLevelGameplayManager>().LastOrDefault();
            if (endActions == null)
            {
                endActions = Resources.FindObjectsOfTypeAll <MissionLevelGameplayManager>().LastOrDefault();
            }

            if (endActions != null && scoreController != null && energyCounter != null && rankCounter != null && audioController != null && comboUIController != null)
            {
                objectManager   = (BeatmapObjectManager)_beatmapObjectManager.GetValue(scoreController);
                comboController = (ComboController)_comboController.GetValue(comboUIController);
                objectManager.noteWasCutEvent    += NoteHit;
                objectManager.noteWasMissedEvent += NoteMiss;
                comboController.comboBreakingEventHappenedEvent += ComboBreak;
                endActions.levelFinishedEvent += LevelFinished;
                endActions.levelFailedEvent   += LevelFinished;
                Logger.log.Debug("PerformanceMeter reloaded successfully");
            }
            else
            {
                Logger.log.Error("Could not reload PerformanceMeter. This may occur when playing online - if so, disregard this message.");
                scoreController = null;
                objectManager   = null;
                comboController = null;
                energyCounter   = null;
                rankCounter     = null;
                audioController = null;
                endActions      = null;
            }
        }
예제 #9
0
        void GameSceneLeft()
        {
            if (beatmapObjectManager)
            {
                beatmapObjectManager.noteWasSpawnedEvent -= OnNoteSpawned;
                beatmapObjectManager = null;
            }

            HarmonyPatches.GameNoteController_HandleCut.sabers  = null;
            HarmonyPatches.GameNoteController_HandleCut.spawner = null;
        }
예제 #10
0
 public BSEvents([InjectOptional] ILevelEndActions levelEndActions, IReadonlyBeatmapData beatmapData, ObstacleSaberSparkleEffectManager obstacleSaberSparkleEffectManager, ScoreController scoreController, BeatmapObjectManager beatmapObjectManager, BeatmapCallbacksController beatmapCallbacksController, ComboController comboController)
 {
     _levelEndActions = levelEndActions;
     _beatmapData     = beatmapData;
     _obstacleSaberSparkleEffectManager = obstacleSaberSparkleEffectManager;
     _scoreController            = scoreController;
     _beatmapObjectManager       = beatmapObjectManager;
     _beatmapCallbacksController = beatmapCallbacksController;
     _comboController            = comboController;
     _bombSubtypeIdentifier      = NoteData.SubtypeIdentifier(ColorType.None);
 }
예제 #11
0
        // printing char each cycle -> going into serial monitor (Arduino IDE) -> enabling timestamps => Subtract earlier time from newer time.

        void Awake()
        {
            _spawnController = FindObjectOfType <BeatmapObjectManager>();

            Plugin.log.Notice("Initializing..");
            Plugin.log.Notice(Settings.instance.EventChoice);

            BSEvents.gameSceneActive += OnGameSceneActive;
            BSEvents.songPaused      += OnSongPaused;
            BSEvents.songUnpaused    += OnSongUnpaused;

            Ec  = Resources.FindObjectsOfTypeAll <BeatmapObjectCallbackController>().FirstOrDefault();
            Cm  = Resources.FindObjectsOfTypeAll <ColorManager>().LastOrDefault();
            BMD = Resources.FindObjectsOfTypeAll <BeatmapLevelSO>().FirstOrDefault();
            if (Settings.instance.EventChoice == "noteCuts")
            {
                Plugin.log.Info("Adding event listner to noteCuts");
                _spawnController.noteWasCutEvent += OnNoteCut;  //Flash on note cuts
            }

            if (Settings.instance.EventChoice == "lightEvents")
            {
                Plugin.log.Info("Adding event listner to lightEvents");
                Ec.beatmapEventDidTriggerEvent += EventHappened; //Flash on map's light events
            }

            BSEvents.menuSceneActive += menuSceneActive;

            C1         = Cm.ColorForNoteType(NoteType.NoteB);
            redLeft    = Mathf.RoundToInt(C1.r * 255);
            greenLeft  = Mathf.RoundToInt(C1.g * 255);
            blueLeft   = Mathf.RoundToInt(C1.b * 255);
            C2         = Cm.ColorForNoteType(NoteType.NoteA);
            redRight   = Mathf.RoundToInt(C2.r * 255);
            greenRight = Mathf.RoundToInt(C2.g * 255);
            blueRight  = Mathf.RoundToInt(C2.b * 255);

            BPM = (int)BMD.beatsPerMinute; //Not used, may come useful in future

            Plugin.log.Info(" BPM = " + BPM.ToString());

            if (Settings.arduinoPort.IsOpen)
            {
                if (Settings.instance.RainbowMode)
                {
                    StartRainbowMode(Settings.arduinoPort);
                }
                else
                {
                    Plugin.log.Info("Sending Color to arduino...");
                    SendColorToArduino(Settings.arduinoPort);
                }
            }
        }
예제 #12
0
 public CountersData()
 {
     BOM                     = Resources.FindObjectsOfTypeAll <BeatmapObjectManager>().First();
     ScoreController         = Resources.FindObjectsOfTypeAll <ScoreController>().First();
     PlayerController        = Resources.FindObjectsOfTypeAll <PlayerController>().First();
     AudioTimeSyncController = Resources.FindObjectsOfTypeAll <AudioTimeSyncController>().First();
     PlayerData              = Resources.FindObjectsOfTypeAll <PlayerDataModel>().First();
     ModifiersData           = Resources.FindObjectsOfTypeAll <GameplayModifiersModelSO>().First();
     GCSSD                   = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData; //By the time all of these load, so should GCSSD.
     Is360Or90Level          = Resources.FindObjectsOfTypeAll <FlyingGameHUDRotation>().Any(x => x.isActiveAndEnabled);
 }
예제 #13
0
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
        private static bool Prefix(BeatmapObjectManager __instance, NoteController noteController, NoteCutInfo noteCutInfo)
#pragma warning restore SA1313 // Parameter names should begin with lower-case letter
        {
            if (!FakeNoteHelper.GetFakeNote(noteController))
            {
                NoteCutCoreEffectsSpawnerStart.NoteCutCoreEffectsSpawner.HandleNoteWasCut(noteController, noteCutInfo);
                _despawnMethod.Invoke(__instance, new object[] { noteController });

                return(false);
            }

            return(true);
        }
예제 #14
0
        private void GameSceneLoaded()
        {
            PlayerDataModel dataModel = UnityEngine.Resources.FindObjectsOfTypeAll <PlayerDataModel>().FirstOrDefault();

            if (!ConfigHelper.Config.Enabled || (dataModel?.playerData.playerSpecificSettings.noTextsAndHuds ?? false))
            {
                return;
            }
            _colorManager    = GameObject.FindObjectOfType <ColorManager>();
            _spawnController = GameObject.FindObjectOfType <BeatmapObjectManager>();
            _spawnController.noteWasCutEvent += OnNoteCut;
            _parentCanvas = GameObject.Instantiate(AssetBundleHelper.Canvas).transform;

            if (TwoNoteMode)
            {
                _sliceControllers = new SliceController[2];
                float minX = -Separation * 0.5f;
                for (int x = 0; x < 2; ++x)
                {
                    int   index = x;
                    float posX  = minX + (Separation * x);
                    float posY  = 0f;

                    SliceController controller = CreateSliceController(posX, posY);
                    Color           color      = UseCustomNoteColors ? _colorManager.ColorForNoteType((NoteType)index) : _defaultColors[index];
                    controller.UpdateBlockColor(color);
                    _sliceControllers[index] = controller;
                }
            }
            else
            {
                _sliceControllers = new SliceController[12];
                float minX = -Separation * 1.5f;
                for (int x = 0; x < 4; ++x)
                {
                    for (int y = 0; y < 3; ++y)
                    {
                        int   index = 3 * x + y;
                        float posX  = minX + (Separation * x);
                        float posY  = (Separation * y);

                        _sliceControllers[index] = CreateSliceController(posX, posY);
                    }
                }
            }

            _parentCanvas.localPosition = Position;
            _parentCanvas.eulerAngles   = Rotation;
            _parentCanvas.localScale   *= Scale;
        }
예제 #15
0
        public void Init(OnlinePlayerController newOwner, OnlineAudioTimeController syncController)
        {
            BeatmapObjectManager original = FindObjectsOfType <BeatmapObjectManager>().First(x => !(x is OnlineBeatmapObjectManager));

            transform.position = original.transform.position;

            foreach (FieldInfo info in original.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic).Where(x => !x.Name.ToLower().Contains("event")))
            {
                info.SetValue(this, info.GetValue(original));
            }

            owner = newOwner;
            onlineSyncController = syncController;

            _localPlayer         = FindObjectsOfType <PlayerController>().First(x => !(x is OnlinePlayerController));
            _localSyncController = FindObjectsOfType <AudioTimeSyncController>().First(x => !(x is OnlineAudioTimeController));
        }
예제 #16
0
        internal override void Init(CountersData data, Vector3 position)
        {
            string  iniValue = FormatLabel(0, 0, settings.AveragePrecision);
            Vector3 leftOffset; // Added this so you don't have to change position after creating the text
            TextAlignmentOptions leftAlign;

            _RankObject = new GameObject("Counters+ | Cut Label");
            _RankObject.transform.parent = transform;
            beatmapObjectManager         = data.BOM;
            TextHelper.CreateText(out cutLabel, position);
            cutLabel.text      = "Average Cut";
            cutLabel.fontSize  = 3;
            cutLabel.color     = Color.white;
            cutLabel.alignment = TextAlignmentOptions.Center;

            if (settings.SeparateSaberCounts)
            {
                TextHelper.CreateText(out cutCounterRight, position - new Vector3(-0.2f, 0.2f, 0));
                cutCounterRight.fontSize    = 4;
                cutCounterRight.color       = Color.white;
                cutCounterRight.lineSpacing = -26;
                cutCounterRight.text        = settings.SeparateCutValues ? $"{iniValue}\n{iniValue}\n{iniValue}" : $"{iniValue}";
                cutCounterRight.alignment   = TextAlignmentOptions.TopLeft;

                leftOffset = new Vector3(0.2f, 0.2f, 0);
                leftAlign  = TextAlignmentOptions.TopRight;
            }
            else
            {
                leftOffset = new Vector3(0, 0.2f, 0);
                leftAlign  = TextAlignmentOptions.Top;
            }

            TextHelper.CreateText(out cutCounterLeft, position - leftOffset);
            cutCounterLeft.fontSize    = 4;
            cutCounterLeft.color       = Color.white;
            cutCounterLeft.lineSpacing = -26;
            cutCounterLeft.text        = settings.SeparateCutValues ? $"{iniValue}\n{iniValue}\n{iniValue}" : $"{iniValue}";
            cutCounterLeft.alignment   = leftAlign;

            if (beatmapObjectManager != null)
            {
                beatmapObjectManager.noteWasCutEvent += UpdateScore;
            }
        }
예제 #17
0
 public BSEvents(BeatmapObjectManager beatmapObjectManager,
                 GameEnergyCounter gameEnergyCounter,
                 GameplayCoreSceneSetupData gameplayCoreSceneSetupData,
                 ObstacleSaberSparkleEffectManager obstacleSaberSparkleEffectManager,
                 ScoreController scoreController,
                 PlayerDataModel playerDataModel,
                 PrepareLevelCompletionResults prepareLevelCompletionResults,
                 IBeatmapObjectCallbackController beatmapObjectCallbackController,
                 IDifficultyBeatmap difficultyBeatmap)
 {
     _beatmapObjectManager              = beatmapObjectManager;
     _gameEnergyCounter                 = gameEnergyCounter;
     _gameplayCoreSceneSetupData        = gameplayCoreSceneSetupData;
     _obstacleSaberSparkleEffectManager = obstacleSaberSparkleEffectManager;
     _scoreController = scoreController;
     _playerDataModel = playerDataModel;
     _prepareLevelCompletionResults   = prepareLevelCompletionResults;
     _beatmapObjectCallbackController = beatmapObjectCallbackController;
     _difficultyBeatmap = difficultyBeatmap;
 }
예제 #18
0
 void DismissGraph(ResultsViewController vc)
 {
     if (panel != null)
     {
         panel.SetActive(false);
         Destroy(panel, 1);
         panel           = null;
         scoreController = null;
         objectManager   = null;
         comboController = null;
         energyCounter   = null;
         rankCounter     = null;
         audioController = null;
         endActions      = null;
     }
     if (vc != null)
     {
         vc.continueButtonPressedEvent -= DismissGraph;
         vc.restartButtonPressedEvent  -= DismissGraph;
     }
 }
예제 #19
0
        static bool Prefix(BeatmapObjectManager __instance, NoteController noteController)
        {
            try
            {
                if (Config.Instance.SpectatorMode && SpectatingController.Instance != null && SpectatingController.active && Client.Instance != null && Client.Instance.connected && SpectatingController.Instance.spectatedPlayer != null && SpectatingController.Instance.spectatedPlayer.playerInfo != null)
                {
                    ulong playerId = SpectatingController.Instance.spectatedPlayer.playerInfo.playerId;

                    if (SpectatingController.Instance.playerUpdates.ContainsKey(playerId) && SpectatingController.Instance.playerUpdates[playerId].hits.Count > 0)
                    {
                        if (SpectatingController.Instance.playerUpdates[playerId].hits.TryGetValue(noteController.noteData.id, out HitData hit))
                        {
                            if (hit.noteWasCut)
                            {
#if DEBUG
                                Plugin.log.Warn("We missed the note, but the player cut it");
#endif
                                __instance.Despawn(noteController);
                                return(false);
                            }
                            else
                            {
                                return(true);
                            }
                        }
                    }

                    return(true);
                }
                else
                {
                    return(true);
                }
            }
            catch (Exception e)
            {
                Plugin.log.Error("Exception in Harmony patch BeatmapObjectSpawnController.NoteWasMissed: " + e);
                return(true);
            }
        }
예제 #20
0
        internal static IEnumerator DelayedStart(BeatmapObjectSpawnController beatmapObjectSpawnController)
        {
            yield return(new WaitForEndOfFrame());

            BeatmapObjectSpawnController = beatmapObjectSpawnController;

            // prone to breaking if anything else implements these interfaces
            BeatmapObjectManager            beatmapObjectManager = (BeatmapObjectManager)_beatmapObjectSpawnAccessor(ref beatmapObjectSpawnController);
            BeatmapObjectCallbackController coreSetup            = (BeatmapObjectCallbackController)_callbackControllerAccessor(ref beatmapObjectSpawnController);

            IAudioTimeSource = _audioTimeSourceAccessor(ref coreSetup);
            IReadonlyBeatmapData beatmapData = _beatmapDataAccessor(ref coreSetup);

            beatmapObjectManager.noteWasCutEvent -= NoteColorizer.ColorizeSaber;
            beatmapObjectManager.noteWasCutEvent += NoteColorizer.ColorizeSaber;

            if (ChromaIsActive)
            {
                if (beatmapData is CustomBeatmapData customBeatmap)
                {
                    if (ChromaConfig.Instance !.EnvironmentEnhancementsEnabled)
                    {
                        EnvironmentEnhancementManager.Init(customBeatmap, beatmapObjectSpawnController.noteLinesDistance);
                    }
                }

                try
                {
                    // please let me kill legacy
                    LegacyLightHelper.Activate(beatmapData.beatmapEventsData);
                }
                catch (System.Exception e)
                {
                    Plugin.Logger.Log("Could not run Legacy Chroma Lights");
                    Plugin.Logger.Log(e);
                }
            }
        }
예제 #21
0
        public EventPlayerInterface(
            PluginConfig pluginConfig,
            [Inject(Id = "LastNoteId")] float lastNoteTime,
            ObstacleSaberSparkleEffectManager obstacleSaberSparkleEffectManager,
            GameEnergyCounter energyCounter,
            ScoreController scoreController,
            BeatmapObjectManager beatmapObjectManager)
        {
            _pluginConfig = pluginConfig;
            _lastNoteTime = lastNoteTime;
            _obstacleSaberSparkleEffectManager = obstacleSaberSparkleEffectManager;
            _energyCounter        = energyCounter;
            _scoreController      = scoreController;
            _beatmapObjectManager = beatmapObjectManager;
            _partEventsList       = new List <PartEvents>();

            if (!_pluginConfig.EnableEvents)
            {
                return;
            }

            // OnSlice LevelEnded Combobreak
            _beatmapObjectManager.noteWasCutEvent    += OnNoteCut;
            _beatmapObjectManager.noteWasMissedEvent += OnNoteMiss;

            // Sabers clashing
            _obstacleSaberSparkleEffectManager.sparkleEffectDidStartEvent += SaberStartCollide;
            _obstacleSaberSparkleEffectManager.sparkleEffectDidEndEvent   += SaberEndCollide;

            // OnLevelFail
            _energyCounter.gameEnergyDidReach0Event += InvokeOnLevelFail;

            // MultiplierUp
            _scoreController.multiplierDidChangeEvent += MultiplayerDidChange;

            // Combo changed
            _scoreController.comboDidChangeEvent += InvokeComboChanged;
        }
예제 #22
0
        IEnumerator WaitForLoad()
        {
            while (!loaded)
            {
                var playerHeadAndObstacleInteraction = Resources.FindObjectsOfTypeAll <ScoreController>().FirstOrDefault()?.GetField <PlayerHeadAndObstacleInteraction, ScoreController>("_playerHeadAndObstacleInteraction");
                beatmapObjectManager = playerHeadAndObstacleInteraction?.GetField <BeatmapObjectManager, PlayerHeadAndObstacleInteraction>("_beatmapObjectManager");
                saberManager         = Resources.FindObjectsOfTypeAll <SaberManager>().FirstOrDefault();
                if (beatmapObjectManager == null || saberManager == null)
                {
                    yield return(new WaitForSeconds(0.1f));
                }
                else
                {
                    loaded = true;
                }
            }

            yield return(new WaitForSeconds(0.1f));

            sabers    = new Saber[2];
            sabers[0] = saberManager.leftSaber;
            sabers[1] = saberManager.rightSaber;
        }
예제 #23
0
        internal override void Init(CountersData data, Vector3 position)
        {
            beatmapObjectManager = data.BOM;
            TextHelper.CreateText(out counterText, position - new Vector3(0, 0.4f, 0));
            counterText.text      = settings.ShowPercentage ? "0 / 0 - (100%)" : "0 / 0";
            counterText.fontSize  = 4;
            counterText.color     = Color.white;
            counterText.alignment = TextAlignmentOptions.Center;

            GameObject labelGO = new GameObject("Counters+ | Notes Label");

            labelGO.transform.parent = transform;
            TextHelper.CreateText(out TMP_Text label, position);
            label.text      = "Notes";
            label.fontSize  = 3;
            label.color     = Color.white;
            label.alignment = TextAlignmentOptions.Center;

            if (beatmapObjectManager != null)
            {
                beatmapObjectManager.noteWasCutEvent    += OnNoteCut;
                beatmapObjectManager.noteWasMissedEvent += OnNoteMiss;
            }
        }
예제 #24
0
        private IEnumerator DelayedSetup()
        {
            //Slight delay before grabbing needed objects
            yield return(new WaitForSeconds(0.1f));

            _timeSync                  = Resources.FindObjectsOfTypeAll <AudioTimeSyncController>().LastOrDefault(x => x.isActiveAndEnabled);
            _songAudio                 = _timeSync.GetField <AudioSource>("_audioSource");
            _levelLoader               = Resources.FindObjectsOfTypeAll <CustomLevelLoader>().First();
            _spawnController           = Resources.FindObjectsOfTypeAll <BeatmapObjectSpawnController>().LastOrDefault(x => x.isActiveAndEnabled);
            _originalSpawnMovementData = _spawnController.GetField <BeatmapObjectSpawnMovementData>("_beatmapObjectSpawnMovementData");
            _pauseController           = Resources.FindObjectsOfTypeAll <PauseController>().LastOrDefault(x => x.isActiveAndEnabled);
            _callbackController        = Resources.FindObjectsOfTypeAll <BeatmapObjectCallbackController>().LastOrDefault(x => x.isActiveAndEnabled);
            _seManager                 = Resources.FindObjectsOfTypeAll <NoteCutSoundEffectManager>().LastOrDefault(x => x.isActiveAndEnabled);
            _beatmapObjectManager      = _seManager.GetField <BeatmapObjectManager>("_beatmapObjectManager");
            _cancelSource              = new CancellationTokenSource();
            var level = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData.difficultyBeatmap.level;

            if (!(level is CustomPreviewBeatmapLevel))
            {
                yield break;
            }
            _currentLevel = level as CustomPreviewBeatmapLevel;

            //Get DifficultyBeatmap
            BeatmapDifficulty       levelDiff           = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData.difficultyBeatmap.difficulty;
            BeatmapCharacteristicSO levelCharacteristic = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData.difficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic;

            _currentDiffBeatmap = _currentLevel.standardLevelInfoSaveData.difficultyBeatmapSets.First(
                x => x.beatmapCharacteristicName == levelCharacteristic.serializedName).difficultyBeatmaps.First(
                x => x.difficulty == levelDiff.ToString());

            _originalInitData = _timeSync.GetField <AudioTimeSyncController.InitData>("_initData");
            _songStartTime    = _originalInitData.startSongTime;
            //Initialize if everything successfully grabbed
            _init = true;
        }
예제 #25
0
        static bool Prefix(BeatmapObjectManager __instance, NoteController noteController, NoteCutInfo noteCutInfo)
        {
            try
            {
                if (Config.Instance.SpectatorMode && SpectatingController.Instance != null && SpectatingController.active && Client.Instance != null && Client.Instance.connected && SpectatingController.Instance.spectatedPlayer != null && SpectatingController.Instance.spectatedPlayer.playerInfo != null)
                {
                    ulong playerId = SpectatingController.Instance.spectatedPlayer.playerInfo.playerId;

                    if (SpectatingController.Instance.playerUpdates.ContainsKey(playerId) && SpectatingController.Instance.playerUpdates[playerId].hits.Count > 0)
                    {
                        if (SpectatingController.Instance.playerUpdates[playerId].hits.TryGetValue(noteController.noteData.id, out HitData hit))
                        {
                            bool allIsOKExpected = hit.noteWasCut && hit.speedOK && hit.saberTypeOK && hit.directionOK && !hit.wasCutTooSoon;

                            if (hit.noteWasCut)
                            {
                                if (noteCutInfo.allIsOK == allIsOKExpected)
                                {
                                    return(true);
                                }
                                else if (!noteCutInfo.allIsOK && allIsOKExpected)
                                {
#if DEBUG
                                    Plugin.log.Warn("Oopsie, we missed it, let's forget about that");
#endif
                                    __instance.Despawn(noteController);

                                    return(false);
                                }
                                else if (noteCutInfo.allIsOK && !allIsOKExpected)
                                {
#if DEBUG
                                    Plugin.log.Warn("We cut the note, but the player cut it wrong");
#endif

                                    noteCutInfo.SetProperty("wasCutTooSoon", hit.wasCutTooSoon);
                                    noteCutInfo.SetProperty("directionOK", hit.directionOK);
                                    noteCutInfo.SetProperty("saberTypeOK", hit.saberTypeOK);
                                    noteCutInfo.SetProperty("speedOK", hit.speedOK);

                                    return(true);
                                }
                            }
                            else
                            {
#if DEBUG
                                Plugin.log.Warn("We cut the note, but the player missed it");
#endif
                                __instance.HandleNoteWasMissed(noteController);

                                return(false);
                            }
                        }
                    }

                    return(true);
                }
                else
                {
                    return(true);
                }
            }catch (Exception e)
            {
                Plugin.log.Error("Exception in Harmony patch BeatmapObjectSpawnController.NoteWasCut: " + e);
                return(true);
            }
        }
예제 #26
0
        public async void HandleSongStart()
        {
            // Check if level data is actually available in BS_Utils before proceeding further. It isn't available in the tutorial
            if (!BS_Utils.Plugin.LevelData.IsSet)
            {
                Plugin.log.Debug("BS_Utils level data is not present. Probably due to the tutorial being active.");
                return;
            }

            GameStatus gameStatus = statusManager.gameStatus;

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

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

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

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

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

                multiplayerLocalActivePlayerFacade = FindFirstOrDefaultOptional <MultiplayerLocalActivePlayerFacade>();

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

                return;
            }

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

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

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

            gameplayCoreSceneSetupData = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData;

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

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

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

            gameStatus.partyMode = Gamemode.IsPartyActive;

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

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

            float songSpeedMul = gameplayModifiers.songSpeedMul;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            gameStatus.ResetPerformance();

            UpdateModMultiplier();

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

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

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

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

            statusManager.EmitStatusUpdate(ChangedProperties.AllButNoteCut, "songStart");
        }
예제 #27
0
        private void CleanUpSong()
        {
            statusManager.gameStatus.ResetMapInfo();
            statusManager.gameStatus.ResetPerformance();

            noteControllerMapping.Clear();

            // Release references for AfterCutScoreBuffers that don't resolve due to player leaving the map before finishing.
            foreach (var noteCutItem in noteCutMapping)
            {
                // CutScoreBuffers are pooled. Remove the event listener just in case it never fires the event.
                noteCutItem.Key.didFinishEvent.Remove(this);
            }
            noteCutMapping.Clear();

            // Clear note id mappings.
            noteToIdMapping = null;

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

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

            if (beatmapObjectManager != null)
            {
                beatmapObjectManager.noteWasSpawnedEvent -= OnNoteWasSpawned;
                beatmapObjectManager = null;
            }

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

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

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

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

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

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

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

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

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

            if (gameplayModiferParamsList != null)
            {
                gameplayModiferParamsList = null;
            }
        }
예제 #28
0
 // Ask for the BeatmapObjectManager polietly. The BeatmapObjectManager is a MonoBehaviour that's already injected by the base game. As long as you know it's injected, you can ask for it!
 public GameManager(BeatmapObjectManager beatmapObjectManager)
 {
     _objectManager = beatmapObjectManager;
 }
예제 #29
0
 public BreaktimeManager(BreaktimeSettings settings, [InjectOptional] IReadonlyBeatmapData readonlyBeatmapData, [InjectOptional] BeatmapObjectManager beatmapObjectManager)
 {
     _settings             = settings;
     _readonlyBeatmapData  = readonlyBeatmapData;
     _beatmapObjectManager = beatmapObjectManager;
 }
예제 #30
0
        internal static IEnumerator DelayedStart()
        {
            yield return(new WaitForEndOfFrame());

            AudioTimeSyncController = Resources.FindObjectsOfTypeAll <AudioTimeSyncController>().First();
            BeatmapObjectSpawnController beatmapObjectSpawnController = Resources.FindObjectsOfTypeAll <BeatmapObjectSpawnController>().First();
            BeatmapObjectManager         beatmapObjectManager         = _beatmapObjectSpawnAccessor(ref beatmapObjectSpawnController) as BeatmapObjectManager;

            SongBPM = beatmapObjectSpawnController.currentBpm;
            BeatmapObjectCallbackController coreSetup   = Resources.FindObjectsOfTypeAll <BeatmapObjectCallbackController>().First();
            IReadonlyBeatmapData            beatmapData = coreSetup.GetField <IReadonlyBeatmapData, BeatmapObjectCallbackController>("_beatmapData");

            beatmapObjectManager.noteWasCutEvent -= NoteColorizer.ColorizeSaber;
            beatmapObjectManager.noteWasCutEvent += NoteColorizer.ColorizeSaber;

            if (ChromaConfig.Instance.LightshowModifier)
            {
                foreach (BeatmapLineData b in beatmapData.beatmapLinesData)
                {
                    BeatmapLineData refBeatmapLineData = b;
                    _beatmapObjectsDataAccessor(ref refBeatmapLineData) = b.beatmapObjectsData.Where((source, index) => b.beatmapObjectsData[index].beatmapObjectType != BeatmapObjectType.Note).ToList();
                }

                foreach (Saber saber in Resources.FindObjectsOfTypeAll <Saber>())
                {
                    saber.gameObject.SetActive(false);
                }

                BS_Utils.Gameplay.ScoreSubmission.DisableSubmission("Chroma");

                if (ChromaConfig.Instance.PlayersPlace)
                {
                    GameObject.Find("PlayersPlace")?.SetActive(false);
                }

                if (ChromaConfig.Instance.Spectrograms)
                {
                    GameObject.Find("Spectrograms")?.SetActive(false);
                }

                if (ChromaConfig.Instance.BackColumns)
                {
                    GameObject.Find("BackColumns")?.SetActive(false);
                }

                if (ChromaConfig.Instance.Buildings)
                {
                    GameObject.Find("Buildings")?.SetActive(false);
                }
            }

            if (Harmony.HasAnyPatches(HARMONYID))
            {
                if (beatmapData is CustomBeatmapData customBeatmap)
                {
                    if (ChromaConfig.Instance.EnvironmentEnhancementsEnabled)
                    {
                        // Spaghetti code below until I can figure out a better way of doing this
                        dynamic       dynData       = customBeatmap.beatmapCustomData;
                        List <object> objectsToKill = Trees.at(dynData, "_environmentRemoval");
                        if (objectsToKill != null)
                        {
                            IEnumerable <GameObject> gameObjects = Resources.FindObjectsOfTypeAll <GameObject>();
                            foreach (string s in objectsToKill.Cast <string>())
                            {
                                if (s == "TrackLaneRing" || s == "BigTrackLaneRing")
                                {
                                    foreach (GameObject n in gameObjects.Where(obj => obj.name.Contains(s)))
                                    {
                                        if (s == "TrackLaneRing" && n.name.Contains("Big"))
                                        {
                                            continue;
                                        }

                                        n.SetActive(false);
                                    }
                                }
                                else
                                {
                                    foreach (GameObject n in gameObjects
                                             .Where(obj => obj.name.Contains(s) && (obj.scene.name?.Contains("Environment") ?? false) && (!obj.scene.name?.Contains("Menu") ?? false)))
                                    {
                                        n.SetActive(false);
                                    }
                                }
                            }
                        }
                    }
                }

                // please let me kill legacy
                LegacyLightHelper.Activate(beatmapData.beatmapEventsData);
            }
        }