mirror of
https://github.com/ppy/osu.git
synced 2025-01-15 06:33:20 +08:00
Fix catch hardrock mod not using the correct RNG (#5561)
Fix catch hardrock mod not using the correct RNG Co-authored-by: Dean Herbert <pe@ppy.sh>
This commit is contained in:
commit
6d4d6a6532
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Rulesets.Catch.Mods;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Catch.UI;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
@ -22,7 +23,10 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
[TestCase("spinner")]
|
||||
[TestCase("spinner-and-circles")]
|
||||
[TestCase("slider")]
|
||||
public void Test(string name) => base.Test(name);
|
||||
[TestCase("hardrock-stream", new[] { typeof(CatchModHardRock) })]
|
||||
[TestCase("hardrock-repeat-slider", new[] { typeof(CatchModHardRock) })]
|
||||
[TestCase("hardrock-spinner", new[] { typeof(CatchModHardRock) })]
|
||||
public new void Test(string name, params Type[] mods) => base.Test(name, mods);
|
||||
|
||||
protected override IEnumerable<ConvertValue> CreateConvertValue(HitObject hitObject)
|
||||
{
|
||||
|
@ -10,6 +10,7 @@ using osu.Game.Rulesets.Catch.UI;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osuTK;
|
||||
using osu.Game.Rulesets.Catch.MathUtils;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
{
|
||||
@ -26,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
{
|
||||
base.PostProcess();
|
||||
|
||||
applyPositionOffsets();
|
||||
ApplyPositionOffsets(Beatmap);
|
||||
|
||||
initialiseHyperDash((List<CatchHitObject>)Beatmap.HitObjects);
|
||||
|
||||
@ -40,19 +41,29 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
}
|
||||
}
|
||||
|
||||
private void applyPositionOffsets()
|
||||
public static void ApplyPositionOffsets(IBeatmap beatmap, params Mod[] mods)
|
||||
{
|
||||
var rng = new FastRandom(RNG_SEED);
|
||||
// todo: HardRock displacement should be applied here
|
||||
|
||||
foreach (var obj in Beatmap.HitObjects)
|
||||
bool shouldApplyHardRockOffset = mods.Any(m => m is ModHardRock);
|
||||
float? lastPosition = null;
|
||||
double lastStartTime = 0;
|
||||
|
||||
foreach (var obj in beatmap.HitObjects.OfType<CatchHitObject>())
|
||||
{
|
||||
obj.XOffset = 0;
|
||||
|
||||
switch (obj)
|
||||
{
|
||||
case Fruit fruit:
|
||||
if (shouldApplyHardRockOffset)
|
||||
applyHardRockOffset(fruit, ref lastPosition, ref lastStartTime, rng);
|
||||
break;
|
||||
|
||||
case BananaShower bananaShower:
|
||||
foreach (var banana in bananaShower.NestedHitObjects.OfType<Banana>())
|
||||
{
|
||||
banana.X = (float)rng.NextDouble();
|
||||
banana.XOffset = (float)rng.NextDouble();
|
||||
rng.Next(); // osu!stable retrieved a random banana type
|
||||
rng.Next(); // osu!stable retrieved a random banana rotation
|
||||
rng.Next(); // osu!stable retrieved a random banana colour
|
||||
@ -63,12 +74,13 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
case JuiceStream juiceStream:
|
||||
foreach (var nested in juiceStream.NestedHitObjects)
|
||||
{
|
||||
var hitObject = (CatchHitObject)nested;
|
||||
if (hitObject is TinyDroplet)
|
||||
hitObject.X += rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH;
|
||||
else if (hitObject is Droplet)
|
||||
var catchObject = (CatchHitObject)nested;
|
||||
catchObject.XOffset = 0;
|
||||
|
||||
if (catchObject is TinyDroplet)
|
||||
catchObject.XOffset = MathHelper.Clamp(rng.Next(-20, 20) / CatchPlayfield.BASE_WIDTH, -catchObject.X, 1 - catchObject.X);
|
||||
else if (catchObject is Droplet)
|
||||
rng.Next(); // osu!stable retrieved a random droplet rotation
|
||||
hitObject.X = MathHelper.Clamp(hitObject.X, 0, 1);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -76,6 +88,105 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyHardRockOffset(CatchHitObject hitObject, ref float? lastPosition, ref double lastStartTime, FastRandom rng)
|
||||
{
|
||||
if (hitObject is JuiceStream stream)
|
||||
{
|
||||
lastPosition = stream.EndX;
|
||||
lastStartTime = stream.EndTime;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(hitObject is Fruit))
|
||||
return;
|
||||
|
||||
float offsetPosition = hitObject.X;
|
||||
double startTime = hitObject.StartTime;
|
||||
|
||||
if (lastPosition == null)
|
||||
{
|
||||
lastPosition = offsetPosition;
|
||||
lastStartTime = startTime;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
float positionDiff = offsetPosition - lastPosition.Value;
|
||||
double timeDiff = startTime - lastStartTime;
|
||||
|
||||
if (timeDiff > 1000)
|
||||
{
|
||||
lastPosition = offsetPosition;
|
||||
lastStartTime = startTime;
|
||||
return;
|
||||
}
|
||||
|
||||
if (positionDiff == 0)
|
||||
{
|
||||
applyRandomOffset(ref offsetPosition, timeDiff / 4d, rng);
|
||||
hitObject.XOffset = offsetPosition - hitObject.X;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Math.Abs(positionDiff * CatchPlayfield.BASE_WIDTH) < timeDiff / 3d)
|
||||
applyOffset(ref offsetPosition, positionDiff);
|
||||
|
||||
hitObject.XOffset = offsetPosition - hitObject.X;
|
||||
|
||||
lastPosition = offsetPosition;
|
||||
lastStartTime = startTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a random offset in a random direction to a position, ensuring that the final position remains within the boundary of the playfield.
|
||||
/// </summary>
|
||||
/// <param name="position">The position which the offset should be applied to.</param>
|
||||
/// <param name="maxOffset">The maximum offset, cannot exceed 20px.</param>
|
||||
/// <param name="rng">The random number generator.</param>
|
||||
private static void applyRandomOffset(ref float position, double maxOffset, FastRandom rng)
|
||||
{
|
||||
bool right = rng.NextBool();
|
||||
float rand = Math.Min(20, (float)rng.Next(0, Math.Max(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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies an offset to a position, ensuring that the final position remains within the boundary of the playfield.
|
||||
/// </summary>
|
||||
/// <param name="position">The position which the offset should be applied to.</param>
|
||||
/// <param name="amount">The amount to offset by.</param>
|
||||
private static 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;
|
||||
}
|
||||
}
|
||||
|
||||
private void initialiseHyperDash(List<CatchHitObject> objects)
|
||||
{
|
||||
List<CatchHitObject> objectWithDroplets = new List<CatchHitObject>();
|
||||
|
@ -61,6 +61,14 @@ namespace osu.Game.Rulesets.Catch.MathUtils
|
||||
/// <returns>The random value.</returns>
|
||||
public int Next(int lowerBound, int upperBound) => (int)(lowerBound + NextDouble() * (upperBound - lowerBound));
|
||||
|
||||
/// <summary>
|
||||
/// Generates a random integer value within the range [<paramref name="lowerBound"/>, <paramref name="upperBound"/>).
|
||||
/// </summary>
|
||||
/// <param name="lowerBound">The lower bound of the range.</param>
|
||||
/// <param name="upperBound">The upper bound of the range.</param>
|
||||
/// <returns>The random value.</returns>
|
||||
public int Next(double lowerBound, double upperBound) => (int)(lowerBound + NextDouble() * (upperBound - lowerBound));
|
||||
|
||||
/// <summary>
|
||||
/// Generates a random double value within the range [0, 1).
|
||||
/// </summary>
|
||||
|
@ -1,121 +1,17 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Catch.UI;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using System;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Beatmaps;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Mods
|
||||
{
|
||||
public class CatchModHardRock : ModHardRock, IApplicableToHitObject
|
||||
public class CatchModHardRock : ModHardRock, IApplicableToBeatmap
|
||||
{
|
||||
public override double ScoreMultiplier => 1.12;
|
||||
public override bool Ranked => true;
|
||||
|
||||
private float? lastPosition;
|
||||
private double lastStartTime;
|
||||
|
||||
public void ApplyToHitObject(HitObject hitObject)
|
||||
{
|
||||
if (hitObject is JuiceStream stream)
|
||||
{
|
||||
lastPosition = stream.EndX;
|
||||
lastStartTime = stream.EndTime;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(hitObject is Fruit))
|
||||
return;
|
||||
|
||||
var catchObject = (CatchHitObject)hitObject;
|
||||
|
||||
float position = catchObject.X;
|
||||
double startTime = hitObject.StartTime;
|
||||
|
||||
if (lastPosition == null)
|
||||
{
|
||||
lastPosition = position;
|
||||
lastStartTime = startTime;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
float positionDiff = position - lastPosition.Value;
|
||||
double timeDiff = startTime - lastStartTime;
|
||||
|
||||
if (timeDiff > 1000)
|
||||
{
|
||||
lastPosition = position;
|
||||
lastStartTime = startTime;
|
||||
return;
|
||||
}
|
||||
|
||||
if (positionDiff == 0)
|
||||
{
|
||||
applyRandomOffset(ref position, timeDiff / 4d);
|
||||
catchObject.X = position;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Math.Abs(positionDiff * CatchPlayfield.BASE_WIDTH) < timeDiff / 3d)
|
||||
applyOffset(ref position, positionDiff);
|
||||
|
||||
catchObject.X = position;
|
||||
|
||||
lastPosition = position;
|
||||
lastStartTime = startTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a random offset in a random direction to a position, ensuring that the final position remains within the boundary of the playfield.
|
||||
/// </summary>
|
||||
/// <param name="position">The position which the offset should be applied to.</param>
|
||||
/// <param name="maxOffset">The maximum offset, cannot exceed 20px.</param>
|
||||
private void applyRandomOffset(ref float position, double maxOffset)
|
||||
{
|
||||
bool right = RNG.NextBool();
|
||||
float rand = Math.Min(20, (float)RNG.NextDouble(0, Math.Max(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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies an offset to a position, ensuring that the final position remains within the boundary of the playfield.
|
||||
/// </summary>
|
||||
/// <param name="position">The position which the offset should be applied to.</param>
|
||||
/// <param name="amount">The amount to offset by.</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
public void ApplyToBeatmap(IBeatmap beatmap) => CatchBeatmapProcessor.ApplyPositionOffsets(beatmap, this);
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Catch.Beatmaps;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
|
||||
@ -12,7 +13,18 @@ namespace osu.Game.Rulesets.Catch.Objects
|
||||
{
|
||||
public const double OBJECT_RADIUS = 44;
|
||||
|
||||
public float X { get; set; }
|
||||
private float x;
|
||||
|
||||
public float X
|
||||
{
|
||||
get => x + XOffset;
|
||||
set => x = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A random offset applied to <see cref="X"/>, set by the <see cref="CatchBeatmapProcessor"/>.
|
||||
/// </summary>
|
||||
internal float XOffset { get; set; }
|
||||
|
||||
public double TimePreempt = 1000;
|
||||
|
||||
|
@ -0,0 +1,150 @@
|
||||
{
|
||||
"Mappings": [{
|
||||
"StartTime": 369,
|
||||
"Objects": [{
|
||||
"StartTime": 369,
|
||||
"Position": 177
|
||||
},
|
||||
{
|
||||
"StartTime": 450,
|
||||
"Position": 216.539276
|
||||
},
|
||||
{
|
||||
"StartTime": 532,
|
||||
"Position": 256.5667
|
||||
},
|
||||
{
|
||||
"StartTime": 614,
|
||||
"Position": 296.594116
|
||||
},
|
||||
{
|
||||
"StartTime": 696,
|
||||
"Position": 336.621521
|
||||
},
|
||||
{
|
||||
"StartTime": 778,
|
||||
"Position": 376.99762
|
||||
},
|
||||
{
|
||||
"StartTime": 860,
|
||||
"Position": 337.318878
|
||||
},
|
||||
{
|
||||
"StartTime": 942,
|
||||
"Position": 297.291443
|
||||
},
|
||||
{
|
||||
"StartTime": 1024,
|
||||
"Position": 257.264038
|
||||
},
|
||||
{
|
||||
"StartTime": 1106,
|
||||
"Position": 217.2366
|
||||
},
|
||||
{
|
||||
"StartTime": 1188,
|
||||
"Position": 177
|
||||
},
|
||||
{
|
||||
"StartTime": 1270,
|
||||
"Position": 216.818192
|
||||
},
|
||||
{
|
||||
"StartTime": 1352,
|
||||
"Position": 256.8456
|
||||
},
|
||||
{
|
||||
"StartTime": 1434,
|
||||
"Position": 296.873047
|
||||
},
|
||||
{
|
||||
"StartTime": 1516,
|
||||
"Position": 336.900452
|
||||
},
|
||||
{
|
||||
"StartTime": 1598,
|
||||
"Position": 376.99762
|
||||
},
|
||||
{
|
||||
"StartTime": 1680,
|
||||
"Position": 337.039948
|
||||
},
|
||||
{
|
||||
"StartTime": 1762,
|
||||
"Position": 297.0125
|
||||
},
|
||||
{
|
||||
"StartTime": 1844,
|
||||
"Position": 256.9851
|
||||
},
|
||||
{
|
||||
"StartTime": 1926,
|
||||
"Position": 216.957672
|
||||
},
|
||||
{
|
||||
"StartTime": 2008,
|
||||
"Position": 177
|
||||
},
|
||||
{
|
||||
"StartTime": 2090,
|
||||
"Position": 217.097137
|
||||
},
|
||||
{
|
||||
"StartTime": 2172,
|
||||
"Position": 257.124573
|
||||
},
|
||||
{
|
||||
"StartTime": 2254,
|
||||
"Position": 297.152
|
||||
},
|
||||
{
|
||||
"StartTime": 2336,
|
||||
"Position": 337.179443
|
||||
},
|
||||
{
|
||||
"StartTime": 2418,
|
||||
"Position": 376.99762
|
||||
},
|
||||
{
|
||||
"StartTime": 2500,
|
||||
"Position": 336.760956
|
||||
},
|
||||
{
|
||||
"StartTime": 2582,
|
||||
"Position": 296.733643
|
||||
},
|
||||
{
|
||||
"StartTime": 2664,
|
||||
"Position": 256.7062
|
||||
},
|
||||
{
|
||||
"StartTime": 2746,
|
||||
"Position": 216.678772
|
||||
},
|
||||
{
|
||||
"StartTime": 2828,
|
||||
"Position": 177
|
||||
},
|
||||
{
|
||||
"StartTime": 2909,
|
||||
"Position": 216.887909
|
||||
},
|
||||
{
|
||||
"StartTime": 2991,
|
||||
"Position": 256.915344
|
||||
},
|
||||
{
|
||||
"StartTime": 3073,
|
||||
"Position": 296.942749
|
||||
},
|
||||
{
|
||||
"StartTime": 3155,
|
||||
"Position": 336.970184
|
||||
},
|
||||
{
|
||||
"StartTime": 3237,
|
||||
"Position": 376.99762
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
osu file format v14
|
||||
|
||||
[General]
|
||||
StackLeniency: 0.4
|
||||
Mode: 0
|
||||
|
||||
[Difficulty]
|
||||
CircleSize:4
|
||||
OverallDifficulty:7
|
||||
ApproachRate:8
|
||||
SliderMultiplier:1.6
|
||||
SliderTickRate:4
|
||||
|
||||
[TimingPoints]
|
||||
369,327.868852459016,4,2,2,32,1,0
|
||||
|
||||
[HitObjects]
|
||||
177,191,369,6,0,L|382:192,7,200
|
@ -0,0 +1,74 @@
|
||||
{
|
||||
"Mappings": [{
|
||||
"StartTime": 369,
|
||||
"Objects": [{
|
||||
"StartTime": 369,
|
||||
"Position": 65
|
||||
},
|
||||
{
|
||||
"StartTime": 450,
|
||||
"Position": 482
|
||||
},
|
||||
{
|
||||
"StartTime": 532,
|
||||
"Position": 164
|
||||
},
|
||||
{
|
||||
"StartTime": 614,
|
||||
"Position": 315
|
||||
},
|
||||
{
|
||||
"StartTime": 696,
|
||||
"Position": 145
|
||||
},
|
||||
{
|
||||
"StartTime": 778,
|
||||
"Position": 159
|
||||
},
|
||||
{
|
||||
"StartTime": 860,
|
||||
"Position": 310
|
||||
},
|
||||
{
|
||||
"StartTime": 942,
|
||||
"Position": 441
|
||||
},
|
||||
{
|
||||
"StartTime": 1024,
|
||||
"Position": 428
|
||||
},
|
||||
{
|
||||
"StartTime": 1106,
|
||||
"Position": 243
|
||||
},
|
||||
{
|
||||
"StartTime": 1188,
|
||||
"Position": 422
|
||||
},
|
||||
{
|
||||
"StartTime": 1270,
|
||||
"Position": 481
|
||||
},
|
||||
{
|
||||
"StartTime": 1352,
|
||||
"Position": 104
|
||||
},
|
||||
{
|
||||
"StartTime": 1434,
|
||||
"Position": 473
|
||||
},
|
||||
{
|
||||
"StartTime": 1516,
|
||||
"Position": 135
|
||||
},
|
||||
{
|
||||
"StartTime": 1598,
|
||||
"Position": 360
|
||||
},
|
||||
{
|
||||
"StartTime": 1680,
|
||||
"Position": 123
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
osu file format v14
|
||||
|
||||
[General]
|
||||
StackLeniency: 0.4
|
||||
Mode: 0
|
||||
|
||||
[Difficulty]
|
||||
CircleSize:4
|
||||
OverallDifficulty:7
|
||||
ApproachRate:8
|
||||
SliderMultiplier:1.6
|
||||
SliderTickRate:4
|
||||
|
||||
[TimingPoints]
|
||||
369,327.868852459016,4,2,2,32,1,0
|
||||
|
||||
[HitObjects]
|
||||
256,192,369,12,0,1680,0:0:0:0:
|
@ -0,0 +1,234 @@
|
||||
{
|
||||
"Mappings": [{
|
||||
"StartTime": 369,
|
||||
"Objects": [{
|
||||
"StartTime": 369,
|
||||
"Position": 258
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 450,
|
||||
"Objects": [{
|
||||
"StartTime": 450,
|
||||
"Position": 254
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 532,
|
||||
"Objects": [{
|
||||
"StartTime": 532,
|
||||
"Position": 241
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 614,
|
||||
"Objects": [{
|
||||
"StartTime": 614,
|
||||
"Position": 238
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 696,
|
||||
"Objects": [{
|
||||
"StartTime": 696,
|
||||
"Position": 238
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 778,
|
||||
"Objects": [{
|
||||
"StartTime": 778,
|
||||
"Position": 278
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 860,
|
||||
"Objects": [{
|
||||
"StartTime": 860,
|
||||
"Position": 238
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 942,
|
||||
"Objects": [{
|
||||
"StartTime": 942,
|
||||
"Position": 278
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 1024,
|
||||
"Objects": [{
|
||||
"StartTime": 1024,
|
||||
"Position": 238
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 1106,
|
||||
"Objects": [{
|
||||
"StartTime": 1106,
|
||||
"Position": 278
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 1188,
|
||||
"Objects": [{
|
||||
"StartTime": 1188,
|
||||
"Position": 278
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 1270,
|
||||
"Objects": [{
|
||||
"StartTime": 1270,
|
||||
"Position": 278
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 1352,
|
||||
"Objects": [{
|
||||
"StartTime": 1352,
|
||||
"Position": 238
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 1434,
|
||||
"Objects": [{
|
||||
"StartTime": 1434,
|
||||
"Position": 258
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 1516,
|
||||
"Objects": [{
|
||||
"StartTime": 1516,
|
||||
"Position": 253
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 1598,
|
||||
"Objects": [{
|
||||
"StartTime": 1598,
|
||||
"Position": 238
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 1680,
|
||||
"Objects": [{
|
||||
"StartTime": 1680,
|
||||
"Position": 260
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 1762,
|
||||
"Objects": [{
|
||||
"StartTime": 1762,
|
||||
"Position": 238
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 1844,
|
||||
"Objects": [{
|
||||
"StartTime": 1844,
|
||||
"Position": 278
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 1926,
|
||||
"Objects": [{
|
||||
"StartTime": 1926,
|
||||
"Position": 278
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 2008,
|
||||
"Objects": [{
|
||||
"StartTime": 2008,
|
||||
"Position": 238
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 2090,
|
||||
"Objects": [{
|
||||
"StartTime": 2090,
|
||||
"Position": 238
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 2172,
|
||||
"Objects": [{
|
||||
"StartTime": 2172,
|
||||
"Position": 243
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 2254,
|
||||
"Objects": [{
|
||||
"StartTime": 2254,
|
||||
"Position": 278
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 2336,
|
||||
"Objects": [{
|
||||
"StartTime": 2336,
|
||||
"Position": 278
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 2418,
|
||||
"Objects": [{
|
||||
"StartTime": 2418,
|
||||
"Position": 238
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 2500,
|
||||
"Objects": [{
|
||||
"StartTime": 2500,
|
||||
"Position": 258
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 2582,
|
||||
"Objects": [{
|
||||
"StartTime": 2582,
|
||||
"Position": 256
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 2664,
|
||||
"Objects": [{
|
||||
"StartTime": 2664,
|
||||
"Position": 242
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 2746,
|
||||
"Objects": [{
|
||||
"StartTime": 2746,
|
||||
"Position": 238
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 2828,
|
||||
"Objects": [{
|
||||
"StartTime": 2828,
|
||||
"Position": 238
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 2909,
|
||||
"Objects": [{
|
||||
"StartTime": 2909,
|
||||
"Position": 271
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 2991,
|
||||
"Objects": [{
|
||||
"StartTime": 2991,
|
||||
"Position": 254
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
osu file format v14
|
||||
|
||||
[General]
|
||||
StackLeniency: 0.4
|
||||
Mode: 0
|
||||
|
||||
[Difficulty]
|
||||
CircleSize:4
|
||||
OverallDifficulty:7
|
||||
ApproachRate:8
|
||||
SliderMultiplier:1.6
|
||||
SliderTickRate:1
|
||||
|
||||
[TimingPoints]
|
||||
369,327.868852459016,4,2,2,32,1,0
|
||||
|
||||
[HitObjects]
|
||||
258,189,369,1,0,0:0:0:0:
|
||||
258,189,450,1,0,0:0:0:0:
|
||||
258,189,532,1,0,0:0:0:0:
|
||||
258,189,614,1,0,0:0:0:0:
|
||||
258,189,696,1,0,0:0:0:0:
|
||||
258,189,778,1,0,0:0:0:0:
|
||||
258,189,860,1,0,0:0:0:0:
|
||||
258,189,942,1,0,0:0:0:0:
|
||||
258,189,1024,1,0,0:0:0:0:
|
||||
258,189,1106,1,0,0:0:0:0:
|
||||
258,189,1188,1,0,0:0:0:0:
|
||||
258,189,1270,1,0,0:0:0:0:
|
||||
258,189,1352,1,0,0:0:0:0:
|
||||
258,189,1434,1,0,0:0:0:0:
|
||||
258,189,1516,1,0,0:0:0:0:
|
||||
258,189,1598,1,0,0:0:0:0:
|
||||
258,189,1680,1,0,0:0:0:0:
|
||||
258,189,1762,1,0,0:0:0:0:
|
||||
258,189,1844,1,0,0:0:0:0:
|
||||
258,189,1926,1,0,0:0:0:0:
|
||||
258,189,2008,1,0,0:0:0:0:
|
||||
258,189,2090,1,0,0:0:0:0:
|
||||
258,189,2172,1,0,0:0:0:0:
|
||||
258,189,2254,1,0,0:0:0:0:
|
||||
258,189,2336,1,0,0:0:0:0:
|
||||
258,189,2418,1,0,0:0:0:0:
|
||||
258,189,2500,1,0,0:0:0:0:
|
||||
258,189,2582,1,0,0:0:0:0:
|
||||
258,189,2664,1,0,0:0:0:0:
|
||||
258,189,2746,1,0,0:0:0:0:
|
||||
258,189,2828,1,0,0:0:0:0:
|
||||
258,189,2909,1,0,0:0:0:0:
|
||||
258,189,2991,1,0,0:0:0:0:
|
Loading…
Reference in New Issue
Block a user