Пример #1
0
    private IEnumerator ConvertToLegacy()
    {
        List <BeatmapObject>          ToSpawn   = new List <BeatmapObject>();
        List <BeatmapObjectContainer> ToDestroy = new List <BeatmapObjectContainer>();

        yield return(PersistentUI.Instance.FadeInLoadingScreen());

        if (BeatSaberSongContainer.Instance != null)
        {
            foreach (BeatmapObjectContainer container in notesContainer.LoadedContainers)
            {
                BeatmapNoteContainer note = container as BeatmapNoteContainer;
                if (note.mapNoteData is BeatmapChromaNote)
                {
                    ToSpawn.Add((note.mapNoteData as BeatmapChromaNote).ConvertToNote());
                    BeatmapNote bombData = new BeatmapNote((note.mapNoteData as BeatmapChromaNote).ConvertToNote().ConvertToJSON());
                    bombData._type         = BeatmapNote.NOTE_TYPE_BOMB;
                    bombData._cutDirection = (note.mapNoteData as BeatmapChromaNote).BombRotation;
                    ToSpawn.Add(bombData);
                    ToDestroy.Add(note);
                }
            }
        }
        notesContainer.SortObjects();
        foreach (BeatmapObjectContainer con in ToDestroy)
        {
            notesContainer.DeleteObject(con);
        }
        foreach (BeatmapObject data in ToSpawn)
        {
            notesContainer.SpawnObject(data, out _);
        }
        SelectionController.RefreshMap();
        yield return(PersistentUI.Instance.FadeOutLoadingScreen());
    }
Пример #2
0
    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 &&
                                                          ((BeatmapNote)obj)._lineLayer == ((BeatmapNote)x.objectData)._lineLayer &&
                                                          ((BeatmapNote)obj)._lineIndex == ((BeatmapNote)x.objectData)._lineIndex &&
                                                          ((BeatmapNote)obj)._type == ((BeatmapNote)x.objectData)._type &&
                                                          ConflictingByTrackIDs(obj, x.objectData)
                                                          );
            if (conflicting != null)
            {
                DeleteObject(conflicting, true, $"Conflicted with a newer object at time {obj._time}");
            }
        }
        BeatmapNoteContainer beatmapNote = BeatmapNoteContainer.SpawnBeatmapNote(obj as BeatmapNote, ref notePrefab, ref bombPrefab, ref noteAppearanceSO);

        beatmapNote.transform.SetParent(GridTransform);
        beatmapNote.UpdateGridPosition();
        LoadedContainers.Add(beatmapNote);
        if (Settings.Instance.HighlightLastPlacedNotes)
        {
            beatmapNote.SetOutlineColor(Color.magenta);
        }
        if (refreshMap)
        {
            SelectionController.RefreshMap();
        }
        return(beatmapNote);
    }
Пример #3
0
        private void UpdateNote(BeatmapNoteContainer container, int lineIndex, int lineLayer, int cutDirection)
        {
            var note = (BeatmapNote)container.objectData;

            note._lineIndex    = lineIndex;
            note._lineLayer    = lineLayer;
            note._cutDirection = cutDirection;
            container.UpdateGridPosition();
            container.transform.localEulerAngles = BeatmapNoteContainer.Directionalize(note);
        }
Пример #4
0
    public static BeatmapNoteContainer SpawnBeatmapNote(BeatmapNote noteData, ref GameObject notePrefab, ref GameObject bombPrefab, ref NoteAppearanceSO appearanceSO)
    {
        bool isBomb = noteData._type == BeatmapNote.NOTE_TYPE_BOMB;
        BeatmapNoteContainer container = Instantiate(isBomb ? bombPrefab : notePrefab).GetComponent <BeatmapNoteContainer>();

        container.isBomb         = isBomb;
        container.mapNoteData    = noteData;
        container.noteAppearance = appearanceSO;
        appearanceSO.SetNoteAppearance(container);
        container.Directionalize(noteData._cutDirection);
        container._timeForEditor = noteData._time;
        return(container);
    }
Пример #5
0
    protected override void UpdateContainerData(BeatmapObjectContainer con, BeatmapObject obj)
    {
        BeatmapNoteContainer note     = con as BeatmapNoteContainer;
        BeatmapNote          noteData = obj as BeatmapNote;

        note.SetBomb(noteData._type == BeatmapNote.NOTE_TYPE_BOMB);
        noteAppearanceSO.SetNoteAppearance(note);
        note.Setup();
        note.transform.localEulerAngles = BeatmapNoteContainer.Directionalize(noteData);
        Track track = tracksManager.GetTrackAtTime(obj._time);

        track.AttachContainer(con);
        foreach (Material mat in con.ModelMaterials)
        {
            allNoteRenderers.Add(mat);
            mat.SetFloat("_Rotation", track.RotationValue.y);
        }
    }
Пример #6
0
    public override BeatmapObjectContainer SpawnObject(BeatmapObject obj)
    {
        BeatmapObjectContainer conflicting = LoadedContainers.FirstOrDefault(x => x.objectData._time == obj._time &&
                                                                             (obj as BeatmapNote)._lineLayer == (x.objectData as BeatmapNote)._lineLayer &&
                                                                             (obj as BeatmapNote)._lineIndex == (x.objectData as BeatmapNote)._lineIndex
                                                                             );

        if (conflicting != null)
        {
            DeleteObject(conflicting);
        }
        BeatmapNoteContainer beatmapNote = BeatmapNoteContainer.SpawnBeatmapNote(obj as BeatmapNote, ref notePrefab, ref bombPrefab, ref noteAppearanceSO);

        beatmapNote.transform.SetParent(GridTransform);
        beatmapNote.UpdateGridPosition();
        LoadedContainers.Add(beatmapNote);
        return(beatmapNote);
    }
Пример #7
0
    public override BeatmapObjectContainer SpawnObject(BeatmapObject obj, out BeatmapObjectContainer conflicting, bool removeConflicting = true)
    {
        conflicting = LoadedContainers.FirstOrDefault(x => x.objectData._time == obj._time &&
                                                      (obj as BeatmapNote)._lineLayer == (x.objectData as BeatmapNote)._lineLayer &&
                                                      (obj as BeatmapNote)._lineIndex == (x.objectData as BeatmapNote)._lineIndex &&
                                                      (obj as BeatmapNote)._type == (x.objectData as BeatmapNote)._type &&
                                                      ConflictingByTrackIDs(obj, x.objectData)
                                                      );
        if (conflicting != null && removeConflicting)
        {
            DeleteObject(conflicting);
        }
        BeatmapNoteContainer beatmapNote = BeatmapNoteContainer.SpawnBeatmapNote(obj as BeatmapNote, ref notePrefab, ref bombPrefab, ref noteAppearanceSO);

        beatmapNote.transform.SetParent(GridTransform);
        beatmapNote.UpdateGridPosition();
        LoadedContainers.Add(beatmapNote);
        SelectionController.RefreshMap();
        return(beatmapNote);
    }
    public void UpdateAppearance(BeatmapObjectContainer obj)
    {
        switch (obj)
        {
        case BeatmapNoteContainer note:
            note.transform.localEulerAngles = BeatmapNoteContainer.Directionalize(note.mapNoteData);
            noteAppearance.SetNoteAppearance(note);
            break;

        case BeatmapEventContainer e:
            eventAppearance.SetEventAppearance(e);
            break;

        case BeatmapObstacleContainer o:
            obstacleAppearance.SetObstacleAppearance(o);
            break;
        }
        tracksManager.RefreshTracks();
        obj.UpdateGridPosition();
        SelectionController.RefreshMap();
    }
Пример #9
0
    private IEnumerator ConvertFromLegacy()
    {
        yield return(PersistentUI.Instance.FadeInLoadingScreen());

        List <BeatmapObject>          ToSpawn   = new List <BeatmapObject>();
        List <BeatmapObjectContainer> ToDestroy = new List <BeatmapObjectContainer>();

        if (BeatSaberSongContainer.Instance != null)
        {
            foreach (BeatmapObjectContainer container in notesContainer.LoadedContainers)
            {
                BeatmapNoteContainer note       = container as BeatmapNoteContainer;
                BeatmapNoteContainer chromaBomb = notesContainer.LoadedContainers.Where((BeatmapObjectContainer x) =>
                                                                                        x.objectData._time == note.objectData._time && (x as BeatmapNoteContainer).mapNoteData._type == BeatmapNote.NOTE_TYPE_BOMB &&
                                                                                        (x as BeatmapNoteContainer).mapNoteData._lineIndex == note.mapNoteData._lineIndex &&
                                                                                        (x as BeatmapNoteContainer).mapNoteData._lineLayer == note.mapNoteData._lineLayer
                                                                                        ).FirstOrDefault() as BeatmapNoteContainer;
                if (chromaBomb != null && note.mapNoteData._type != BeatmapNote.NOTE_TYPE_BOMB) //Chroma note PogU
                {
                    BeatmapChromaNote chromaNote = new BeatmapChromaNote(note.mapNoteData);
                    chromaNote.BombRotation = chromaBomb.mapNoteData._cutDirection;
                    ToDestroy.Add(container);
                    ToDestroy.Add(chromaBomb);
                    ToSpawn.Add(chromaNote);
                }
            }
        }
        notesContainer.SortObjects();
        foreach (BeatmapObjectContainer con in ToDestroy)
        {
            notesContainer.DeleteObject(con);
        }
        foreach (BeatmapObject data in ToSpawn)
        {
            notesContainer.SpawnObject(data, out _);
        }
        SelectionController.RefreshMap();
        yield return(PersistentUI.Instance.FadeOutLoadingScreen());
    }
Пример #10
0
 public BeatmapNotePlacementAction(BeatmapNoteContainer note) : base(note)
 {
 }
Пример #11
0
    private void NotePassedThreshold(bool natural, int id, BeatmapObject obj)
    {
        BeatmapNote note = obj as BeatmapNote;

        if (!InstantiatedNotes.ContainsKey(note._type))
        {
            InstantiatedNotes.Add(note._type, new Dictionary <GameObject, Image>());
        }

        if (lastByType.TryGetValue(note._type, out BeatmapNote lastInTime) && lastInTime._time != obj._time)
        {
            foreach (KeyValuePair <GameObject, Image> child in InstantiatedNotes[note._type])
            {
                child.Key.SetActive(false);
            }
        }

        if (note._type == BeatmapNote.NOTE_TYPE_BOMB)
        {
            return;
        }

        float gridPosX = note._lineIndex, gridPosY = note._lineLayer;

        if (note._customData?.HasKey("_position") ?? false)
        {
            Vector2 pos = note._customData["_position"];
            gridPosX = pos.x + 2f;
            gridPosY = pos.y;
        }
        else //mapping extensions ew
        {
            if (gridPosX >= 1000)
            {
                gridPosX = gridPosX / 1000 - 1f;
            }
            else if (gridPosX <= -1000f)
            {
                gridPosX = gridPosX / 1000f + 1f;
            }

            if (gridPosY >= 1000)
            {
                gridPosY = gridPosY / 1000f - 1f;
            }
            else if (gridPosY <= -1000f)
            {
                gridPosY = gridPosY / 1000f + 1f;
            }
        }

        var position = new Vector3(_gridSize * gridPosX, _gridSize * gridPosY, 1);

        if (InstantiatedNotes[note._type].Any(x => x.Key.activeSelf && x.Value.transform.localPosition == position))
        {
            // Note already visible
            return;
        }

        GameObject g;   //Instead of instantiating new objects every frame (Bad on performance), we are instead using a pooled system to use
        Image      img; //Already existing notes, and only create ones we need.

        if (InstantiatedNotes[note._type].Any(x => !x.Key.activeSelf))
        {
            g   = InstantiatedNotes[note._type].First(x => !x.Key.activeSelf).Key;
            img = InstantiatedNotes[note._type][g];
            g.SetActive(true);
            g.transform.SetSiblingIndex(g.transform.parent.childCount);
            foreach (Transform child in g.transform)
            {
                child.gameObject.SetActive(true);
            }
        }
        else
        {
            g   = Instantiate(gridNotePrefab, notes.transform, true);
            img = g.GetComponent <Image>();
            InstantiatedNotes[note._type].Add(g, img);
        }

        var transform1 = img.transform;

        transform1.localPosition = position;
        float sc = scale / 10f + .06f;

        transform1.localScale = new Vector3(sc, sc); //I have to do this because the UI scaling is weird

        //transform1.rotation = o.transform.rotation; //This code breaks when using 360 maps; use local rotation instead.
        transform1.localEulerAngles = Vector3.forward * BeatmapNoteContainer.Directionalize(note).z; //Sets the rotation of the image to match the same rotation as the block
        img.color = note._type == BeatmapNote.NOTE_TYPE_A ? noteAppearance.RedColor : noteAppearance.BlueColor;

        bool dotEnabled = note._cutDirection == BeatmapNote.NOTE_CUT_DIRECTION_ANY; //Checks to see if the Dot is visible on the block

        if (dotEnabled)
        {
            g.transform.GetChild(0).gameObject.SetActive(false);
        }
        else
        {
            g.transform.GetChild(1).gameObject.SetActive(false);
        }
        img.enabled = true;

        if (!lastByType.ContainsKey(note._type))
        {
            lastByType.Add(note._type, note);
        }
        else
        {
            lastByType[note._type] = note;
        }
    }
Пример #12
0
    public void SetNoteAppearance(BeatmapNoteContainer note)
    {
        if (!note.isBomb)
        {
            if (note.gameObject.transform.Find("Bidirectional"))
            {
                Destroy(note.gameObject.transform.Find("Bidirectional").gameObject);
            }
            Transform dot = note.gameObject.transform.Find("NoteDot");
            dot.localScale = new Vector3(0.2f, 0.2f, 0.2f);
            switch (note.mapNoteData._cutDirection)
            {
            case BeatmapNote.NOTE_CUT_DIRECTION_UP:
            case BeatmapNote.NOTE_CUT_DIRECTION_DOWN:
            case BeatmapNote.NOTE_CUT_DIRECTION_LEFT:
            case BeatmapNote.NOTE_CUT_DIRECTION_RIGHT:
            case BeatmapNote.NOTE_CUT_DIRECTION_UP_RIGHT:
            case BeatmapNote.NOTE_CUT_DIRECTION_UP_LEFT:
            case BeatmapNote.NOTE_CUT_DIRECTION_DOWN_LEFT:
            case BeatmapNote.NOTE_CUT_DIRECTION_DOWN_RIGHT:
                //note.SetArrowSprite(arrowSprite);
                note.SetArrowVisible(true);
                note.SetDotVisible(false);
                break;

            case BeatmapNote.NOTE_CUT_DIRECTION_ANY:
                note.SetDotSprite(dotSprite);
                note.SetArrowVisible(false);
                note.SetDotVisible(true);
                break;

            default:
                note.SetDotSprite(dotSprite);
                note.SetArrowVisible(true);
                note.SetDotVisible(false);
                break;
            }

            switch (note.mapNoteData._type)
            {
            case BeatmapNote.NOTE_TYPE_A:
                note.SetModelMaterial(RedInstance);
                break;

            case BeatmapNote.NOTE_TYPE_B:
                note.SetModelMaterial(BlueInstance);
                break;

            default:
                note.SetModelMaterial(unknownNoteMaterial);
                break;
            }
            if (note.mapNoteData is BeatmapChromaNote)
            {
                BeatmapChromaNote chromaNote = note.mapNoteData as BeatmapChromaNote;
                switch (chromaNote.BombRotation)
                {
                case BeatmapChromaNote.ALTERNATE:
                    if (note.mapNoteData._type == BeatmapNote.NOTE_TYPE_A)
                    {
                        note.SetModelMaterial(magentaNoteSharedMaterial);
                    }
                    else if (note.mapNoteData._type == BeatmapNote.NOTE_TYPE_B)
                    {
                        note.SetModelMaterial(greenNoteSharedMaterial);
                    }
                    break;

                case BeatmapChromaNote.BIDIRECTIONAL:
                    note.SetArrowVisible(true);
                    note.SetDotVisible(false);
                    Transform copied = Instantiate(note.gameObject.transform.Find("Direction"), note.transform);
                    copied.gameObject.name  = "Bidirectional";
                    copied.localEulerAngles = new Vector3(0, 0, 180);
                    copied.localPosition    = new Vector3(0, -0.1f, -0.25f);
                    break;

                case BeatmapChromaNote.DUOCHROME:
                    note.SetModelMaterial(duochromeSharedNoteMaterial);
                    break;

                case BeatmapChromaNote.HOT_GARBAGE:
                    note.SetModelMaterial(superNoteSharedMaterial);
                    break;

                case BeatmapChromaNote.DEFLECT:
                    dot.localScale = new Vector3(0.2f, 0.5f, 0.2f);
                    note.SetArrowVisible(false);
                    note.SetDotVisible(true);
                    break;

                case BeatmapChromaNote.MONOCHROME:
                    note.SetModelMaterial(monochromeSharedNoteMaterial);
                    break;
                }
            }
        }
    }
Пример #13
0
    public void RefreshSpecialAngles(BeatmapObject obj, bool objectWasSpawned, bool isNatural)
    {
        // Do not bother refreshing if objects are despawning naturally (while playing back the song)
        if (!objectWasSpawned && isNatural)
        {
            return;
        }
        // Do not do special angles for bombs
        if ((obj as BeatmapNote)._type == BeatmapNote.NOTE_TYPE_BOMB)
        {
            return;
        }
        // Grab all objects with the same type, and time (within epsilon)

        objectsAtSameTime.Clear();
        foreach (var x in LoadedContainers)
        {
            if (!(x.Key._time - Epsilon <= obj._time && x.Key._time + Epsilon >= obj._time &&
                  (x.Key as BeatmapNote)._type == (obj as BeatmapNote)._type))
            {
                continue;
            }

            objectsAtSameTime.Add(x.Value);
        }

        // Only execute if we have exactly 2 notes with the same type
        if (objectsAtSameTime.Count == 2)
        {
            // Due to the potential for "obj" not having a container, we cannot reuse it as "a".
            BeatmapNote a = objectsAtSameTime.First().objectData as BeatmapNote;
            BeatmapNote b = objectsAtSameTime.Last().objectData as BeatmapNote;

            // Grab the containers we will be flipping
            BeatmapObjectContainer containerA = objectsAtSameTime.First();
            BeatmapObjectContainer containerB = objectsAtSameTime.Last();

            // Do not execute if cut directions are not the same (and both are not dot notes)
            if (a._cutDirection != b._cutDirection && a._cutDirection != BeatmapNote.NOTE_CUT_DIRECTION_ANY &&
                b._cutDirection != BeatmapNote.NOTE_CUT_DIRECTION_ANY)
            {
                return;
            }
            if (a._cutDirection == BeatmapNote.NOTE_CUT_DIRECTION_ANY)
            {
                (a, b) = (b, a); // You can flip variables like this in C#. Who knew?
                (containerA, containerB) = (containerB, containerA);
            }
            Vector2 posA      = containerA.transform.localPosition;
            Vector2 posB      = containerB.transform.localPosition;
            Vector2 cutVector = a._cutDirection == BeatmapNote.NOTE_CUT_DIRECTION_ANY ? Vector2.up : Direction(a);
            Vector2 line      = posA - posB;
            float   angle     = SignedAngleToLine(cutVector, line);

            // if both notes are dots, line them up with each other by adding the signed angle.
            if (a._cutDirection == BeatmapNote.NOTE_CUT_DIRECTION_ANY && b._cutDirection == BeatmapNote.NOTE_CUT_DIRECTION_ANY)
            {
                containerA.transform.localEulerAngles = Vector3.forward * angle;
                containerB.transform.localEulerAngles = Vector3.forward * angle;
            }
            else
            {
                Vector3 originalA = BeatmapNoteContainer.Directionalize(a);
                Vector3 originalB = BeatmapNoteContainer.Directionalize(b);
                // We restrict angles below 40 (For 45 just use diagonal notes KEKW)
                if (Mathf.Abs(angle) <= 40)
                {
                    containerA.transform.localEulerAngles = originalA + (Vector3.forward * angle);
                    if (b._cutDirection == BeatmapNote.NOTE_CUT_DIRECTION_ANY && !a.IsMainDirection)
                    {
                        containerB.transform.localEulerAngles = originalB + (Vector3.forward * (angle + 45));
                    }
                    else
                    {
                        containerB.transform.localEulerAngles = originalB + (Vector3.forward * angle);
                    }
                }
            }
        }
        else
        {
            foreach (var toReset in objectsAtSameTime)
            {
                Vector3 direction = BeatmapNoteContainer.Directionalize(toReset.objectData as BeatmapNote);
                toReset.transform.localEulerAngles = direction;
            }
        }
    }
Пример #14
0
 public BeatmapNoteDeletionAction(BeatmapNoteContainer note) : base(note)
 {
 }
Пример #15
0
    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);
    }
Пример #16
0
    public void SetNoteAppearance(BeatmapNoteContainer note)
    {
        if (note.mapNoteData._type != BeatmapNote.NOTE_TYPE_BOMB)
        {
            if (note.gameObject.transform.Find("Bidirectional"))
            {
                Destroy(note.gameObject.transform.Find("Bidirectional").gameObject);
            }
            Transform dot = note.gameObject.transform.Find("NoteDot");
            dot.localScale = new Vector3(0.25f, 0.25f, 0.25f);
            switch (note.mapNoteData._cutDirection)
            {
            case BeatmapNote.NOTE_CUT_DIRECTION_UP:
            case BeatmapNote.NOTE_CUT_DIRECTION_DOWN:
            case BeatmapNote.NOTE_CUT_DIRECTION_LEFT:
            case BeatmapNote.NOTE_CUT_DIRECTION_RIGHT:
            case BeatmapNote.NOTE_CUT_DIRECTION_UP_RIGHT:
            case BeatmapNote.NOTE_CUT_DIRECTION_UP_LEFT:
            case BeatmapNote.NOTE_CUT_DIRECTION_DOWN_LEFT:
            case BeatmapNote.NOTE_CUT_DIRECTION_DOWN_RIGHT:
                note.SetArrowVisible(true);
                note.SetDotVisible(false);
                break;

            case BeatmapNote.NOTE_CUT_DIRECTION_ANY:
                note.SetArrowVisible(false);
                note.SetDotVisible(true);
                break;

            default:
                note.SetArrowVisible(true);
                note.SetDotVisible(false);
                break;
            }

            //Since sometimes the user can hover over the note grid before all the notes are loading,
            //we create material instances here to prevent NullReferenceExceptions.
            switch (note.mapNoteData._type)
            {
            case BeatmapNote.NOTE_TYPE_A:
                note.SetColor(RedColor);
                break;

            case BeatmapNote.NOTE_TYPE_B:
                note.SetColor(BlueColor);
                break;

            default:
                note.SetColor(null);
                break;
            }
            if (note.mapNoteData is BeatmapChromaNote)
            {
                BeatmapChromaNote chromaNote = note.mapNoteData as BeatmapChromaNote;
                switch (chromaNote.BombRotation)
                {
                case BeatmapChromaNote.ALTERNATE:
                    if (note.mapNoteData._type == BeatmapNote.NOTE_TYPE_A)
                    {
                        note.SetModelMaterial(magentaNoteSharedMaterial);
                    }
                    else if (note.mapNoteData._type == BeatmapNote.NOTE_TYPE_B)
                    {
                        note.SetModelMaterial(greenNoteSharedMaterial);
                    }
                    break;

                case BeatmapChromaNote.BIDIRECTIONAL:
                    note.SetArrowVisible(true);
                    note.SetDotVisible(false);
                    Transform copied = Instantiate(note.gameObject.transform.Find("Direction"), note.transform);
                    copied.gameObject.name  = "Bidirectional";
                    copied.localEulerAngles = new Vector3(0, 0, 180);
                    copied.localPosition    = new Vector3(0, -0.1f, -0.25f);
                    break;

                case BeatmapChromaNote.DUOCHROME:
                    note.SetModelMaterial(duochromeSharedNoteMaterial);
                    break;

                case BeatmapChromaNote.HOT_GARBAGE:
                    note.SetModelMaterial(superNoteSharedMaterial);
                    break;

                case BeatmapChromaNote.DEFLECT:
                    dot.localScale = new Vector3(0.25f, 0.5f, 0.25f);
                    note.SetArrowVisible(false);
                    note.SetDotVisible(true);
                    break;

                case BeatmapChromaNote.MONOCHROME:
                    note.SetModelMaterial(monochromeSharedNoteMaterial);
                    break;
                }
            }
        }
        else
        {
            note.SetArrowVisible(false);
            note.SetDotVisible(false);
            note.SetColor(null);
        }
        if (note.mapNoteData._customData?.HasKey("_color") ?? false)
        {
            note.SetColor(note.mapNoteData._customData["_color"]);
        }
    }
Пример #17
0
    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();
    }
Пример #18
0
    public void Mirror()
    {
        if (!SelectionController.HasSelectedObjects())
        {
            PersistentUI.Instance.DisplayMessage("Select stuff first!", PersistentUI.DisplayMessageType.BOTTOM);
            return;
        }
        foreach (BeatmapObjectContainer con in SelectionController.SelectedObjects)
        {
            if (con is BeatmapObstacleContainer obstacle)
            {
                bool precisionWidth = obstacle.obstacleData._width >= 1000;
                int  __state        = obstacle.obstacleData._lineIndex;
                if (__state >= 1000 || __state <= -1000 || precisionWidth) // precision lineIndex
                {
                    int newIndex = __state;
                    if (newIndex <= -1000) // normalize index values, we'll fix them later
                    {
                        newIndex += 1000;
                    }
                    else if (newIndex >= 1000)
                    {
                        newIndex -= 1000;
                    }
                    else
                    {
                        newIndex = newIndex * 1000;               //convert lineIndex to precision if not already
                    }
                    newIndex = (((newIndex - 2000) * -1) + 2000); //flip lineIndex

                    int newWidth = obstacle.obstacleData._width;  //normalize wall width
                    if (newWidth < 1000)
                    {
                        newWidth = newWidth * 1000;
                    }
                    else
                    {
                        newWidth -= 1000;
                    }
                    newIndex = newIndex - newWidth;

                    if (newIndex < 0)
                    { //this is where we fix them
                        newIndex -= 1000;
                    }
                    else
                    {
                        newIndex += 1000;
                    }
                    obstacle.obstacleData._lineIndex = newIndex;
                }
                else // state > -1000 || state < 1000 assumes no precision width
                {
                    int mirrorLane = (((__state - 2) * -1) + 2); //flip lineIndex
                    obstacle.obstacleData._lineIndex = mirrorLane - obstacle.obstacleData._width; //adjust for wall width
                }
                con.UpdateGridPosition();
            }
            else if (con is BeatmapNoteContainer note)
            {
                int __state = note.mapNoteData._lineIndex; // flip line index
                if (__state > 3 || __state < 0)            // precision case
                {
                    int newIndex = __state;
                    if (newIndex <= -1000) // normalize index values, we'll fix them later
                    {
                        newIndex += 1000;
                    }
                    else if (newIndex >= 1000)
                    {
                        newIndex -= 1000;
                    }
                    newIndex = (((newIndex - 1500) * -1) + 1500); //flip lineIndex

                    if (newIndex < 0)                             //this is where we fix them
                    {
                        newIndex -= 1000;
                    }
                    else
                    {
                        newIndex += 1000;
                    }
                    note.mapNoteData._lineIndex = newIndex;
                }
                else
                {
                    int mirrorLane = (int)(((__state - 1.5f) * -1) + 1.5f);
                    note.mapNoteData._lineIndex = mirrorLane;
                }
                con.UpdateGridPosition();

                //flip colors
                if (note.mapNoteData is BeatmapChromaNote chroma)
                {
                    note.mapNoteData = chroma.originalNote;                                               //Revert Chroma status, then invert types
                }
                if (note.mapNoteData._type != BeatmapNote.NOTE_TYPE_BOMB)
                {
                    note.mapNoteData._type = note.mapNoteData._type == BeatmapNote.NOTE_TYPE_A ? BeatmapNote.NOTE_TYPE_B : BeatmapNote.NOTE_TYPE_A;

                    //flip cut direction horizontally
                    if (CutDirectionToMirrored.ContainsKey(note.mapNoteData._cutDirection))
                    {
                        note.mapNoteData._cutDirection  = CutDirectionToMirrored[note.mapNoteData._cutDirection];
                        note.transform.localEulerAngles = BeatmapNoteContainer.Directionalize(note.mapNoteData);
                    }
                }
                noteAppearance.SetNoteAppearance(note);
            }
            else if (con is BeatmapEventContainer e)
            {
                if (e.eventData.IsRotationEvent)
                {
                    int?rotation = e.eventData.GetRotationDegreeFromValue();
                    if (rotation != null)
                    {
                        if (e.eventData._value >= 0 && e.eventData._value < MapEvent.LIGHT_VALUE_TO_ROTATION_DEGREES.Length)
                        {
                            e.eventData._value = MapEvent.LIGHT_VALUE_TO_ROTATION_DEGREES.ToList().IndexOf((rotation ?? 0) * -1);
                        }
                        else if (e.eventData._value >= 1000 && e.eventData._value <= 1720) //Invert Mapping Extensions rotation
                        {
                            e.eventData._value = 1720 - (e.eventData._value - 1000);
                        }
                    }
                    eventAppearance?.SetEventAppearance(e);
                    tracksManager?.RefreshTracks();
                    return;
                }
                if (e.eventData.IsUtilityEvent)
                {
                    return;
                }
                if (e.eventData._value > 4 && e.eventData._value < 8)
                {
                    e.eventData._value -= 4;
                }
                else if (e.eventData._value > 0 && e.eventData._value <= 4)
                {
                    e.eventData._value += 4;
                }
                eventAppearance?.SetEventAppearance(e);
            }
        }
        SelectionController.RefreshMap();
    }
Пример #19
0
    public override BeatmapObjectContainer CreateContainer()
    {
        BeatmapObjectContainer con = BeatmapNoteContainer.SpawnBeatmapNote(null, ref notePrefab);

        return(con);
    }