예제 #1
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);
        }
예제 #2
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);
    }
예제 #3
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);
        }
    }
    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();
    }
예제 #5
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;
        }
    }
예제 #6
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();
    }
예제 #7
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;
            }
        }
    }