/// <summary> /// </summary> /// <param name="sv"></param> /// <param name="isSelected"></param> private void OnSvButtonClicked(SliderVelocityInfo sv, bool isSelected) { var t = TimeSpan.FromMilliseconds(sv.StartTime); if (!ImGui.Button($"{t.Minutes:00}:{t.Seconds:00}:{t.Milliseconds:000}", new Vector2())) { return; } // User is holding control down, so add this SV to the selected ones if (KeyboardManager.CurrentState.IsKeyDown(Keys.LeftControl) || KeyboardManager.CurrentState.IsKeyDown(Keys.LeftControl)) { if (isSelected) { if (SelectedVelocities.Count != 1) { SelectedVelocities.Remove(sv); } if (SelectedVelocities.Count == 1) { SetInputTextToFirstSelected(); } } else { SelectedVelocities.Add(sv); if (SelectedVelocities.Count == 1) { SetInputTextToFirstSelected(); } else { TextTime = ""; TextMultiplier = ""; } } } // Clicking the currently selected button seeks the user to that point in time else { if (isSelected && !AudioEngine.Track.IsDisposed) { AudioEngine.Track.Seek(sv.StartTime); var game = GameBase.Game as QuaverGame; var screen = game?.CurrentScreen as EditorScreen; screen?.SetHitSoundObjectIndex(); } SelectedVelocities.Clear(); SelectedVelocities.Add(sv); TextTime = sv.StartTime.ToString(CultureInfo.InvariantCulture); TextMultiplier = $"{sv.Multiplier:0.00}"; } }
/// <summary> /// </summary> /// <param name="sv"></param> /// <param name="newTime"></param> /// <param name="newMultiplier"></param> public EditorScrollVelocityChangeInfo(SliderVelocityInfo sv, float newTime, float newMultiplier) { Info = sv; OriginalTime = Info.StartTime; OriginalMultiplier = Info.Multiplier; NewTime = newTime; NewMultiplier = newMultiplier; }
/// <summary> /// </summary> /// <param name="sv"></param> /// <returns></returns> public Sprite CreateSliderVelocityLine(SliderVelocityInfo sv) => new Sprite { Parent = this, Alignment = Alignment.TopCenter, Size = new ScalableVector2(Width - 4, 2), Tint = Color.LimeGreen, Y = Height - Height * (float)(sv.StartTime / (AudioEngine.Track.Length)), Image = Pixel, Alpha = 0.85f };
/// <summary> /// </summary> /// <param name="sv"></param> public void MoveSliderVelocityLine(SliderVelocityInfo sv) { if (sv == null || !SliderVelocityLines.ContainsKey(sv)) { return; } SliderVelocityLines[sv].Y = Height - Height * (float)(sv.StartTime / (AudioEngine.Track.Length)); Container.ForceRecache(); }
public TimingPoint(SliderVelocityInfo scrollVelocity, int volume, bool dontUseOffset) { Time = (int)Math.Round(scrollVelocity.StartTime) + (dontUseOffset ? 0 : Osu.OsuBeatmap.QUAVER_TO_OSU_OFFSET); Uninherited = 0; Meter = 0; // osu! can't handle 0x SV, so it's replaced with a very low value instead (0.00000001x) // It clamps all SV values between 0.01x and 10x, so putting -10e10 instead of -10e4 doesn't really // make a difference. It could change with Lazer though, so it's kept in. BeatLength = scrollVelocity.Multiplier <= 0 ? -10e10 : -100 / scrollVelocity.Multiplier; Volume = volume; }
/// <summary> /// </summary> /// <param name="sv"></param> public void RemoveSliderVelocityLine(SliderVelocityInfo sv) { if (sv == null) { return; } if (SliderVelocityLines.ContainsKey(sv)) { SliderVelocityLines[sv].Destroy(); SliderVelocityLines.Remove(sv); } Container.ForceRecache(); }
/// <summary> /// </summary> private void SelectClosestVelocity() { if (WorkingMap.SliderVelocities.Count == 0) { return; } // Find the closest SV point so it can be selected upon opening. SliderVelocityInfo closestVelocity = null; var minDiff = double.MaxValue; WorkingMap.SliderVelocities.ForEach(x => { var diff = Math.Abs(AudioEngine.Track.Time - x.StartTime); if (!(diff < minDiff)) { return; } minDiff = diff; closestVelocity = x; }); if (closestVelocity == null) { return; } SelectedVelocities.Clear(); SelectedVelocities.Add(closestVelocity); NeedsToScroll = true; TextTime = closestVelocity.StartTime.ToString(CultureInfo.InvariantCulture); TextMultiplier = $"{closestVelocity.Multiplier:0.00}"; }
/// <summary> /// </summary> private void HandleAddRemoveButtons() { if (ImGui.Button("Add")) { var sv = new SliderVelocityInfo() { StartTime = (int)AudioEngine.Track.Time, Multiplier = 1.0f }; var game = GameBase.Game as QuaverGame; var screen = game?.CurrentScreen as EditorScreen; screen?.Ruleset.ActionManager.Perform(new EditorActionAddSliderVelocity(WorkingMap, sv)); SelectedVelocities.Clear(); SelectedVelocities.Add(sv); NeedsToScroll = true; TextTime = sv.StartTime.ToString(CultureInfo.InvariantCulture); TextMultiplier = $"{sv.Multiplier:0.00}"; } ImGui.SameLine(); if (ImGui.Button("Remove")) { if (SelectedVelocities.Count == 0) { return; } var game = GameBase.Game as QuaverGame; var screen = game?.CurrentScreen as EditorScreen; var lastSv = SelectedVelocities.Last(); screen?.Ruleset.ActionManager.Perform(new EditorActionRemoveSliderVelocities(WorkingMap, new List <SliderVelocityInfo>(SelectedVelocities))); SelectedVelocities.Clear(); if (WorkingMap.SliderVelocities.Count != 0) { var sv = WorkingMap.SliderVelocities.FindLast(x => x.StartTime <= lastSv.StartTime); if (sv != null) { TextTime = sv.StartTime.ToString(CultureInfo.InvariantCulture); TextMultiplier = $"{sv.Multiplier:0.00}"; SelectedVelocities.Add(sv); } else { TextTime = ""; TextMultiplier = $""; } } else { TextTime = ""; TextMultiplier = $""; } NeedsToScroll = true; } }
public static TimingPoint QuaSVToManiaTP(SliderVelocityInfo quaSV) { TimingPoint maniaTP = new TimingPoint((int)quaSV.StartTime, -1000 / (quaSV.Multiplier * 10)); return(maniaTP); }
/// <summary> /// Generate Scroll Velocity points. /// </summary> /// <param name="qua"></param> private void InitializeScrollVelocities(Qua qua) { // Find average bpm var commonBpm = qua.GetCommonBpm(); // Create SV multiplier timing points var index = 0; for (var i = 0; i < qua.TimingPoints.Count; i++) { var svFound = false; // SV starts after the last timing point if (i == qua.TimingPoints.Count - 1) { for (var j = index; j < qua.SliderVelocities.Count; j++) { var sv = new SliderVelocityInfo() { StartTime = qua.SliderVelocities[j].StartTime, Multiplier = qua.SliderVelocities[j].Multiplier * (float)(qua.TimingPoints[i].Bpm / commonBpm) }; ScrollVelocities.Add(sv); // Toggle SvFound if inheriting point is overlapping timing point if (Math.Abs(sv.StartTime - qua.TimingPoints[i].StartTime) < 1) { svFound = true; } } } // SV does not start after the last timing point else { for (var j = index; j < qua.SliderVelocities.Count; j++) { // SV starts before the first timing point if (qua.SliderVelocities[j].StartTime < qua.TimingPoints[0].StartTime) { var sv = new SliderVelocityInfo() { StartTime = qua.SliderVelocities[j].StartTime, Multiplier = qua.SliderVelocities[j].Multiplier * (float)(qua.TimingPoints[0].Bpm / commonBpm) }; ScrollVelocities.Add(sv); // Toggle SvFound if inheriting point is overlapping timing point if (Math.Abs(sv.StartTime - qua.TimingPoints[0].StartTime) < 1) { svFound = true; } } // SV start is in between two timing points else if (qua.SliderVelocities[j].StartTime >= qua.TimingPoints[i].StartTime && qua.SliderVelocities[j].StartTime < qua.TimingPoints[i + 1].StartTime) { var sv = new SliderVelocityInfo() { StartTime = qua.SliderVelocities[j].StartTime, Multiplier = qua.SliderVelocities[j].Multiplier * (float)(qua.TimingPoints[i].Bpm / commonBpm) }; ScrollVelocities.Add(sv); // Toggle SvFound if inheriting point is overlapping timing point if (Math.Abs(sv.StartTime - qua.TimingPoints[i].StartTime) < 1) { svFound = true; } } // Update current index if SV falls out of range for optimization else { index = j; break; } } } // Create BPM SV if no inheriting point is overlapping the current timing point if (!svFound) { var sv = new SliderVelocityInfo() { StartTime = qua.TimingPoints[i].StartTime, Multiplier = (float)(qua.TimingPoints[i].Bpm / commonBpm) }; ScrollVelocities.Add(sv); } } // Sort SV points by start time ScrollVelocities = ScrollVelocities.OrderBy(o => o.StartTime).ToList(); }
public AutoModIssueScrollVelocityAfterEnd(SliderVelocityInfo sv) : base(AutoModIssueLevel.Warning) { ScrollVelocity = sv; Text = $"The scroll velocity at: {ScrollVelocity.StartTime} is placed after the audio ends."; }
/// <summary> /// </summary> /// <param name="workingMap"></param> /// <param name="sv"></param> public EditorActionAddSliderVelocity(Qua workingMap, SliderVelocityInfo sv) { WorkingMap = workingMap; Velocity = sv; }
/// <summary> /// </summary> /// <param name="sv"></param> public void AddSliderVelocityLine(SliderVelocityInfo sv) { SliderVelocityLines[sv] = CreateSliderVelocityLine(sv); Container.ForceRecache(); }