private void Run() { if (StartController == null) { return; } var savedHighlights = _tree.HighlightedNodes; var settings = CreateSettings(); var solver = Tabs[_selectedTabIndex].CreateSolver(settings); var controllerVm = new ControllerViewModel(solver, Tabs[_selectedTabIndex].DisplayName, _tree); controllerVm.StartSolverAsync(); // Kinda crude, but I'm not going to write a framework for a few popups. StartController.Raise(this, new StartControllerEventArgs(controllerVm)); if (controllerVm.Result == true) { _tree.SkilledNodes = new HashSet <ushort>(controllerVm.BestSoFar); } _tree.HighlightedNodes = savedHighlights; _tree.DrawTreeComparisonHighlight(); _tree.DrawHighlights(); _tree.UpdateAvailNodes(); RunFinished.Raise(this); }
public async Task RunAsync(GeneratorTabViewModel generator) { var savedHighlights = Tree.HighlightedNodes.ToList(); var solver = await generator.CreateSolverAsync(); if (solver == null) { return; } var controllerResult = await _dialogCoordinator .ShowControllerDialogAsync(_dialogContext, solver, generator.DisplayName, Tree); if (controllerResult != null) { Tree.SkilledNodes.Clear(); Tree.AllocateSkillNodes(controllerResult.Select(n => SkillTree.Skillnodes[n])); } Tree.HighlightedNodes.Clear(); Tree.HighlightedNodes.UnionWith(savedHighlights); Tree.DrawHighlights(); RunFinished?.Invoke(this, EventArgs.Empty); }
private void Run_DoneAndUpdate(object sender, RoutedEventArgs e) { UpdateAlertCounter(); if (RunFinished != null) { RunFinished?.Invoke(this, null); } }
private string Run_Program(MapCleanerVm args, BackgroundWorker worker, DoWorkEventArgs _) { var result = new Classes.Tools.MapCleaner.MapCleanerResult(); var reader = EditorReaderStuff.GetFullEditorReaderOrNot(); if (args.Paths.Length == 1) { var editor = EditorReaderStuff.GetNewestVersionOrNot(args.Paths[0], reader); List <TimingPoint> orgininalTimingPoints = editor.Beatmap.BeatmapTiming.TimingPoints.Select(tp => tp.Copy()).ToList(); int oldTimingPointsCount = editor.Beatmap.BeatmapTiming.TimingPoints.Count; result.Add(Classes.Tools.MapCleaner.CleanMap(editor, args.MapCleanerArgs, worker)); // Update result with removed count int removed = oldTimingPointsCount - editor.Beatmap.BeatmapTiming.TimingPoints.Count; result.TimingPointsRemoved += removed; List <TimingPoint> newTimingPoints = editor.Beatmap.BeatmapTiming.TimingPoints; Monitor_Differences(orgininalTimingPoints, newTimingPoints); // Save the file editor.SaveFile(); } else { foreach (string path in args.Paths) { var editor = EditorReaderStuff.GetNewestVersionOrNot(path, reader); int oldTimingPointsCount = editor.Beatmap.BeatmapTiming.TimingPoints.Count; result.Add(Classes.Tools.MapCleaner.CleanMap(editor, args.MapCleanerArgs, worker)); // Update result with removed count int removed = oldTimingPointsCount - editor.Beatmap.BeatmapTiming.TimingPoints.Count; result.TimingPointsRemoved += removed; // Save the file editor.SaveFile(); } } // Do stuff if (args.Quick) { RunFinished?.Invoke(this, new RunToolCompletedEventArgs(true, reader != null)); } // Make an accurate message string message = $"Successfully {(result.TimingPointsRemoved < 0 ? "added" : "removed")} {Math.Abs(result.TimingPointsRemoved)} {(Math.Abs(result.TimingPointsRemoved) == 1 ? "greenline" : "greenlines")}" + (args.MapCleanerArgs.ResnapObjects ? $" and resnapped {result.ObjectsResnapped} {(result.ObjectsResnapped == 1 ? "object" : "objects")}" : "") + (args.MapCleanerArgs.RemoveUnusedSamples ? $" and removed {result.SamplesRemoved} unused {(result.SamplesRemoved == 1 ? "sample" : "samples")}" : "") + "!"; return(args.Quick ? string.Empty : message); }
private string PlaceHitsounds(Arguments args, BackgroundWorker worker, DoWorkEventArgs _) { if (args.Zones.Count == 0) { return("There are no zones!"); } var reader = EditorReaderStuff.GetFullEditorReaderOrNot(); foreach (string path in args.Paths) { var editor = EditorReaderStuff.GetNewestVersionOrNot(path, reader); Beatmap beatmap = editor.Beatmap; Timeline timeline = beatmap.GetTimeline(); for (int i = 0; i < timeline.TimelineObjects.Count; i++) { var tlo = timeline.TimelineObjects[i]; var column = args.Zones.FirstOrDefault(); double best = double.MaxValue; foreach (var c in args.Zones) { double dist = c.Distance(tlo.Origin.Pos); if (dist < best) { best = dist; column = c; } } if (column == null) { continue; } tlo.Filename = column.Filename; tlo.SampleSet = column.SampleSet; tlo.AdditionSet = column.AdditionsSet; tlo.CustomIndex = column.CustomIndex; tlo.SampleVolume = 0; tlo.SetHitsound(column.Hitsound); tlo.HitsoundsToOrigin(); UpdateProgressBar(worker, (int)(100f * i / beatmap.HitObjects.Count)); } // Save the file editor.SaveFile(); } // Do stuff RunFinished?.Invoke(this, new RunToolCompletedEventArgs(true, reader != null, args.Quick)); return(args.Quick ? "" : "Done!"); }
public void Start(GWInputData <PositionData> input) { ComputationInfo.IsActive = true; Input = input; Targets = Input.Targets; StartTime = DateTime.Now; RunStarted.Enter(); Work(); EndTime = DateTime.Now; ComputationInfo.IsActive = false; RunFinished.Enter(); }
private string Run_Program(Arguments args, BackgroundWorker worker, DoWorkEventArgs _) { var result = new MapCleaner.MapCleanerResult(); bool editorRead = EditorReaderStuff.TryGetFullEditorReader(out var reader); if (args.Paths.Length == 1) { var editor = EditorReaderStuff.GetBeatmapEditor(args.Paths[0], reader, editorRead); List<TimingPoint> orgininalTimingPoints = new List<TimingPoint>(); foreach (TimingPoint tp in editor.Beatmap.BeatmapTiming.TimingPoints) { orgininalTimingPoints.Add(tp.Copy()); } int oldTimingPointsCount = editor.Beatmap.BeatmapTiming.TimingPoints.Count; result.Add(MapCleaner.CleanMap(editor, args.CleanerArguments, worker)); // Update result with removed count int removed = oldTimingPointsCount - editor.Beatmap.BeatmapTiming.TimingPoints.Count; result.TimingPointsRemoved += removed; List<TimingPoint> newTimingPoints = editor.Beatmap.BeatmapTiming.TimingPoints; Monitor_Differences(orgininalTimingPoints, newTimingPoints); // Save the file editor.SaveFile(); } else { foreach (string path in args.Paths) { var editor = EditorReaderStuff.GetBeatmapEditor(path, reader, editorRead); int oldTimingPointsCount = editor.Beatmap.BeatmapTiming.TimingPoints.Count; result.Add(MapCleaner.CleanMap(editor, args.CleanerArguments, worker)); // Update result with removed count int removed = oldTimingPointsCount - editor.Beatmap.BeatmapTiming.TimingPoints.Count; result.TimingPointsRemoved += removed; // Save the file editor.SaveFile(); } } // Do stuff if (args.Quick) RunFinished?.Invoke(this, new RunToolCompletedEventArgs(true, editorRead)); // Make an accurate message string message = $"Successfully {(result.TimingPointsRemoved < 0 ? "added" : "removed")} {Math.Abs(result.TimingPointsRemoved)} {(Math.Abs(result.TimingPointsRemoved) == 1 ? "greenline" : "greenlines")}" + (args.CleanerArguments.ResnapObjects ? $" and resnapped {result.ObjectsResnapped} {(result.ObjectsResnapped == 1 ? "object" : "objects")}" : "") + (args.CleanerArguments.RemoveUnusedSamples ? $" and removed {result.SamplesRemoved} unused {(result.SamplesRemoved == 1 ? "sample" : "samples")}" : "") + "!"; return args.Quick ? "" : message; }
private string ExportPattern(PatternGalleryVm args, BackgroundWorker worker, DoWorkEventArgs _) { var reader = EditorReaderStuff.GetFullEditorReaderOrNot(); var editor = EditorReaderStuff.GetNewestVersionOrNot(IOHelper.GetCurrentBeatmapOrCurrentBeatmap(), reader); var pattern = args.Patterns.FirstOrDefault(o => o.IsSelected); if (pattern == null) { throw new Exception("No pattern has been selected to export."); } var patternBeatmap = pattern.GetPatternBeatmap(args.FileHandler); var patternPlacer = args.OsuPatternPlacer; if (reader != null) { patternPlacer.PlaceOsuPatternAtTime(patternBeatmap, editor.Beatmap, reader.EditorTime(), false); } else { patternPlacer.PlaceOsuPattern(patternBeatmap, editor.Beatmap, protectBeatmapPattern: false); } editor.SaveFile(); // Increase pattern use count and time pattern.UseCount++; pattern.LastUsedTime = DateTime.Now; // Complete progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(100); } // Do stuff if (args.Quick) { RunFinished?.Invoke(this, new RunToolCompletedEventArgs(true, reader != null)); } return("Successfully exported pattern!"); }
public async Task RunAsync() { var savedHighlights = _tree.HighlightedNodes; var settings = CreateSettings(); var solver = Tabs[_selectedTabIndex].CreateSolver(settings); var controllerResult = await _dialogCoordinator .ShowControllerDialogAsync(this, solver, Tabs[_selectedTabIndex].DisplayName, _tree); if (controllerResult != null) { _tree.SkilledNodes.Clear(); _tree.AllocateSkillNodes(controllerResult.Select(n => SkillTree.Skillnodes[n])); } _tree.HighlightedNodes.Clear(); _tree.HighlightedNodes.UnionWith(savedHighlights); _tree.DrawHighlights(); RunFinished?.Invoke(this, EventArgs.Empty); }
public async Task RunAsync() { var savedHighlights = _tree.HighlightedNodes; var settings = CreateSettings(); var solver = Tabs[_selectedTabIndex].CreateSolver(settings); var controllerResult = await _dialogCoordinator .ShowControllerDialogAsync(this, solver, Tabs[_selectedTabIndex].DisplayName, _tree); if (controllerResult != null) { _tree.SkilledNodes = new HashSet <ushort>(controllerResult); } _tree.HighlightedNodes = savedHighlights; _tree.DrawTreeComparisonHighlight(); _tree.DrawHighlights(); _tree.UpdateAvailNodes(); RunFinished.Raise(this); }
public void OnTestEvent(string report) { XmlNode xmlNode = XmlHelper.CreateXmlNode(report); switch (xmlNode.Name) { case "start-test": TestStarting?.Invoke(new TestNodeEventArgs(TestAction.TestStarting, new TestNode(xmlNode))); break; case "start-suite": SuiteStarting?.Invoke(new TestNodeEventArgs(TestAction.SuiteStarting, new TestNode(xmlNode))); break; case "start-run": RunStarting?.Invoke(new RunStartingEventArgs(xmlNode.GetAttribute("count", -1))); break; case "test-case": ResultNode result = new ResultNode(xmlNode); _resultIndex[result.Id] = result; TestFinished?.Invoke(new TestResultEventArgs(TestAction.TestFinished, result)); break; case "test-suite": result = new ResultNode(xmlNode); _resultIndex[result.Id] = result; SuiteFinished?.Invoke(new TestResultEventArgs(TestAction.SuiteFinished, result)); break; case "test-run": result = new ResultNode(xmlNode); _resultIndex[result.Id] = result; RunFinished?.Invoke(new TestResultEventArgs(TestAction.RunFinished, result)); break; } }
private string Sliderate(SlideratorVm arg, BackgroundWorker worker) { // Make a position function for Sliderator Classes.Tools.Sliderator.PositionFunctionDelegate positionFunction; // Test if the function is a constant velocity bool constantVelocity; // We convert the graph GetValue function to a function that works like ms -> px // d is a value representing the number of milliseconds into the slider if (arg.GraphModeSetting == SlideratorVm.GraphMode.Velocity) { // Here we use SvGraphMultiplier to get an accurate conversion from SV to slider completion per beat // Completion = (100 * SliderMultiplier / PixelLength) * SV * Beats positionFunction = d => arg.GraphState.GetIntegral(0, d * arg.BeatsPerMinute / 60000) * arg.SvGraphMultiplier * arg.PixelLength; constantVelocity = Precision.AlmostEquals(AnchorCollection.GetMaxValue(arg.GraphState.Anchors), AnchorCollection.GetMinValue(arg.GraphState.Anchors)); } else { positionFunction = d => arg.GraphState.GetValue(d * arg.BeatsPerMinute / 60000) * arg.PixelLength; constantVelocity = Precision.AlmostEquals(AnchorCollection.GetMaxDerivative(arg.GraphState.Anchors), AnchorCollection.GetMinDerivative(arg.GraphState.Anchors)); } // Dont do Sliderator if the velocity is constant AND equal to the new velocity var simplifyShape = constantVelocity && Precision.AlmostEquals( arg.PixelLength / arg.GraphBeats / arg.GlobalSv / 100, arg.NewVelocity); // Get the highest velocity occuring in the graph double velocity = arg.NewVelocity; // Velocity is in SV // Do bad stuff to the velocity to make sure its the same SV as after writing it to .osu code velocity = -100 / double.Parse((-100 / velocity).ToInvariant(), CultureInfo.InvariantCulture); // Other velocity is in px / ms var otherVelocity = velocity * arg.SvGraphMultiplier * arg.PixelLength * arg.BeatsPerMinute / 60000; // Time between timeline ticks for stream export var deltaT = 60000 / arg.BeatsPerMinute / arg.BeatSnapDivisor; // Update progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(10); } List <Vector2> slideration = new List <Vector2>(); var sliderator = new Classes.Tools.Sliderator { PositionFunction = positionFunction, MaxT = arg.GraphBeats / arg.BeatsPerMinute * 60000, Velocity = otherVelocity, MinDendriteLength = arg.MinDendrite }; if (!simplifyShape) { // Get slider path like from the hit object preview var sliderPath = new SliderPath(arg.VisibleHitObject.SliderType, arg.VisibleHitObject.GetAllCurvePoints().ToArray(), GetMaxCompletion(arg, arg.GraphState.Anchors) * arg.PixelLength); var path = new List <Vector2>(); sliderPath.GetPathToProgress(path, 0, 1); // Update progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(20); } // Do Sliderator sliderator.SetPath(path); slideration = arg.ExportAsStream ? sliderator.SliderateStream(deltaT) : sliderator.Sliderate(); // Check for some illegal output if (double.IsInfinity(sliderator.MaxS) || double.IsNaN(sliderator.MaxS) || slideration.Any(v => double.IsNaN(v.X) || double.IsNaN(v.Y))) { return("Encountered unexpected values from Sliderator. Please check your input."); } } // Update progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(60); } // Exporting stuff BeatmapEditor editor; bool editorRead = false; if (arg.DoEditorRead) { editor = EditorReaderStuff.GetNewestVersionOrNot(arg.Path, out _, out var exception); if (exception == null) { editorRead = true; } arg.DoEditorRead = false; } else { editor = new BeatmapEditor(arg.Path); } var beatmap = editor.Beatmap; var timing = beatmap.BeatmapTiming; // Get hit object that might be present at the export time or make a new one var hitObjectHere = beatmap.HitObjects.FirstOrDefault(o => Math.Abs(arg.ExportTime - o.Time) < 5) ?? new HitObject(arg.ExportTime, 0, SampleSet.Auto, SampleSet.Auto); // Clone the hit object to not affect the already existing hit object instance with changes var clone = new HitObject(hitObjectHere.GetLine()) { IsCircle = arg.ExportAsStream, IsSpinner = false, IsHoldNote = false, IsSlider = !arg.ExportAsStream }; // Update progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(70); } if (!arg.ExportAsStream) { // Give the new hit object the sliderated anchors if (simplifyShape) { // The velocity is constant, so you can simplify to the original slider shape clone.SetAllCurvePoints(arg.VisibleHitObject.GetAllCurvePoints()); clone.SliderType = arg.VisibleHitObject.SliderType; } else { clone.SetAllCurvePoints(slideration); clone.SliderType = PathType.Bezier; } clone.PixelLength = sliderator.MaxS; clone.SliderVelocity = -100 / velocity; // Add hit object if (arg.ExportModeSetting == SlideratorVm.ExportMode.Add) { beatmap.HitObjects.Add(clone); } else { beatmap.HitObjects.Remove(hitObjectHere); beatmap.HitObjects.Add(clone); } // Add SV var timingPointsChanges = new List <TimingPointsChange>(); if (arg.DelegateToBpm) { var tpAfter = timing.GetRedlineAtTime(clone.Time).Copy(); var tpOn = tpAfter.Copy(); tpAfter.Offset = clone.Time; tpOn.Offset = clone.Time - 1; // This one will be on the slider tpAfter.OmitFirstBarLine = true; tpOn.OmitFirstBarLine = true; // Express velocity in BPM tpOn.MpB /= -100 / clone.SliderVelocity; // NaN SV results in removal of slider ticks clone.SliderVelocity = arg.RemoveSliderTicks ? double.NaN : -100; // Add redlines timingPointsChanges.Add(new TimingPointsChange(tpOn, mpb: true, inherited: true, omitFirstBarLine: true, fuzzyness: 0)); timingPointsChanges.Add(new TimingPointsChange(tpAfter, mpb: true, inherited: true, omitFirstBarLine: true, fuzzyness: 0)); clone.Time -= 1; } // Add SV for every hit object so the SV doesnt change for anything else than the sliderated slider timingPointsChanges.AddRange(beatmap.HitObjects.Select(ho => { var sv = ho == clone ? ho.SliderVelocity : timing.GetSvAtTime(ho.Time); var tp = timing.GetTimingPointAtTime(ho.Time).Copy(); tp.MpB = sv; tp.Offset = ho.Time; return(new TimingPointsChange(tp, mpb: true, fuzzyness: 0)); })); TimingPointsChange.ApplyChanges(timing, timingPointsChanges); } else { // Add hit objects if (arg.ExportModeSetting == SlideratorVm.ExportMode.Override) { beatmap.HitObjects.Remove(hitObjectHere); } double t = arg.ExportTime; foreach (var pos in slideration) { clone.Pos = pos; clone.Time = t; beatmap.HitObjects.Add(clone); clone = new HitObject(clone.GetLine()) { IsCircle = true, IsSpinner = false, IsHoldNote = false, IsSlider = false, NewCombo = false }; t += deltaT; } } // Update progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(80); } beatmap.SortHitObjects(); editor.SaveFile(); // Complete progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(100); } // Do stuff if (arg.Quick) { RunFinished?.Invoke(this, new RunToolCompletedEventArgs(true, editorRead)); } return(arg.Quick ? string.Empty : "Done!"); }
private string Run_Program(AutoFailDetectorVm args, BackgroundWorker worker, DoWorkEventArgs _) { var reader = EditorReaderStuff.GetFullEditorReaderOrNot(); var editor = EditorReaderStuff.GetNewestVersionOrNot(args.Paths[0], reader); var beatmap = editor.Beatmap; // Get approach time and radius of the 50 score hit window var ar = args.ApproachRateOverride == -1 ? editor.Beatmap.Difficulty["ApproachRate"].DoubleValue : args.ApproachRateOverride; var approachTime = (int)Beatmap.GetApproachTime(ar); var od = args.OverallDifficultyOverride == -1 ? editor.Beatmap.Difficulty["OverallDifficulty"].DoubleValue : args.OverallDifficultyOverride; var window50 = (int)Math.Ceiling(200 - 10 * od); // Start time and end time var mapStartTime = (int)beatmap.GetMapStartTime(); var mapEndTime = (int)beatmap.GetMapEndTime(); var autoFailTime = (int)beatmap.GetAutoFailCheckTime(); // Detect auto-fail var autoFailDetector = new Classes.Tools.AutoFailDetector(beatmap.HitObjects, mapStartTime, mapEndTime, autoFailTime, approachTime, window50, args.PhysicsUpdateLeniency); var autoFail = autoFailDetector.DetectAutoFail(); if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(33); } // Fix auto-fail if (args.GetAutoFailFix) { var placedFix = autoFailDetector.AutoFailFixDialogue(args.AutoPlaceFix); if (placedFix) { editor.SaveFile(); } } if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(67); } // Set the timeline lists _unloadingObjects = args.ShowUnloadingObjects ? autoFailDetector.UnloadingObjects : new List <double>(); _potentialUnloadingObjects = args.ShowPotentialUnloadingObjects ? autoFailDetector.PotentialUnloadingObjects : new List <double>(); _potentialDisruptors = args.ShowPotentialDisruptors ? autoFailDetector.Disruptors : new List <double>(); // Set end time for the timeline _endTimeMonitor = mapEndTime; // Complete progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(100); } // Do stuff RunFinished?.Invoke(this, new RunToolCompletedEventArgs(true, false, args.Quick)); return(autoFail ? $"{autoFailDetector.UnloadingObjects.Count} unloading objects detected and {autoFailDetector.PotentialUnloadingObjects.Count} potential unloading objects detected!" : autoFailDetector.PotentialUnloadingObjects.Count > 0 ? $"No auto-fail, but {autoFailDetector.PotentialUnloadingObjects.Count} potential unloading objects detected." : "No auto-fail detected."); }
public void Handle(RunFinished @event) { EventHandlerPolicy.SafeInvoke(RunFinished, this, System.EventArgs.Empty); }
private string Merge_Sliders(Arguments arg, BackgroundWorker worker) { var slidersMerged = 0; var editorRead = EditorReaderStuff.TryGetFullEditorReader(out var reader); foreach (var path in arg.Paths) { var editor = EditorReaderStuff.GetBeatmapEditor(path, reader, editorRead, out var selected, out var editorActuallyRead); if (arg.SelectionMode == 0 && !editorActuallyRead) { return(EditorReaderStuff.SelectedObjectsReadFailText); } var beatmap = editor.Beatmap; var markedObjects = arg.SelectionMode == 0 ? selected : arg.SelectionMode == 1 ? beatmap.GetBookmarkedObjects() : beatmap.HitObjects; var mergeLast = false; for (var i = 0; i < markedObjects.Count - 1; i++) { var ho1 = markedObjects[i]; var ho2 = markedObjects[i + 1]; if (ho1.IsSlider && ho2.IsSlider && (ho1.CurvePoints.Last() - ho2.Pos).Length <= arg.Leniency) { var sp1 = BezierConverter.ConvertToBezier(ho1.SliderPath).ControlPoints; var sp2 = BezierConverter.ConvertToBezier(ho2.SliderPath).ControlPoints; double extraLength = 0; switch (arg.ConnectionMode) { case ConnectionMode.Move: Move(sp2, sp1.Last() - sp2.First()); break; case ConnectionMode.Linear: sp1.Add(sp1.Last()); sp1.Add(sp2.First()); extraLength = (ho1.CurvePoints.Last() - ho2.Pos).Length; break; } var mergedAnchors = sp1.Concat(sp2).ToList(); mergedAnchors.Round(); var linearLinear = arg.LinearOnLinear && IsLinearBezier(sp1) && IsLinearBezier(sp2); if (linearLinear) { for (var j = 0; j < mergedAnchors.Count - 1; j++) { if (mergedAnchors[j] != mergedAnchors[j + 1]) { continue; } mergedAnchors.RemoveAt(j); j--; } } var mergedPath = new SliderPath(linearLinear ? PathType.Linear : PathType.Bezier, mergedAnchors.ToArray(), ho1.PixelLength + ho2.PixelLength + extraLength); ho1.SliderPath = mergedPath; beatmap.HitObjects.Remove(ho2); markedObjects.Remove(ho2); i--; slidersMerged++; if (!mergeLast) { slidersMerged++; } mergeLast = true; } else if (ho1.IsSlider && ho2.IsCircle && (ho1.CurvePoints.Last() - ho2.Pos).Length <= arg.Leniency) { var sp1 = BezierConverter.ConvertToBezier(ho1.SliderPath).ControlPoints; sp1.Add(sp1.Last()); sp1.Add(ho2.Pos); var extraLength = (ho1.CurvePoints.Last() - ho2.Pos).Length; var mergedAnchors = sp1; mergedAnchors.Round(); var linearLinear = arg.LinearOnLinear && IsLinearBezier(sp1); if (linearLinear) { for (var j = 0; j < mergedAnchors.Count - 1; j++) { if (mergedAnchors[j] != mergedAnchors[j + 1]) { continue; } mergedAnchors.RemoveAt(j); j--; } } var mergedPath = new SliderPath(linearLinear ? PathType.Linear : PathType.Bezier, mergedAnchors.ToArray(), ho1.PixelLength + extraLength); ho1.SliderPath = mergedPath; beatmap.HitObjects.Remove(ho2); markedObjects.Remove(ho2); i--; slidersMerged++; if (!mergeLast) { slidersMerged++; } mergeLast = true; } else if (ho1.IsCircle && ho2.IsSlider && (ho1.Pos - ho2.Pos).Length <= arg.Leniency) { var sp2 = BezierConverter.ConvertToBezier(ho2.SliderPath).ControlPoints; sp2.Insert(0, sp2.First()); sp2.Insert(0, ho1.Pos); var extraLength = (ho1.Pos - ho2.Pos).Length; var mergedAnchors = sp2; mergedAnchors.Round(); var linearLinear = arg.LinearOnLinear && IsLinearBezier(sp2); if (linearLinear) { for (var j = 0; j < mergedAnchors.Count - 1; j++) { if (mergedAnchors[j] != mergedAnchors[j + 1]) { continue; } mergedAnchors.RemoveAt(j); j--; } } var mergedPath = new SliderPath(linearLinear ? PathType.Linear : PathType.Bezier, mergedAnchors.ToArray(), ho2.PixelLength + extraLength); ho2.SliderPath = mergedPath; beatmap.HitObjects.Remove(ho1); markedObjects.Remove(ho1); i--; slidersMerged++; if (!mergeLast) { slidersMerged++; } mergeLast = true; } else if (ho1.IsCircle && ho2.IsCircle && (ho1.Pos - ho2.Pos).Length <= arg.Leniency) { var mergedAnchors = new List <Vector2> { ho1.Pos, ho2.Pos }; var mergedPath = new SliderPath(arg.LinearOnLinear ? PathType.Linear : PathType.Bezier, mergedAnchors.ToArray(), (ho1.Pos - ho2.Pos).Length); ho1.SliderPath = mergedPath; ho1.IsCircle = false; ho1.IsSlider = true; ho1.Repeat = 1; ho1.EdgeHitsounds = new List <int> { ho1.GetHitsounds(), ho2.GetHitsounds() }; ho1.EdgeSampleSets = new List <SampleSet> { ho1.SampleSet, ho2.SampleSet }; ho1.EdgeAdditionSets = new List <SampleSet> { ho1.AdditionSet, ho2.AdditionSet }; beatmap.HitObjects.Remove(ho2); markedObjects.Remove(ho2); i--; slidersMerged++; if (!mergeLast) { slidersMerged++; } mergeLast = true; } else { mergeLast = false; } if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(i / markedObjects.Count); } } // Save the file editor.SaveFile(); } // Complete progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(100); } // Do stuff if (arg.Quick) { RunFinished?.Invoke(this, new RunToolCompletedEventArgs(true, editorRead)); } // Make an accurate message var message = ""; if (Math.Abs(slidersMerged) == 1) { message += "Successfully merged " + slidersMerged + " slider!"; } else { message += "Successfully merged " + slidersMerged + " sliders!"; } return(arg.Quick ? "" : message); }
protected void OnRunFinished() { RunFinished?.Invoke(this, EventArgs.Empty); }
private string Complete_Sliders(SliderCompletionatorVm arg, BackgroundWorker worker, DoWorkEventArgs _) { int slidersCompleted = 0; var reader = EditorReaderStuff.GetFullEditorReaderOrNot(out var editorReaderException1); if (arg.ImportModeSetting == SliderCompletionatorVm.ImportMode.Selected && editorReaderException1 != null) { throw new Exception("Could not fetch selected hit objects.", editorReaderException1); } foreach (string path in arg.Paths) { var editor = EditorReaderStuff.GetNewestVersionOrNot(path, reader, out var selected, out var editorReaderException2); if (arg.ImportModeSetting == SliderCompletionatorVm.ImportMode.Selected && editorReaderException2 != null) { throw new Exception("Could not fetch selected hit objects.", editorReaderException2); } Beatmap beatmap = editor.Beatmap; Timing timing = beatmap.BeatmapTiming; List <HitObject> markedObjects = arg.ImportModeSetting == SliderCompletionatorVm.ImportMode.Selected ? selected : arg.ImportModeSetting == SliderCompletionatorVm.ImportMode.Bookmarked ? beatmap.GetBookmarkedObjects() : arg.ImportModeSetting == SliderCompletionatorVm.ImportMode.Time ? beatmap.QueryTimeCode(arg.TimeCode).ToList() : beatmap.HitObjects; for (int i = 0; i < markedObjects.Count; i++) { HitObject ho = markedObjects[i]; if (ho.IsSlider) { double oldSpatialLength = ho.PixelLength; double newSpatialLength = arg.SpatialLength != -1 ? ho.GetSliderPath(fullLength: true).Distance *arg.SpatialLength : oldSpatialLength; double oldTemporalLength = timing.CalculateSliderTemporalLength(ho.Time, ho.PixelLength); double newTemporalLength = arg.TemporalLength != -1 ? timing.GetMpBAtTime(ho.Time) * arg.TemporalLength : oldTemporalLength; double oldSv = timing.GetSvAtTime(ho.Time); double newSv = oldSv / ((newSpatialLength / oldSpatialLength) / (newTemporalLength / oldTemporalLength)); if (double.IsNaN(newSv)) { throw new Exception("Encountered NaN slider velocity. Make sure none of the inputs are zero."); } ho.SliderVelocity = newSv; ho.PixelLength = newSpatialLength; // Scale anchors to completion if (arg.MoveAnchors) { ho.SetAllCurvePoints(SliderPathUtil.MoveAnchorsToLength( ho.GetAllCurvePoints(), ho.SliderType, ho.PixelLength, out var pathType)); ho.SliderType = pathType; } slidersCompleted++; } if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(i / markedObjects.Count); } } // Reconstruct SliderVelocity List <TimingPointsChange> timingPointsChanges = new List <TimingPointsChange>(); // Add Hitobject stuff foreach (HitObject ho in beatmap.HitObjects) { if (ho.IsSlider) // SliderVelocity changes { TimingPoint tp = ho.TimingPoint.Copy(); tp.Offset = ho.Time; tp.MpB = ho.SliderVelocity; timingPointsChanges.Add(new TimingPointsChange(tp, mpb: true)); } } // Add the new SliderVelocity changes TimingPointsChange.ApplyChanges(timing, timingPointsChanges); // Save the file editor.SaveFile(); } // Complete progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(100); } // Do stuff if (arg.Quick) { RunFinished?.Invoke(this, new RunToolCompletedEventArgs(true, reader != null)); } // Make an accurate message string message = ""; if (Math.Abs(slidersCompleted) == 1) { message += "Successfully completed " + slidersCompleted + " slider!"; } else { message += "Successfully completed " + slidersCompleted + " sliders!"; } return(arg.Quick ? "" : message); }
public void Handle(RunFinished @event) { stopwatch.Stop(); ElapsedTime.Value = stopwatch.Elapsed; }
private void ViewModelRunFinished(object sender, EventArgs args) { RunFinished?.Invoke(this, EventArgs.Empty); }
private string Merge_Sliders(SliderMergerVm arg, BackgroundWorker worker) { var slidersMerged = 0; var reader = EditorReaderStuff.GetFullEditorReaderOrNot(out var editorReaderException1); if (arg.ImportModeSetting == 0 && editorReaderException1 != null) { throw new Exception("Could not fetch selected hit objects.", editorReaderException1); } foreach (var path in arg.Paths) { var editor = EditorReaderStuff.GetNewestVersionOrNot(path, reader, out var selected, out var editorReaderException2); if (arg.ImportModeSetting == SliderMergerVm.ImportMode.Selected && editorReaderException2 != null) { throw new Exception("Could not fetch selected hit objects.", editorReaderException2); } var beatmap = editor.Beatmap; var markedObjects = arg.ImportModeSetting == 0 ? selected : arg.ImportModeSetting == SliderMergerVm.ImportMode.Bookmarked ? beatmap.GetBookmarkedObjects() : arg.ImportModeSetting == SliderMergerVm.ImportMode.Time ? beatmap.QueryTimeCode(arg.TimeCode).ToList() : beatmap.HitObjects; var mergeLast = false; for (var i = 0; i < markedObjects.Count - 1; i++) { if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(i / markedObjects.Count); } var ho1 = markedObjects[i]; var ho2 = markedObjects[i + 1]; var lastPos1 = ho1.IsSlider ? arg.MergeOnSliderEnd ? ho1.GetSliderPath().PositionAt(1) : ho1.CurvePoints.Last() : ho1.Pos; double dist = Vector2.Distance(lastPos1, ho2.Pos); if (dist > arg.Leniency) { mergeLast = false; continue; } if (ho1.IsSlider && ho2.IsSlider) { if (arg.MergeOnSliderEnd) { // In order to merge on the slider end we first move the anchors such that the last anchor is exactly on the slider end // After that merge as usual ho1.SetAllCurvePoints(SliderPathUtil.MoveAnchorsToLength( ho1.GetAllCurvePoints(), ho1.SliderType, ho1.PixelLength, out var pathType)); ho1.SliderType = pathType; } var sp1 = BezierConverter.ConvertToBezier(ho1.SliderPath).ControlPoints; var sp2 = BezierConverter.ConvertToBezier(ho2.SliderPath).ControlPoints; double extraLength = 0; switch (arg.ConnectionModeSetting) { case SliderMergerVm.ConnectionMode.Move: Move(sp2, sp1.Last() - sp2.First()); break; case SliderMergerVm.ConnectionMode.Linear: sp1.Add(sp1.Last()); sp1.Add(sp2.First()); extraLength = (ho1.CurvePoints.Last() - ho2.Pos).Length; break; } var mergedAnchors = sp1.Concat(sp2).ToList(); mergedAnchors.Round(); var linearLinear = arg.LinearOnLinear && IsLinearBezier(sp1) && IsLinearBezier(sp2); if (linearLinear) { for (var j = 0; j < mergedAnchors.Count - 1; j++) { if (mergedAnchors[j] != mergedAnchors[j + 1]) { continue; } mergedAnchors.RemoveAt(j); j--; } } var mergedPath = new SliderPath(linearLinear ? PathType.Linear : PathType.Bezier, mergedAnchors.ToArray(), ho1.PixelLength + ho2.PixelLength + extraLength); ho1.SliderPath = mergedPath; beatmap.HitObjects.Remove(ho2); markedObjects.Remove(ho2); i--; slidersMerged++; if (!mergeLast) { slidersMerged++; } mergeLast = true; } else if (ho1.IsSlider && ho2.IsCircle) { var sp1 = BezierConverter.ConvertToBezier(ho1.SliderPath).ControlPoints; sp1.Add(sp1.Last()); sp1.Add(ho2.Pos); var extraLength = (ho1.CurvePoints.Last() - ho2.Pos).Length; var mergedAnchors = sp1; mergedAnchors.Round(); var linearLinear = arg.LinearOnLinear && IsLinearBezier(sp1); if (linearLinear) { for (var j = 0; j < mergedAnchors.Count - 1; j++) { if (mergedAnchors[j] != mergedAnchors[j + 1]) { continue; } mergedAnchors.RemoveAt(j); j--; } } var mergedPath = new SliderPath(linearLinear ? PathType.Linear : PathType.Bezier, mergedAnchors.ToArray(), ho1.PixelLength + extraLength); ho1.SliderPath = mergedPath; beatmap.HitObjects.Remove(ho2); markedObjects.Remove(ho2); i--; slidersMerged++; if (!mergeLast) { slidersMerged++; } mergeLast = true; } else if (ho1.IsCircle && ho2.IsSlider) { var sp2 = BezierConverter.ConvertToBezier(ho2.SliderPath).ControlPoints; sp2.Insert(0, sp2.First()); sp2.Insert(0, ho1.Pos); var extraLength = (ho1.Pos - ho2.Pos).Length; var mergedAnchors = sp2; mergedAnchors.Round(); var linearLinear = arg.LinearOnLinear && IsLinearBezier(sp2); if (linearLinear) { for (var j = 0; j < mergedAnchors.Count - 1; j++) { if (mergedAnchors[j] != mergedAnchors[j + 1]) { continue; } mergedAnchors.RemoveAt(j); j--; } } var mergedPath = new SliderPath(linearLinear ? PathType.Linear : PathType.Bezier, mergedAnchors.ToArray(), ho2.PixelLength + extraLength); ho2.SliderPath = mergedPath; beatmap.HitObjects.Remove(ho1); markedObjects.Remove(ho1); i--; slidersMerged++; if (!mergeLast) { slidersMerged++; } mergeLast = true; } else if (ho1.IsCircle && ho2.IsCircle) { var mergedAnchors = new List <Vector2> { ho1.Pos, ho2.Pos }; var mergedPath = new SliderPath(arg.LinearOnLinear ? PathType.Linear : PathType.Bezier, mergedAnchors.ToArray(), (ho1.Pos - ho2.Pos).Length); ho1.SliderPath = mergedPath; ho1.IsCircle = false; ho1.IsSlider = true; ho1.Repeat = 1; ho1.EdgeHitsounds = new List <int> { ho1.GetHitsounds(), ho2.GetHitsounds() }; ho1.EdgeSampleSets = new List <SampleSet> { ho1.SampleSet, ho2.SampleSet }; ho1.EdgeAdditionSets = new List <SampleSet> { ho1.AdditionSet, ho2.AdditionSet }; beatmap.HitObjects.Remove(ho2); markedObjects.Remove(ho2); i--; slidersMerged++; if (!mergeLast) { slidersMerged++; } mergeLast = true; } else { mergeLast = false; } } // Save the file editor.SaveFile(); } // Complete progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(100); } // Do stuff if (arg.Quick) { RunFinished?.Invoke(this, new RunToolCompletedEventArgs(true, reader != null)); } // Make an accurate message var message = ""; if (Math.Abs(slidersMerged) == 1) { message += "Successfully merged " + slidersMerged + " slider!"; } else { message += "Successfully merged " + slidersMerged + " sliders!"; } return(arg.Quick ? "" : message); }
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) { markers.Add(new Marker(tp.Offset)); } } } if (arg.Redlines) { // Get the offsets of redlines foreach (TimingPoint tp in timing.TimingPoints) { if (tp.Uninherited) { 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); } // Do QuickRun stuff if (arg.Quick) { RunFinished?.Invoke(this, new RunToolCompletedEventArgs(true, editorRead)); } // 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); }
private string Complete_Sliders(Arguments arg, BackgroundWorker worker, DoWorkEventArgs _) { int slidersCompleted = 0; bool editorRead = EditorReaderStuff.TryGetFullEditorReader(out var reader); foreach (string path in arg.Paths) { var editor = EditorReaderStuff.GetBeatmapEditor(path, reader, editorRead, out var selected, out var editorActuallyRead); if (arg.SelectionMode == 0 && !editorActuallyRead) { return(EditorReaderStuff.SelectedObjectsReadFailText); } Beatmap beatmap = editor.Beatmap; Timing timing = beatmap.BeatmapTiming; List <HitObject> markedObjects = arg.SelectionMode == 0 ? selected : arg.SelectionMode == 1 ? beatmap.GetBookmarkedObjects() : beatmap.HitObjects; for (int i = 0; i < markedObjects.Count; i++) { HitObject ho = markedObjects[i]; if (ho.IsSlider) { double oldSpatialLength = ho.PixelLength; double newSpatialLength = arg.SpatialLength != -1 ? ho.GetSliderPath(fullLength: true).Distance *arg.SpatialLength : oldSpatialLength; double oldTemporalLength = timing.CalculateSliderTemporalLength(ho.Time, ho.PixelLength); double newTemporalLength = arg.TemporalLength != -1 ? timing.GetMpBAtTime(ho.Time) * arg.TemporalLength : oldTemporalLength; double oldSv = timing.GetSvAtTime(ho.Time); double newSv = oldSv / ((newSpatialLength / oldSpatialLength) / (newTemporalLength / oldTemporalLength)); ho.SliderVelocity = newSv; ho.PixelLength = newSpatialLength; // Scale anchors to completion if (arg.MoveAnchors) { ho.SetAllCurvePoints(SliderPathUtil.MoveAnchorsToLength( ho.GetAllCurvePoints(), ho.SliderType, ho.PixelLength, out var pathType)); ho.SliderType = pathType; } slidersCompleted++; } if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(i / markedObjects.Count); } } // Reconstruct SliderVelocity List <TimingPointsChange> timingPointsChanges = new List <TimingPointsChange>(); // Add Hitobject stuff foreach (HitObject ho in beatmap.HitObjects) { if (ho.IsSlider) // SliderVelocity changes { TimingPoint tp = ho.TimingPoint.Copy(); tp.Offset = ho.Time; tp.MpB = ho.SliderVelocity; timingPointsChanges.Add(new TimingPointsChange(tp, mpb: true)); } } // Add the new SliderVelocity changes TimingPointsChange.ApplyChanges(timing, timingPointsChanges); // Save the file editor.SaveFile(); } // Complete progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(100); } // Do stuff if (arg.Quick) { RunFinished?.Invoke(this, new RunToolCompletedEventArgs(true, editorRead)); } // Make an accurate message string message = ""; if (Math.Abs(slidersCompleted) == 1) { message += "Successfully completed " + slidersCompleted + " slider!"; } else { message += "Successfully completed " + slidersCompleted + " sliders!"; } return(arg.Quick ? "" : message); }
private string ExportPattern(PatternGalleryVm args, BackgroundWorker worker, DoWorkEventArgs _) { EditorReader reader; double exportTime = 0; bool usePatternOffset = false; switch (args.ExportTimeMode) { case ExportTimeMode.Current: try { reader = EditorReaderStuff.GetFullEditorReader(); exportTime = reader.EditorTime(); } catch (Exception e) { throw new Exception("Could not fetch the current editor time.", e); } break; case ExportTimeMode.Pattern: reader = EditorReaderStuff.GetFullEditorReaderOrNot(); usePatternOffset = true; break; case ExportTimeMode.Custom: reader = EditorReaderStuff.GetFullEditorReaderOrNot(); exportTime = args.CustomExportTime; break; default: throw new ArgumentOutOfRangeException(nameof(ExportTimeMode), "Invalid value encountered"); } var editor = EditorReaderStuff.GetNewestVersionOrNot(args.Paths[0], reader); var patternCount = args.Patterns.Count(o => o.IsSelected); if (patternCount == 0) { throw new Exception("No pattern has been selected to export."); } var patternPlacer = args.OsuPatternPlacer; foreach (var pattern in args.Patterns.Where(o => o.IsSelected)) { var patternBeatmap = pattern.GetPatternBeatmap(args.FileHandler); if (usePatternOffset) { patternPlacer.PlaceOsuPattern(patternBeatmap, editor.Beatmap, protectBeatmapPattern: false); } else { patternPlacer.PlaceOsuPatternAtTime(patternBeatmap, editor.Beatmap, exportTime, false); } // Increase pattern use count and time pattern.UseCount++; pattern.LastUsedTime = DateTime.Now; } editor.SaveFile(); // Complete progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(100); } // Do stuff RunFinished?.Invoke(this, new RunToolCompletedEventArgs(true, reader != null, args.Quick)); return("Successfully exported pattern!"); }
public void Handle(RunFinished @event) { testExplorerModel.CanEditTree.Value = true; }
private string Complete_Sliders(SliderCompletionatorVm arg, BackgroundWorker worker, DoWorkEventArgs _) { int slidersCompleted = 0; var reader = EditorReaderStuff.GetFullEditorReaderOrNot(out var editorReaderException1); if (arg.ImportModeSetting == SliderCompletionatorVm.ImportMode.Selected && editorReaderException1 != null) { throw new Exception("Could not fetch selected hit objects.", editorReaderException1); } foreach (string path in arg.Paths) { var editor = EditorReaderStuff.GetNewestVersionOrNot(path, reader, out var selected, out var editorReaderException2); if (arg.ImportModeSetting == SliderCompletionatorVm.ImportMode.Selected && editorReaderException2 != null) { throw new Exception("Could not fetch selected hit objects.", editorReaderException2); } Beatmap beatmap = editor.Beatmap; Timing timing = beatmap.BeatmapTiming; List <HitObject> markedObjects = arg.ImportModeSetting switch { SliderCompletionatorVm.ImportMode.Selected => selected, SliderCompletionatorVm.ImportMode.Bookmarked => beatmap.GetBookmarkedObjects(), SliderCompletionatorVm.ImportMode.Time => beatmap.QueryTimeCode(arg.TimeCode).ToList(), SliderCompletionatorVm.ImportMode.Everything => beatmap.HitObjects, _ => throw new ArgumentException("Unexpected import mode.") }; for (int i = 0; i < markedObjects.Count; i++) { HitObject ho = markedObjects[i]; if (ho.IsSlider) { double mpb = timing.GetMpBAtTime(ho.Time); double oldDuration = timing.CalculateSliderTemporalLength(ho.Time, ho.PixelLength); double oldLength = ho.PixelLength; double oldSv = timing.GetSvAtTime(ho.Time); double newDuration = arg.UseEndTime ? arg.EndTime == -1 ? oldDuration : arg.EndTime - ho.Time : arg.Duration == -1 ? oldDuration : timing.WalkBeatsInMillisecondTime(arg.Duration, ho.Time) - ho.Time; double newLength = arg.Length == -1 ? oldLength : ho.GetSliderPath(fullLength: true).Distance *arg.Length; double newSv = arg.SliderVelocity == -1 ? oldSv : -100 / arg.SliderVelocity; switch (arg.FreeVariableSetting) { case SliderCompletionatorVm.FreeVariable.Velocity: newSv = -10000 * timing.SliderMultiplier * newDuration / (newLength * mpb); break; case SliderCompletionatorVm.FreeVariable.Duration: // This actually doesn't get used anymore because the .osu doesn't store the duration newDuration = newLength * newSv * mpb / (-10000 * timing.SliderMultiplier); break; case SliderCompletionatorVm.FreeVariable.Length: newLength = -10000 * timing.SliderMultiplier * newDuration / (newSv * mpb); break; default: throw new ArgumentException("Unexpected free variable setting."); } if (double.IsNaN(newSv)) { throw new Exception("Encountered NaN slider velocity. Make sure none of the inputs are zero."); } if (newDuration < 0) { throw new Exception("Encountered slider with negative duration. Make sure the end time is greater than the end time of all selected sliders."); } ho.SliderVelocity = newSv; ho.PixelLength = newLength; // Scale anchors to completion if (arg.MoveAnchors) { ho.SetAllCurvePoints(SliderPathUtil.MoveAnchorsToLength( ho.GetAllCurvePoints(), ho.SliderType, ho.PixelLength, out var pathType)); ho.SliderType = pathType; } slidersCompleted++; } if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(i / markedObjects.Count); } } // Reconstruct SliderVelocity List <TimingPointsChange> timingPointsChanges = new List <TimingPointsChange>(); // Add Hitobject stuff foreach (HitObject ho in beatmap.HitObjects) { // SliderVelocity changes if (ho.IsSlider) { if (markedObjects.Contains(ho) && arg.DelegateToBpm) { var tpAfter = timing.GetRedlineAtTime(ho.Time).Copy(); var tpOn = tpAfter.Copy(); tpAfter.Offset = ho.Time; tpOn.Offset = ho.Time - 1; // This one will be on the slider tpAfter.OmitFirstBarLine = true; tpOn.OmitFirstBarLine = true; // Express velocity in BPM tpOn.MpB *= ho.SliderVelocity / -100; // NaN SV results in removal of slider ticks ho.SliderVelocity = arg.RemoveSliderTicks ? double.NaN : -100; // Add redlines timingPointsChanges.Add(new TimingPointsChange(tpOn, mpb: true, unInherited: true, omitFirstBarLine: true, fuzzyness: Precision.DOUBLE_EPSILON)); timingPointsChanges.Add(new TimingPointsChange(tpAfter, mpb: true, unInherited: true, omitFirstBarLine: true, fuzzyness: Precision.DOUBLE_EPSILON)); ho.Time -= 1; } TimingPoint tp = ho.TimingPoint.Copy(); tp.Offset = ho.Time; tp.MpB = ho.SliderVelocity; timingPointsChanges.Add(new TimingPointsChange(tp, mpb: true, fuzzyness: Precision.DOUBLE_EPSILON)); } } // Add the new SliderVelocity changes TimingPointsChange.ApplyChanges(timing, timingPointsChanges); // Save the file editor.SaveFile(); } // Complete progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(100); } // Do stuff RunFinished?.Invoke(this, new RunToolCompletedEventArgs(true, reader != null, arg.Quick)); // Make an accurate message string message = ""; if (Math.Abs(slidersCompleted) == 1) { message += "Successfully completed " + slidersCompleted + " slider!"; } else { message += "Successfully completed " + slidersCompleted + " sliders!"; } return(arg.Quick ? "" : message); }