protected new void LateUpdate()
    {
        // Re-do the controller's position setting
        base.LateUpdate();

        var events = editor.currentChart.events;

        float offset = ChartEventController.BASE_OFFSET;
        int   index, length;

        SongObjectHelper.GetRange(events, chartEvent.tick, chartEvent.tick, out index, out length);

        // Determine the offset for the object
        for (int i = index; i < index + length; ++i)
        {
            if (events[i].GetType() != chartEvent.GetType())
            {
                continue;
            }

            offset += ChartEventController.OFFSET_SPACING;
        }

        transform.position = new Vector3(SongObjectController.CHART_CENTER_POS + ChartEventController.position, chartEvent.worldYPosition, offset);
    }
Exemple #2
0
    public static float GetOffset(ChartEditor editor, ChartEvent chartEvent)
    {
        var events = editor.currentChart.events;

        int offset = 0;
        int index, length;

        SongObjectHelper.GetRange(events, chartEvent.tick, chartEvent.tick, out index, out length);

        // Determine the offset for the object
        for (int i = index; i < index + length; ++i)
        {
            if (events[i].GetType() != chartEvent.GetType())
            {
                continue;
            }

            if (events[i] < chartEvent)
            {
                offset += OFFSET_SPACING;
            }
        }

        return(offset);
    }
Exemple #3
0
    void CollectStarpowerInViewRange(IList <Starpower> starpowers)
    {
        collectedStarpowerInRange.Clear();
        int index, length;

        SongObjectHelper.GetRange(starpowers, editor.minPos, editor.maxPos, out index, out length);
        for (int i = index; i < index + length; ++i)
        {
            collectedStarpowerInRange.Add(starpowers[i]);
        }

        int arrayPos = SongObjectHelper.FindClosestPosition(editor.minPos, editor.currentChart.starPower);

        if (arrayPos != SongObjectHelper.NOTFOUND)
        {
            // Find the back-most position
            while (arrayPos > 0 && editor.currentChart.starPower[arrayPos].tick >= editor.minPos)
            {
                --arrayPos;
            }
            // Render previous sp sustain in case of overlap into current position
            if (arrayPos >= 0 && editor.currentChart.starPower[arrayPos].tick + editor.currentChart.starPower[arrayPos].length > editor.minPos &&
                (editor.currentChart.starPower[arrayPos].tick + editor.currentChart.starPower[arrayPos].length) < editor.maxPos)
            {
                collectedStarpowerInRange.Add(editor.currentChart.starPower[arrayPos]);
            }
        }
    }
Exemple #4
0
    public void EnableSections(IList <Section> sections)
    {
        int index, length;

        SongObjectHelper.GetRange(sections, editor.minPos, editor.maxPos, out index, out length);
        sectionPool.Activate(sections, index, length);
    }
    public static void PerformPreChartInsertCorrections(Note note, Chart chart, IList <BaseAction> subActions, bool extendedSustainsEnabled)
    {
        int index, length;

        SongObjectHelper.GetRange(chart.chartObjects, note.tick, note.tick, out index, out length);

        // Account for when adding an exact note as what's already in
        if (length > 0)
        {
            for (int i = index + length - 1; i >= index; --i)
            {
                Note overwriteNote = chart.chartObjects[i] as Note;
                if (overwriteNote == null)
                {
                    continue;
                }

                bool sameFret = note.guitarFret == overwriteNote.guitarFret;
                bool isOverwritableOpenNote = (note.IsOpenNote() || overwriteNote.IsOpenNote()) && !Globals.drumMode;
                if (isOverwritableOpenNote || sameFret)
                {
                    SongEditCommand.AddAndInvokeSubAction(new DeleteAction(overwriteNote), subActions);
                }
            }
        }
    }
Exemple #6
0
    public void EnableChartEvents(IList <ChartEvent> events)
    {
        int index, length;

        SongObjectHelper.GetRange(events, editor.minPos, editor.maxPos, out index, out length);
        chartEventPool.Activate(events, index, length);
    }
Exemple #7
0
    public void EnableSongEvents(IList <MoonscraperChartEditor.Song.Event> events)
    {
        int index, length;

        SongObjectHelper.GetRange(events, editor.minPos, editor.maxPos, out index, out length);
        songEventPool.Activate(events, index, length);
    }
    protected new void LateUpdate()
    {
        base.LateUpdate();

        // Re-do the controller's position setting
        var events = editor.currentSong.events;

        int offset = 0;
        int index, length;

        SongObjectHelper.GetRange(events, songEvent.tick, songEvent.tick, out index, out length);

        // Determine the offset for the object
        for (int i = index; i < index + length; ++i)
        {
            if (events[i].GetType() != songEvent.GetType())
            {
                continue;
            }

            offset += EventController.OFFSET_SPACING;
        }

        transform.position = new Vector3(SongObjectController.CHART_CENTER_POS + EventController.position + offset, songEvent.worldYPosition, 0);
    }
Exemple #9
0
    public void EnableBPM(IList <BPM> bpms)
    {
        int index, length;

        SongObjectHelper.GetRange(bpms, editor.minPos, editor.maxPos, out index, out length);

        bpmPool.Activate(bpms, index, length);
    }
Exemple #10
0
    public void EnableTS(IList <TimeSignature> timeSignatures)
    {
        int index, length;

        SongObjectHelper.GetRange(timeSignatures, editor.minPos, editor.maxPos, out index, out length);

        tsPool.Activate(timeSignatures, index, length);
    }
Exemple #11
0
    // Update is called once per frame
    public override void SystemUpdate()
    {
        int index, length;
        IList <SongObject> viewRange = editor.selectedObjectsManager.currentSelectedObjects;

        SongObjectHelper.GetRange(viewRange, editor.minPos, editor.maxPos, out index, out length);

        var  currentTool   = ChartEditor.Instance.toolManager.currentToolId;
        bool validTool     = currentTool != EditorObjectToolManager.ToolID.Note && currentTool != EditorObjectToolManager.ToolID.Starpower;
        bool showHighlight = editor.currentState != ChartEditor.State.Playing && validTool;

        int pos = index;

        foreach (GameObject selectedHighlight in selectedHighlightPool)
        {
            if (showHighlight && pos < index + length && viewRange[pos].controller != null && viewRange[pos].controller.gameObject.activeSelf)
            {
                selectedHighlight.transform.position = viewRange[pos].controller.transform.position;

                Collider   col3d = viewRange[pos].controller.GetComponent <Collider>();
                Collider2D col   = viewRange[pos].controller.GetComponent <Collider2D>();

                Vector3 scale = viewRange[pos].controller.transform.localScale;

                if (col3d)
                {
                    scale = col3d.bounds.size;
                }
                else
                {
                    scale = col.bounds.size;
                }

                if (scale.z == 0)
                {
                    scale.z = 0.1f;
                }
                selectedHighlight.transform.localScale = scale;

                selectedHighlight.SetActive(true);
                ++pos;
            }
            else
            {
                if (!selectedHighlight.activeSelf)
                {
                    break;
                }

                selectedHighlight.SetActive(false);
            }
        }
    }
    // Update is called once per frame
    void Update()
    {
        int index, length;

        SongObject[] viewRange = editor.currentSelectedObjects;
        SongObjectHelper.GetRange(viewRange, editor.minPos, editor.maxPos, out index, out length);

        bool showHighlight = (Globals.applicationMode != Globals.ApplicationMode.Playing &&
                              (Toolpane.currentTool != Toolpane.Tools.Note && Toolpane.currentTool != Toolpane.Tools.Starpower)
                              /*(Toolpane.currentTool == Toolpane.Tools.Cursor || Toolpane.currentTool == Toolpane.Tools.Eraser || Toolpane.currentTool == Toolpane.Tools.GroupSelect)*/);

        int pos = index;

        foreach (GameObject selectedHighlight in selectedHighlightPool)
        {
            if (showHighlight && pos < index + length && viewRange[pos].controller != null && viewRange[pos].controller.gameObject.activeSelf)
            {
                selectedHighlight.transform.position = viewRange[pos].controller.transform.position;

                Collider   col3d = viewRange[pos].controller.GetComponent <Collider>();
                Collider2D col   = viewRange[pos].controller.GetComponent <Collider2D>();

                Vector3 scale = viewRange[pos].controller.transform.localScale;

                if (col3d)
                {
                    scale = col3d.bounds.size;
                }
                else
                {
                    scale = col.bounds.size;
                }

                if (scale.z == 0)
                {
                    scale.z = 0.1f;
                }
                selectedHighlight.transform.localScale = scale;

                selectedHighlight.SetActive(true);
                ++pos;
            }
            else
            {
                if (!selectedHighlight.activeSelf)
                {
                    break;
                }

                selectedHighlight.SetActive(false);
            }
        }
    }
Exemple #13
0
    public void SetInViewRangeDirty <T>(IList <T> songObjects) where T : SongObject
    {
        int index, length;

        SongObjectHelper.GetRange(songObjects, editor.minPos, editor.maxPos, out index, out length);

        for (int i = index; i < index + length; ++i)
        {
            if (songObjects[i].controller)
            {
                songObjects[i].controller.SetDirty();
            }
        }
    }
Exemple #14
0
    public static void SetNotesDirty(Starpower sp, IList <ChartObject> notes)
    {
        int start, length;

        SongObjectHelper.GetRange(notes, sp.tick, sp.tick + sp.length, out start, out length);

        for (int i = start; i < start + length; ++i)
        {
            if (notes[i].classID == (int)SongObject.ID.Note && notes[i].controller)
            {
                notes[i].controller.SetDirty();
            }
        }
    }
    static void SetNotesDirty(Starpower sp)
    {
        int start, length;
        var notes = sp.chart.notes;

        SongObjectHelper.GetRange(notes, sp.tick, sp.tick + sp.length, out start, out length);

        for (int i = start; i < start + length; ++i)
        {
            if (notes[i].controller)
            {
                notes[i].controller.SetDirty();
            }
        }
    }
    public static int ExpensiveGetExtendedSustainMask(this Note note)
    {
        int mask = 0;

        if (note.length > 0 && note.chart != null)
        {
            int index, length;
            var notes = note.chart.notes;
            SongObjectHelper.GetRange(notes, note.tick, note.tick + note.length - 1, out index, out length);

            for (int i = index; i < index + length; ++i)
            {
                mask |= notes[i].mask;
            }
        }

        return(mask);
    }
Exemple #17
0
    ChartObject[] ScanArea(Vector2 cornerA, Vector2 cornerB, uint minLimitInclusive, uint maxLimitNonInclusive)
    {
        Clipboard.SelectionArea area = new Clipboard.SelectionArea(cornerA, cornerB, minLimitInclusive, maxLimitNonInclusive);
        Rect areaRect = area.GetRect(editor.currentSong);

        List <ChartObject> chartObjectsList = new List <ChartObject>();
        int index, length;
        var chartObjects = editor.currentChart.chartObjects;

        SongObjectHelper.GetRange(chartObjects, minLimitInclusive, maxLimitNonInclusive, out index, out length);

        for (int i = index; i < index + length; ++i)
        {
            if (chartObjects[i].tick < maxLimitNonInclusive && PrefabGlobals.HorizontalCollisionCheck(PrefabGlobals.GetCollisionRect(chartObjects[i]), areaRect))
            {
                chartObjectsList.Add(chartObjects[i]);
            }
        }

        return(chartObjectsList.ToArray());
    }
    void UpdateLastPlacedSp()
    {
        uint prevSpLength = lastPlacedSP.length;

        lastPlacedSP.SetLengthByPos(objectSnappedChartPos);

        if (prevSpLength != lastPlacedSP.length)
        {
            int  index, length;
            var  notes     = editor.currentChart.notes;
            uint maxLength = prevSpLength > lastPlacedSP.length ? prevSpLength : lastPlacedSP.length;

            SongObjectHelper.GetRange(notes, lastPlacedSP.tick, lastPlacedSP.tick + maxLength, out index, out length);

            for (int i = index; i < index + length; ++i)
            {
                if (notes[i].controller)
                {
                    notes[i].controller.SetDirty();
                }
            }
        }
    }
    void TailDrag()
    {
        ChartEditor.isDirty = true;
        uint snappedChartPos;

        if (Mouse.world2DPosition != null && ((Vector2)Mouse.world2DPosition).y < editor.mouseYMaxLimit.position.y)
        {
            snappedChartPos = Snapable.TickToSnappedTick(starpower.song.WorldYPositionToTick(((Vector2)Mouse.world2DPosition).y), GameSettings.step, starpower.song.resolution);
        }
        else
        {
            snappedChartPos = Snapable.TickToSnappedTick(starpower.song.WorldYPositionToTick(editor.mouseYMaxLimit.position.y), GameSettings.step, starpower.song.resolution);
        }

        uint max = starpower.length;

        starpower.SetLengthByPos(snappedChartPos);

        if (starpower.length > max)
        {
            max = starpower.length;
        }

        int start, length;
        var notes = starpower.chart.notes;

        SongObjectHelper.GetRange(notes, starpower.tick, starpower.tick + max, out start, out length);

        for (int i = start; i < start + length; ++i)
        {
            if (notes[i].controller)
            {
                notes[i].controller.SetDirty();
            }
        }
    }
    public static float GetOffset(ChartEditor editor, Event songEvent)
    {
        var events = editor.currentSong.events;

        int index, length;

        SongObjectHelper.GetRange(events, songEvent.tick, songEvent.tick, out index, out length);

        // Determine the offset for the object
        for (int i = index; i < index + length; ++i)
        {
            if (events[i].GetType() != songEvent.GetType())
            {
                continue;
            }

            if (events[i] == songEvent)
            {
                return(BASE_OFFSET + (length - (i - index) - 1) * OFFSET_SPACING);
            }
        }

        return(BASE_OFFSET);
    }
    public static ActionHistory.Action[] AddObjectToCurrentChart(Note note, ChartEditor editor, out Note addedNote, bool update = true, bool copy = true)
    {
        List <ActionHistory.Action> noteRecord = new List <ActionHistory.Action>();

        int index, length;

        SongObjectHelper.GetRange(editor.currentChart.notes, note.tick, note.tick, out index, out length);

        // Account for when adding an exact note as what's already in
        if (length > 0)
        {
            bool cancelAdd = false;
            for (int i = index; i < index + length; ++i)
            {
                Note overwriteNote = editor.currentChart.notes[i];

                if (note.AllValuesCompare(overwriteNote))
                {
                    cancelAdd = true;
                    break;
                }
                if ((((note.IsOpenNote() || overwriteNote.IsOpenNote()) && !Globals.drumMode) || note.guitarFret == overwriteNote.guitarFret) && !note.AllValuesCompare(overwriteNote))
                {
                    noteRecord.Add(new ActionHistory.Delete(overwriteNote));
                }
            }
            if (!cancelAdd)
            {
                noteRecord.Add(new ActionHistory.Add(note));
            }
        }
        else
        {
            noteRecord.Add(new ActionHistory.Add(note));
        }

        Note noteToAdd;

        if (copy)
        {
            noteToAdd = new Note(note);
        }
        else
        {
            noteToAdd = note;
        }

        if (noteToAdd.IsOpenNote())
        {
            noteToAdd.flags &= ~Note.Flags.Tap;
        }

        editor.currentChart.Add(noteToAdd, update);
        if (noteToAdd.cannotBeForced)
        {
            noteToAdd.flags &= ~Note.Flags.Forced;
        }

        noteToAdd.ApplyFlagsToChord();

        //NoteController nCon = editor.CreateNoteObject(noteToAdd);
        standardOverwriteOpen(noteToAdd);

        noteRecord.InsertRange(0, CapNoteCheck(noteToAdd));
        noteRecord.InsertRange(0, ForwardCap(noteToAdd));     // Do this due to pasting from the clipboard

        // Check if the automatic un-force will kick in
        ActionHistory.Action forceCheck = AutoForcedCheck(noteToAdd);

        addedNote = noteToAdd;

        if (forceCheck != null)
        {
            noteRecord.Insert(0, forceCheck);           // Insert at the start so that the modification happens at the end of the undo function, otherwise the natural force check prevents it from being forced
        }
        foreach (Note chordNote in addedNote.chord)
        {
            if (chordNote.controller)
            {
                chordNote.controller.SetDirty();
            }
        }

        Note next = addedNote.nextSeperateNote;

        if (next != null)
        {
            foreach (Note chordNote in next.chord)
            {
                if (chordNote.controller)
                {
                    chordNote.controller.SetDirty();
                }
            }
        }

        return(noteRecord.ToArray());
    }
    public override void OnSelectableMouseDown()
    {
        if (editor.toolManager.currentToolId == EditorObjectToolManager.ToolID.Cursor && editor.currentState == ChartEditor.State.Editor && Input.GetMouseButtonDown(0) && !Input.GetMouseButton(1))
        {
            var selectedObjectsManager = editor.selectedObjectsManager;

            // Ctrl-clicking
            if (Globals.modifierInputActive)
            {
                if (selectedObjectsManager.IsSelected(songObject))
                {
                    selectedObjectsManager.RemoveFromSelectedObjects(songObject);
                }
                else
                {
                    selectedObjectsManager.AddToSelectedObjects(songObject);
                }

                return;
            }

            // Shift-clicking
            if (Globals.secondaryInputActive)
            {
                int pos = SongObjectHelper.FindClosestPosition(this.songObject, editor.selectedObjectsManager.currentSelectedObjects);

                if (pos != SongObjectHelper.NOTFOUND)
                {
                    uint min;
                    uint max;

                    if (editor.selectedObjectsManager.currentSelectedObjects[pos].tick > songObject.tick)
                    {
                        max = editor.selectedObjectsManager.currentSelectedObjects[pos].tick;
                        min = songObject.tick;
                    }
                    else
                    {
                        min = editor.selectedObjectsManager.currentSelectedObjects[pos].tick;
                        max = songObject.tick;
                    }

                    var chartObjects = editor.currentChart.chartObjects;
                    int index, length;
                    SongObjectHelper.GetRange(chartObjects, min, max, out index, out length);
                    selectedObjectsManager.SetCurrentSelectedObjects(chartObjects, index, length);

                    return;
                }
            }

            // Regular clicking
            if (!selectedObjectsManager.IsSelected(songObject))
            {
                if (MSChartEditorInput.GetInput(MSChartEditorInputActions.ChordSelect))
                {
                    selectedObjectsManager.SetCurrentSelectedObjects(note.chord);
                }
                else
                {
                    selectedObjectsManager.currentSelectedObject = songObject;
                }

                return;
            }
        }

        // Delete the object on left and right click shortcut
        else if (editor.currentState == ChartEditor.State.Editor &&
                 Input.GetMouseButtonDown(0) && Input.GetMouseButton(1))
        {
            if (MSChartEditorInput.GetInput(MSChartEditorInputActions.ChordSelect))
            {
                Note[] chordNotes = note.GetChord();
                if (Input.GetMouseButton(1))
                {
                    if (SustainController.SustainDraggingInProgress)
                    {
                        editor.commandStack.Pop();  // Cancel the last sustain drag action
                    }
                    Debug.Log("Deleted " + note + " chord at position " + note.tick + " with hold-right left-click shortcut");
                    editor.commandStack.Push(new SongEditDelete(chordNotes));

                    SustainController.ResetSustainDragData();
                }
            }
            else if (Input.GetMouseButton(1))
            {
                if (SustainController.SustainDraggingInProgress)
                {
                    editor.commandStack.Pop();    // Cancel the last sustain drag action
                }
                Debug.Log("Deleted " + note + " at position " + note.tick + " with hold-right left-click shortcut");
                editor.commandStack.Push(new SongEditDelete(note));
                SustainController.ResetSustainDragData();
            }
        }
        else
        {
            sustain.OnSelectableMouseDown();
        }
    }
    private static void ReadNotes(IList <MidiEvent> track, Song song, Song.Instrument instrument)
    {
        List <NoteOnEvent> forceNotesList    = new List <NoteOnEvent>();
        List <NoteOnEvent> proDrumsNotesList = new List <NoteOnEvent>();
        List <SysexEvent>  tapAndOpenEvents  = new List <SysexEvent>();

        Chart unrecognised = new Chart(song, Song.Instrument.Unrecognised);

        Chart.GameMode gameMode = Song.InstumentToChartGameMode(instrument);

        if (instrument == Song.Instrument.Unrecognised)
        {
            song.unrecognisedCharts.Add(unrecognised);
        }

        int rbSustainFixLength = (int)(64 * song.resolution / SongConfig.STANDARD_BEAT_RESOLUTION);

        // Load all the notes
        for (int i = 0; i < track.Count; i++)
        {
            var text = track[i] as TextEvent;
            if (text != null)
            {
                if (i == 0)
                {
                    if (instrument == Song.Instrument.Unrecognised)
                    {
                        unrecognised.name = text.Text;
                    }
                    continue;           // We don't want the first event because that is the name of the track
                }

                var        tick       = (uint)text.AbsoluteTime;
                var        eventName  = text.Text.Trim(new char[] { '[', ']' });
                ChartEvent chartEvent = new ChartEvent(tick, eventName);

                if (instrument == Song.Instrument.Unrecognised)
                {
                    unrecognised.Add(chartEvent);
                }
                else
                {
                    song.GetChart(instrument, Song.Difficulty.Expert).Add(chartEvent);
                }
            }

            var note = track[i] as NoteOnEvent;
            if (note != null && note.OffEvent != null)
            {
                Song.Difficulty difficulty;

                var tick = (uint)note.AbsoluteTime;
                var sus  = (uint)(note.OffEvent.AbsoluteTime - tick);

                if (instrument == Song.Instrument.Unrecognised)
                {
                    int  rawNote = SelectRawNoteValue(note.NoteNumber);
                    Note newNote = new Note(tick, rawNote, sus);
                    //difficulty = SelectRawNoteDifficulty(note.NoteNumber);
                    unrecognised.Add(newNote);
                    continue;
                }

                // Check if starpower event
                if (note.NoteNumber == MidIOHelper.STARPOWER_NOTE)
                {
                    foreach (Song.Difficulty diff in EnumX <Song.Difficulty> .Values)
                    {
                        song.GetChart(instrument, diff).Add(new Starpower(tick, sus), false);
                    }

                    continue;
                }

                if (note.NoteNumber == MidIOHelper.SOLO_NOTE)
                {
                    foreach (Song.Difficulty diff in EnumX <Song.Difficulty> .Values)
                    {
                        Chart chart = song.GetChart(instrument, diff);
                        chart.Add(new ChartEvent(tick, MidIOHelper.SoloEventText));
                        chart.Add(new ChartEvent(tick + sus, MidIOHelper.SoloEndEventText));
                    }

                    continue;
                }

                if (gameMode == Chart.GameMode.Drums)
                {
                    Note.DrumPad dummy;
                    if (MidIOHelper.CYMBAL_TO_PAD_LOOKUP.TryGetValue(note.NoteNumber, out dummy))
                    {
                        // Cymbals toggles
                        proDrumsNotesList.Add(note);
                        continue;
                    }
                }

                // Determine which difficulty we are manipulating
                try
                {
                    if (gameMode == Chart.GameMode.GHLGuitar)
                    {
                        difficulty = SelectGHLNoteDifficulty(note.NoteNumber);
                    }
                    else
                    {
                        difficulty = SelectNoteDifficulty(note.NoteNumber);
                    }
                }
                catch
                {
                    continue;
                }

                // Check if we're reading a forcing event instead of a regular note
                if (gameMode != Chart.GameMode.Drums)
                {
                    switch (note.NoteNumber)
                    {
                    case 65:
                    case 66:
                    case 77:
                    case 78:
                    case 89:
                    case 90:
                    case 101:
                    case 102:
                        forceNotesList.Add(note);           // Store the event for later processing and continue
                        continue;

                    default:
                        break;
                    }
                }

                int fret;

                if (sus <= rbSustainFixLength)
                {
                    sus = 0;
                }

                Note.Flags flags = Note.Flags.None;

                if (gameMode == Chart.GameMode.Drums)
                {
                    fret = (int)GetDrumFretType(note.NoteNumber);

                    int cymbalToggleId;
                    if (MidIOHelper.PAD_TO_CYMBAL_LOOKUP.TryGetValue((Note.DrumPad)fret, out cymbalToggleId))
                    {
                        flags |= Note.Flags.ProDrums_Cymbal;
                    }
                }
                else if (gameMode == Chart.GameMode.GHLGuitar)
                {
                    fret = (int)GetGHLFretType(note.NoteNumber);
                }
                else
                {
                    fret = (int)GetStandardFretType(note.NoteNumber);
                }

                {
                    // Add the note to the correct chart
                    Note newNote = new Note(tick, fret, sus, flags);
                    song.GetChart(instrument, difficulty).Add(newNote, false);
                }
            }

            var sysexEvent = track[i] as SysexEvent;
            if (sysexEvent != null)
            {
                tapAndOpenEvents.Add(sysexEvent);
            }
        }

        // Update all chart arrays
        if (instrument != Song.Instrument.Unrecognised)
        {
            foreach (Song.Difficulty diff in EnumX <Song.Difficulty> .Values)
            {
                song.GetChart(instrument, diff).UpdateCache();
            }
        }
        else
        {
            unrecognised.UpdateCache();
        }

        // Apply tap and open note events
        Chart[] chartsOfInstrument;

        if (instrument == Song.Instrument.Unrecognised)
        {
            chartsOfInstrument = new Chart[] { unrecognised };
        }
        else
        {
            chartsOfInstrument = new Chart[EnumX <Song.Difficulty> .Count];

            int difficultyCount = 0;
            foreach (Song.Difficulty difficulty in EnumX <Song.Difficulty> .Values)
            {
                chartsOfInstrument[difficultyCount++] = song.GetChart(instrument, difficulty);
            }
        }

        for (int i = 0; i < tapAndOpenEvents.Count; ++i)
        {
            var    se1   = tapAndOpenEvents[i];
            byte[] bytes = se1.GetData();

            // Check for tap event
            if (bytes.Length == 8 && bytes[5] == 255 && bytes[7] == 1)
            {
                // Identified a tap section
                // 8 total bytes, 5th byte is FF, 7th is 1 to start, 0 to end
                uint tick   = (uint)se1.AbsoluteTime;
                uint endPos = 0;

                // Find the end of the tap section
                for (int j = i; j < tapAndOpenEvents.Count; ++j)
                {
                    var se2    = tapAndOpenEvents[j];
                    var bytes2 = se2.GetData();
                    /// Check for tap section end
                    if (bytes2.Length == 8 && bytes2[5] == 255 && bytes2[7] == 0)
                    {
                        endPos = (uint)(se2.AbsoluteTime - tick);

                        if (endPos > 0)
                        {
                            --endPos;
                        }

                        break;
                    }
                }

                // Apply tap property
                foreach (Chart chart in chartsOfInstrument)
                {
                    int index, length;
                    SongObjectHelper.GetRange(chart.notes, tick, tick + endPos, out index, out length);
                    for (int k = index; k < index + length; ++k)
                    {
                        chart.notes[k].SetType(Note.NoteType.Tap);
                    }
                }
            }

            // Check for open notes
            // 5th byte determines the difficulty to apply to
            else if (bytes.Length == 8 && bytes[5] >= 0 && bytes[5] < 4 && bytes[7] == 1)
            {
                uint            tick = (uint)se1.AbsoluteTime;
                Song.Difficulty difficulty;
                switch (bytes[5])
                {
                case 0: difficulty = Song.Difficulty.Easy; break;

                case 1: difficulty = Song.Difficulty.Medium; break;

                case 2: difficulty = Song.Difficulty.Hard; break;

                case 3: difficulty = Song.Difficulty.Expert; break;

                default: continue;
                }

                uint endPos = 0;
                for (int j = i; j < tapAndOpenEvents.Count; ++j)
                {
                    var se2 = tapAndOpenEvents[j] as SysexEvent;
                    if (se2 != null)
                    {
                        var b2 = se2.GetData();
                        if (b2.Length == 8 && b2[5] == bytes[5] && b2[7] == 0)
                        {
                            endPos = (uint)(se2.AbsoluteTime - tick);

                            if (endPos > 0)
                            {
                                --endPos;
                            }

                            break;
                        }
                    }
                }

                int index, length;
                SongObjectCache <Note> notes;
                if (instrument == Song.Instrument.Unrecognised)
                {
                    notes = unrecognised.notes;
                }
                else
                {
                    notes = song.GetChart(instrument, difficulty).notes;
                }
                SongObjectHelper.GetRange(notes, tick, tick + endPos, out index, out length);
                for (int k = index; k < index + length; ++k)
                {
                    notes[k].guitarFret = Note.GuitarFret.Open;

                    if (gameMode == Chart.GameMode.Drums)
                    {
                        notes[k].guitarFret = NoteFunctions.LoadDrumNoteToGuitarNote(notes[k].guitarFret);
                    }
                }
            }
        }

        // Apply forcing events
        foreach (NoteOnEvent flagEvent in forceNotesList)
        {
            uint tick   = (uint)flagEvent.AbsoluteTime;
            uint endPos = (uint)(flagEvent.OffEvent.AbsoluteTime - tick);

            Song.Difficulty difficulty;

            // Determine which difficulty we are manipulating
            try
            {
                difficulty = SelectNoteDifficulty(flagEvent.NoteNumber);
            }
            catch
            {
                continue;
            }

            Chart chart;
            if (instrument != Song.Instrument.Unrecognised)
            {
                chart = song.GetChart(instrument, difficulty);
            }
            else
            {
                chart = unrecognised;
            }

            int index, length;
            SongObjectHelper.GetRange(chart.notes, tick, tick + endPos, out index, out length);

            for (int i = index; i < index + length; ++i)
            {
                if ((chart.notes[i].flags & Note.Flags.Tap) != 0)
                {
                    continue;
                }

                // if NoteNumber is odd force hopo, if even force strum
                if (flagEvent.NoteNumber % 2 != 0)
                {
                    chart.notes[i].SetType(Note.NoteType.Hopo);
                }
                else
                {
                    chart.notes[i].SetType(Note.NoteType.Strum);
                }
            }
        }

        foreach (var flagEvent in proDrumsNotesList)
        {
            uint tick   = (uint)flagEvent.AbsoluteTime;
            uint endPos = (uint)(flagEvent.OffEvent.AbsoluteTime - tick);
            if (endPos > 0)
            {
                --endPos;
            }

            Debug.Assert(instrument == Song.Instrument.Drums);

            foreach (Song.Difficulty difficulty in EnumX <Song.Difficulty> .Values)
            {
                Chart chart = song.GetChart(instrument, difficulty);

                int index, length;
                SongObjectHelper.GetRange(chart.notes, tick, tick + endPos, out index, out length);

                Note.DrumPad drumPadForFlag;
                if (!MidIOHelper.CYMBAL_TO_PAD_LOOKUP.TryGetValue(flagEvent.NoteNumber, out drumPadForFlag))
                {
                    Debug.Assert(false, "Unknown note number flag " + flagEvent.NoteNumber);
                    continue;
                }

                for (int i = index; i < index + length; ++i)
                {
                    Note note = chart.notes[i];

                    if (note.drumPad == drumPadForFlag)
                    {
                        // Reverse cymbal flag
                        note.flags ^= Note.Flags.ProDrums_Cymbal;
                    }
                }
            }
        }
    }
    public override void OnSelectableMouseDown()
    {
        if (Toolpane.currentTool == Toolpane.Tools.Cursor && Globals.applicationMode == Globals.ApplicationMode.Editor && Input.GetMouseButtonDown(0) && !Input.GetMouseButton(1))
        {
            // Shift-clicking
            // Find the closest object already selected
            // Select all objects in range of that found and the clicked object

            if (Globals.viewMode == Globals.ViewMode.Chart && (Globals.modifierInputActive || Globals.secondaryInputActive))
            {
                // Ctrl-clicking
                if (Globals.modifierInputActive)
                {
                    if (editor.IsSelected(songObject))
                    {
                        editor.RemoveFromSelectedObjects(songObject);
                    }
                    else
                    {
                        editor.AddToSelectedObjects(songObject);
                    }
                }
                // Shift-clicking
                else
                {
                    int pos = SongObjectHelper.FindClosestPosition(this.songObject, editor.currentSelectedObjects);

                    if (pos != SongObjectHelper.NOTFOUND)
                    {
                        uint min;
                        uint max;

                        if (editor.currentSelectedObjects[pos].tick > songObject.tick)
                        {
                            max = editor.currentSelectedObjects[pos].tick;
                            min = songObject.tick;
                        }
                        else
                        {
                            min = editor.currentSelectedObjects[pos].tick;
                            max = songObject.tick;
                        }

                        var chartObjects = editor.currentChart.chartObjects;
                        int index, length;
                        SongObjectHelper.GetRange(chartObjects, min, max, out index, out length);
                        editor.currentSelectedObjects.Clear();
                        for (int i = index; i < index + length; ++i)
                        {
                            editor.currentSelectedObjects.Add(chartObjects[i]);
                        }
                    }
                }
            }
            else if (!editor.IsSelected(songObject))
            {
                editor.currentSelectedObject = songObject;
            }
        }

        // Delete the object on erase tool or by holding right click and pressing left-click
        else if (Globals.applicationMode == Globals.ApplicationMode.Editor &&
                 Input.GetMouseButtonDown(0) && Input.GetMouseButton(1)
                 )
        {
            if ((songObject.classID != (int)SongObject.ID.BPM && songObject.classID != (int)SongObject.ID.TimeSignature) || songObject.tick != 0)
            {
                if (Input.GetMouseButton(1))
                {
                    Debug.Log("Deleted " + songObject + " at position " + songObject.tick + " with hold-right left-click shortcut");
                    editor.commandStack.Push(new SongEditDelete(songObject));
                }
                editor.currentSelectedObject = null;
            }
        }
    }
    SongObject[] ScanArea(Vector2 cornerA, Vector2 cornerB, uint minLimitInclusive, uint maxLimitNonInclusive)
    {
        Clipboard.SelectionArea area = new Clipboard.SelectionArea(cornerA, cornerB, minLimitInclusive, maxLimitNonInclusive);
        Rect areaRect = area.GetRect(editor.currentSong);

        List <SongObject> chartObjectsList = new List <SongObject>();

        if (Globals.viewMode == Globals.ViewMode.Chart)
        {
            int index, length;
            SongObjectHelper.GetRange(editor.currentChart.chartObjects, minLimitInclusive, maxLimitNonInclusive, out index, out length);

            for (int i = index; i < index + length; ++i)
            {
                ChartObject chartObject = editor.currentChart.chartObjects[i];
                float       offset      = 0;

                if ((SongObject.ID)chartObject.classID == SongObject.ID.Note)
                {
                    // If the object is within a lane that is not currently included we need to skip over this note
                    if (((Note)chartObject).ShouldBeCulledFromLanes(editor.laneInfo))
                    {
                        continue;
                    }
                }

                if (chartObject.tick < maxLimitNonInclusive && PrefabGlobals.HorizontalCollisionCheck(PrefabGlobals.GetCollisionRect(chartObject, 0, offset), areaRect))
                {
                    chartObjectsList.Add(chartObject);
                }
            }
        }
        else
        {
            // Gather synctrack, sections and events
            int index, length;
            SongObjectHelper.GetRange(editor.currentSong.syncTrack, minLimitInclusive, maxLimitNonInclusive, out index, out length);

            // Synctrack
            for (int i = index; i < index + length; ++i)
            {
                SongObject chartObject = editor.currentSong.syncTrack[i];

                if (chartObject.tick < maxLimitNonInclusive && PrefabGlobals.HorizontalCollisionCheck(PrefabGlobals.GetCollisionRect(chartObject), areaRect))
                {
                    chartObjectsList.Add(chartObject);
                }
            }

            SongObjectHelper.GetRange(editor.currentSong.eventsAndSections, minLimitInclusive, maxLimitNonInclusive, out index, out length);

            // Events and sections
            for (int i = index; i < index + length; ++i)
            {
                SongObject chartObject = editor.currentSong.eventsAndSections[i];
                float      offset      = 0;

                if (chartObject.tick < maxLimitNonInclusive && PrefabGlobals.HorizontalCollisionCheck(PrefabGlobals.GetCollisionRect(chartObject, 0, offset), areaRect))
                {
                    chartObjectsList.Add(chartObject);
                }
            }
        }

        return(chartObjectsList.ToArray());
    }
    public override void OnSelectableMouseDown()
    {
        if (Toolpane.currentTool == Toolpane.Tools.Cursor && Globals.applicationMode == Globals.ApplicationMode.Editor && Input.GetMouseButtonDown(0) && !Input.GetMouseButton(1))
        {
            // Ctrl-clicking
            if (Globals.modifierInputActive)
            {
                if (editor.IsSelected(songObject))
                {
                    editor.RemoveFromSelectedObjects(songObject);
                }
                else
                {
                    editor.AddToSelectedObjects(songObject);
                }
            }
            // Shift-clicking
            else if (Globals.secondaryInputActive)
            {
                int pos = SongObjectHelper.FindClosestPosition(this.songObject, editor.currentSelectedObjects);

                if (pos != SongObjectHelper.NOTFOUND)
                {
                    uint min;
                    uint max;

                    if (editor.currentSelectedObjects[pos].tick > songObject.tick)
                    {
                        max = editor.currentSelectedObjects[pos].tick;
                        min = songObject.tick;
                    }
                    else
                    {
                        min = editor.currentSelectedObjects[pos].tick;
                        max = songObject.tick;
                    }

                    var chartObjects = editor.currentChart.chartObjects;
                    int index, length;
                    SongObjectHelper.GetRange(chartObjects, min, max, out index, out length);
                    editor.SetCurrentSelectedObjects(chartObjects, index, length);
                }
            }
            // Regular clicking
            else if (!editor.IsSelected(songObject))
            {
                if (ShortcutInput.GetInput(Shortcut.ChordSelect))
                {
                    editor.SetCurrentSelectedObjects(note.chord);
                }
                else
                {
                    editor.currentSelectedObject = songObject;
                }
            }
        }

        // Delete the object on left and right click shortcut
        else if (Globals.applicationMode == Globals.ApplicationMode.Editor &&
                 Input.GetMouseButtonDown(0) && Input.GetMouseButton(1))
        {
            if (ShortcutInput.GetInput(Shortcut.ChordSelect))
            {
                Note[] chordNotes = note.GetChord();
                if (Input.GetMouseButton(1))
                {
                    Debug.Log("Deleted " + note + " chord at position " + note.tick + " with hold-right left-click shortcut");
                    editor.commandStack.Push(new SongEditDelete(chordNotes));
                }
            }
            else if (Input.GetMouseButton(1))
            {
                Debug.Log("Deleted " + note + " at position " + note.tick + " with hold-right left-click shortcut");
                editor.commandStack.Push(new SongEditDelete(note));
            }
        }
        else
        {
            sustain.OnSelectableMouseDown();
        }
    }
    static string CheckForErrorsMoonscraper(Song song, ValidationParameters validationParams, ref bool hasErrors)
    {
        bool          hasErrorsLocal = false;
        StringBuilder sb             = new StringBuilder();

        sb.AppendLine("Moonscraper validation report: ");

        // Check if any objects have exceeded the max length
        {
            uint tick = song.TimeToTick(validationParams.songLength, song.resolution);

            // Song objects
            {
                // Synctrack
                {
                    int index, length;
                    SongObjectHelper.GetRange(song.syncTrack, tick, uint.MaxValue, out index, out length);

                    for (int i = index; i < length; ++i)
                    {
                        hasErrorsLocal |= true;

                        SyncTrack st = song.syncTrack[i];

                        sb.AppendFormat("\tFound synctrack object beyond the length of the song-\n");
                        sb.AppendFormat("\t\tType = {0}, position = {1}\n", st.GetType(), st.tick);
                    }
                }

                // Events
                {
                    int index, length;
                    SongObjectHelper.GetRange(song.eventsAndSections, tick, uint.MaxValue, out index, out length);

                    for (int i = index; i < length; ++i)
                    {
                        hasErrorsLocal |= true;

                        MoonscraperChartEditor.Song.Event eventObject = song.eventsAndSections[i];

                        sb.AppendFormat("\tFound event object beyond the length of the song-\n");
                        sb.AppendFormat("\t\tType = {0}, position = {1}\n", eventObject.GetType(), eventObject.tick);
                    }
                }
            }

            // Chart objects
            foreach (Song.Instrument instrument in EnumX <Song.Instrument> .Values)
            {
                if (instrument == Song.Instrument.Unrecognised)
                {
                    continue;
                }

                foreach (Song.Difficulty difficulty in EnumX <Song.Difficulty> .Values)
                {
                    Chart chart = song.GetChart(instrument, difficulty);

                    int index, length;
                    SongObjectHelper.GetRange(chart.chartObjects, tick, uint.MaxValue, out index, out length);

                    for (int i = index; i < length; ++i)
                    {
                        hasErrorsLocal |= true;

                        ChartObject co = chart.chartObjects[i];

                        sb.AppendFormat("\tFound chart object beyond the length of the song-\n");
                        sb.AppendFormat("\t\tType = {0}, position = {1}\n", co.GetType(), co.tick);
                    }
                }
            }
        }

        if (!hasErrorsLocal)
        {
            sb.AppendLine("\tNo errors detected");
        }

        hasErrors |= hasErrorsLocal;

        return(sb.ToString());
    }
Exemple #28
0
    void CollectNotesInViewRange(IList <Note> notes)
    {
        bool extendedSustainsEnabled = GameSettings.extendedSustainsEnabled;

        uint min_pos = editor.minPos;

        if (noteVisibilityRangeYPosOverride.HasValue)
        {
            uint gameplayPos = editor.currentSong.WorldYPositionToTick(noteVisibilityRangeYPosOverride.Value, editor.currentSong.resolution);
            if (min_pos < gameplayPos)
            {
                min_pos = gameplayPos;
            }
        }

        collectedNotesInRange.Clear();
        int index, length;

        SongObjectHelper.GetRange(notes, min_pos, editor.maxPos, out index, out length);
        for (int i = index; i < index + length; ++i)
        {
            collectedNotesInRange.Add(notes[i]);
        }

        if (min_pos == editor.minPos)
        {
            if (collectedNotesInRange.Count > 0)
            {
                NoteFunctions.GetPreviousOfSustains(prevSustainCache, collectedNotesInRange[0], extendedSustainsEnabled);
                // Find the last known note of each fret type to find any sustains that might overlap into the camera view
                foreach (Note prevNote in prevSustainCache)
                {
                    if (prevNote.tick + prevNote.length > editor.minPos)
                    {
                        collectedNotesInRange.Add(prevNote);
                    }
                }
            }
            else
            {
                int minArrayPos = SongObjectHelper.FindClosestPosition(editor.minPos, editor.currentChart.notes);

                if (minArrayPos != SongObjectHelper.NOTFOUND)
                {
                    while (minArrayPos > 0 && editor.currentChart.notes[minArrayPos].tick == editor.currentChart.notes[minArrayPos - 1].tick)
                    {
                        --minArrayPos;
                    }

                    Note minNote = editor.currentChart.notes[minArrayPos];

                    if (minNote.tick + minNote.length > editor.minPos && minNote.tick < editor.maxPos)
                    {
                        foreach (Note note in minNote.chord)
                        {
                            if (note.tick + note.length > editor.minPos)
                            {
                                collectedNotesInRange.Add(note);
                            }
                        }
                    }

                    NoteFunctions.GetPreviousOfSustains(prevSustainCache, minNote, extendedSustainsEnabled);
                    foreach (Note prevNote in prevSustainCache)
                    {
                        if (prevNote.tick + prevNote.length > editor.minPos)
                        {
                            collectedNotesInRange.Add(prevNote);
                        }
                    }
                }
            }
        }

        // Make sure the notes are within the allowable lanes
        for (int i = collectedNotesInRange.Count - 1; i >= 0; --i)
        {
            Note note = collectedNotesInRange[i];
            if (!note.IsOpenNote() && ((1 << note.rawNote) & editor.laneInfo.laneMask) == 0)
            {
                collectedNotesInRange.RemoveAt(i);
            }
        }
    }
    SongObject[] ScanArea(Vector2 cornerA, Vector2 cornerB, uint minLimitInclusive, uint maxLimitNonInclusive)
    {
        Clipboard.SelectionArea area = new Clipboard.SelectionArea(cornerA, cornerB, minLimitInclusive, maxLimitNonInclusive);
        Rect areaRect = area.GetRect(editor.currentSong);

        List <SongObject> chartObjectsList = new List <SongObject>();

        if (Globals.viewMode == Globals.ViewMode.Chart)
        {
            int index, length;
            SongObjectHelper.GetRange(editor.currentChart.chartObjects, minLimitInclusive, maxLimitNonInclusive, out index, out length);

            for (int i = index; i < index + length; ++i)
            {
                ChartObject chartObject = editor.currentChart.chartObjects[i];
                float       offset      = 0;
                if ((SongObject.ID)chartObject.classID == SongObject.ID.ChartEvent)
                {
                    offset = ChartEventController.GetOffset(editor, (ChartEvent)chartObject);
                }

                if (chartObject.tick < maxLimitNonInclusive && PrefabGlobals.HorizontalCollisionCheck(PrefabGlobals.GetCollisionRect(chartObject, 0, offset), areaRect))
                {
                    chartObjectsList.Add(chartObject);
                }
            }
        }
        else
        {
            // Gather synctrack, sections and events
            int index, length;
            SongObjectHelper.GetRange(editor.currentSong.syncTrack, minLimitInclusive, maxLimitNonInclusive, out index, out length);

            // Synctrack
            for (int i = index; i < index + length; ++i)
            {
                SongObject chartObject = editor.currentSong.syncTrack[i];

                if (chartObject.tick < maxLimitNonInclusive && PrefabGlobals.HorizontalCollisionCheck(PrefabGlobals.GetCollisionRect(chartObject), areaRect))
                {
                    chartObjectsList.Add(chartObject);
                }
            }

            SongObjectHelper.GetRange(editor.currentSong.eventsAndSections, minLimitInclusive, maxLimitNonInclusive, out index, out length);

            // Events and sections
            for (int i = index; i < index + length; ++i)
            {
                SongObject chartObject = editor.currentSong.eventsAndSections[i];
                float      offset      = 0;
                if ((SongObject.ID)chartObject.classID == SongObject.ID.Event)
                {
                    offset = EventController.GetOffset(editor, (Event)chartObject);
                }

                if (chartObject.tick < maxLimitNonInclusive && PrefabGlobals.HorizontalCollisionCheck(PrefabGlobals.GetCollisionRect(chartObject, 0, offset), areaRect))
                {
                    chartObjectsList.Add(chartObject);
                }
            }
        }

        return(chartObjectsList.ToArray());
    }
Exemple #30
0
    void GenerateForcedFlagFixupCommands(UndoRedoJumpInfo jumpInfo)
    {
        Chart chart = ChartEditor.Instance.currentChart;

        if (chart.chartObjects.Count <= 0)
        {
            return;
        }

        int index, length;

        SongObjectHelper.GetRange(chart.chartObjects, jumpInfo.min.GetValueOrDefault(0), jumpInfo.max.GetValueOrDefault(0), out index, out length);

        Note lastCheckedNote = null;

        for (int i = index; i < index + length; ++i)
        {
            if (chart.chartObjects[i].classID == (int)SongObject.ID.Note)
            {
                Note note = chart.chartObjects[i] as Note;

                if ((note.flags & Note.Flags.Forced) != 0 && note.cannotBeForced)
                {
                    foreach (Note chordNote in note.chord)
                    {
                        Note modifiedNote = new Note(chordNote);
                        modifiedNote.flags &= ~Note.Flags.Forced;

                        SongEditModify <Note> command = new SongEditModify <Note>(chordNote, modifiedNote);
                        command.postExecuteEnabled = false;
                        forcedFlagFixup.Add(command);
                    }
                }

                lastCheckedNote = note;
            }
        }

        // Do last final check for next note that may not have been included in the range
        if (lastCheckedNote != null)
        {
            Note note = lastCheckedNote.nextSeperateNote;

            if (note != null && (note.flags & Note.Flags.Forced) != 0 && note.cannotBeForced)
            {
                foreach (Note chordNote in note.chord)
                {
                    Note modifiedNote = new Note(chordNote);
                    modifiedNote.flags &= ~Note.Flags.Forced;

                    SongEditModify <Note> command = new SongEditModify <Note>(chordNote, modifiedNote);
                    command.postExecuteEnabled = false;
                    forcedFlagFixup.Add(command);
                }
            }
        }

        // Get the note to start on, then we will traverse the linked list

        /*
         * Note currentNote = null;
         * for (int i = 0; i < chart.chartObjects.Count; ++i)
         * {
         *  Note note = chart.chartObjects[i] as Note;
         *  if (note != null)
         *  {
         *      Note prev = note.previousSeperateNote;
         *      if (prev != null)
         *      {
         *          currentNote = prev;
         *      }
         *      else
         *      {
         *          currentNote = note;
         *      }
         *  }
         * }
         *
         * while (currentNote != null)
         * {
         *  if ((currentNote.flags & Note.Flags.Forced) != 0 && currentNote.cannotBeForced)
         *  {
         *      foreach (Note chordNote in currentNote.chord)
         *      {
         *          Note modifiedNote = new Note(chordNote);
         *          modifiedNote.flags &= ~Note.Flags.Forced;
         *
         *          SongEditModify<Note> command = new SongEditModify<Note>(chordNote, modifiedNote);
         *          command.postExecuteEnabled = false;
         *          forcedFlagFixup.Add(command);
         *      }
         *  }
         *
         *  currentNote = currentNote.nextSeperateNote;
         * }*/

        cannotBeForcedFixupCommandsGenerated = true;
    }