From 1f9bac3ace9536d79c6269167b4bdf555e873893 Mon Sep 17 00:00:00 2001 From: WilliamQiufeng Date: Sat, 2 Nov 2024 17:20:12 +0000 Subject: [PATCH 1/2] Add Scroll Speed Factor --- Quaver.API/Maps/Qua.cs | 21 +++++++ Quaver.API/Maps/Structures/ScrollGroup.cs | 14 ++++- .../Maps/Structures/ScrollSpeedFactorInfo.cs | 61 +++++++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 Quaver.API/Maps/Structures/ScrollSpeedFactorInfo.cs diff --git a/Quaver.API/Maps/Qua.cs b/Quaver.API/Maps/Qua.cs index d12ec4159..5dc347f70 100644 --- a/Quaver.API/Maps/Qua.cs +++ b/Quaver.API/Maps/Qua.cs @@ -489,6 +489,7 @@ public void Sort() SortSoundEffects(); SortTimingPoints(); SortSliderVelocities(); + SortScrollSpeedFactors(); } /// @@ -630,6 +631,14 @@ public TimingPointInfo GetTimingPointAt(double time) public SliderVelocityInfo GetScrollVelocityAt(double time, string timingGroupId = DefaultScrollGroupId) => ((ScrollGroup)TimingGroups[timingGroupId]).GetScrollVelocityAt(time); + /// + /// Gets a scroll velocity at a particular time in the map + /// + /// + /// + public ScrollSpeedFactorInfo GetScrollSpeedFactorAt(double time, string timingGroupId = DefaultScrollGroupId) => + ((ScrollGroup)TimingGroups[timingGroupId]).GetScrollSpeedFactorAt(time); + /// /// Finds the length of a timing point. /// @@ -1019,6 +1028,18 @@ public void MirrorHitObjects() /// public void SortBookmarks() => Bookmarks.HybridSort(); + /// + /// + public void SortScrollSpeedFactors() + { + foreach (var (_, timingGroup) in TimingGroups) + { + if (!(timingGroup is ScrollGroup scrollGroup)) + continue; + scrollGroup.ScrollSpeedFactors.HybridSort(); + } + } + /// /// public void SortHitObjects() => HitObjects.HybridSort(); diff --git a/Quaver.API/Maps/Structures/ScrollGroup.cs b/Quaver.API/Maps/Structures/ScrollGroup.cs index 8bfd21c8a..facbb2094 100644 --- a/Quaver.API/Maps/Structures/ScrollGroup.cs +++ b/Quaver.API/Maps/Structures/ScrollGroup.cs @@ -19,11 +19,22 @@ public class ScrollGroup : TimingGroup public List ScrollVelocities { get; [MoonSharpHidden] set; } = new List(); + /// + /// Scroll Speed Factor .qua data + /// + public List ScrollSpeedFactors { get; [MoonSharpHidden] set; } = + new List(); + public SliderVelocityInfo GetScrollVelocityAt(double time) { return ScrollVelocities.AtTime((float)time); } + public ScrollSpeedFactorInfo GetScrollSpeedFactorAt(double time) + { + return ScrollSpeedFactors.AtTime((float)time); + } + /// /// /// @@ -31,7 +42,8 @@ public SliderVelocityInfo GetScrollVelocityAt(double time) protected bool Equals(ScrollGroup other) { return base.Equals(other) && InitialScrollVelocity.Equals(other.InitialScrollVelocity) && - ScrollVelocities.SequenceEqual(other.ScrollVelocities, SliderVelocityInfo.ByValueComparer); + ScrollVelocities.SequenceEqual(other.ScrollVelocities, SliderVelocityInfo.ByValueComparer) && + ScrollSpeedFactors.SequenceEqual(other.ScrollSpeedFactors, ScrollSpeedFactorInfo.ByValueComparer); } /// diff --git a/Quaver.API/Maps/Structures/ScrollSpeedFactorInfo.cs b/Quaver.API/Maps/Structures/ScrollSpeedFactorInfo.cs new file mode 100644 index 000000000..9dcbaf3f0 --- /dev/null +++ b/Quaver.API/Maps/Structures/ScrollSpeedFactorInfo.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MoonSharp.Interpreter; + +namespace Quaver.API.Maps.Structures +{ + /// + /// ScrollSpeedFactors section of the .qua + /// + [Serializable] + [MoonSharpUserData] + public class ScrollSpeedFactorInfo : IStartTime + { + /// + /// The time in milliseconds at which the scroll speed factor will be exactly + /// + public float StartTime { get; [MoonSharpHidden] set; } + + /// + /// The multiplier given to the scroll speed. + /// It will be lerped to the next scroll speed factor like keyframes, unless this is the last factor change. + /// + public float Multiplier { get; [MoonSharpHidden] set; } + + private sealed class StartTimeRelationalComparer : IComparer + { + public int Compare(ScrollSpeedFactorInfo x, ScrollSpeedFactorInfo y) + { + if (ReferenceEquals(x, y)) return 0; + if (ReferenceEquals(null, y)) return 1; + if (ReferenceEquals(null, x)) return -1; + return x.StartTime.CompareTo(y.StartTime); + } + } + + public static IComparer StartTimeComparer { get; } = new StartTimeRelationalComparer(); + + /// + /// By-value comparer, auto-generated by Rider. + /// + private sealed class ByValueEqualityComparer : IEqualityComparer + { + public bool Equals(ScrollSpeedFactorInfo x, ScrollSpeedFactorInfo y) + { + if (ReferenceEquals(x, y)) return true; + if (ReferenceEquals(x, null)) return false; + if (ReferenceEquals(y, null)) return false; + if (x.GetType() != y.GetType()) return false; + return x.StartTime.Equals(y.StartTime) && x.Multiplier.Equals(y.Multiplier); + } + + public int GetHashCode(ScrollSpeedFactorInfo obj) + { + return HashCode.Combine(obj.StartTime, obj.Multiplier); + } + } + + public static IEqualityComparer ByValueComparer { get; } = new ByValueEqualityComparer(); + } +} \ No newline at end of file From efbab036c06da9321856e419e635c16c03036d9a Mon Sep 17 00:00:00 2001 From: WilliamQiufeng Date: Tue, 5 Nov 2024 14:43:46 +0000 Subject: [PATCH 2/2] Add lua api for setters --- .../Maps/Structures/ScrollSpeedFactorInfo.cs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/Quaver.API/Maps/Structures/ScrollSpeedFactorInfo.cs b/Quaver.API/Maps/Structures/ScrollSpeedFactorInfo.cs index 9dcbaf3f0..50341447c 100644 --- a/Quaver.API/Maps/Structures/ScrollSpeedFactorInfo.cs +++ b/Quaver.API/Maps/Structures/ScrollSpeedFactorInfo.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Text; using MoonSharp.Interpreter; +using MoonSharp.Interpreter.Interop; +using YamlDotNet.Serialization; namespace Quaver.API.Maps.Structures { @@ -23,6 +25,50 @@ public class ScrollSpeedFactorInfo : IStartTime /// public float Multiplier { get; [MoonSharpHidden] set; } + /// + /// Returns if the SSF is allowed to be edited in lua scripts + /// + [YamlIgnore] + public bool IsEditableInLuaScript + { + get; + [MoonSharpVisible(false)] + set; + } + + /// + /// Sets the start time of the SSF. + /// FOR USE IN LUA SCRIPTS ONLY. + /// + /// + /// + public void SetStartTime(float time) + { + ThrowUneditableException(); + StartTime = time; + } + + /// + /// Sets the multiplier of the SSF. + /// FOR USE IN LUA SCRIPTS ONLY. + /// + /// + /// + public void SetMultiplier(float multiplier) + { + ThrowUneditableException(); + Multiplier = multiplier; + } + + /// + /// + /// + private void ThrowUneditableException() + { + if (!IsEditableInLuaScript) + throw new InvalidOperationException("Value is not allowed to be edited in lua scripts."); + } + private sealed class StartTimeRelationalComparer : IComparer { public int Compare(ScrollSpeedFactorInfo x, ScrollSpeedFactorInfo y)