diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs
index 0cfa3e98f7..275c9a500c 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs
@@ -15,77 +15,100 @@ namespace osu.Game.Rulesets.Catch.Mods
public override double ScoreMultiplier => 1.12;
public override bool Ranked => true;
- private float lastStartX;
- private int lastStartTime;
+ private float? lastPosition;
+ private double lastStartTime;
public void ApplyToHitObject(HitObject hitObject)
{
+ if (!(hitObject is Fruit))
+ return;
+
var catchObject = (CatchHitObject)hitObject;
float position = catchObject.X;
- int startTime = (int)hitObject.StartTime;
+ double startTime = hitObject.StartTime;
- if (lastStartX == 0)
+ if (lastPosition == null)
{
- lastStartX = position;
+ lastPosition = position;
lastStartTime = startTime;
+
return;
}
- float diff = lastStartX - position;
- int timeDiff = startTime - lastStartTime;
+ float positionDiff = position - lastPosition.Value;
+ double timeDiff = startTime - lastStartTime;
if (timeDiff > 1000)
{
- lastStartX = position;
+ lastPosition = position;
lastStartTime = startTime;
return;
}
- if (diff == 0)
+ if (positionDiff == 0)
{
- bool right = RNG.NextBool();
-
- float rand = Math.Min(20, (float)RNG.NextDouble(0, timeDiff / 4d)) / CatchPlayfield.BASE_WIDTH;
-
- if (right)
- {
- if (position + rand <= 1)
- position += rand;
- else
- position -= rand;
- }
- else
- {
- if (position - rand >= 0)
- position -= rand;
- else
- position += rand;
- }
-
+ applyRandomOffset(ref position, timeDiff / 4d);
catchObject.X = position;
-
return;
}
- if (Math.Abs(diff) < timeDiff / 3d)
- {
- if (diff > 0)
- {
- if (position - diff > 0)
- position -= diff;
- }
- else
- {
- if (position - diff < 1)
- position -= diff;
- }
- }
+ if (Math.Abs(positionDiff * CatchPlayfield.BASE_WIDTH) < timeDiff / 3d)
+ applyOffset(ref position, positionDiff);
catchObject.X = position;
- lastStartX = position;
+ lastPosition = position;
lastStartTime = startTime;
}
+
+ ///
+ /// Applies a random offset in a random direction to a position, ensuring that the final position remains within the boundary of the playfield.
+ ///
+ /// The position which the offset should be applied to.
+ /// The maximum offset, cannot exceed 20px.
+ private void applyRandomOffset(ref float position, double maxOffset)
+ {
+ bool right = RNG.NextBool();
+ float rand = Math.Min(20, (float)RNG.NextDouble(0, maxOffset)) / CatchPlayfield.BASE_WIDTH;
+
+ if (right)
+ {
+ // Clamp to the right bound
+ if (position + rand <= 1)
+ position += rand;
+ else
+ position -= rand;
+ }
+ else
+ {
+ // Clamp to the left bound
+ if (position - rand >= 0)
+ position -= rand;
+ else
+ position += rand;
+ }
+ }
+
+ ///
+ /// Applies an offset to a position, ensuring that the final position remains within the boundary of the playfield.
+ ///
+ /// The position which the offset should be applied to.
+ /// The amount to offset by.
+ private void applyOffset(ref float position, float amount)
+ {
+ if (amount > 0)
+ {
+ // Clamp to the right bound
+ if (position + amount < 1)
+ position += amount;
+ }
+ else
+ {
+ // Clamp to the left bound
+ if (position + amount > 0)
+ position += amount;
+ }
+ }
}
}
diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs
index f5e1f612ca..1182cacfc1 100644
--- a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs
+++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs
@@ -7,6 +7,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Textures;
using osu.Game.IO;
+using osu.Game.Screens.Play;
namespace osu.Game.Storyboards.Drawables
{
@@ -55,9 +56,12 @@ namespace osu.Game.Storyboards.Drawables
});
}
- [BackgroundDependencyLoader]
- private void load(FileStore fileStore)
+ [BackgroundDependencyLoader(true)]
+ private void load(FileStore fileStore, GameplayClock clock)
{
+ if (clock != null)
+ Clock = clock;
+
dependencies.Cache(new TextureStore(new TextureLoaderStore(fileStore.Store), false, scaleAdjust: 1));
foreach (var layer in Storyboard.Layers)