private string Run_Program2(List <string> arguments, BackgroundWorker worker, DoWorkEventArgs e) { // Retrieve all arguments string path = arguments[0]; bool volumeSliders = arguments[1] == "True"; bool samplesetSliders = arguments[2] == "True"; bool volumeSpinners = arguments[3] == "True"; bool resnapObjects = arguments[4] == "True"; bool resnapBookmarks = arguments[5] == "True"; int snap1 = int.Parse(arguments[6].Split('/')[1]); int snap2 = int.Parse(arguments[7].Split('/')[1]); bool removeSliderendMuting = arguments[8] == "True"; bool removeUnclickabeHitsounds = arguments[9] == "True"; Editor editor = new Editor(path); Timing timing = editor.Beatmap.BeatmapTiming; Timeline timeline = editor.Beatmap.GetTimeline(); int mode = editor.Beatmap.General["Mode"].Value; int num_timingPoints = editor.Beatmap.BeatmapTiming.TimingPoints.Count; int objectsResnapped = 0; // Count total stages int maxStages = 11; // Collect Kiai toggles and SV changes for mania/taiko List <TimingPoint> kiaiToggles = new List <TimingPoint>(); List <TimingPoint> svChanges = new List <TimingPoint>(); bool lastKiai = false; double lastSV = -100; for (int i = 0; i < timing.TimingPoints.Count; i++) { TimingPoint tp = timing.TimingPoints[i]; if (tp.Kiai != lastKiai) { kiaiToggles.Add(tp.Copy()); lastKiai = tp.Kiai; } if (tp.Inherited) { lastSV = -100; } else { if (tp.MpB != lastSV) { svChanges.Add(tp.Copy()); lastSV = tp.MpB; } } UpdateProgressbar(worker, (double)i / timing.TimingPoints.Count, 0, maxStages); } // Resnap shit if (resnapObjects) { // Resnap all objects for (int i = 0; i < editor.Beatmap.HitObjects.Count; i++) { HitObject ho = editor.Beatmap.HitObjects[i]; bool resnapped = ho.ResnapSelf(timing, snap1, snap2); if (resnapped) { objectsResnapped += 1; } ho.ResnapEnd(timing, snap1, snap2); UpdateProgressbar(worker, (double)i / editor.Beatmap.HitObjects.Count, 1, maxStages); } // Resnap Kiai toggles and SV changes for (int i = 0; i < kiaiToggles.Count; i++) { TimingPoint tp = kiaiToggles[i]; tp.ResnapSelf(timing, snap1, snap2); UpdateProgressbar(worker, (double)i / kiaiToggles.Count, 2, maxStages); } for (int i = 0; i < svChanges.Count; i++) { TimingPoint tp = svChanges[i]; tp.ResnapSelf(timing, snap1, snap2); UpdateProgressbar(worker, (double)i / svChanges.Count, 3, maxStages); } } if (resnapBookmarks) { // Resnap the bookmarks List <double> newBookmarks = new List <double>(); List <double> bookmarks = editor.Beatmap.GetBookmarks(); for (int i = 0; i < bookmarks.Count; i++) { double bookmark = bookmarks[i]; newBookmarks.Add(Math.Floor(timing.Resnap(bookmark, snap1, snap2))); UpdateProgressbar(worker, (double)i / bookmarks.Count, 4, maxStages); } editor.Beatmap.SetBookmarks(newBookmarks); } // Maybe mute unclickable timelineobjects if (removeUnclickabeHitsounds) { foreach (TimelineObject tlo in timeline.TimeLineObjects) { if (!(tlo.IsCircle || tlo.IsSliderHead || tlo.IsHoldnoteHead)) // Not clickable { tlo.FenoSampleVolume = 5; // 5% volume mute } } } // Make new timingpoints List <Change> changes = new List <Change>(); // Add redlines List <TimingPoint> redlines = timing.GetAllRedlines(); for (int i = 0; i < redlines.Count; i++) { TimingPoint tp = redlines[i]; changes.Add(new Change(tp, mpb: true, meter: true, inherited: true)); UpdateProgressbar(worker, (double)i / redlines.Count, 5, maxStages); } // Add SV changes for taiko and mania if (mode == 1 || mode == 3) { for (int i = 0; i < svChanges.Count; i++) { TimingPoint tp = svChanges[i]; changes.Add(new Change(tp, mpb: true)); UpdateProgressbar(worker, (double)i / svChanges.Count, 6, maxStages); } } // Add Kiai toggles for (int i = 0; i < kiaiToggles.Count; i++) { TimingPoint tp = kiaiToggles[i]; changes.Add(new Change(tp, kiai: true)); UpdateProgressbar(worker, (double)i / kiaiToggles.Count, 7, maxStages); } // Add Hitobject stuff for (int i = 0; i < editor.Beatmap.HitObjects.Count; i++) { HitObject ho = editor.Beatmap.HitObjects[i]; if (ho.IsSlider) // SV changes { TimingPoint tp = ho.TP.Copy(); tp.Offset = ho.Time; tp.MpB = ho.SV; changes.Add(new Change(tp, mpb: true)); } // Body hitsounds bool vol = (ho.IsSlider && volumeSliders) || (ho.IsSpinner && volumeSpinners); bool sam = (ho.IsSlider && samplesetSliders && ho.SampleSet == 0); bool ind = (ho.IsSlider && samplesetSliders); bool samplesetActuallyChanged = false; foreach (TimingPoint tp in ho.BodyHitsounds) { if (tp.Volume == 5 && removeSliderendMuting) { vol = false; } // Removing sliderbody silencing changes.Add(new Change(tp, volume: vol, index: ind, sampleset: sam)); if (tp.SampleSet != ho.HitsoundTP.SampleSet) { samplesetActuallyChanged = samplesetSliders && ho.SampleSet == 0; } // True for sampleset change in sliderbody } if (ho.IsSlider && (!samplesetActuallyChanged) && ho.SampleSet == 0) // Case can put sampleset on sliderbody { ho.SampleSet = ho.HitsoundTP.SampleSet; ho.SliderExtras = true; } if (ho.IsSlider && samplesetActuallyChanged) // Make it start out with the right sampleset { TimingPoint tp = ho.HitsoundTP.Copy(); tp.Offset = ho.Time; changes.Add(new Change(tp, sampleset: true)); } UpdateProgressbar(worker, (double)i / editor.Beatmap.HitObjects.Count, 8, maxStages); } // Add timeline hitsounds for (int i = 0; i < timeline.TimeLineObjects.Count; i++) { TimelineObject tlo = timeline.TimeLineObjects[i]; // Change the samplesets in the hitobjects if (tlo.Origin.IsCircle) { tlo.Origin.SampleSet = tlo.FenoSampleSet; tlo.Origin.AdditionSet = tlo.FenoAdditionSet; if (mode == 3) { tlo.Origin.CustomIndex = tlo.FenoCustomIndex; tlo.Origin.SampleVolume = tlo.FenoSampleVolume; } } else if (tlo.Origin.IsSlider) { tlo.Origin.EdgeHitsounds[tlo.Repeat] = tlo.GetHitsounds(); tlo.Origin.EdgeSampleSets[tlo.Repeat] = tlo.FenoSampleSet; tlo.Origin.EdgeAdditionSets[tlo.Repeat] = tlo.FenoAdditionSet; tlo.Origin.SliderExtras = true; if (tlo.Origin.EdgeAdditionSets[tlo.Repeat] == tlo.Origin.EdgeSampleSets[tlo.Repeat]) // Simplify additions to auto { tlo.Origin.EdgeAdditionSets[tlo.Repeat] = 0; } } else if (tlo.Origin.IsSpinner) { if (tlo.Repeat == 1) { tlo.Origin.SampleSet = tlo.FenoSampleSet; tlo.Origin.AdditionSet = tlo.FenoAdditionSet; } } else if (tlo.Origin.IsHoldNote) { if (tlo.Repeat == 0) { tlo.Origin.SampleSet = tlo.FenoSampleSet; tlo.Origin.AdditionSet = tlo.FenoAdditionSet; tlo.Origin.CustomIndex = tlo.FenoCustomIndex; tlo.Origin.SampleVolume = tlo.FenoSampleVolume; } } if (tlo.Origin.AdditionSet == tlo.Origin.SampleSet) // Simplify additions to auto { tlo.Origin.AdditionSet = 0; } if (mode == 0 && tlo.HasHitsound) // Add greenlines for custom indexes and volumes { TimingPoint tp = tlo.Origin.TP.Copy(); tp.Offset = tlo.Time; tp.SampleIndex = tlo.FenoCustomIndex; tp.Volume = tlo.FenoSampleVolume; bool ind = !(tlo.Filename != "" && (tlo.IsCircle || tlo.IsHoldnoteHead || tlo.IsSpinnerEnd)); // Index doesnt have to change if custom is overridden by Filename bool vol = !(tp.Volume == 5 && removeSliderendMuting && (tlo.IsSliderEnd || tlo.IsSpinnerEnd)); // Remove volume change if sliderend muting or spinnerend muting changes.Add(new Change(tp, volume: vol, index: ind)); } UpdateProgressbar(worker, (double)i / timeline.TimeLineObjects.Count, 9, maxStages); } // Add the new timingpoints changes = changes.OrderBy(o => o.TP.Offset).ToList(); List <TimingPoint> newTimingPoints = new List <TimingPoint>(); for (int i = 0; i < changes.Count; i++) { Change c = changes[i]; c.AddChange(newTimingPoints, timing); UpdateProgressbar(worker, (double)i / changes.Count, 10, maxStages); } // Replace the old timingpoints timing.TimingPoints = newTimingPoints; // Save the file editor.SaveFile(); // Complete progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(100); } // Make an accurate message (Softwareporn) int removed = num_timingPoints - newTimingPoints.Count; string message = ""; if (removed < 0) { message += "Succesfully added " + Math.Abs(removed); } else { message += "Succesfully removed " + removed; } if (Math.Abs(removed) == 1) { message += " greenline and resnapped " + objectsResnapped; } else { message += " greenlines and resnapped " + objectsResnapped; } if (Math.Abs(objectsResnapped) == 1) { message += " object!"; } else { message += " objects!"; } return(message); }