Beispiel #1
0
 private static TimingPointsChange GetTimingPointsChange(TimingPoint tp, bool sv, bool hs)
 {
     tp             = tp.Copy();
     tp.MpB         = tp.Uninherited ? -100 : tp.MpB;
     tp.Uninherited = false;
     return(new TimingPointsChange(tp, sv, false, hs, hs, hs));
 }
Beispiel #2
0
        public void AddChange(List <TimingPoint> list, bool allAfter = false)
        {
            TimingPoint        addingTimingPoint = null;
            TimingPoint        prevTimingPoint   = null;
            List <TimingPoint> onTimingPoints    = new List <TimingPoint>();
            bool onHasRed   = false;
            bool onHasGreen = false;

            foreach (TimingPoint tp in list)
            {
                if (tp == null)
                {
                    continue;
                }                              // Continue nulls to avoid exceptions
                if (tp.Offset < MyTP.Offset && (prevTimingPoint == null || tp.Offset >= prevTimingPoint.Offset))
                {
                    prevTimingPoint = tp;
                }
                if (Math.Abs(tp.Offset - MyTP.Offset) <= Fuzzyness)
                {
                    onTimingPoints.Add(tp);
                    onHasRed   = tp.Uninherited || onHasRed;
                    onHasGreen = !tp.Uninherited || onHasGreen;
                }
            }

            if (onTimingPoints.Count > 0)
            {
                prevTimingPoint = onTimingPoints.Last();
            }

            if (Inherited && !onHasRed)
            {
                // Make new redline
                if (prevTimingPoint == null)
                {
                    addingTimingPoint = MyTP;
                }
                else
                {
                    addingTimingPoint             = prevTimingPoint.Copy();
                    addingTimingPoint.Offset      = MyTP.Offset;
                    addingTimingPoint.Uninherited = true;
                }
                onTimingPoints.Add(addingTimingPoint);
            }
            if (!Inherited && (onTimingPoints.Count == 0 || (MpB && !onHasGreen)))
            {
                // Make new greenline (based on prev)
                if (prevTimingPoint == null)
                {
                    addingTimingPoint = MyTP;
                }
                else
                {
                    addingTimingPoint             = prevTimingPoint.Copy();
                    addingTimingPoint.Offset      = MyTP.Offset;
                    addingTimingPoint.Uninherited = false;
                    if (prevTimingPoint.Uninherited)
                    {
                        addingTimingPoint.MpB = -100;
                    }
                }
                onTimingPoints.Add(addingTimingPoint);
            }

            foreach (TimingPoint on in onTimingPoints)
            {
                if (MpB && (Inherited ? on.Uninherited : !on.Uninherited))
                {
                    on.MpB = MyTP.MpB;
                }
                if (Meter && Inherited && on.Uninherited)
                {
                    on.Meter = MyTP.Meter;
                }
                if (Sampleset)
                {
                    on.SampleSet = MyTP.SampleSet;
                }
                if (Index)
                {
                    on.SampleIndex = MyTP.SampleIndex;
                }
                if (Volume)
                {
                    on.Volume = MyTP.Volume;
                }
                if (Kiai)
                {
                    on.Kiai = MyTP.Kiai;
                }
                if (OmitFirstBarLine && Inherited && on.Uninherited)
                {
                    on.OmitFirstBarLine = MyTP.OmitFirstBarLine;
                }
            }

            if (addingTimingPoint != null && (prevTimingPoint == null || !addingTimingPoint.SameEffect(prevTimingPoint) || Inherited))
            {
                list.Add(addingTimingPoint);
            }

            if (allAfter) // Change every timingpoint after
            {
                foreach (TimingPoint tp in list)
                {
                    if (tp.Offset > MyTP.Offset)
                    {
                        if (Sampleset)
                        {
                            tp.SampleSet = MyTP.SampleSet;
                        }
                        if (Index)
                        {
                            tp.SampleIndex = MyTP.SampleIndex;
                        }
                        if (Volume)
                        {
                            tp.Volume = MyTP.Volume;
                        }
                        if (Kiai)
                        {
                            tp.Kiai = MyTP.Kiai;
                        }
                    }
                }
            }
        }
Beispiel #3
0
        private string Adjust_Timing(Arguments arg, BackgroundWorker worker, DoWorkEventArgs _)
        {
            // Count
            int RedlinesAdded = 0;

            bool editorRead = EditorReaderStuff.TryGetFullEditorReader(out var reader);

            foreach (string path in arg.Paths)
            {
                // Open beatmap
                var     editor  = EditorReaderStuff.GetBeatmapEditor(path, reader, editorRead);
                Beatmap beatmap = editor.Beatmap;
                Timing  timing  = beatmap.BeatmapTiming;

                // Get all the times to snap
                List <Marker> markers = new List <Marker>();
                if (arg.Objects)
                {
                    foreach (HitObject ho in beatmap.HitObjects)
                    {
                        markers.Add(new Marker(ho.Time));
                    }
                }
                if (arg.Bookmarks)
                {
                    foreach (double time in beatmap.GetBookmarks())
                    {
                        markers.Add(new Marker(time));
                    }
                }
                if (arg.Greenlines)
                {
                    // Get the offsets of greenlines
                    foreach (TimingPoint tp in timing.TimingPoints)
                    {
                        if (tp.Uninherited == false)
                        {
                            markers.Add(new Marker(tp.Offset));
                        }
                    }
                }
                if (arg.Redlines)
                {
                    // Get the offsets of redlines
                    foreach (TimingPoint tp in timing.TimingPoints)
                    {
                        if (tp.Uninherited == true)
                        {
                            markers.Add(new Marker(tp.Offset));
                        }
                    }
                }

                // Update progressbar
                if (worker != null && worker.WorkerReportsProgress)
                {
                    worker.ReportProgress(20);
                }

                // Sort the markers
                markers = markers.OrderBy(o => o.Time).ToList();

                // Calculate the beats between time and the last time or redline for each time
                // Time the same is 0
                // Time a little after is smallest snap
                for (int i = 0; i < markers.Count; i++)
                {
                    Marker marker = markers[i];
                    double time   = marker.Time;

                    TimingPoint redline = timing.GetRedlineAtTime(time - 1);

                    // Resnap to that redline only
                    double resnappedTime = timing.Resnap(time, arg.Snap1, arg.Snap2, false, redline);

                    // Calculate beats from the redline
                    double beatsFromRedline = (resnappedTime - redline.Offset) / redline.MpB;

                    // Avoid problems
                    if (MathHelper.ApproximatelyEquivalent(beatsFromRedline, 0, 0.0001))
                    {
                        beatsFromRedline = 1 / Math.Max(arg.Snap1, arg.Snap2);
                    }
                    if (time == redline.Offset)
                    {
                        beatsFromRedline = 0;
                    }

                    // Initialize the beats from last marker
                    double beatsFromLastMarker = beatsFromRedline;

                    // Get the times between redline and this time
                    List <Marker> timesBefore = markers.Where(o => o.Time <time && o.Time> redline.Offset).ToList();

                    if (timesBefore.Count > 0)
                    {
                        // Get the last time info
                        double lastTime       = timesBefore.Last().Time;
                        double resnappedTimeL = timing.Resnap(lastTime, arg.Snap1, arg.Snap2, false);

                        // Change the beats from last marker
                        beatsFromLastMarker = (resnappedTime - resnappedTimeL) / redline.MpB;

                        // Avoid problems
                        if (MathHelper.ApproximatelyEquivalent(beatsFromLastMarker, 0, 0.0001))
                        {
                            beatsFromLastMarker = 1f / Math.Max(arg.Snap1, arg.Snap2);
                        }
                        if (lastTime == time)
                        {
                            beatsFromLastMarker = 0;
                        }
                    }

                    // Set the variable
                    marker.BeatsFromLastMarker = beatsFromLastMarker;
                }

                // Remove redlines except the first redline
                if (!arg.Redlines)
                {
                    var first = timing.TimingPoints.FirstOrDefault(o => o.Uninherited);
                    timing.TimingPoints.RemoveAll(o => o.Uninherited && o != first);
                }

                // Update progressbar
                if (worker != null && worker.WorkerReportsProgress)
                {
                    worker.ReportProgress(40);
                }

                // Loop through all the markers
                for (int i = 0; i < markers.Count; i++)
                {
                    Marker marker = markers[i];
                    double time   = marker.Time;

                    TimingPoint redline = timing.GetRedlineAtTime(time - 1);

                    double beatsFromLastMarker = arg.BeatsBetween != -1 ? arg.BeatsBetween : marker.BeatsFromLastMarker;

                    // Skip if 0 beats from last marker
                    if (beatsFromLastMarker == 0)
                    {
                        continue;
                    }

                    // Get the times between redline and this time including this time
                    List <Marker> markersBefore = markers.Where(o => o.Time <time && o.Time> redline.Offset).ToList();
                    markersBefore.Add(marker);

                    // Calculate MpB
                    // Average MpB from timesBefore and use time from redline
                    double mpb = 0;
                    double beatsFromRedline = 0;
                    foreach (Marker markerB in markersBefore)
                    {
                        beatsFromRedline += markerB.BeatsFromLastMarker;
                        mpb += GetMpB(markerB.Time - redline.Offset, beatsFromRedline, 0);
                    }
                    mpb /= markersBefore.Count;

                    // Check if this MpB doesn't make the markers go offsnap too far
                    bool canChangeRedline = CheckMpB(mpb, markersBefore, redline, arg);

                    // Make changes
                    if (canChangeRedline)
                    {
                        // Round the MpB to human values first
                        mpb = HumanRoundMpB(mpb, markersBefore, redline, arg);

                        // Change the MpB of the redline
                        redline.MpB = mpb;
                    }
                    else
                    {
                        // Get the last time info and not the current
                        markersBefore.Remove(marker);
                        double lastTime = markersBefore.Last().Time;

                        // Make new redline
                        TimingPoint newRedline    = redline.Copy();
                        TimingPoint lastHitsounds = timing.GetTimingPointAtTime(lastTime + 5);
                        newRedline.Offset           = lastTime;
                        newRedline.OmitFirstBarLine = arg.OmitBarline; // Set omit to the argument
                        newRedline.Kiai             = lastHitsounds.Kiai;
                        newRedline.SampleIndex      = lastHitsounds.SampleIndex;
                        newRedline.SampleSet        = lastHitsounds.SampleSet;
                        newRedline.Volume           = lastHitsounds.Volume;
                        timing.TimingPoints.Add(newRedline);
                        timing.Sort();

                        // Set the MpB
                        newRedline.MpB = GetMpB(time - lastTime, beatsFromLastMarker, arg.Leniency);

                        // Update the counter
                        RedlinesAdded++;
                    }

                    // Update progressbar
                    if (worker != null && worker.WorkerReportsProgress)
                    {
                        worker.ReportProgress(i * 60 / markers.Count + 40);
                    }
                }

                // Save the file
                editor.SaveFile();
            }


            // Complete progressbar
            if (worker != null && worker.WorkerReportsProgress)
            {
                worker.ReportProgress(100);
            }

            // Make an accurate message
            string message = "Successfully added ";

            message += RedlinesAdded;
            if (Math.Abs(RedlinesAdded) == 1)
            {
                message += " redlines!";
            }
            else
            {
                message += " redlines!";
            }
            return(message);
        }
        private string Adjust_Timing(TimingHelperVm arg, BackgroundWorker worker, DoWorkEventArgs _)
        {
            // Count
            int redlinesAdded = 0;

            var reader = EditorReaderStuff.GetFullEditorReaderOrNot();

            foreach (string path in arg.Paths)
            {
                // Open beatmap
                var     editor  = EditorReaderStuff.GetNewestVersionOrNot(path, reader);
                Beatmap beatmap = editor.Beatmap;
                Timing  timing  = beatmap.BeatmapTiming;

                // Get all the times to snap
                List <Marker> markers = new List <Marker>();
                if (arg.Objects)
                {
                    markers.AddRange(beatmap.HitObjects.Select(ho => new Marker(ho.Time)));
                }
                if (arg.Bookmarks)
                {
                    markers.AddRange(beatmap.GetBookmarks().Select(time => new Marker(time)));
                }
                if (arg.Greenlines)
                {
                    // Get the offsets of greenlines
                    markers.AddRange(from tp in timing.TimingPoints where !tp.Uninherited select new Marker(tp.Offset));
                }
                if (arg.Redlines)
                {
                    // Get the offsets of redlines
                    markers.AddRange(from tp in timing.TimingPoints where tp.Uninherited select new Marker(tp.Offset));
                }

                // Update progressbar
                if (worker != null && worker.WorkerReportsProgress)
                {
                    worker.ReportProgress(20);
                }

                // Sort the markers
                markers = markers.OrderBy(o => o.Time).ToList();

                // If there are no redlines add one with a default BPM
                if (!timing.TimingPoints.Any(tp => tp.Uninherited))
                {
                    timing.Add(new TimingPoint(0, 1000, 4, SampleSet.Soft, 0, 100, true, false, false));
                }

                // Remove multiple markers on the same tick
                var newMarkers = new List <Marker>(markers.Count);
                newMarkers.AddRange(markers.Where((t, i) => i == 0 || Math.Abs(t.Time - markers[i - 1].Time) >= arg.Leniency + Precision.DOUBLE_EPSILON));
                markers = newMarkers;

                // Calculate the beats between time and the last time or redline for each time
                // Time the same is 0
                // Time a little after is smallest snap
                foreach (var marker in markers)
                {
                    double time = marker.Time;

                    TimingPoint redline = timing.GetRedlineAtTime(time - 1);

                    // Resnap to that redline only
                    double resnappedTime = timing.Resnap(time, arg.BeatDivisors, false, tp: redline);

                    // Calculate beats from the redline
                    double beatsFromRedline = (resnappedTime - redline.Offset) / redline.MpB;

                    // Avoid problems
                    if (MathHelper.ApproximatelyEquivalent(beatsFromRedline, 0, 0.0001))
                    {
                        beatsFromRedline = arg.BeatDivisors.Min(o => o.GetValue());
                    }
                    if (time == redline.Offset)
                    {
                        beatsFromRedline = 0;
                    }

                    // Initialize the beats from last marker
                    double beatsFromLastMarker = beatsFromRedline;

                    // Get the times between redline and this time
                    List <Marker> timesBefore = markers.Where(o => o.Time <time && o.Time> redline.Offset).ToList();

                    if (timesBefore.Count > 0)
                    {
                        // Get the last time info
                        double lastTime       = timesBefore.Last().Time;
                        double resnappedTimeL = timing.Resnap(lastTime, arg.BeatDivisors, false);

                        // Change the beats from last marker
                        beatsFromLastMarker = (resnappedTime - resnappedTimeL) / redline.MpB;

                        // Avoid problems
                        if (MathHelper.ApproximatelyEquivalent(beatsFromLastMarker, 0, 0.0001))
                        {
                            beatsFromLastMarker = arg.BeatDivisors.Min(o => o.GetValue());
                        }
                        if (lastTime == time)
                        {
                            beatsFromLastMarker = 0;
                        }
                    }

                    // Set the variable
                    marker.BeatsFromLastMarker = beatsFromLastMarker;

                    if (arg.BeatsBetween != -1)
                    {
                        marker.BeatsFromLastMarker = arg.BeatsBetween;
                    }
                }

                // Remove redlines except the first redline
                if (!arg.Redlines)
                {
                    var first = timing.TimingPoints.FirstOrDefault(o => o.Uninherited);
                    timing.RemoveAll(o => o.Uninherited && o != first);
                }

                // Update progressbar
                if (worker != null && worker.WorkerReportsProgress)
                {
                    worker.ReportProgress(40);
                }

                // Loop through all the markers
                for (int i = 0; i < markers.Count; i++)
                {
                    Marker marker = markers[i];
                    double time   = marker.Time;

                    TimingPoint redline = timing.GetRedlineAtTime(time - 1);

                    double beatsFromLastMarker = marker.BeatsFromLastMarker;

                    // Skip if 0 beats from last marker
                    if (beatsFromLastMarker == 0)
                    {
                        continue;
                    }

                    // Get the times between redline and this time including this time
                    List <Marker> markersBefore = markers.Where(o => o.Time <time && o.Time> redline.Offset).ToList();
                    markersBefore.Add(marker);

                    // Calculate MpB
                    // Average MpB from timesBefore and use time from redline
                    double mpb = 0;
                    double beatsFromRedline = 0;
                    foreach (Marker markerB in markersBefore)
                    {
                        beatsFromRedline += markerB.BeatsFromLastMarker;
                        mpb += GetMpB(markerB.Time - redline.Offset, beatsFromRedline, 0);
                    }
                    mpb /= markersBefore.Count;

                    // Check if this MpB doesn't make the markers go offsnap too far
                    bool canChangeRedline = CheckMpB(mpb, markersBefore, redline, arg);

                    // Make changes
                    if (canChangeRedline)
                    {
                        // Round the MpB to human values first
                        mpb = HumanRoundMpB(mpb, markersBefore, redline, arg);

                        // Change the MpB of the redline
                        redline.MpB = mpb;
                    }
                    else
                    {
                        // Get the last time info and not the current
                        markersBefore.Remove(marker);
                        double lastTime = markersBefore.Last().Time;

                        // Make new redline
                        TimingPoint newRedline    = redline.Copy();
                        TimingPoint lastHitsounds = timing.GetTimingPointAtTime(lastTime + 5);
                        newRedline.Offset           = lastTime;
                        newRedline.OmitFirstBarLine = arg.OmitBarline; // Set omit to the argument
                        newRedline.Kiai             = lastHitsounds.Kiai;
                        newRedline.SampleIndex      = lastHitsounds.SampleIndex;
                        newRedline.SampleSet        = lastHitsounds.SampleSet;
                        newRedline.Volume           = lastHitsounds.Volume;
                        timing.Add(newRedline);

                        // Set the MpB
                        newRedline.MpB = GetMpB(time - lastTime, beatsFromLastMarker, arg.Leniency);

                        // Update the counter
                        redlinesAdded++;
                    }

                    // Update progressbar
                    if (worker != null && worker.WorkerReportsProgress)
                    {
                        worker.ReportProgress(i * 60 / markers.Count + 40);
                    }
                }

                // Save the file
                editor.SaveFile();
            }


            // Complete progressbar
            if (worker != null && worker.WorkerReportsProgress)
            {
                worker.ReportProgress(100);
            }

            // Do QuickRun stuff
            RunFinished?.Invoke(this, new RunToolCompletedEventArgs(true, reader != null, arg.Quick));

            // Make an accurate message
            string message = "Successfully added ";

            message += redlinesAdded;
            if (Math.Abs(redlinesAdded) == 1)
            {
                message += " redlines!";
            }
            else
            {
                message += " redlines!";
            }

            return(arg.Quick ? string.Empty : message);
        }