public override BeatmapObjectContainer SpawnObject(BeatmapObject obj, out BeatmapObjectContainer conflicting, bool removeConflicting = true, bool refreshMap = true) { conflicting = null; if (removeConflicting) { conflicting = LoadedContainers.FirstOrDefault(x => x.objectData._time == obj._time && ((BeatmapObstacle)obj)._lineIndex == ((BeatmapObstacle)x.objectData)._lineIndex && ((BeatmapObstacle)obj)._type == ((BeatmapObstacle)x.objectData)._type && ConflictingByTrackIDs(obj, x.objectData) ); if (conflicting != null) { DeleteObject(conflicting, true, $"Conflicted with a newer object at time {obj._time}"); } } BeatmapObstacleContainer beatmapObstacle = BeatmapObstacleContainer.SpawnObstacle(obj as BeatmapObstacle, AudioTimeSyncController, ref obstaclePrefab, ref obstacleAppearanceSO); beatmapObstacle.transform.SetParent(GridTransform); beatmapObstacle.UpdateGridPosition(); LoadedContainers.Add(beatmapObstacle); if (refreshMap) { SelectionController.RefreshMap(); } return(beatmapObstacle); }
protected override void UpdateContainerData(BeatmapObjectContainer con, BeatmapObject obj) { BeatmapObstacleContainer obstacle = con as BeatmapObstacleContainer; if (!obstacle.IsRotatedByNoodleExtensions) { Track track = tracksManager.GetTrackAtTime(obj._time); track.AttachContainer(con); } foreach (Material mat in obstacle.ModelMaterials) { mat.SetFloat("_CircleRadius", EditorScaleController.EditorScale * 2); if (!mat.HasProperty("_OutsideAlpha")) { continue; } if (AudioTimeSyncController.IsPlaying) { mat.SetFloat("_OutsideAlpha", 0); } else { mat.SetFloat("_OutsideAlpha", mat.GetFloat("_MainAlpha")); } } obstacleAppearanceSO.SetObstacleAppearance(obstacle); }
public static BeatmapObstacleContainer SpawnObstacle(BeatmapObstacle data, AudioTimeSyncController atsc, ref GameObject prefab, ref ObstacleAppearanceSO appearanceSO) { BeatmapObstacleContainer container = Instantiate(prefab).GetComponent <BeatmapObstacleContainer>(); container.obstacleData = data; container.obstacleAppearance = appearanceSO; container.atsc = atsc; appearanceSO.SetObstacleAppearance(container); return(container); }
public override BeatmapObjectContainer SpawnObject(BeatmapObject obj) { BeatmapObjectContainer conflicting = LoadedContainers.FirstOrDefault(x => x.objectData._time == obj._time && (obj as BeatmapObstacle)._lineIndex == (x.objectData as BeatmapObstacle)._lineIndex && (obj as BeatmapObstacle)._type == (x.objectData as BeatmapObstacle)._type ); if (conflicting != null) { DeleteObject(conflicting); } BeatmapObstacleContainer beatmapObstacle = BeatmapObstacleContainer.SpawnObstacle(obj as BeatmapObstacle, AudioTimeSyncController, ref obstaclePrefab, ref obstacleAppearanceSO); beatmapObstacle.transform.SetParent(GridTransform); beatmapObstacle.UpdateGridPosition(); LoadedContainers.Add(beatmapObstacle); return(beatmapObstacle); }
public void SetObstacleAppearance(BeatmapObstacleContainer obj, PlatformDescriptor platform = null) { if (platform != null) { defaultObstacleColor = platform.ObstacleColor; } Renderer[] renderers = obj.GetComponentsInChildren <Renderer>(); foreach (Renderer renderer in renderers) { Material mat = renderer.material; if (obj.obstacleData._duration < 0 && Settings.Instance.ColorFakeWalls) { mat.SetColor(ColorTint, negativeDurationColor); } else { if (obj.obstacleData._customData != null) { Vector2 wallSize = obj.obstacleData._customData["_scale"]?.ReadVector2() ?? Vector2.one; if (wallSize.x < 0 || wallSize.y < 0 && Settings.Instance.ColorFakeWalls) { mat.SetColor(ColorTint, negativeWidthColor); } else { mat.SetColor(ColorTint, defaultObstacleColor); } if (obj.obstacleData._customData["_color"] != null) { mat.SetColor(ColorTint, obj.obstacleData._customData["_color"].ReadColor(defaultObstacleColor)); } } else if (obj.obstacleData._width < 0 && Settings.Instance.ColorFakeWalls) { mat.SetColor(ColorTint, negativeWidthColor); } else { mat.SetColor(ColorTint, defaultObstacleColor); } } } }
protected void UpdateChunks(int nearestChunk) { int distance = AudioTimeSyncController.IsPlaying ? 2 : Settings.Instance.ChunkDistance; foreach (BeatmapObjectContainer e in LoadedContainers) { int chunkID = e.ChunkID; bool isWall = e is BeatmapObstacleContainer; BeatmapObstacleContainer o = isWall ? e as BeatmapObstacleContainer : null; if ((!isWall && chunkID < nearestChunk - distance) || (isWall && o?.ChunkEnd < nearestChunk - distance)) { if (BoxSelectionPlacementController.IsSelecting) { continue; } e.SafeSetActive(false); continue; } if (chunkID > nearestChunk + distance) { if (BoxSelectionPlacementController.IsSelecting) { continue; } e.SafeSetActive(false); continue; } if (TrackFilterID != null) { if ((e.objectData._customData?["track"] ?? "") != TrackFilterID && !IgnoreTrackFilter) { if (BoxSelectionPlacementController.IsSelecting) { continue; } e.SafeSetActive(false); continue; } } e.SafeSetActive(true); } }
public void SetObstacleAppearance(BeatmapObstacleContainer obj) { Renderer[] renderers = obj.GetComponentsInChildren <Renderer>(); foreach (Renderer renderer in renderers) { Material mat = renderer.material; if (obj.obstacleData._duration < 0) { mat.SetColor("_ColorTint", negativeDurationColor); } else if (obj.obstacleData._width <= 0) { mat.SetColor("_ColorTint", negativeWidthColor); } else { mat.SetColor("_ColorTint", defaultObstacleColor); } } }
public void SetObstacleAppearance(BeatmapObstacleContainer obj, PlatformDescriptor platform = null) { if (platform != null) { defaultObstacleColor = platform.colors.ObstacleColor; } foreach (Material mat in obj.ModelMaterials) { if (obj.obstacleData._duration < 0 && Settings.Instance.ColorFakeWalls) { mat.SetColor(ColorTint, negativeDurationColor); } else { if (obj.obstacleData._customData != null) { Vector2 wallSize = obj.obstacleData._customData["_scale"]?.ReadVector2() ?? Vector2.one; if (wallSize.x < 0 || wallSize.y < 0 && Settings.Instance.ColorFakeWalls) { mat.SetColor(ColorTint, negativeWidthColor); } else { mat.SetColor(ColorTint, defaultObstacleColor); } if (obj.obstacleData._customData.HasKey("_color")) { mat.SetColor(ColorTint, obj.obstacleData._customData["_color"].ReadColor(defaultObstacleColor)); } } else if (obj.obstacleData._width < 0 && Settings.Instance.ColorFakeWalls) { mat.SetColor(ColorTint, negativeWidthColor); } else { mat.SetColor(ColorTint, defaultObstacleColor); } } } }
public override BeatmapObjectContainer CreateContainer() => BeatmapObstacleContainer.SpawnObstacle(null, tracksManager, ref obstaclePrefab);
public IEnumerator LoadMap() { if (BeatSaberSongContainer.Instance == null) { yield break; } PersistentUI.Instance.LevelLoadSlider.gameObject.SetActive(true); yield return(new WaitUntil(() => atsc.gridStartPosition != -1)); //I need a way to find out when Start has been called. song = BeatSaberSongContainer.Instance.song; float offset = 0; int environmentID = 0; int batchSize = Settings.Instance.InitialLoadBatchSize; bool customPlat = false; environmentID = SongInfoEditUI.GetEnvironmentIDFromString(song.environmentName); if (song.customData != null && song.customData["_customEnvironment"] != null && song.customData["_customEnvironment"].Value != "") { environmentID = SongInfoEditUI.GetCustomPlatformsIndexFromString(song.customData["_customEnvironment"]); customPlat = true; } GameObject platform = (customPlat ? CustomPlatformPrefabs[environmentID] : PlatformPrefabs[environmentID]) ?? PlatformPrefabs[0]; GameObject instantiate = Instantiate(platform, new Vector3(0, -0.5f, -1.5f), Quaternion.identity); PlatformDescriptor descriptor = instantiate.GetComponent <PlatformDescriptor>(); BeatmapEventContainer.ModifyTypeMode = descriptor.SortMode; PlatformLoadedEvent.Invoke(descriptor); descriptor.RedColor = BeatSaberSongContainer.Instance.difficultyData.colorLeft; descriptor.BlueColor = BeatSaberSongContainer.Instance.difficultyData.colorRight; map = BeatSaberSongContainer.Instance.map; offset = (song.beatsPerMinute / 60) * (BeatSaberSongContainer.Instance.song.songTimeOffset / 1000); int noteLaneSize = 2; //Half of it, anyways int noteLayerSize = 3; Queue <BeatmapObject> queuedData = new Queue <BeatmapObject>( //Take all of our object data and combine them for batch loading. map._notes.Concat <BeatmapObject>(map._obstacles).Concat(map._events).Concat(map._BPMChanges)); totalObjectsToLoad = queuedData.Count; if (map != null) { while (queuedData.Count > 0) { for (int i = 0; i < batchSize; i++) { if (queuedData.Count == 0) { break; } BeatmapObject data = queuedData.Dequeue(); if (data is BeatmapNote noteData) { BeatmapNoteContainer beatmapNote = notesContainer.SpawnObject(noteData) as BeatmapNoteContainer; if (noteData._lineIndex >= 1000 || noteData._lineIndex <= -1000 || noteData._lineLayer >= 1000 || noteData._lineLayer <= -1000) { continue; } if (2 - noteData._lineIndex > noteLaneSize) { noteLaneSize = 2 - noteData._lineIndex; } if (noteData._lineIndex - 1 > noteLaneSize) { noteLaneSize = noteData._lineIndex - 1; } if (noteData._lineLayer + 1 > noteLayerSize) { noteLayerSize = noteData._lineLayer + 1; } } else if (data is BeatmapObstacle obstacleData) { BeatmapObstacleContainer beatmapObstacle = obstaclesContainer.SpawnObject(obstacleData) as BeatmapObstacleContainer; if (obstacleData._lineIndex >= 1000 || obstacleData._lineIndex <= -1000) { continue; } if (2 - obstacleData._lineIndex > noteLaneSize) { noteLaneSize = 2 - obstacleData._lineIndex; } if (obstacleData._lineIndex - 1 > noteLaneSize) { noteLaneSize = obstacleData._lineIndex - 1; } } else if (data is MapEvent eventData) { eventsContainer.SpawnObject(eventData); } else if (data is BeatmapBPMChange bpmData) { bpmContainer.SpawnObject(bpmData); } } UpdateSlider(batchSize); yield return(new WaitForEndOfFrame()); } notesContainer.SortObjects(); obstaclesContainer.SortObjects(); eventsContainer.SortObjects(); bpmContainer.SortObjects(); noteGrid.localScale = new Vector3((float)(noteLaneSize * 2) / 10 + 0.01f, 1, 1); } PersistentUI.Instance.LevelLoadSlider.gameObject.SetActive(false); }
public IEnumerator LoadMap() { if (BeatSaberSongContainer.Instance == null) { yield break; } PersistentUI.Instance.LevelLoadSlider.gameObject.SetActive(true); PersistentUI.Instance.LevelLoadSliderLabel.text = ""; yield return(new WaitUntil(() => atsc.gridStartPosition != -1)); //I need a way to find out when Start has been called. song = BeatSaberSongContainer.Instance.song; //Grab songe data diff = BeatSaberSongContainer.Instance.difficultyData; //Set up some local variables int environmentID = 0; int batchSize = Settings.Instance.InitialLoadBatchSize; bool customPlat = false; environmentID = SongInfoEditUI.GetEnvironmentIDFromString(song.environmentName); //Grab platform by name (Official or Custom) if (song.customData != null && song.customData["_customEnvironment"] != null && song.customData["_customEnvironment"].Value != "") { if (SongInfoEditUI.GetCustomPlatformsIndexFromString(song.customData["_customEnvironment"]) >= 0) { environmentID = SongInfoEditUI.GetCustomPlatformsIndexFromString(song.customData["_customEnvironment"]); customPlat = true; } } //Instantiate platform, grab descriptor GameObject platform = (customPlat ? CustomPlatformPrefabs[environmentID] : PlatformPrefabs[environmentID]) ?? PlatformPrefabs[0]; GameObject instantiate = Instantiate(platform, new Vector3(0, -0.5f, -1.5f), Quaternion.identity); PlatformDescriptor descriptor = instantiate.GetComponent <PlatformDescriptor>(); BeatmapEventContainer.ModifyTypeMode = descriptor.SortMode; //Change sort mode //Update Colors Color leftNote = BeatSaberSong.DEFAULT_LEFTNOTE; //Have default note as base if (descriptor.RedColor != BeatSaberSong.DEFAULT_LEFTCOLOR) { leftNote = descriptor.RedColor; //Prioritize platforms } if (diff.colorLeft != BeatSaberSong.DEFAULT_LEFTNOTE) { leftNote = diff.colorLeft; //Then prioritize custom colors } Color rightNote = BeatSaberSong.DEFAULT_RIGHTNOTE; if (descriptor.BlueColor != BeatSaberSong.DEFAULT_RIGHTCOLOR) { rightNote = descriptor.BlueColor; } if (diff.colorRight != BeatSaberSong.DEFAULT_RIGHTNOTE) { rightNote = diff.colorRight; } notesContainer.UpdateColor(leftNote, rightNote); obstaclesContainer.UpdateColor(diff.obstacleColor); if (diff.colorLeft != BeatSaberSong.DEFAULT_LEFTNOTE) { descriptor.RedColor = diff.colorLeft; } if (diff.colorRight != BeatSaberSong.DEFAULT_RIGHTNOTE) { descriptor.BlueColor = diff.colorRight; } if (diff.envColorLeft != BeatSaberSong.DEFAULT_LEFTCOLOR) { descriptor.RedColor = diff.envColorLeft; } if (diff.envColorRight != BeatSaberSong.DEFAULT_RIGHTCOLOR) { descriptor.BlueColor = diff.envColorRight; } PlatformLoadedEvent.Invoke(descriptor); //Trigger event for classes that use the platform map = BeatSaberSongContainer.Instance.map; //Grab map info, do some stuff int noteLaneSize = 2; //Half of it, anyways int noteLayerSize = 3; Queue <BeatmapObject> queuedData = new Queue <BeatmapObject>( //Take all of our object data and combine them for batch loading. map._notes.Concat <BeatmapObject>(map._obstacles).Concat(map._events).Concat(map._BPMChanges).Concat(map._customEvents)); totalObjectsToLoad = queuedData.Count; if (map != null) { while (queuedData.Count > 0) { //Batch loading is loading a certain amount of objects (Batch Size) every frame, so at least ChroMapper remains active. for (int i = 0; i < batchSize; i++) { if (queuedData.Count == 0) { break; } BeatmapObject data = queuedData.Dequeue(); //Dequeue and load them into ChroMapper. if (data is BeatmapNote noteData) { BeatmapNoteContainer beatmapNote = notesContainer.SpawnObject(noteData, out _) as BeatmapNoteContainer; if (noteData._lineIndex >= 1000 || noteData._lineIndex <= -1000 || noteData._lineLayer >= 1000 || noteData._lineLayer <= -1000) { continue; } if (2 - noteData._lineIndex > noteLaneSize) { noteLaneSize = 2 - noteData._lineIndex; } if (noteData._lineIndex - 1 > noteLaneSize) { noteLaneSize = noteData._lineIndex - 1; } if (noteData._lineLayer + 1 > noteLayerSize) { noteLayerSize = noteData._lineLayer + 1; } } else if (data is BeatmapObstacle obstacleData) { BeatmapObstacleContainer beatmapObstacle = obstaclesContainer.SpawnObject(obstacleData, out _) as BeatmapObstacleContainer; if (obstacleData._lineIndex >= 1000 || obstacleData._lineIndex <= -1000) { continue; } if (2 - obstacleData._lineIndex > noteLaneSize) { noteLaneSize = 2 - obstacleData._lineIndex; } if (obstacleData._lineIndex - 1 > noteLaneSize) { noteLaneSize = obstacleData._lineIndex - 1; } } else if (data is MapEvent eventData) { eventsContainer.SpawnObject(eventData, out _); } else if (data is BeatmapBPMChange bpmData) { bpmContainer.SpawnObject(bpmData, out _); } else if (data is BeatmapCustomEvent customData) { customEventsContainer.SpawnObject(customData, out _); } } UpdateSlider(batchSize); yield return(new WaitForEndOfFrame()); } notesContainer.SortObjects(); //Sort these boyes. obstaclesContainer.SortObjects(); eventsContainer.SortObjects(); bpmContainer.SortObjects(); customEventsContainer.SortObjects(); noteGrid.localScale = new Vector3((float)(noteLaneSize * 2) / 10 + 0.01f, 1, 1); //Set note lanes appropriately } PersistentUI.Instance.LevelLoadSlider.gameObject.SetActive(false); //Disable progress bar LevelLoadedEvent?.Invoke(); }
public BeatmapObstacleDeletionAction(BeatmapObstacleContainer obstacle) : base(obstacle) { }
public BeatmapObstaclePlacementAction(BeatmapObstacleContainer obstacle) : base(obstacle) { }