/// <summary> /// Performs the transformation /// </summary> public IEnumerator TransformBeatMap() { yield return(new WaitForSecondsRealtime(0.1f)); if (this.NoArrowsOption && BS_Utils.Plugin.LevelData.IsSet) { GameplayCoreSceneSetupData data = BS_Utils.Plugin.LevelData?.GameplayCoreSceneSetupData; var beatmap = data.difficultyBeatmap; string characteristic = beatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.characteristicName; // Logging.Info($"Characteristic: {characteristic}"); if (characteristic == ("One Saber") || characteristic == ("No Arrows")) { // Do not transform for One Saber or legitimate No Arrows mode Logging.Info($"Cannot transform song: {beatmap.level.songName} due to being a One Saber or No Arrows map"); yield break; } Logging.Info("Disabling submission on NoArrowsOption turned on."); BS_Utils.Gameplay.ScoreSubmission.DisableSubmission("NoArrowsRandom"); var gameplayCore = Resources.FindObjectsOfTypeAll <GameplayCoreSceneSetup>().FirstOrDefault(); if (gameplayCore == null) { yield break; } // Applying NoArrowsRandom transformation Logging.Info($"Transforming song: {beatmap.level.songName}"); var transformedBeatmap = BeatmapDataNoArrowsTransform.CreateTransformedData(beatmap.beatmapData, true); var beatmapDataModel = gameplayCore.GetPrivateField <BeatmapDataModel>("_beatmapDataModel"); beatmapDataModel.SetPrivateField("_beatmapData", transformedBeatmap); } }
private IEnumerator TransformMap() { yield return(new WaitForSecondsRealtime(0.01f)); if (BS_Utils.Plugin.LevelData.Mode == BS_Utils.Gameplay.Mode.Multiplayer) { yield break; } var config = Configuration.instance.ConfigurationData; // Set up for One Color if (config.OneColor && !config.NoArrowsRandom) { this.useLeft = (config.PlayMode == PlayMode.BeatSaber && config.UseLeftSaber) || (config.PlayMode == PlayMode.DarthMaul && config.UseLeftController) || (config.PlayMode == PlayMode.BeatSpear && config.UseLeftSpear); this.undesiredNoteType = this.useLeft ? ColorType.ColorB : ColorType.ColorA; } try { BeatmapObjectCallbackController callbackController = null; BeatmapData beatmapData = null; BeatmapObjectCallbackController[] callbackControllers = Resources.FindObjectsOfTypeAll <BeatmapObjectCallbackController>(); foreach (BeatmapObjectCallbackController cbc in callbackControllers) { if (cbc.GetField <BeatmapData>("_beatmapData") != null) { callbackController = cbc; beatmapData = callbackController.GetField <BeatmapData>("_beatmapData"); } } if (config.NoArrowsRandom) { // Transform the map to No Arrows Random using the ingame algorithm first AlternativePlay.Logger.Info($"Transforming NoArrowsRandom for song: {this.currentBeatmap.level.songName}"); var transformedBeatmap = BeatmapDataNoArrowsTransform.CreateTransformedData(beatmapData); callbackController.SetNewBeatmapData(transformedBeatmap); } // Transform every note this.TransformNotes(beatmapData); // Touch Notes speed detection is not handled here but in the HarmonyPatches } catch (Exception e) { AlternativePlay.Logger.Error($"Transforming Error: {this.currentBeatmap.level.songName}"); AlternativePlay.Logger.Error($"Error Message: {e.Message}"); AlternativePlay.Logger.Error($"Stack Trace: {e.StackTrace}"); } }
/// <summary> /// Performs the transformation /// </summary> public IEnumerator TransformBeatMap() { yield return(new WaitForSecondsRealtime(0.1f)); if (this.NoArrowsOption && BS_Utils.Plugin.LevelData.IsSet) { // Check for game mode and early exit on One Saber or NoArrows GameplayCoreSceneSetupData data = BS_Utils.Plugin.LevelData?.GameplayCoreSceneSetupData; var beatmap = data.difficultyBeatmap; string serializedName = beatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName; if (serializedName == OneSaberName || serializedName == NoArrowsName) { // Do not transform for One Saber or legitimate No Arrows mode Logging.Info($"Cannot transform song: {beatmap.level.songName} due to being a One Saber or No Arrows map"); yield break; } // Transform the loaded in-memory map GameplayCoreSceneSetup gameplayCoreSceneSetup = Resources.FindObjectsOfTypeAll <GameplayCoreSceneSetup>().First(); if (gameplayCoreSceneSetup == null) { yield break; } BeatmapDataModel dataModel = gameplayCoreSceneSetup.GetField <BeatmapDataModel>("_beatmapDataModel"); BeatmapData beatmapData = dataModel.beatmapData; Logging.Info("Disabling submission on NoArrowsOption turned on."); BS_Utils.Gameplay.ScoreSubmission.DisableSubmission("NoArrowsRandom"); // Applying NoArrowsRandom transformation Logging.Info($"Transforming song: {beatmap.level.songName}"); var transformedBeatmap = BeatmapDataNoArrowsTransform.CreateTransformedData(beatmapData, true); var beatmapDataModel = gameplayCoreSceneSetup.GetPrivateField <BeatmapDataModel>("_beatmapDataModel"); beatmapDataModel.SetPrivateField("_beatmapData", transformedBeatmap); } }
private void DelayedNoteJumpMovementSpeedFix() { //Beat Saber 0.11.1 introduced a check for if noteJumpMovementSpeed <= 0 //This breaks songs that have a negative noteJumpMovementSpeed and previously required a patcher to get working again //I've added this to add support for that again, because why not. if (CurrentLevelPlaying.noteJumpMovementSpeed <= 0) { var beatmapObjectSpawnController = Resources.FindObjectsOfTypeAll <BeatmapObjectSpawnController>().FirstOrDefault(); if (beatmapObjectSpawnController != null) { var disappearingArrows = beatmapObjectSpawnController.GetPrivateField <bool>("_disappearingArrows"); beatmapObjectSpawnController.Init(CurrentLevelPlaying.level.beatsPerMinute, CurrentLevelPlaying.beatmapData.beatmapLinesData.Length, CurrentLevelPlaying.noteJumpMovementSpeed, CurrentLevelPlaying.noteJumpStartBeatOffset, disappearingArrows); } } //Also change beatmap to no arrow if no arrow was selected, since Beat Saber no longer does runtime conversion for that. if (!_noArrowsSelected) { return; } var gameplayCore = Resources.FindObjectsOfTypeAll <GameplayCoreSceneSetup>().FirstOrDefault(); if (gameplayCore == null) { return; } Console.WriteLine("Applying no arrow transformation"); var transformedBeatmap = BeatmapDataNoArrowsTransform.CreateTransformedData(CurrentLevelPlaying.beatmapData); var beatmapDataModel = gameplayCore.GetPrivateField <BeatmapDataModel>("_beatmapDataModel"); beatmapDataModel.SetPrivateField("_beatmapData", transformedBeatmap); }
private IEnumerator TransformMap() { yield return(new WaitForSecondsRealtime(0.1f)); // Set up for One Color if (ConfigOptions.instance.OneColor && !ConfigOptions.instance.NoArrowsRandom) { this.useLeft = (ConfigOptions.instance.PlayMode == PlayMode.BeatSaber && ConfigOptions.instance.UseLeftSaber) || (ConfigOptions.instance.PlayMode == PlayMode.DarthMaul && ConfigOptions.instance.UseLeftController) || (ConfigOptions.instance.PlayMode == PlayMode.BeatSpear && ConfigOptions.instance.UseLeftSpear); this.undesiredNoteType = this.useLeft ? NoteType.NoteB : NoteType.NoteA; // Change the other saber to desired type Saber.SaberType desiredSaberType = this.useLeft ? Saber.SaberType.SaberA : Saber.SaberType.SaberB; var saberObject = new GameObject("SaberTypeObject").AddComponent <SaberTypeObject>(); saberObject.SetField("_saberType", desiredSaberType); var player = Resources.FindObjectsOfTypeAll <PlayerController>().FirstOrDefault(); Saber saberToSwap = this.useLeft ? player.rightSaber : player.leftSaber; saberToSwap.SetField("_saberType", saberObject); if (ConfigOptions.instance.RemoveOtherSaber && ConfigOptions.instance.PlayMode == PlayMode.BeatSaber) { // Hide the off color saber Saber saberToHide = ConfigOptions.instance.UseLeftSaber ? this.playerController.rightSaber : this.playerController.leftSaber; saberToHide.gameObject.SetActive(false); } } // Get the in memory beat map BeatmapObjectCallbackController callbackController = Resources.FindObjectsOfTypeAll <BeatmapObjectCallbackController>().First(); BeatmapData beatmapData = callbackController.GetField <BeatmapData>("_beatmapData"); if (ConfigOptions.instance.NoArrowsRandom) { // Transform the map to No Arrows Random using the ingame algorithm first Logging.Info($"Transforming NoArrowsRandom for song: {this.currentBeatmap.level.songName}"); var transformedBeatmap = BeatmapDataNoArrowsTransform.CreateTransformedData(beatmapData, true); callbackController.SetNewBeatmapData(transformedBeatmap); } // Transform every note var allNoteObjects = beatmapData.beatmapLinesData .SelectMany(line => line.beatmapObjectsData) .Where(objectData => objectData.beatmapObjectType == BeatmapObjectType.Note) .ToList(); allNoteObjects.ForEach(beatmapObject => { var note = beatmapObject as NoteData; // Transform for NoArrows or TouchNotes here but do not if NoArrowsRandom was already applied if ((ConfigOptions.instance.NoArrows || ConfigOptions.instance.TouchNotes) && !ConfigOptions.instance.NoArrowsRandom) { note.SetNoteToAnyCutDirection(); } // Transform for One Color if this is the other note type if (ConfigOptions.instance.OneColor && note.noteType == undesiredNoteType) { note.SwitchNoteType(); } }); // Touch Notes speed detection is not handled here but in the HarmonyPatches }
private IEnumerator TransformMap() { yield return(new WaitForSecondsRealtime(0.1f)); var config = Configuration.instance.ConfigurationData; // Set up for One Color if (config.OneColor && !config.NoArrowsRandom) { this.useLeft = (config.PlayMode == PlayMode.BeatSaber && config.UseLeftSaber) || (config.PlayMode == PlayMode.DarthMaul && config.UseLeftController) || (config.PlayMode == PlayMode.BeatSpear && config.UseLeftSpear); this.undesiredNoteType = this.useLeft ? ColorType.ColorB : ColorType.ColorA; // Change the other saber to desired type SaberType desiredSaberType = this.useLeft ? SaberType.SaberA : SaberType.SaberB; var saberObject = new GameObject("SaberTypeObject").AddComponent <SaberTypeObject>(); saberObject.SetField("_saberType", desiredSaberType); var player = Resources.FindObjectsOfTypeAll <SaberManager>().FirstOrDefault(); Saber saberToSwap = this.useLeft ? player.rightSaber : player.leftSaber; saberToSwap.SetField("_saberType", saberObject); } try { BeatmapObjectCallbackController callbackController = null; BeatmapData beatmapData = null; BeatmapObjectCallbackController[] callbackControllers = Resources.FindObjectsOfTypeAll <BeatmapObjectCallbackController>(); foreach (BeatmapObjectCallbackController cbc in callbackControllers) { if (cbc.GetField <BeatmapData>("_beatmapData") != null) { callbackController = cbc; beatmapData = callbackController.GetField <BeatmapData>("_beatmapData"); } } //BeatmapObjectCallbackController callbackController = Resources.FindObjectsOfTypeAll<BeatmapObjectCallbackController>().FirstOrDefault(); // BeatmapData beatmapData = callbackController.GetField<BeatmapData>("_beatmapData"); if (config.NoArrowsRandom) { // Transform the map to No Arrows Random using the ingame algorithm first AlternativePlay.Logger.Info($"Transforming NoArrowsRandom for song: {this.currentBeatmap.level.songName}"); var transformedBeatmap = BeatmapDataNoArrowsTransform.CreateTransformedData(beatmapData); callbackController.SetNewBeatmapData(transformedBeatmap); } // Transform every note var allNoteObjects = beatmapData.beatmapLinesData .SelectMany(line => line.beatmapObjectsData) .Where(objectData => objectData.beatmapObjectType == BeatmapObjectType.Note) .ToList(); allNoteObjects.ForEach(beatmapObject => { var note = beatmapObject as NoteData; // Transform for NoArrows or TouchNotes here but do not if NoArrowsRandom was already applied if ((config.NoArrows || config.TouchNotes) && !config.NoArrowsRandom) { note.SetNoteToAnyCutDirection(); } // Transform for One Color if this is the other note type if (config.OneColor && note.colorType == this.undesiredNoteType) { note.SwitchNoteColorType(); } }); // Touch Notes speed detection is not handled here but in the HarmonyPatches } catch { AlternativePlay.Logger.Info($"Transforming Error: {this.currentBeatmap.level.songName}"); } // Touch Notes speed detection is not handled here but in the HarmonyPatches }