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)); }
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; } } } } }
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); }