Compare commits
5 Commits
master
...
old-testin
| Author | SHA1 | Date | |
|---|---|---|---|
| 17d56f8db0 | |||
| 9637ea1df7 | |||
| 0940d61f7e | |||
| e6a6352a9c | |||
| e78c8fa03d |
@@ -21,7 +21,7 @@
|
||||
]
|
||||
},
|
||||
"ppy.localisationanalyser.tools": {
|
||||
"version": "2025.1208.0",
|
||||
"version": "2024.802.0",
|
||||
"commands": [
|
||||
"localisation"
|
||||
]
|
||||
|
||||
@@ -55,7 +55,9 @@ When in doubt, it's probably best to start with a discussion first. We will esca
|
||||
|
||||
While pull requests from unaffiliated contributors are welcome, please note that due to significant community interest and limited review throughput, the core team's primary focus is on the issues which are currently [on the roadmap](https://github.com/orgs/ppy/projects/7/views/6). Reviewing PRs that fall outside of the scope of the roadmap is done on a best-effort basis, so please be aware that it may take a while before a core maintainer gets around to review your change.
|
||||
|
||||
The [issue tracker](https://github.com/ppy/osu/issues) should provide plenty of issues to start with. In the case of simple issues, a direct PR is okay. However, if you decide to work on an existing issue which doesn't seem trivial, **please ask us first**. This way we can try to estimate if it is a good fit for you and provide the correct direction on how to address it. In addition, note that while we do not rule out external contributors from working on roadmapped issues, we will generally prefer to handle them ourselves unless they're not very time sensitive.
|
||||
The [issue tracker](https://github.com/ppy/osu/issues) should provide plenty of issues to start with. We also have a [`good first issue`](https://github.com/ppy/osu/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label, although from experience it is not used very often, as it is relatively rare that we can spot an issue that will definitively be a good first issue for a new contributor regardless of their programming experience.
|
||||
|
||||
In the case of simple issues, a direct PR is okay. However, if you decide to work on an existing issue which doesn't seem trivial, **please ask us first**. This way we can try to estimate if it is a good fit for you and provide the correct direction on how to address it. In addition, note that while we do not rule out external contributors from working on roadmapped issues, we will generally prefer to handle them ourselves unless they're not very time sensitive.
|
||||
|
||||
If you'd like to propose a subjective change to one of the visual aspects of the game, or there is a bigger task you'd like to work on, but there is no corresponding issue or discussion thread yet for it, **please open a discussion or issue first** to avoid wasted effort. This in particular applies if you want to work on [one of the available designs from the osu! Figma master library](https://www.figma.com/file/VIkXMYNPMtQem2RJg9k2iQ/Master-Library).
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2026.303.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2025.1209.0" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<!-- Fody does not handle Android build well, and warns when unchanged.
|
||||
|
||||
@@ -7,7 +7,6 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
|
||||
@@ -33,7 +32,7 @@ namespace osu.Desktop.Security
|
||||
{
|
||||
public ElevatedPrivilegesNotification()
|
||||
{
|
||||
Text = NotificationsStrings.ElevatedPrivileges(RuntimeInfo.IsUnix ? "root" : "Administrator");
|
||||
Text = $"Running osu! as {(RuntimeInfo.IsUnix ? "root" : "administrator")} does not improve performance, may break integrations and poses a security risk. Please run the game as a normal user.";
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
|
||||
@@ -5,7 +5,7 @@ using BenchmarkDotNet.Attributes;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Tests.NonVisual.Filtering;
|
||||
using osu.Game.Screens.Select.Carousel;
|
||||
|
||||
namespace osu.Game.Benchmarks
|
||||
{
|
||||
@@ -42,7 +42,7 @@ namespace osu.Game.Benchmarks
|
||||
Status = BeatmapOnlineStatus.Loved
|
||||
};
|
||||
|
||||
private FilterMatchingTest.CarouselBeatmap carouselBeatmap = null!;
|
||||
private CarouselBeatmap carouselBeatmap = null!;
|
||||
private FilterCriteria criteria1 = null!;
|
||||
private FilterCriteria criteria2 = null!;
|
||||
private FilterCriteria criteria3 = null!;
|
||||
@@ -55,7 +55,7 @@ namespace osu.Game.Benchmarks
|
||||
var beatmap = getExampleBeatmap();
|
||||
beatmap.OnlineID = 20201010;
|
||||
beatmap.BeatmapSet = new BeatmapSetInfo { OnlineID = 1535 };
|
||||
carouselBeatmap = new FilterMatchingTest.CarouselBeatmap(beatmap);
|
||||
carouselBeatmap = new CarouselBeatmap(beatmap);
|
||||
criteria1 = new FilterCriteria();
|
||||
criteria2 = new FilterCriteria
|
||||
{
|
||||
|
||||
@@ -35,9 +35,11 @@
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
</array>
|
||||
<key>XSAppIconAssets</key>
|
||||
<string>Assets.xcassets/AppIcon.appiconset</string>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
</plist>
|
||||
@@ -176,20 +176,15 @@ namespace osu.Game.Rulesets.Catch
|
||||
|
||||
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetCatch };
|
||||
|
||||
public override IEnumerable<HitResult> GetValidHitResults()
|
||||
protected override IEnumerable<HitResult> GetValidHitResults()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
HitResult.Great,
|
||||
HitResult.Miss,
|
||||
|
||||
HitResult.LargeTickHit,
|
||||
HitResult.LargeTickMiss,
|
||||
HitResult.SmallTickHit,
|
||||
HitResult.SmallTickMiss,
|
||||
HitResult.LargeBonus,
|
||||
HitResult.IgnoreHit,
|
||||
HitResult.IgnoreMiss,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -305,7 +300,7 @@ namespace osu.Game.Rulesets.Catch
|
||||
Description = "Affects how early fruits fade in on the screen.",
|
||||
AdditionalMetrics =
|
||||
[
|
||||
new RulesetBeatmapAttribute.AdditionalMetric("Fade-in time", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRangeInt(effectiveDifficulty.ApproachRate, CatchHitObject.PREEMPT_RANGE):#,0.##} ms"))
|
||||
new RulesetBeatmapAttribute.AdditionalMetric("Fade-in time", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRange(effectiveDifficulty.ApproachRate, CatchHitObject.PREEMPT_RANGE):#,0.##} ms"))
|
||||
]
|
||||
};
|
||||
yield return new RulesetBeatmapAttribute(SongSelectStrings.HPDrain, @"HP", originalDifficulty.DrainRate, effectiveDifficulty.DrainRate, 10)
|
||||
|
||||
@@ -150,7 +150,7 @@ namespace osu.Game.Rulesets.Catch.Objects
|
||||
{
|
||||
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
||||
|
||||
TimePreempt = IBeatmapDifficultyInfo.DifficultyRangeInt(difficulty.ApproachRate, PREEMPT_RANGE);
|
||||
TimePreempt = (float)IBeatmapDifficultyInfo.DifficultyRange(difficulty.ApproachRate, PREEMPT_RANGE);
|
||||
|
||||
Scale = LegacyRulesetExtensions.CalculateScaleFromCircleSize(difficulty.CircleSize);
|
||||
}
|
||||
|
||||
@@ -72,9 +72,6 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
|
||||
leaderboard.Origin = Anchor.CentreLeft;
|
||||
leaderboard.X = 10;
|
||||
}
|
||||
|
||||
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||
d.UsesFixedAnchor = true;
|
||||
})
|
||||
{
|
||||
Children = new Drawable[]
|
||||
|
||||
@@ -35,9 +35,11 @@
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
</array>
|
||||
<key>XSAppIconAssets</key>
|
||||
<string>Assets.xcassets/AppIcon.appiconset</string>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
</plist>
|
||||
@@ -383,7 +383,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
return (PlayfieldType)Enum.GetValues(typeof(PlayfieldType)).Cast<int>().OrderDescending().First(v => variant >= v);
|
||||
}
|
||||
|
||||
public override IEnumerable<HitResult> GetValidHitResults()
|
||||
protected override IEnumerable<HitResult> GetValidHitResults()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
@@ -392,11 +392,9 @@ namespace osu.Game.Rulesets.Mania
|
||||
HitResult.Good,
|
||||
HitResult.Ok,
|
||||
HitResult.Meh,
|
||||
HitResult.Miss,
|
||||
|
||||
HitResult.IgnoreHit,
|
||||
HitResult.ComboBreak,
|
||||
HitResult.IgnoreMiss,
|
||||
// HitResult.SmallBonus is used for awarding perfect bonus score but is not included here as
|
||||
// it would be a bit redundant to show this to the user.
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Graphics.UserInterfaceV2;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Overlays.Settings;
|
||||
using osu.Game.Rulesets.Mania.Configuration;
|
||||
@@ -31,45 +31,47 @@ namespace osu.Game.Rulesets.Mania
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SettingsItemV2(new FormEnumDropdown<ManiaScrollingDirection>
|
||||
new SettingsEnumDropdown<ManiaScrollingDirection>
|
||||
{
|
||||
Caption = RulesetSettingsStrings.ScrollingDirection,
|
||||
LabelText = RulesetSettingsStrings.ScrollingDirection,
|
||||
Current = config.GetBindable<ManiaScrollingDirection>(ManiaRulesetSetting.ScrollDirection)
|
||||
}),
|
||||
new SettingsItemV2(new FormSliderBar<double>
|
||||
},
|
||||
new SettingsSlider<double, ManiaScrollSlider>
|
||||
{
|
||||
Caption = RulesetSettingsStrings.ScrollSpeed,
|
||||
LabelText = RulesetSettingsStrings.ScrollSpeed,
|
||||
Current = config.GetBindable<double>(ManiaRulesetSetting.ScrollSpeed),
|
||||
KeyboardStep = 1,
|
||||
LabelFormat = v => RulesetSettingsStrings.ScrollSpeedTooltip((int)DrawableManiaRuleset.ComputeScrollTime(v), v),
|
||||
}),
|
||||
new SettingsItemV2(new FormCheckBox
|
||||
{
|
||||
Caption = RulesetSettingsStrings.TimingBasedColouring,
|
||||
Current = config.GetBindable<bool>(ManiaRulesetSetting.TimingBasedNoteColouring),
|
||||
})
|
||||
KeyboardStep = 1
|
||||
},
|
||||
new SettingsCheckbox
|
||||
{
|
||||
Keywords = new[] { "color" },
|
||||
LabelText = RulesetSettingsStrings.TimingBasedColouring,
|
||||
Current = config.GetBindable<bool>(ManiaRulesetSetting.TimingBasedNoteColouring),
|
||||
},
|
||||
};
|
||||
|
||||
Add(new SettingsItemV2(new FormCheckBox
|
||||
Add(new SettingsCheckbox
|
||||
{
|
||||
Caption = RulesetSettingsStrings.TouchOverlay,
|
||||
LabelText = RulesetSettingsStrings.TouchOverlay,
|
||||
Current = config.GetBindable<bool>(ManiaRulesetSetting.TouchOverlay)
|
||||
}));
|
||||
});
|
||||
|
||||
if (RuntimeInfo.IsMobile)
|
||||
{
|
||||
Add(new SettingsItemV2(new FormEnumDropdown<ManiaMobileLayout>
|
||||
Add(new SettingsEnumDropdown<ManiaMobileLayout>
|
||||
{
|
||||
Caption = RulesetSettingsStrings.MobileLayout,
|
||||
LabelText = RulesetSettingsStrings.MobileLayout,
|
||||
Current = config.GetBindable<ManiaMobileLayout>(ManiaRulesetSetting.MobileLayout),
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
Items = Enum.GetValues<ManiaMobileLayout>().Where(l => l != ManiaMobileLayout.LandscapeWithOverlay),
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private partial class ManiaScrollSlider : RoundedSliderBar<double>
|
||||
{
|
||||
public override LocalisableString TooltipText => RulesetSettingsStrings.ScrollSpeedTooltip((int)DrawableManiaRuleset.ComputeScrollTime(Current.Value), Current.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,9 +57,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||
|
||||
if (spectatorList != null)
|
||||
spectatorList.Position = new Vector2(36, -66);
|
||||
|
||||
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||
d.UsesFixedAnchor = true;
|
||||
})
|
||||
{
|
||||
new DrawableGameplayLeaderboard(),
|
||||
|
||||
@@ -122,9 +122,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
|
||||
leaderboard.Origin = Anchor.CentreLeft;
|
||||
leaderboard.X = 10;
|
||||
}
|
||||
|
||||
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||
d.UsesFixedAnchor = true;
|
||||
})
|
||||
{
|
||||
new LegacyManiaComboCounter(),
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
|
||||
var hitWindows = new ManiaHitWindows();
|
||||
|
||||
AddInternal(judgementPooler = new JudgementPooler<DrawableManiaJudgement>(Enum.GetValues<HitResult>().Where(hitWindows.IsHitResultAllowed)));
|
||||
AddInternal(judgementPooler = new JudgementPooler<DrawableManiaJudgement>(Enum.GetValues<HitResult>().Where(r => hitWindows.IsHitResultAllowed(r))));
|
||||
|
||||
RegisterPool<BarLine, DrawableBarLine>(50, 200);
|
||||
}
|
||||
|
||||
@@ -35,9 +35,11 @@
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
</array>
|
||||
<key>XSAppIconAssets</key>
|
||||
<string>Assets.xcassets/AppIcon.appiconset</string>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
</plist>
|
||||
@@ -3,13 +3,10 @@
|
||||
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders;
|
||||
using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.UI;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
@@ -33,16 +30,6 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
||||
PathType.LINEAR,
|
||||
new Vector2(100, 0),
|
||||
new Vector2(100, 100)
|
||||
),
|
||||
createPathSegment(
|
||||
PathType.PERFECT_CURVE,
|
||||
new Vector2(100.009f, -50.0009f),
|
||||
new Vector2(200.0089f, -100)
|
||||
),
|
||||
createPathSegment(
|
||||
PathType.PERFECT_CURVE,
|
||||
new Vector2(25, -50),
|
||||
new Vector2(100, 75)
|
||||
)
|
||||
};
|
||||
|
||||
@@ -61,13 +48,9 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
||||
|
||||
[TestCase(0, 250)]
|
||||
[TestCase(0, 200)]
|
||||
[TestCase(1, 120, false, false)]
|
||||
[TestCase(1, 80, false, false)]
|
||||
[TestCase(2, 250)]
|
||||
[TestCase(2, 190)]
|
||||
[TestCase(3, 250)]
|
||||
[TestCase(3, 190)]
|
||||
public void TestSliderReversal(int pathIndex, double length, bool assertEqualDistances = true, bool assertSliderReduction = true)
|
||||
[TestCase(1, 120)]
|
||||
[TestCase(1, 80)]
|
||||
public void TestSliderReversal(int pathIndex, double length)
|
||||
{
|
||||
var controlPoints = paths[pathIndex];
|
||||
|
||||
@@ -107,215 +90,6 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
||||
InputManager.ReleaseKey(Key.LControl);
|
||||
});
|
||||
|
||||
if (pathIndex == 2)
|
||||
{
|
||||
AddRepeatStep("Reverse slider again", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.LControl);
|
||||
InputManager.Key(Key.G);
|
||||
InputManager.ReleaseKey(Key.LControl);
|
||||
}, 2);
|
||||
}
|
||||
|
||||
if (assertEqualDistances)
|
||||
{
|
||||
AddAssert("Middle control point has the same distance from start to end", () =>
|
||||
{
|
||||
var pathControlPoints = selectedSlider.Path.ControlPoints;
|
||||
float middleToStart = Vector2.Distance(pathControlPoints[^2].Position, pathControlPoints[0].Position);
|
||||
float middleToEnd = Vector2.Distance(pathControlPoints[^2].Position, pathControlPoints[^1].Position);
|
||||
|
||||
return Precision.AlmostEquals(middleToStart, middleToEnd, 1f);
|
||||
});
|
||||
}
|
||||
|
||||
AddAssert("Middle control point is not at start or end", () =>
|
||||
Vector2.Distance(selectedSlider.Path.ControlPoints[^2].Position, oldStartPos) > 1 &&
|
||||
Vector2.Distance(selectedSlider.Path.ControlPoints[^2].Position, oldEndPos) > 1
|
||||
);
|
||||
|
||||
AddAssert("Slider has correct length", () =>
|
||||
Precision.AlmostEquals(selectedSlider.Path.Distance, oldDistance));
|
||||
|
||||
AddAssert("Slider has correct start position", () =>
|
||||
Vector2.Distance(selectedSlider.Position, oldEndPos) < 1);
|
||||
|
||||
AddAssert("Slider has correct end position", () =>
|
||||
Vector2.Distance(selectedSlider.EndPosition, oldStartPos) < 1);
|
||||
|
||||
AddAssert("Control points have correct types", () =>
|
||||
{
|
||||
var newControlPointTypes = selectedSlider.Path.ControlPoints.Select(p => p.Type).ToArray();
|
||||
|
||||
return oldControlPointTypes.Take(newControlPointTypes.Length).SequenceEqual(newControlPointTypes);
|
||||
});
|
||||
|
||||
if (assertSliderReduction)
|
||||
{
|
||||
AddStep("Move to marker", () =>
|
||||
{
|
||||
var marker = this.ChildrenOfType<SliderEndDragMarker>().Single();
|
||||
var markerPos = (marker.ScreenSpaceDrawQuad.TopRight + marker.ScreenSpaceDrawQuad.BottomRight) / 2;
|
||||
// sometimes the cursor may miss the marker's hitbox so we
|
||||
// add a little offset here to be sure it lands in a clickable position.
|
||||
var position = new Vector2(markerPos.X + 2f, markerPos.Y);
|
||||
InputManager.MoveMouseTo(position);
|
||||
});
|
||||
AddStep("Click", () => InputManager.PressButton(MouseButton.Left));
|
||||
AddStep("Reduce slider", () =>
|
||||
{
|
||||
var middleControlPoint = this.ChildrenOfType<PathControlPointPiece<Slider>>().ToArray()[^2];
|
||||
InputManager.MoveMouseTo(middleControlPoint);
|
||||
});
|
||||
AddStep("Release click", () => InputManager.ReleaseButton(MouseButton.Left));
|
||||
|
||||
AddStep("Save half slider info", () =>
|
||||
{
|
||||
oldStartPos = selectedSlider.Position;
|
||||
oldEndPos = selectedSlider.EndPosition;
|
||||
oldDistance = selectedSlider.Path.Distance;
|
||||
});
|
||||
|
||||
AddStep("Reverse slider", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.LControl);
|
||||
InputManager.Key(Key.G);
|
||||
InputManager.ReleaseKey(Key.LControl);
|
||||
});
|
||||
|
||||
AddAssert("Middle control point has the same distance from start to end", () =>
|
||||
{
|
||||
var pathControlPoints = selectedSlider.Path.ControlPoints;
|
||||
float middleToStart = Vector2.Distance(pathControlPoints[^2].Position, pathControlPoints[0].Position);
|
||||
float middleToEnd = Vector2.Distance(pathControlPoints[^2].Position, pathControlPoints[^1].Position);
|
||||
|
||||
return Precision.AlmostEquals(middleToStart, middleToEnd, 1f);
|
||||
});
|
||||
|
||||
AddAssert("Middle control point is not at start or end", () =>
|
||||
Vector2.Distance(selectedSlider.Path.ControlPoints[^2].Position, oldStartPos) > 1 &&
|
||||
Vector2.Distance(selectedSlider.Path.ControlPoints[^2].Position, oldEndPos) > 1
|
||||
);
|
||||
|
||||
AddAssert("Slider has correct length", () =>
|
||||
Precision.AlmostEquals(selectedSlider.Path.Distance, oldDistance));
|
||||
|
||||
AddAssert("Slider has correct start position", () =>
|
||||
Vector2.Distance(selectedSlider.Position, oldEndPos) < 1);
|
||||
|
||||
AddAssert("Slider has correct end position", () =>
|
||||
Vector2.Distance(selectedSlider.EndPosition, oldStartPos) < 1);
|
||||
|
||||
AddAssert("Control points have correct types", () =>
|
||||
{
|
||||
var newControlPointTypes = selectedSlider.Path.ControlPoints.Select(p => p.Type).ToArray();
|
||||
|
||||
return oldControlPointTypes.Take(newControlPointTypes.Length).SequenceEqual(newControlPointTypes);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSegmentedSliderReversal()
|
||||
{
|
||||
PathControlPoint[] segmentedSliderPath =
|
||||
[
|
||||
new PathControlPoint
|
||||
{
|
||||
Position = new Vector2(0, 0),
|
||||
Type = PathType.PERFECT_CURVE
|
||||
},
|
||||
new PathControlPoint
|
||||
{
|
||||
Position = new Vector2(100, 150),
|
||||
},
|
||||
new PathControlPoint
|
||||
{
|
||||
Position = new Vector2(75, -50),
|
||||
Type = PathType.PERFECT_CURVE
|
||||
},
|
||||
new PathControlPoint
|
||||
{
|
||||
Position = new Vector2(225, -75),
|
||||
},
|
||||
new PathControlPoint
|
||||
{
|
||||
Position = new Vector2(350, 50),
|
||||
Type = PathType.PERFECT_CURVE
|
||||
},
|
||||
new PathControlPoint
|
||||
{
|
||||
Position = new Vector2(500, -75),
|
||||
},
|
||||
new PathControlPoint
|
||||
{
|
||||
Position = new Vector2(350, -120),
|
||||
},
|
||||
];
|
||||
|
||||
Vector2 oldStartPos = default;
|
||||
Vector2 oldEndPos = default;
|
||||
double oldDistance = default;
|
||||
|
||||
var oldControlPointTypes = segmentedSliderPath.Select(p => p.Type);
|
||||
|
||||
AddStep("Add slider", () =>
|
||||
{
|
||||
var slider = new Slider
|
||||
{
|
||||
Position = new Vector2(0, 200),
|
||||
Path = new SliderPath(segmentedSliderPath)
|
||||
{
|
||||
ExpectedDistance = { Value = 1314 }
|
||||
}
|
||||
};
|
||||
|
||||
EditorBeatmap.Add(slider);
|
||||
|
||||
oldStartPos = slider.Position;
|
||||
oldEndPos = slider.EndPosition;
|
||||
oldDistance = slider.Path.Distance;
|
||||
});
|
||||
|
||||
AddStep("Select slider", () =>
|
||||
{
|
||||
var slider = (Slider)EditorBeatmap.HitObjects[0];
|
||||
EditorBeatmap.SelectedHitObjects.Add(slider);
|
||||
});
|
||||
|
||||
AddRepeatStep("Reverse slider", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.LControl);
|
||||
InputManager.Key(Key.G);
|
||||
InputManager.ReleaseKey(Key.LControl);
|
||||
}, 3);
|
||||
|
||||
AddAssert("First arc's control is not at the slider's middle", () =>
|
||||
Vector2.Distance(selectedSlider.Path.ControlPoints[^2].Position, selectedSlider.Path.PositionAt(0.5)) > 1
|
||||
);
|
||||
|
||||
AddAssert("Last arc's control is not at the slider's middle", () =>
|
||||
Vector2.Distance(selectedSlider.Path.ControlPoints[1].Position, selectedSlider.Path.PositionAt(0.5)) > 1
|
||||
);
|
||||
|
||||
AddAssert("First arc centered middle control point", () =>
|
||||
{
|
||||
var pathControlPoints = selectedSlider.Path.ControlPoints;
|
||||
float middleToStart = Vector2.Distance(pathControlPoints[1].Position, pathControlPoints[0].Position);
|
||||
float middleToEnd = Vector2.Distance(pathControlPoints[1].Position, pathControlPoints[2].Position);
|
||||
|
||||
return Precision.AlmostEquals(middleToStart, middleToEnd, 1f);
|
||||
});
|
||||
|
||||
AddAssert("Last arc centered middle control point", () =>
|
||||
{
|
||||
var pathControlPoints = selectedSlider.Path.ControlPoints;
|
||||
float middleToStart = Vector2.Distance(pathControlPoints[^2].Position, pathControlPoints[^3].Position);
|
||||
float middleToEnd = Vector2.Distance(pathControlPoints[^2].Position, pathControlPoints[^1].Position);
|
||||
|
||||
return Precision.AlmostEquals(middleToStart, middleToEnd, 1f);
|
||||
});
|
||||
|
||||
AddAssert("Slider has correct length", () =>
|
||||
Precision.AlmostEquals(selectedSlider.Path.Distance, oldDistance));
|
||||
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
// 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 System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osu.Game.Tests.Visual;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests.Mods
|
||||
{
|
||||
public partial class TestSceneOsuModEasy : OsuModTestScene
|
||||
{
|
||||
protected override bool AllowFail => true;
|
||||
|
||||
[Test]
|
||||
public void TestMultipleApplication()
|
||||
{
|
||||
bool reapplied = false;
|
||||
CreateModTest(new ModTestData
|
||||
{
|
||||
Mods = [new OsuModEasy { Retries = { Value = 1 } }],
|
||||
Autoplay = false,
|
||||
CreateBeatmap = () =>
|
||||
{
|
||||
// do stuff to speed up fails
|
||||
var b = new TestBeatmap(new OsuRuleset().RulesetInfo)
|
||||
{
|
||||
Difficulty = { DrainRate = 10 }
|
||||
};
|
||||
|
||||
foreach (var ho in b.HitObjects)
|
||||
ho.StartTime /= 4;
|
||||
|
||||
return b;
|
||||
},
|
||||
PassCondition = () =>
|
||||
{
|
||||
if (((ModEasyTestPlayer)Player).FailuresSuppressed > 0 && !reapplied)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var mod in Player.GameplayState.Mods.OfType<IApplicableToDifficulty>())
|
||||
mod.ApplyToDifficulty(new BeatmapDifficulty());
|
||||
|
||||
foreach (var mod in Player.GameplayState.Mods.OfType<IApplicableToPlayer>())
|
||||
mod.ApplyToPlayer(Player);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// don't care if this fails. in fact a failure here is probably better than the alternative.
|
||||
}
|
||||
finally
|
||||
{
|
||||
reapplied = true;
|
||||
}
|
||||
}
|
||||
|
||||
return Player.GameplayState.HasFailed && ((ModEasyTestPlayer)Player).FailuresSuppressed <= 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected override TestPlayer CreateModPlayer(Ruleset ruleset) => new ModEasyTestPlayer(CurrentTestData, AllowFail);
|
||||
|
||||
private partial class ModEasyTestPlayer : ModTestPlayer
|
||||
{
|
||||
public int FailuresSuppressed { get; private set; }
|
||||
|
||||
public ModEasyTestPlayer(ModTestData data, bool allowFail)
|
||||
: base(data, allowFail)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool CheckModsAllowFailure()
|
||||
{
|
||||
bool failureAllowed = GameplayState.Mods.OfType<IApplicableFailOverride>().All(m => m.PerformFail());
|
||||
|
||||
if (!failureAllowed)
|
||||
FailuresSuppressed++;
|
||||
|
||||
return failureAllowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests.Mods
|
||||
{
|
||||
@@ -21,39 +18,5 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
|
||||
Autoplay = false,
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSkipToFirstCircleNotSuppressed()
|
||||
{
|
||||
CreateModTest(new ModTestData
|
||||
{
|
||||
Mod = new OsuModFreezeFrame(),
|
||||
CreateBeatmap = () => new OsuBeatmap
|
||||
{
|
||||
HitObjects =
|
||||
{
|
||||
new HitCircle { StartTime = 5000, Position = OsuPlayfield.BASE_SIZE / 2 }
|
||||
}
|
||||
},
|
||||
PassCondition = () => Player.GameplayClockContainer.GameplayStartTime > 0
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSkipToFirstSpinnerNotSuppressed()
|
||||
{
|
||||
CreateModTest(new ModTestData
|
||||
{
|
||||
Mod = new OsuModFreezeFrame(),
|
||||
CreateBeatmap = () => new OsuBeatmap
|
||||
{
|
||||
HitObjects =
|
||||
{
|
||||
new Spinner { StartTime = 5000, Position = OsuPlayfield.BASE_SIZE / 2 }
|
||||
}
|
||||
},
|
||||
PassCondition = () => Player.GameplayClockContainer.GameplayStartTime > 0
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,9 +27,6 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
[TestCase("multi-segment-slider")]
|
||||
[TestCase("nan-slider")]
|
||||
[TestCase("1124896")]
|
||||
[TestCase("1341554")]
|
||||
[TestCase("2593923")]
|
||||
[TestCase("801165")]
|
||||
public void Test(string name) => base.Test(name);
|
||||
|
||||
protected override IEnumerable<ConvertValue> CreateConvertValue(HitObject hitObject)
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,941 +0,0 @@
|
||||
osu file format v14
|
||||
|
||||
[General]
|
||||
AudioLeadIn: 0
|
||||
PreviewTime: 76429
|
||||
Countdown: 0
|
||||
SampleSet: Soft
|
||||
StackLeniency: 0.2
|
||||
Mode: 0
|
||||
LetterboxInBreaks: 0
|
||||
WidescreenStoryboard: 1
|
||||
|
||||
[Difficulty]
|
||||
HPDrainRate:5
|
||||
CircleSize:4.3
|
||||
OverallDifficulty:8
|
||||
ApproachRate:9.3
|
||||
SliderMultiplier:2.99999995231628
|
||||
SliderTickRate:1
|
||||
|
||||
[Events]
|
||||
//Background and Video events
|
||||
//Break Periods
|
||||
//Storyboard Layer 0 (Background)
|
||||
//Storyboard Layer 1 (Fail)
|
||||
//Storyboard Layer 2 (Pass)
|
||||
//Storyboard Layer 3 (Foreground)
|
||||
//Storyboard Sound Samples
|
||||
|
||||
[TimingPoints]
|
||||
763,444.444444444444,4,2,1,60,1,0
|
||||
763,-111.111111111111,4,2,1,60,0,0
|
||||
1929,-100,4,2,1,5,0,0
|
||||
1985,-100,4,2,1,60,0,0
|
||||
2040,-100,4,2,1,5,0,0
|
||||
2096,-153.846153846153,4,2,1,60,0,0
|
||||
2429,-133.333333333333,4,2,1,5,0,0
|
||||
2540,-71.4285714285714,4,2,1,70,0,1
|
||||
2985,-100,4,2,1,70,0,1
|
||||
4485,-100,4,2,1,5,0,1
|
||||
4540,-100,4,2,1,70,0,1
|
||||
4707,-100,4,2,1,5,0,1
|
||||
4762,-100,4,2,1,70,0,1
|
||||
4929,-100,4,2,1,5,0,1
|
||||
4985,-100,4,2,1,70,0,1
|
||||
5096,-83.3333333333333,4,2,1,70,0,1
|
||||
5429,-133.333333333333,4,2,1,70,0,1
|
||||
5596,-133.333333333333,4,2,1,70,0,1
|
||||
5652,-133.333333333333,4,2,1,70,0,1
|
||||
5818,-133.333333333333,4,2,1,70,0,1
|
||||
5874,-133.333333333333,4,2,1,70,0,1
|
||||
6040,-133.333333333333,4,2,1,70,0,1
|
||||
6096,-100,4,2,1,70,0,1
|
||||
6540,-100,4,2,1,70,0,1
|
||||
8040,-100,4,2,1,5,0,1
|
||||
8096,-100,4,2,1,70,0,1
|
||||
8262,-100,4,2,1,5,0,1
|
||||
8318,-100,4,2,1,70,0,1
|
||||
8485,-100,4,2,1,5,0,1
|
||||
8540,-133.333333333333,4,2,1,70,0,1
|
||||
8874,-100,4,2,1,5,0,1
|
||||
8985,-100,4,2,1,70,0,1
|
||||
9651,-100,4,2,1,70,0,1
|
||||
10096,-100,4,2,1,70,0,1
|
||||
11596,-100,4,2,1,5,0,1
|
||||
11651,-100,4,2,1,70,0,1
|
||||
11818,-100,4,2,1,5,0,1
|
||||
11873,-100,4,2,1,70,0,1
|
||||
11874,-80,4,2,1,70,0,1
|
||||
12040,-80,4,2,1,5,0,1
|
||||
12096,-80,4,2,1,70,0,1
|
||||
12207,-133.333333333333,4,2,1,70,0,1
|
||||
12429,-100,4,2,1,5,0,1
|
||||
12540,-100,4,2,1,70,0,1
|
||||
12707,-100,4,2,1,70,0,1
|
||||
12763,-100,4,2,1,70,0,1
|
||||
12929,-100,4,2,1,70,0,1
|
||||
12985,-100,4,2,1,70,0,1
|
||||
13429,-300,4,2,1,70,0,1
|
||||
13651,-83.3333333333333,4,2,1,70,0,1
|
||||
13874,-100,4,2,1,70,0,1
|
||||
15151,-100,4,2,1,5,0,1
|
||||
15207,-100,4,2,1,70,0,1
|
||||
15373,-100,4,2,1,5,0,1
|
||||
15429,-100,4,2,1,70,0,1
|
||||
15596,-100,4,2,1,5,0,1
|
||||
15651,-100,4,2,1,70,0,1
|
||||
15985,-100,4,2,1,5,0,1
|
||||
16096,-100,4,2,1,70,0,1
|
||||
16262,-100,4,2,1,70,0,1
|
||||
16318,-83.3333333333333,4,2,1,70,0,1
|
||||
16651,-100,4,2,1,70,0,1
|
||||
16762,-133.333333333333,4,2,1,60,0,0
|
||||
17096,-133.333333333333,4,2,1,5,0,0
|
||||
17207,-200,4,2,1,60,0,0
|
||||
18096,-66.6666666666667,4,2,1,60,0,0
|
||||
18262,-66.6666666666667,4,2,1,5,0,0
|
||||
18318,-66.6666666666667,4,2,1,60,0,0
|
||||
18540,-100,4,2,1,60,0,0
|
||||
18874,-100,4,2,1,5,0,0
|
||||
18985,-100,4,2,1,60,0,0
|
||||
19985,-100,4,2,1,60,0,0
|
||||
20485,-100,4,2,1,5,0,0
|
||||
20540,-100,4,2,1,60,0,0
|
||||
20707,-100,4,2,1,5,0,0
|
||||
20762,-200,4,2,1,60,0,0
|
||||
20985,-100,4,2,1,60,0,0
|
||||
21095,-100,4,2,1,60,0,0
|
||||
21374,-100,4,2,1,5,0,0
|
||||
21429,-100,4,2,1,60,0,0
|
||||
21596,-100,4,2,1,5,0,0
|
||||
21651,-100,4,2,1,60,0,0
|
||||
21818,-100,4,2,1,5,0,0
|
||||
21874,-66.6666666666667,4,2,1,60,0,0
|
||||
21985,-100,4,2,1,60,0,0
|
||||
22096,-100,4,2,1,60,0,0
|
||||
22985,-200,4,2,1,60,0,0
|
||||
23318,-100,4,2,1,60,0,0
|
||||
23429,-100,4,2,1,60,0,0
|
||||
23540,-100,4,2,1,60,0,0
|
||||
23651,-100,4,2,1,60,0,0
|
||||
23762,-100,4,2,1,60,0,0
|
||||
23874,-133.333333333333,4,2,1,60,0,0
|
||||
24208,-133.333333333333,4,2,1,5,0,0
|
||||
24318,-200,4,2,1,5,0,0
|
||||
24319,-200,4,2,1,60,0,0
|
||||
24540,-100,4,2,1,60,0,0
|
||||
24651,-66.6666666666667,4,2,1,60,0,0
|
||||
24874,-100,4,2,1,60,0,0
|
||||
25374,-100,4,2,1,5,0,0
|
||||
25429,-100,4,2,1,60,0,0
|
||||
27096,-100,4,2,1,60,0,0
|
||||
27596,-100,4,2,1,5,0,0
|
||||
27651,-100,4,2,1,60,0,0
|
||||
27818,-100,4,2,1,5,0,0
|
||||
27873,-133.333333333333,4,2,1,60,0,0
|
||||
28096,-100,4,2,1,60,0,0
|
||||
28206,-100,4,2,1,60,0,0
|
||||
28485,-100,4,2,1,5,0,0
|
||||
28540,-100,4,2,1,60,0,0
|
||||
28707,-100,4,2,1,5,0,0
|
||||
28762,-100,4,2,1,60,0,0
|
||||
28929,-100,4,2,1,5,0,0
|
||||
28985,-66.6666666666667,4,2,1,60,0,0
|
||||
29151,-100,4,2,1,60,0,0
|
||||
29207,-100,4,2,1,60,0,0
|
||||
29651,-100,4,2,1,60,0,0
|
||||
30429,-100,4,2,1,60,0,0
|
||||
30540,-58.8235294117647,4,2,1,60,0,0
|
||||
30874,-58.8235294117647,4,2,1,5,0,0
|
||||
30985,-58.8235294117647,4,2,1,60,0,0
|
||||
31040,-100,4,2,1,5,0,0
|
||||
31429,-100,4,2,1,60,0,0
|
||||
32485,-100,4,2,1,60,0,0
|
||||
32540,-100,4,2,1,60,0,0
|
||||
32707,-100,4,2,1,60,0,0
|
||||
32762,-100,4,2,1,60,0,0
|
||||
32985,-100,4,2,1,60,0,0
|
||||
34318,-50,4,2,1,60,0,0
|
||||
34485,-100,4,2,1,5,0,0
|
||||
34540,-100,4,2,1,60,0,0
|
||||
35151,-100,4,2,1,5,0,0
|
||||
35207,-100,4,2,1,60,0,0
|
||||
35374,-100,4,2,1,5,0,0
|
||||
35430,-100,4,2,1,60,0,0
|
||||
35818,-100,4,2,1,5,0,0
|
||||
35874,-200,4,2,1,60,0,0
|
||||
36429,-100,4,2,1,60,0,0
|
||||
37818,-100,4,2,1,5,0,0
|
||||
37874,-100,4,2,1,60,0,0
|
||||
38040,-100,4,2,1,5,0,0
|
||||
38096,-50,4,2,1,60,0,0
|
||||
38151,-100,4,2,1,5,0,0
|
||||
38540,-100,4,2,1,60,0,0
|
||||
39596,-100,4,2,1,5,0,0
|
||||
39651,-100,4,2,1,60,0,0
|
||||
39818,-100,4,2,1,60,0,0
|
||||
39873,-100,4,2,1,60,0,0
|
||||
40096,-100,4,2,1,60,0,0
|
||||
41429,-50,4,2,1,60,0,0
|
||||
41596,-100,4,2,1,5,0,0
|
||||
41651,-100,4,2,1,60,0,0
|
||||
41818,-100,4,2,1,5,0,0
|
||||
41874,-100,4,2,1,60,0,0
|
||||
42040,-100,4,2,1,5,0,0
|
||||
42096,-100,4,2,1,60,0,0
|
||||
44318,-100,4,2,1,60,0,0
|
||||
44762,-83.3333333333333,4,2,1,60,0,0
|
||||
45207,-66.6666666666667,4,2,1,45,0,0
|
||||
45651,-133.333333333333,4,2,1,45,0,0
|
||||
51540,-133.333333333333,4,2,1,50,0,0
|
||||
51651,-133.333333333333,4,2,1,45,0,0
|
||||
52318,-133.333333333333,4,2,1,45,0,0
|
||||
58540,-76.9230769230769,4,2,1,45,0,0
|
||||
58818,-100,4,2,1,45,0,0
|
||||
58874,-111.111111111111,4,2,1,45,0,0
|
||||
59318,-111.111111111111,4,2,1,45,0,0
|
||||
59429,-83.3333333333333,4,2,1,60,0,0
|
||||
59540,-83.3333333333333,4,2,1,5,0,0
|
||||
59874,-100,4,2,1,60,0,0
|
||||
60096,-100,4,2,1,5,0,0
|
||||
60207,-100,4,2,1,60,0,0
|
||||
60707,-100,4,2,1,5,0,0
|
||||
60763,-100,4,2,1,60,0,0
|
||||
60818,-100,4,2,1,5,0,0
|
||||
60874,-100,4,2,1,60,0,0
|
||||
60929,-100,4,2,1,5,0,0
|
||||
60985,-100,4,2,1,60,0,0
|
||||
61040,-100,4,2,1,5,0,0
|
||||
61096,-100,4,2,1,60,0,0
|
||||
61151,-100,4,2,1,5,0,0
|
||||
61207,-100,4,2,1,60,0,0
|
||||
61596,-100,4,2,1,5,0,0
|
||||
61651,-100,4,2,1,60,0,0
|
||||
61762,-83.3333333333333,4,2,1,60,0,0
|
||||
61985,-100,4,2,1,5,0,0
|
||||
62096,-100,4,2,1,60,0,0
|
||||
62151,-100,4,2,1,5,0,0
|
||||
62207,-100,4,2,1,60,0,0
|
||||
62262,-100,4,2,1,5,0,0
|
||||
62318,-100,4,2,1,60,0,0
|
||||
62374,-100,4,2,1,5,0,0
|
||||
62430,-100,4,2,1,60,0,0
|
||||
62485,-100,4,2,1,5,0,0
|
||||
62540,-100,4,2,1,60,0,0
|
||||
62596,-100,4,2,1,5,0,0
|
||||
62651,-100,4,2,1,60,0,0
|
||||
62707,-100,4,2,1,5,0,0
|
||||
62762,-100,4,2,1,60,0,0
|
||||
62818,-100,4,2,1,5,0,0
|
||||
62874,-100,4,2,1,60,0,0
|
||||
62929,-100,4,2,1,60,0,0
|
||||
62930,-100,4,2,1,5,0,0
|
||||
62985,-100,4,2,1,60,0,0
|
||||
63707,-100,4,2,1,5,0,0
|
||||
63762,-100,4,2,1,60,0,0
|
||||
64262,-100,4,2,1,5,0,0
|
||||
64318,-100,4,2,1,60,0,0
|
||||
64485,-100,4,2,1,5,0,0
|
||||
64540,-100,4,2,1,60,0,0
|
||||
64596,-100,4,2,1,5,0,0
|
||||
64651,-100,4,2,1,60,0,0
|
||||
64707,-100,4,2,1,5,0,0
|
||||
64762,-71.4285714285714,4,2,1,60,0,0
|
||||
64929,-71.4285714285714,4,2,1,5,0,0
|
||||
64984,-133.333333333333,4,2,1,60,0,0
|
||||
65151,-133.333333333333,4,2,1,5,0,0
|
||||
65206,-71.4285714285714,4,2,1,60,0,0
|
||||
65374,-71.4285714285714,4,2,1,5,0,0
|
||||
65429,-133.333333333333,4,2,1,60,0,0
|
||||
65596,-133.333333333333,4,2,1,5,0,0
|
||||
65651,-100,4,2,1,60,0,0
|
||||
66540,-66.6666666666667,4,2,1,60,0,0
|
||||
66596,-66.6666666666667,4,2,1,5,0,0
|
||||
66929,-100,4,2,1,5,0,0
|
||||
66985,-200,4,2,1,60,0,0
|
||||
67207,-200,4,2,1,5,0,0
|
||||
67318,-100,4,2,1,60,0,0
|
||||
67818,-100,4,2,1,5,0,0
|
||||
67874,-100,4,2,1,60,0,0
|
||||
67929,-100,4,2,1,5,0,0
|
||||
67985,-100,4,2,1,60,0,0
|
||||
68040,-100,4,2,1,5,0,0
|
||||
68096,-100,4,2,1,60,0,0
|
||||
68151,-100,4,2,1,5,0,0
|
||||
68207,-100,4,2,1,60,0,0
|
||||
68262,-100,4,2,1,5,0,0
|
||||
68318,-100,4,2,1,60,0,0
|
||||
68874,-83.3333333333333,4,2,1,60,0,0
|
||||
69096,-100,4,2,1,60,0,0
|
||||
69097,-100,4,2,1,5,0,0
|
||||
69207,-100,4,2,1,60,0,0
|
||||
69263,-100,4,2,1,5,0,0
|
||||
69319,-100,4,2,1,60,0,0
|
||||
69374,-100,4,2,1,5,0,0
|
||||
69430,-100,4,2,1,60,0,0
|
||||
69486,-100,4,2,1,5,0,0
|
||||
69542,-100,4,2,1,60,0,0
|
||||
69597,-100,4,2,1,5,0,0
|
||||
69651,-100,4,2,1,60,0,0
|
||||
69707,-100,4,2,1,5,0,0
|
||||
69762,-100,4,2,1,60,0,0
|
||||
69818,-100,4,2,1,5,0,0
|
||||
69874,-100,4,2,1,60,0,0
|
||||
69929,-100,4,2,1,5,0,0
|
||||
69985,-100,4,2,1,60,0,0
|
||||
70040,-100,4,2,1,60,0,0
|
||||
70041,-100,4,2,1,5,0,0
|
||||
70096,-100,4,2,1,60,0,0
|
||||
70818,-100,4,2,1,5,0,0
|
||||
70873,-100,4,2,1,60,0,0
|
||||
71207,-71.4285714285714,4,2,1,60,0,0
|
||||
71429,-100,4,2,1,60,0,0
|
||||
71874,-71.4285714285714,4,2,1,60,0,0
|
||||
72041,-71.4285714285714,4,2,1,5,0,0
|
||||
72096,-133.333333333333,4,2,1,60,0,0
|
||||
72263,-133.333333333333,4,2,1,5,0,0
|
||||
72318,-71.4285714285714,4,2,1,60,0,0
|
||||
72485,-71.4285714285714,4,2,1,5,0,0
|
||||
72540,-133.333333333333,4,2,1,60,0,0
|
||||
72985,-66.6666666666667,4,2,1,60,0,0
|
||||
73207,-100,4,2,1,60,0,0
|
||||
73651,-133.333333333333,4,2,1,45,0,0
|
||||
75318,-133.333333333333,4,2,1,5,0,0
|
||||
75429,-133.333333333333,4,2,1,45,0,0
|
||||
76762,-100,4,2,1,45,0,0
|
||||
77096,-100,4,2,1,5,0,0
|
||||
77207,-100,4,2,1,70,0,1
|
||||
77818,-100,4,2,1,5,0,1
|
||||
77874,-100,4,2,1,70,0,1
|
||||
78262,-100,4,2,1,5,0,1
|
||||
78318,-100,4,2,1,70,0,1
|
||||
78540,-83.3333333333333,4,2,1,70,0,1
|
||||
78985,-100,4,2,1,70,0,1
|
||||
79596,-100,4,2,1,5,0,1
|
||||
79651,-100,4,2,1,70,0,1
|
||||
80040,-100,4,2,1,5,0,1
|
||||
80096,-100,4,2,1,70,0,1
|
||||
80318,-83.3333333333333,4,2,1,70,0,1
|
||||
84318,-100,4,2,1,70,0,1
|
||||
84929,-100,4,2,1,5,0,1
|
||||
84985,-100,4,2,1,70,0,1
|
||||
85207,-100,4,2,1,70,0,1
|
||||
85374,-100,4,2,1,5,0,1
|
||||
85429,-100,4,2,1,70,0,1
|
||||
85651,-83.3333333333333,4,2,1,70,0,1
|
||||
86096,-100,4,2,1,70,0,1
|
||||
86707,-100,4,2,1,5,0,1
|
||||
86762,-100,4,2,1,70,0,1
|
||||
88818,-100,4,2,1,5,0,1
|
||||
88874,-100,4,2,1,70,0,1
|
||||
88929,-100,4,2,1,5,0,1
|
||||
88985,-100,4,2,1,70,0,1
|
||||
89040,-100,4,2,1,5,0,1
|
||||
89096,-100,4,2,1,70,0,1
|
||||
92040,-100,4,2,1,5,0,1
|
||||
92096,-100,4,2,1,70,0,1
|
||||
92485,-100,4,2,1,5,0,1
|
||||
92540,-100,4,2,1,70,0,1
|
||||
97651,-200,4,2,1,70,0,1
|
||||
97818,-200,4,2,1,5,0,1
|
||||
97874,-66.6666666666667,4,2,1,70,0,1
|
||||
97985,-66.6666666666667,4,2,1,70,0,1
|
||||
98040,-66.6666666666667,4,2,1,5,0,1
|
||||
98096,-133.333333333333,4,2,1,70,0,1
|
||||
98262,-133.333333333333,4,2,1,5,0,1
|
||||
98318,-66.6666666666667,4,2,1,70,0,1
|
||||
98540,-100,4,2,1,70,0,1
|
||||
99151,-100,4,2,1,5,0,1
|
||||
99207,-100,4,2,1,70,0,1
|
||||
99596,-100,4,2,1,5,0,1
|
||||
99651,-100,4,2,1,70,0,1
|
||||
103040,-100,4,2,1,5,0,1
|
||||
103096,-100,4,2,1,70,0,1
|
||||
103151,-100,4,2,1,5,0,1
|
||||
103207,-100,4,2,1,70,0,1
|
||||
103262,-100,4,2,1,5,0,1
|
||||
103318,-100,4,2,1,70,0,1
|
||||
105207,-83.3333333333333,4,2,1,70,0,1
|
||||
105540,-83.3333333333333,4,2,1,70,0,1
|
||||
105651,-133.333333333333,4,2,1,60,0,0
|
||||
105985,-133.333333333333,4,2,1,5,0,0
|
||||
106096,-200,4,2,1,60,0,0
|
||||
106985,-66.6666666666667,4,2,1,60,0,0
|
||||
107151,-66.6666666666667,4,2,1,5,0,0
|
||||
107207,-66.6666666666667,4,2,1,60,0,0
|
||||
107429,-100,4,2,1,60,0,0
|
||||
107763,-100,4,2,1,5,0,0
|
||||
107874,-100,4,2,1,60,0,0
|
||||
108874,-100,4,2,1,60,0,0
|
||||
109374,-100,4,2,1,5,0,0
|
||||
109429,-100,4,2,1,60,0,0
|
||||
109596,-100,4,2,1,5,0,0
|
||||
109651,-200,4,2,1,60,0,0
|
||||
109929,-100,4,2,1,60,0,0
|
||||
109984,-100,4,2,1,60,0,0
|
||||
110262,-100,4,2,1,5,0,0
|
||||
110318,-100,4,2,1,60,0,0
|
||||
110485,-100,4,2,1,5,0,0
|
||||
110540,-100,4,2,1,60,0,0
|
||||
110707,-100,4,2,1,5,0,0
|
||||
110762,-66.6666666666667,4,2,1,60,0,0
|
||||
110929,-100,4,2,1,60,0,0
|
||||
110985,-133.333333333333,4,2,1,60,0,0
|
||||
111429,-133.333333333333,4,2,1,60,0,0
|
||||
111596,-133.333333333333,4,2,1,60,0,0
|
||||
111651,-133.333333333333,4,2,1,60,0,0
|
||||
111818,-133.333333333333,4,2,1,60,0,0
|
||||
111874,-100,4,2,1,60,0,1
|
||||
112318,-83.3333333333333,4,2,1,60,0,1
|
||||
112429,-100,4,2,1,5,0,0
|
||||
|
||||
|
||||
[Colours]
|
||||
Combo1 : 112,75,180
|
||||
Combo2 : 0,255,255
|
||||
Combo3 : 255,15,117
|
||||
Combo4 : 255,135,15
|
||||
|
||||
[HitObjects]
|
||||
309,230,763,37,0,3:0:0:0:
|
||||
485,146,985,2,0,L|406:167,1,67.4999968671799,8|0,3:0|0:0,0:0:0:0:
|
||||
374,249,1207,2,0,L|299:227,1,67.4999968671799,8|0,3:0|0:0,0:0:0:0:
|
||||
196,91,1429,2,0,L|191:44,3,33.7499984335899,0|0|0|0,3:0|3:0|3:0|3:0,0:0:0:0:
|
||||
124,173,1651,2,0,L|131:222,2,44.9999979114532,0|0|0,3:0|3:0|3:0,0:0:0:0:
|
||||
221,284,1874,2,0,L|213:208,1,67.4999968671799,0|0,3:0|3:0,0:0:0:0:
|
||||
292,86,2096,38,0,L|310:234,1,146.249990980625,12|0,3:0|0:0,0:0:0:0:
|
||||
314,328,2540,38,0,B|280:359|280:359|230:320|252:242|313:230,1,209.999990253448,0|0,3:0|0:0,0:0:0:0:
|
||||
421,300,2874,1,0,0:0:0:0:
|
||||
421,300,2985,2,0,P|461:288|491:253,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||
309,231,3207,2,0,P|297:190|305:153,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
394,22,3429,5,0,3:0:0:0:
|
||||
461,72,3540,2,0,B|477:103|477:103|461:148,1,74.999998807907,0|4,0:0|0:0,0:0:0:0:
|
||||
378,183,3762,2,0,L|206:157,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||
229,161,4096,2,0,P|227:202|211:250,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
61,384,4318,38,0,P|101:359|134:322,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
317,310,4540,2,0,P|267:305|226:288,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
141,110,4762,2,0,B|121:175|152:226|152:226|152:202|161:183,1,149.999997615814,8|4,3:0|0:0,0:0:0:0:
|
||||
155,196,5096,6,0,P|67:211|79:286,1,179.999991645813,0|0,0:0|0:0,0:0:0:0:
|
||||
212,366,5429,38,0,P|207:335|174:281,1,56.2500012516975,4|0,0:0|0:0,0:0:0:0:
|
||||
206,286,5651,2,0,P|236:297|299:295,1,56.2500012516975,8|0,3:0|0:0,0:0:0:0:
|
||||
281,321,5874,2,0,P|257:340|227:396,1,56.2500012516975,4|0,0:0|0:0,0:0:0:0:
|
||||
124,246,6096,6,0,P|198:198|277:232,1,149.999997615814,0|0,3:0|0:0,0:0:0:0:
|
||||
253,211,6429,1,0,0:0:0:0:
|
||||
276,99,6540,2,0,P|335:139|369:215,1,149.999997615814,8|4,3:0|0:0,0:0:0:0:
|
||||
368,208,6874,1,0,0:0:0:0:
|
||||
430,96,6985,37,0,3:0:0:0:
|
||||
497,147,7096,2,0,P|507:189|488:244,1,74.999998807907,0|4,0:0|0:0,0:0:0:0:
|
||||
414,379,7318,2,0,B|383:322|421:267|421:267|421:308,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||
421,298,7651,2,0,P|378:312|336:304,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
270,170,7874,6,0,P|275:228|236:278,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
94,300,8096,2,0,P|133:263|208:274,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
261,374,8318,2,0,L|176:365,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||
38,377,8540,2,0,L|55:197,1,168.750003755093,4|0,0:0|0:0,0:0:0:0:
|
||||
123,25,8985,38,0,L|132:110,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
217,242,9207,2,0,L|237:168,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||
48,92,9429,5,4,0:0:0:0:
|
||||
63,176,9540,1,0,0:0:0:0:
|
||||
83,259,9651,38,0,P|167:223|231:255,1,149.999997615814,0|0,3:0|0:0,0:0:0:0:
|
||||
274,312,9985,1,0,0:0:0:0:
|
||||
274,312,10096,2,0,L|354:292,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||
459,225,10318,2,0,L|375:204,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
269,107,10540,1,0,3:0:0:0:
|
||||
276,54,10651,1,0,0:0:0:0:
|
||||
313,17,10762,1,4,0:0:0:0:
|
||||
363,9,10874,1,0,0:0:0:0:
|
||||
363,9,11096,5,0,0:0:0:0:
|
||||
432,68,11207,2,0,P|444:107|425:154,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
309,252,11429,38,0,P|297:195|321:158,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
450,316,11651,2,0,L|361:312,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
160,341,11874,2,0,B|187:380|187:380|233:309|177:235,1,187.499997019767,8|4,3:0|0:0,0:0:0:0:
|
||||
116,200,12207,6,0,P|52:224|122:264,1,168.750003755093,0|4,0:0|0:0,0:0:0:0:
|
||||
297,91,12762,37,8,3:0:0:0:
|
||||
276,44,12874,1,0,0:0:0:0:
|
||||
226,27,12985,1,4,0:0:0:0:
|
||||
187,63,13096,1,0,0:0:0:0:
|
||||
196,115,13207,1,0,0:0:0:0:
|
||||
376,144,13429,2,0,L|378:121,2,16.6666664017571,0|0|0,0:0|0:0|0:0,0:0:0:0:
|
||||
436,220,13651,6,0,B|395:211|373:164|373:164|332:208|264:185,1,179.999991645813,8|4,3:0|0:0,0:0:0:0:
|
||||
276,44,13985,1,0,0:0:0:0:
|
||||
196,115,14096,38,0,L|139:124,4,37.4999994039535,0|0|0|0|4,3:0|0:0|0:0|0:0|0:0,0:0:0:0:
|
||||
82,69,14429,1,0,0:0:0:0:
|
||||
106,190,14540,2,0,L|126:276,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||
218,383,14762,2,0,L|234:309,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
26,231,14985,5,0,3:0:0:0:
|
||||
253,202,15207,37,0,0:0:0:0:
|
||||
331,271,15318,1,0,0:0:0:0:
|
||||
233,309,15429,1,8,3:0:0:0:
|
||||
389,73,15651,6,0,P|410:22|447:112,1,224.999996423721,4|0,3:0|0:0,0:0:0:0:
|
||||
391,165,16096,1,0,0:0:0:0:
|
||||
377,177,16207,1,0,0:0:0:0:
|
||||
365,187,16318,38,0,B|253:261|221:119|94:192,1,269.999987468719,0|0,0:0|0:0,0:0:0:0:
|
||||
73,319,16762,22,0,P|133:336|116:236,1,168.750003755093,4|0,3:0|0:0,0:0:0:0:
|
||||
139,258,17207,6,0,P|138:315|69:283,1,112.500002503395,8|0,3:0|0:0,0:0:0:0:
|
||||
92,323,17762,37,0,0:0:0:0:
|
||||
43,245,17874,1,4,0:0:0:0:
|
||||
4,322,17985,1,0,0:0:0:0:
|
||||
133,245,18096,1,0,3:0:0:0:
|
||||
29,105,18318,6,0,L|38:40,3,56.2500012516975,4|0|0|0,3:0|0:0|0:0|0:0,0:0:0:0:
|
||||
50,30,18540,38,0,P|111:56|193:25,1,149.999997615814,0|0,3:0|0:0,0:0:0:0:
|
||||
240,120,18985,2,0,P|328:91|394:125,1,149.999997615814,8|4,3:0|0:0,0:0:0:0:
|
||||
409,213,19318,2,0,B|377:226|377:226|243:200,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||
119,187,19651,2,0,L|127:286,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
179,338,19874,1,8,3:0:0:0:
|
||||
45,307,19985,6,0,L|3:297,2,37.4999994039535,0|0|4,0:0|0:0|0:0,0:0:0:0:
|
||||
103,380,20207,1,0,3:0:0:0:
|
||||
212,257,20318,38,0,P|233:218|231:171,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
111,118,20540,1,4,0:0:0:0:
|
||||
111,118,20762,6,0,L|197:109,1,74.999998807907,8|4,3:0|0:0,0:0:0:0:
|
||||
256,18,21096,37,0,0:0:0:0:
|
||||
337,121,21207,2,0,P|350:60|403:16,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||
384,26,21429,2,0,P|406:86|465:122,1,112.49999821186,0|0,0:0|0:0,0:0:0:0:
|
||||
443,114,21651,2,0,P|377:105|327:131,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||
352,223,21874,6,0,B|369:230|369:230|391:228|391:228|416:239|416:239|440:235|440:235|462:244|462:244|489:249,1,112.500002503395,4|0,0:0|0:0,0:0:0:0:
|
||||
322,343,22096,37,0,3:0:0:0:
|
||||
259,270,22207,2,0,P|223:276|182:263,2,74.999998807907,0|4|0,0:0|0:0|0:0,0:0:0:0:
|
||||
86,360,22540,5,8,3:0:0:0:
|
||||
15,295,22651,2,0,L|0:201,2,74.999998807907,0|4|0,0:0|0:0|0:0,0:0:0:0:
|
||||
94,384,22985,38,0,P|118:328|112:277,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||
0,211,23429,22,0,L|76:196,1,74.999998807907,12|0,3:0|0:0,0:0:0:0:
|
||||
215,134,23651,2,0,L|114:110,1,74.999998807907,12|0,3:0|0:0,0:0:0:0:
|
||||
33,124,23874,22,0,L|43:2,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||
150,269,24318,2,0,L|162:194,1,74.999998807907,0|4,3:0|0:0,0:0:0:0:
|
||||
229,134,24651,6,0,L|386:164,1,112.500002503395,12|0,3:0|0:0,0:0:0:0:
|
||||
486,268,24874,37,0,0:0:0:0:
|
||||
410,119,24985,1,4,0:0:0:0:
|
||||
381,213,25096,1,0,0:0:0:0:
|
||||
512,120,25207,1,0,3:0:0:0:
|
||||
247,36,25429,6,0,L|191:25,3,37.4999994039535,4|0|0|0,3:0|0:0|0:0|0:0,0:0:0:0:
|
||||
185,24,25651,2,0,B|145:72|145:72|174:164,1,149.999997615814,0|0,3:0|0:0,0:0:0:0:
|
||||
253,219,26096,2,0,B|281:311|281:311|228:382,1,149.999997615814,8|4,3:0|0:0,0:0:0:0:
|
||||
100,363,26429,38,0,L|259:354,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||
404,262,26762,1,4,0:0:0:0:
|
||||
390,352,26874,1,0,0:0:0:0:
|
||||
314,295,26985,1,8,3:0:0:0:
|
||||
425,256,27096,6,0,L|492:246,2,37.4999994039535,0|0|4,0:0|0:0|0:0,0:0:0:0:
|
||||
329,216,27318,1,0,3:0:0:0:
|
||||
193,177,27429,38,0,L|266:161,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
322,107,27651,1,4,0:0:0:0:
|
||||
322,107,27874,2,0,L|310:238,1,112.500002503395,8|4,3:0|0:0,0:0:0:0:
|
||||
110,299,28207,5,0,0:0:0:0:
|
||||
164,231,28318,2,0,B|168:303|168:303|121:338,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||
30,284,28540,2,0,B|90:244|90:244|144:267,1,112.49999821186,0|0,0:0|0:0,0:0:0:0:
|
||||
148,371,28762,2,0,B|83:338|83:338|76:280,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||
194,201,28985,38,0,B|207:210|207:210|227:210|227:210|243:217|243:217|265:218|265:218|282:227|282:227|305:225|305:225|325:238,1,112.500002503395,4|0,0:0|0:0,0:0:0:0:
|
||||
492,114,29207,6,0,P|445:136|410:138,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
324,102,29429,2,0,P|291:68|280:29,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
418,17,29651,1,8,3:0:0:0:
|
||||
495,201,29874,1,4,3:2:0:0:
|
||||
221,136,30096,37,0,3:0:0:0:
|
||||
299,188,30207,2,0,B|316:251|316:251|271:352,1,149.999997615814,4|0,3:0|0:0,0:0:0:0:
|
||||
115,334,30540,6,0,P|11:252|167:266,1,382.500001215934,0|0,0:0|0:0,0:0:0:0:
|
||||
216,326,30985,38,0,L|304:331,1,63.7500002026557,4|0,3:0|0:0,0:0:0:0:
|
||||
280,330,31429,6,0,L|293:241,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||
426,252,31651,2,0,L|439:163,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||
253,158,31874,37,0,3:0:0:0:
|
||||
258,132,31985,1,0,0:0:0:0:
|
||||
337,111,32096,5,4,0:0:0:0:
|
||||
341,85,32207,1,0,0:0:0:0:
|
||||
271,30,32318,38,0,B|212:42|212:42|141:19,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||
163,26,32540,2,0,L|144:181,1,149.999997615814,4|0,0:0|3:0,0:0:0:0:
|
||||
445,343,32985,22,0,B|439:234|439:234|384:269,1,149.999997615814,4|8,0:0|3:0,0:0:0:0:
|
||||
240,257,33429,2,0,B|263:148|263:148|291:205,1,149.999997615814,4|0,0:0|3:0,0:0:0:0:
|
||||
68,333,33874,2,0,B|83:233|83:233|41:256,1,149.999997615814,4|8,0:0|3:0,0:0:0:0:
|
||||
344,347,34318,22,0,B|368:372|368:372|455:355|455:355|472:308,1,149.999997615814,4|0,0:0|0:0,0:0:0:0:
|
||||
452,255,34540,2,0,B|389:212|389:212|332:273,1,149.999997615814,0|4,3:0|0:0,0:0:0:0:
|
||||
256,220,34874,5,0,0:0:0:0:
|
||||
256,220,34985,2,0,B|256:128,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||
256,70,35207,2,0,B|256:162,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
112,312,35429,37,0,3:0:0:0:
|
||||
60,255,35540,2,0,B|123:212|123:212|180:273,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||
169,350,35874,6,0,B|144:375|144:375|57:358|57:358|40:311,1,149.999997615814,8|0,3:0|3:0,0:0:0:0:
|
||||
62,169,36429,6,0,L|76:267,2,74.999998807907,0|4|0,0:0|0:0|0:0,0:0:0:0:
|
||||
134,61,36762,1,8,3:0:0:0:
|
||||
201,113,36874,2,0,L|215:211,2,74.999998807907,0|4|0,0:0|0:0|0:0,0:0:0:0:
|
||||
298,272,37207,6,0,L|315:184,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
330,114,37429,1,4,0:0:0:0:
|
||||
446,176,37540,2,0,B|404:214|404:214|307:197,1,149.999997615814,4|0,3:0|0:0,0:0:0:0:
|
||||
231,240,37874,2,0,P|223:199|231:162,1,74.999998807907,4|0,3:0|0:0,0:0:0:0:
|
||||
325,285,38096,6,0,L|154:300,1,149.999997615814,4|0,3:0|0:0,0:0:0:0:
|
||||
175,298,38540,6,0,L|163:396,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||
75,208,38762,2,0,L|63:306,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||
233,74,38985,37,0,3:0:0:0:
|
||||
231,98,39096,1,0,0:0:0:0:
|
||||
156,139,39207,5,4,0:0:0:0:
|
||||
155,165,39318,1,0,0:0:0:0:
|
||||
227,215,39429,38,0,P|282:209|352:230,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||
336,222,39651,2,0,L|366:67,1,149.999997615814,4|0,0:0|3:0,0:0:0:0:
|
||||
81,35,40096,22,0,B|82:105|82:105|118:136|118:136|132:89,1,149.999997615814,4|8,0:0|3:0,0:0:0:0:
|
||||
272,158,40540,2,0,B|270:228|270:228|234:259|234:259|220:212,1,149.999997615814,4|0,0:0|3:0,0:0:0:0:
|
||||
423,36,40985,2,0,B|400:102|400:102|423:143|423:143|453:104,1,149.999997615814,4|8,0:0|3:0,0:0:0:0:
|
||||
512,278,41429,6,0,P|415:258|361:293,1,149.999997615814,4|0,0:0|0:0,0:0:0:0:
|
||||
359,302,41651,6,0,B|320:264|320:264|310:187,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||
322,190,41874,2,0,L|449:171,1,112.49999821186,4|0,0:0|0:0,0:0:0:0:
|
||||
443,159,42096,1,8,3:0:0:0:
|
||||
240,52,42318,6,0,B|255:79|255:79|241:135,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
177,166,42540,1,0,3:0:0:0:
|
||||
163,151,42651,2,0,B|161:207|161:207|192:240|192:240|189:299,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||
131,365,42985,2,0,P|198:322|280:345,1,149.999997615814,8|4,3:0|0:0,0:0:0:0:
|
||||
335,377,43318,1,0,0:0:0:0:
|
||||
442,239,43429,38,0,B|456:178|456:178|422:136|422:136|427:68|427:68|449:112,1,224.999996423721,0|0,3:0|0:0,0:0:0:0:
|
||||
444,103,43874,2,0,P|402:118|356:120,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||
249,28,44096,2,0,P|295:35|324:48,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||
364,201,44318,5,0,0:0:0:0:
|
||||
332,195,44429,1,0,0:0:0:0:
|
||||
251,135,44540,37,0,0:0:0:0:
|
||||
281,123,44651,1,0,0:0:0:0:
|
||||
332,195,44762,6,0,B|356:269|324:333|324:333|303:293,1,179.999991645813,4|0,0:3|0:0,0:0:0:0:
|
||||
61,25,45207,38,0,L|88:158,1,112.500002503395,0|0,3:0|0:0,0:0:0:0:
|
||||
84,136,45651,1,8,3:0:0:0:
|
||||
84,136,46096,1,0,3:0:0:0:
|
||||
176,33,46207,2,0,L|164:103,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
219,207,46429,2,0,L|232:152,1,56.2500012516975,0|8,0:0|3:0,0:0:0:0:
|
||||
312,65,46651,1,0,0:0:0:0:
|
||||
312,65,46762,2,0,L|398:94,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
512,176,46985,5,0,3:0:0:0:
|
||||
421,192,47096,1,0,0:0:0:0:
|
||||
421,192,47429,1,8,3:0:0:0:
|
||||
402,357,47651,37,0,0:0:0:0:
|
||||
394,277,47762,1,0,0:0:0:0:
|
||||
328,324,47874,1,0,3:0:0:0:
|
||||
328,324,48318,1,8,3:0:0:0:
|
||||
110,357,48540,5,0,0:0:0:0:
|
||||
118,277,48651,1,0,0:0:0:0:
|
||||
184,324,48763,1,0,3:0:0:0:
|
||||
110,357,48874,1,0,0:0:0:0:
|
||||
110,357,49207,1,8,3:0:0:0:
|
||||
110,357,49651,1,0,3:0:0:0:
|
||||
0,283,49762,38,0,P|41:301|97:295,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
188,219,49985,2,0,P|168:236|137:246,1,56.2500012516975,0|8,0:0|3:0,0:0:0:0:
|
||||
49,137,50207,1,0,0:0:0:0:
|
||||
49,137,50318,2,0,P|65:184|93:205,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
107,67,50540,5,0,3:0:0:0:
|
||||
32,15,50651,1,0,0:0:0:0:
|
||||
32,15,50985,1,8,3:0:0:0:
|
||||
265,114,51207,37,0,0:0:0:0:
|
||||
254,196,51318,1,0,0:0:0:0:
|
||||
241,279,51429,1,0,3:0:0:0:
|
||||
241,279,51651,1,0,0:0:0:0:
|
||||
336,207,51762,6,0,P|397:191|371:274,1,168.750003755093,0|0,0:0|0:0,0:0:0:0:
|
||||
83,206,52318,5,0,3:0:0:0:
|
||||
83,206,52429,2,0,L|101:260,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
40,383,52651,2,0,P|70:355|90:324,1,56.2500012516975,0|8,0:0|3:0,0:0:0:0:
|
||||
214,334,52874,1,0,0:0:0:0:
|
||||
214,334,52985,2,0,P|171:322|140:304,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
151,160,53207,5,0,3:0:0:0:
|
||||
188,135,53318,1,0,0:0:0:0:
|
||||
232,129,53429,1,0,0:0:0:0:
|
||||
273,146,53540,1,0,0:0:0:0:
|
||||
339,198,53651,37,8,3:0:0:0:
|
||||
383,199,53762,1,0,0:0:0:0:
|
||||
426,185,53874,1,0,0:0:0:0:
|
||||
450,147,53985,1,0,0:0:0:0:
|
||||
444,61,54096,6,0,P|414:28|377:15,1,56.2500012516975,0|0,3:0|0:0,0:0:0:0:
|
||||
301,28,54318,2,0,P|268:48|255:77,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
189,271,54540,38,0,P|209:222|204:198,1,56.2500012516975,8|0,3:0|0:0,0:0:0:0:
|
||||
186,114,54762,2,0,P|152:74|124:68,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
27,137,54985,5,0,3:0:0:0:
|
||||
34,167,55096,1,0,0:0:0:0:
|
||||
122,204,55207,37,0,0:0:0:0:
|
||||
116,178,55318,1,0,0:0:0:0:
|
||||
48,249,55429,5,8,3:0:0:0:
|
||||
54,274,55540,1,0,0:0:0:0:
|
||||
124,329,55651,38,0,P|157:326|200:310,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
320,185,55874,5,0,3:0:0:0:
|
||||
287,175,55985,1,0,0:0:0:0:
|
||||
254,181,56096,2,0,P|258:221|264:241,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
337,347,56318,2,0,P|348:321|350:293,1,56.2500012516975,8|0,3:0|0:0,0:0:0:0:
|
||||
418,197,56540,37,0,0:0:0:0:
|
||||
418,197,56651,2,0,L|492:180,1,56.2500012516975,0|0,0:0|3:0,0:0:0:0:
|
||||
329,114,56874,2,0,L|262:94,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
436,59,57096,6,0,L|413:126,1,56.2500012516975,0|8,0:0|3:0,0:0:0:0:
|
||||
332,194,57318,2,0,L|353:259,2,56.2500012516975,0|0|0,0:0|0:0|0:0,0:0:0:0:
|
||||
202,194,57651,37,0,3:0:0:0:
|
||||
224,233,57762,1,0,0:0:0:0:
|
||||
222,279,57874,1,0,0:0:0:0:
|
||||
193,314,57985,1,0,0:0:0:0:
|
||||
144,244,58096,5,0,0:0:0:0:
|
||||
127,214,58207,1,0,0:0:0:0:
|
||||
126,180,58318,1,0,0:0:0:0:
|
||||
139,149,58429,1,0,0:0:0:0:
|
||||
224,113,58540,38,0,B|262:88|235:70|189:83|189:83|224:138|194:193,1,194.999987974167
|
||||
299,319,58874,1,0,0:0:0:0:
|
||||
299,319,58985,2,0,B|316:283|314:237|314:237|278:226|278:226|320:243|359:227,1,202.49999060154,4|0,0:0|0:0,0:0:0:0:
|
||||
428,181,59429,22,0,P|454:129|399:4,1,179.999991645813,0|0,3:0|0:0,0:0:0:0:
|
||||
418,18,59874,2,0,L|373:15,6,24.9999996026357,8|0|0|0|0|0|4,3:0|0:0|0:0|0:0|0:0|0:0|0:0,0:0:0:0:
|
||||
428,181,60207,5,0,0:0:0:0:
|
||||
352,209,60318,1,0,3:0:0:0:
|
||||
278,177,60429,1,0,0:0:0:0:
|
||||
208,225,60540,2,0,L|222:267,2,37.4999994039535,4|0|0,0:0|0:0|0:0,0:0:0:0:
|
||||
71,144,60762,38,0,L|65:109,3,24.9999996026357,8|0|0|0,3:0|0:0|0:0|0:0,0:0:0:0:
|
||||
145,86,60985,1,4,0:0:0:0:
|
||||
163,127,61096,1,0,0:0:0:0:
|
||||
161,171,61207,1,0,3:0:0:0:
|
||||
136,208,61318,1,0,0:0:0:0:
|
||||
99,231,61429,2,0,B|91:279|91:279|117:314,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
177,378,61651,5,8,3:0:0:0:
|
||||
177,378,61762,2,0,B|231:371|231:371|272:326|272:326|345:319,1,179.999991645813
|
||||
417,293,62096,1,0,3:0:0:0:
|
||||
438,263,62207,1,0,0:0:0:0:
|
||||
436,225,62318,1,4,0:0:0:0:
|
||||
412,196,62429,1,0,0:0:0:0:
|
||||
320,172,62540,6,0,P|307:192|291:204,1,37.4999994039535,8|0,3:0|0:0,0:0:0:0:
|
||||
291,147,62651,2,0,P|274:156|245:153,1,37.4999994039535,0|0,0:0|0:0,0:0:0:0:
|
||||
276,114,62762,2,0,P|250:107|234:94,1,37.4999994039535,4|0,0:0|0:0,0:0:0:0:
|
||||
283,81,62874,2,0,P|265:61|260:45,1,37.4999994039535,0|0,0:0|0:0,0:0:0:0:
|
||||
365,31,62985,38,0,P|398:44|442:49,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
512,169,63207,2,0,P|466:163|421:176,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
350,107,63429,1,8,3:0:0:0:
|
||||
293,237,63540,38,0,L|276:158,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||
428,269,63762,2,0,B|373:275|373:275|338:249|338:249|267:255,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||
191,318,64096,2,0,B|182:355|182:355|212:395,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
192,186,64318,5,8,3:0:0:0:
|
||||
135,253,64429,2,0,L|56:270,2,74.999998807907,0|4|0,0:0|0:0|0:0,0:0:0:0:
|
||||
24,136,64762,38,0,P|69:76|158:75,1,157.499992690086,0|0,3:0|0:0,0:0:0:0:
|
||||
160,80,64985,6,0,P|193:102|255:102,1,84.3750018775463,4|0,0:0|0:0,0:0:0:0:
|
||||
276,34,65207,38,0,L|290:212,1,157.499992690086,8|0,3:0|0:0,0:0:0:0:
|
||||
291,219,65429,6,0,L|311:132,1,84.3750018775463,4|0,0:0|0:0,0:0:0:0:
|
||||
381,111,65651,38,0,B|418:126|418:126|460:126,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
221,163,65874,2,0,B|186:143|186:143|139:153,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
41,231,66096,1,8,3:0:0:0:
|
||||
49,267,66207,1,0,0:0:0:0:
|
||||
56,303,66318,1,4,0:0:0:0:
|
||||
67,288,66429,1,4,0:0:0:0:
|
||||
77,270,66540,6,0,P|171:255|72:350,1,337.500007510185,0|0,0:0|0:0,0:0:0:0:
|
||||
95,356,66985,38,0,L|185:343,1,74.999998807907,8|4,3:0|0:0,0:0:0:0:
|
||||
274,286,67318,6,0,B|289:324|289:324|268:378,1,74.999998807907,0|0,0:0|3:0,0:0:0:0:
|
||||
191,227,67540,1,0,0:0:0:0:
|
||||
255,168,67651,2,0,L|264:116,2,37.4999994039535,4|0|0,0:0|0:0|0:0,0:0:0:0:
|
||||
147,83,67874,2,0,L|154:108,3,24.9999996026357,8|0|0|0,3:0|0:0|0:0|0:0,0:0:0:0:
|
||||
80,148,68096,38,0,L|98:224,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
125,356,68318,1,0,3:0:0:0:
|
||||
0,319,68429,1,0,0:0:0:0:
|
||||
0,319,68540,2,0,L|76:294,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
277,219,68762,5,8,3:0:0:0:
|
||||
277,219,68874,2,0,B|327:199|327:199|293:138|197:173,1,179.999991645813,0|0,0:0|0:0,0:0:0:0:
|
||||
157,273,69207,37,0,3:0:0:0:
|
||||
175,316,69318,1,0,0:0:0:0:
|
||||
212,334,69429,1,4,0:0:0:0:
|
||||
254,333,69540,1,0,0:0:0:0:
|
||||
332,268,69651,38,0,P|333:237|343:213,1,37.4999994039535,8|0,3:0|0:0,0:0:0:0:
|
||||
373,265,69762,2,0,P|386:239|404:232,1,37.4999994039535,0|0,0:0|0:0,0:0:0:0:
|
||||
413,284,69874,2,0,P|430:269|454:269,1,37.4999994039535,4|0,0:0|0:0,0:0:0:0:
|
||||
433,318,69985,2,0,P|452:320|474:337,1,37.4999994039535,4|0,0:0|0:0,0:0:0:0:
|
||||
401,384,70096,6,0,P|353:378|319:346,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
251,251,70318,2,0,P|240:196|260:154,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
401,18,70540,1,8,3:0:0:0:
|
||||
401,18,70651,2,0,P|409:54|398:90,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||
327,193,70874,2,0,L|304:45,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||
290,26,71207,6,0,L|308:144,1,104.999995126724,0|0,0:0|0:0,0:0:0:0:
|
||||
272,302,71429,2,0,L|187:288,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||
33,217,71651,37,4,0:0:0:0:
|
||||
27,187,71762,1,4,0:0:0:0:
|
||||
20,157,71874,2,0,B|103:140|103:140|162:58,1,157.499992690086,0|0,3:0|0:0,0:0:0:0:
|
||||
145,82,72096,6,0,L|218:75,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
336,136,72318,38,0,P|331:213|231:208,1,157.499992690086
|
||||
263,232,72540,6,0,L|278:300,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
183,384,72762,2,0,L|172:307,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
37,140,72985,38,0,B|10:168|10:168|17:204|17:204|54:220|54:220|89:196|89:196|87:157|87:157|57:138,1,225.00000500679
|
||||
275,372,73651,6,0,P|320:352|387:369,1,112.500002503395
|
||||
380,364,74096,2,0,L|436:358,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
495,271,74318,2,0,L|424:282,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
339,270,74540,1,0,0:0:0:0:
|
||||
339,270,74651,1,0,0:0:0:0:
|
||||
339,270,74762,2,0,L|329:196,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
408,46,74985,38,0,L|392:120,1,56.2500012516975
|
||||
220,230,75207,2,0,L|209:156,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
282,7,75429,37,0,0:0:0:0:
|
||||
300,98,75540,1,0,0:0:0:0:
|
||||
197,25,75651,5,0,0:0:0:0:
|
||||
222,103,75762,1,0,0:0:0:0:
|
||||
126,69,75874,5,0,0:0:0:0:
|
||||
153,134,75985,1,0,0:0:0:0:
|
||||
76,145,76096,5,0,0:0:0:0:
|
||||
116,179,76207,1,0,0:0:0:0:
|
||||
70,222,76318,5,0,0:0:0:0:
|
||||
111,222,76429,1,0,0:0:0:0:
|
||||
134,253,76540,6,0,P|135:298|126:314,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
21,384,76762,2,0,P|124:354|260:391,1,224.999996423721,0|0,0:0|0:0,0:0:0:0:
|
||||
384,366,77207,22,0,L|394:268,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
499,62,77429,2,0,L|486:135,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
507,237,77651,2,0,P|450:231|388:184,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||
404,203,77874,2,0,L|313:217,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
113,212,78096,6,0,P|128:267|111:328,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||
115,319,78318,2,0,L|213:340,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
274,371,78540,38,0,L|257:186,1,179.999991645813,8|0,3:0|0:0,0:0:0:0:
|
||||
128,139,78874,1,0,0:0:0:0:
|
||||
128,139,78985,6,0,L|230:128,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
365,34,79207,37,4,0:0:0:0:
|
||||
430,114,79318,1,0,0:0:0:0:
|
||||
361,184,79429,2,0,P|304:170|277:110,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||
278,126,79651,2,0,L|189:133,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
64,263,79874,6,0,B|37:230|37:230|50:143,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||
66,119,80096,2,0,L|80:210,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
71,361,80318,38,0,B|135:350|135:350|182:305|182:305|243:297,1,179.999991645813,8|0,3:0|0:0,0:0:0:0:
|
||||
302,247,80651,1,0,0:0:0:0:
|
||||
222,211,80762,1,0,3:0:0:0:
|
||||
478,344,80985,5,4,0:0:0:0:
|
||||
491,309,81096,5,0,0:0:0:0:
|
||||
498,265,81207,5,8,3:0:0:0:
|
||||
485,223,81318,5,0,0:0:0:0:
|
||||
458,179,81429,5,4,0:0:0:0:
|
||||
418,147,81540,5,0,0:0:0:0:
|
||||
352,126,81651,5,0,3:0:0:0:
|
||||
281,149,81762,5,0,0:0:0:0:
|
||||
239,221,81874,5,4,0:0:0:0:
|
||||
159,262,81985,5,0,0:0:0:0:
|
||||
66,234,82096,5,8,3:0:0:0:
|
||||
11,145,82207,5,0,0:0:0:0:
|
||||
55,33,82318,5,4,0:0:0:0:
|
||||
273,44,82540,37,0,3:0:0:0:
|
||||
320,103,82651,1,0,0:0:0:0:
|
||||
394,118,82762,1,4,0:0:0:0:
|
||||
468,100,82874,1,0,0:0:0:0:
|
||||
507,36,82985,1,8,3:0:0:0:
|
||||
495,19,83207,5,4,0:0:0:0:
|
||||
335,83,83318,1,0,0:0:0:0:
|
||||
453,81,83429,1,0,3:0:0:0:
|
||||
283,24,83540,2,0,P|196:37|141:120,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||
60,238,83874,1,8,3:0:0:0:
|
||||
21,164,83985,2,0,P|59:149|175:193,1,149.999997615814,0|8,0:0|3:0,0:0:0:0:
|
||||
252,206,84318,38,0,P|271:160|264:125,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
139,257,84540,2,0,P|131:302|149:340,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
240,379,84762,2,0,B|330:360|330:360|298:344,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||
312,351,84985,2,0,P|279:321|270:287,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
359,165,85207,6,0,B|389:202|389:202|368:282,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||
373,265,85429,2,0,L|454:282,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
498,139,85651,38,0,P|446:120|396:0,1,179.999991645813,8|0,3:0|0:0,0:0:0:0:
|
||||
394,13,85985,1,0,0:0:0:0:
|
||||
301,92,86096,6,0,L|214:83,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
66,66,86318,1,4,0:0:0:0:
|
||||
13,136,86429,1,0,0:0:0:0:
|
||||
72,193,86540,2,0,P|120:210|190:178,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||
176,192,86762,2,0,P|154:237|160:288,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
309,370,86985,37,0,3:0:0:0:
|
||||
359,310,87096,1,0,0:0:0:0:
|
||||
283,297,87207,2,0,L|203:318,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
4,203,87429,2,0,B|55:211|55:211|82:255|82:255|134:266,1,149.999997615814,8|0,3:0|0:0,0:0:0:0:
|
||||
238,217,87762,1,0,0:0:0:0:
|
||||
183,120,87874,6,0,L|89:111,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
98,33,88096,2,0,L|23:26,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
306,182,88318,38,0,L|400:173,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||
391,95,88540,2,0,L|465:88,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
232,28,88762,2,0,L|220:92,1,37.4999994039535,0|0,3:0|0:0,0:0:0:0:
|
||||
243,39,88874,2,0,L|231:103,1,37.4999994039535,0|0,0:0|0:0,0:0:0:0:
|
||||
256,50,88985,2,0,L|251:87,1,37.4999994039535,4|0,0:0|0:0,0:0:0:0:
|
||||
485,87,89207,6,0,L|493:51,3,37.4999994039535,8|0|0|0,3:0|0:0|0:0|0:0,0:0:0:0:
|
||||
396,120,89429,2,0,L|411:197,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
471,317,89651,38,0,P|411:299|320:336,1,149.999997615814,0|4,3:0|0:0,0:0:0:0:
|
||||
61,239,90096,2,0,P|121:221|212:258,1,149.999997615814,8|4,3:0|0:0,0:0:0:0:
|
||||
367,21,90540,6,0,P|336:57|328:104,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
163,96,90762,2,0,P|194:132|202:179,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||
190,346,90985,37,8,3:0:0:0:
|
||||
328,272,91096,1,0,0:0:0:0:
|
||||
154,272,91207,5,8,3:0:0:0:
|
||||
365,338,91318,1,0,0:0:0:0:
|
||||
257,382,91429,38,0,B|290:333|224:286|269:219,1,149.999997615814,4|4,3:0|0:0,0:0:0:0:
|
||||
325,196,91762,1,0,0:0:0:0:
|
||||
325,196,91874,2,0,P|365:210|436:184,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||
430,190,92096,2,0,B|418:110,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
313,19,92318,2,0,L|190:36,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||
201,34,92540,2,0,B|214:117,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
209,252,92762,5,8,3:0:0:0:
|
||||
156,261,92874,1,0,0:0:0:0:
|
||||
112,231,92985,1,4,0:0:0:0:
|
||||
60,222,93096,1,0,0:0:0:0:
|
||||
13,247,93207,38,0,P|4:288|19:328,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
173,186,93429,1,4,0:0:0:0:
|
||||
215,120,93540,1,0,0:0:0:0:
|
||||
162,49,93651,2,0,P|125:39|76:61,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||
234,138,93874,2,0,P|273:157|313:148,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
385,39,94096,5,0,3:0:0:0:
|
||||
337,286,94318,2,0,L|322:373,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
409,327,94540,2,0,P|418:277|280:230,1,224.999996423721,8|0,3:0|0:0,0:0:0:0:
|
||||
239,319,94985,2,0,P|218:357|173:373,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
34,344,95207,37,4,0:0:0:0:
|
||||
21,309,95318,5,0,0:0:0:0:
|
||||
14,265,95429,5,8,3:0:0:0:
|
||||
27,223,95540,5,0,0:0:0:0:
|
||||
54,179,95651,5,4,0:0:0:0:
|
||||
94,147,95762,5,0,0:0:0:0:
|
||||
160,126,95873,5,0,3:0:0:0:
|
||||
231,149,95984,5,0,0:0:0:0:
|
||||
273,221,96096,5,4,0:0:0:0:
|
||||
353,262,96207,5,0,0:0:0:0:
|
||||
446,234,96318,5,8,3:0:0:0:
|
||||
501,145,96429,5,0,0:0:0:0:
|
||||
450,36,96540,5,4,0:0:0:0:
|
||||
239,44,96762,5,0,3:0:0:0:
|
||||
192,103,96873,1,0,0:0:0:0:
|
||||
118,118,96984,1,4,0:0:0:0:
|
||||
44,100,97096,1,0,0:0:0:0:
|
||||
5,36,97207,1,8,3:0:0:0:
|
||||
17,19,97429,37,4,0:0:0:0:
|
||||
146,51,97540,1,0,0:0:0:0:
|
||||
29,122,97651,2,0,L|39:193,1,56.2499991059302,0|0,3:0|0:0,0:0:0:0:
|
||||
44,197,97874,6,0,P|100:231|176:201,1,112.500002503395,4|0,0:0|0:0,0:0:0:0:
|
||||
301,160,98096,38,0,P|329:140|382:137,1,84.3750018775463,8|0,3:0|0:0,0:0:0:0:
|
||||
398,147,98318,6,0,B|431:187|431:187|415:279,1,112.500002503395,4|0,0:0|0:0,0:0:0:0:
|
||||
265,371,98540,38,0,L|180:361,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
127,202,98762,2,0,L|141:113,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
193,260,98985,2,0,P|144:291|68:278,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||
91,290,99207,2,0,L|79:373,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
20,184,99429,6,0,B|4:141|4:141|27:66,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||
23,78,99651,2,0,L|109:91,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
271,74,99874,2,0,P|254:31|222:12,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||
186,180,100096,2,0,P|232:175|260:147,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
132,63,100318,37,0,3:0:0:0:
|
||||
253,157,100540,1,4,0:0:0:0:
|
||||
285,167,100651,1,0,0:0:0:0:
|
||||
357,129,100762,5,8,3:0:0:0:
|
||||
389,139,100873,1,0,0:0:0:0:
|
||||
422,148,100985,2,0,P|407:200|416:233,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
459,377,101207,38,0,P|472:333|459:295,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
398,242,101429,2,0,L|314:257,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
165,354,101651,2,0,P|116:332|211:264,1,224.999996423721,8|0,3:0|0:0,0:0:0:0:
|
||||
302,165,102096,6,0,L|292:89,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
392,91,102318,2,0,L|382:14,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
192,229,102540,38,0,L|212:136,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||
107,172,102762,2,0,L|127:79,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
314,332,102985,6,0,L|305:278,1,37.4999994039535,0|0,3:0|0:0,0:0:0:0:
|
||||
343,345,103096,2,0,L|334:291,1,37.4999994039535,0|0,0:0|0:0,0:0:0:0:
|
||||
370,358,103207,2,0,L|361:304,1,37.4999994039535,4|0,0:0|0:0,0:0:0:0:
|
||||
380,117,103429,38,0,L|374:75,3,37.4999994039535,8|0|0|0,3:0|0:0|0:0|0:0,0:0:0:0:
|
||||
444,166,103651,2,0,P|417:188|346:191,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
392,2,103874,2,0,P|424:14|462:74,1,74.999998807907,4|0,3:0|0:0,0:0:0:0:
|
||||
271,129,104096,2,0,P|265:94|298:31,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
505,113,104318,5,8,3:0:0:0:
|
||||
269,217,104540,38,0,L|216:216,3,37.4999994039535,0|0|0|0,3:0|3:0|3:0|3:0,0:0:0:0:
|
||||
360,220,104762,1,0,3:0:0:0:
|
||||
296,384,104874,1,4,3:0:0:0:
|
||||
102,307,105096,5,0,0:0:0:0:
|
||||
102,307,105207,2,0,B|206:381|258:244|374:330,1,269.999987468719,12|0,3:0|0:0,0:0:0:0:
|
||||
439,319,105651,6,0,P|379:336|396:236,1,168.750003755093,0|0,3:0|0:0,0:0:0:0:
|
||||
373,258,106096,6,0,P|374:315|443:283,1,112.500002503395,8|0,3:0|0:0,0:0:0:0:
|
||||
420,323,106651,37,0,0:0:0:0:
|
||||
469,245,106763,1,4,0:0:0:0:
|
||||
508,322,106874,1,0,0:0:0:0:
|
||||
379,245,106985,1,8,3:0:0:0:
|
||||
483,105,107207,6,0,L|474:40,3,56.2500012516975,4|0|0|0,3:0|0:0|0:0|0:0,0:0:0:0:
|
||||
462,30,107429,38,0,P|401:56|319:25,1,149.999997615814,0|0,3:0|0:0,0:0:0:0:
|
||||
272,120,107874,2,0,P|184:91|118:125,1,149.999997615814,8|4,3:0|0:0,0:0:0:0:
|
||||
103,213,108207,2,0,B|128:232|128:232|269:200,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||
393,187,108540,2,0,L|385:286,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||
333,338,108763,1,8,3:0:0:0:
|
||||
467,307,108874,6,0,L|509:297,2,37.4999994039535,0|0|4,0:0|0:0|0:0,0:0:0:0:
|
||||
409,380,109096,1,0,0:0:0:0:
|
||||
300,257,109207,38,0,P|279:218|281:171,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||
401,118,109429,1,4,0:0:0:0:
|
||||
401,118,109651,6,0,L|315:109,1,74.999998807907,8|4,3:0|0:0,0:0:0:0:
|
||||
256,15,109985,37,0,0:0:0:0:
|
||||
175,121,110096,2,0,P|162:60|109:16,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||
128,26,110318,2,0,P|106:86|47:122,1,112.49999821186,0|0,0:0|0:0,0:0:0:0:
|
||||
69,114,110540,2,0,P|135:105|185:131,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||
160,223,110762,6,0,B|142:230|142:230|120:228|120:228|95:239|95:239|71:235|71:235|49:244|49:244|22:249,1,112.500002503395,4|0,0:0|0:0,0:0:0:0:
|
||||
193,334,110985,38,0,P|216:310|242:301,1,56.2500012516975,0|0,3:0|0:0,0:0:0:0:
|
||||
335,325,111207,2,0,P|366:353|378:379,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||
273,383,111429,2,0,L|304:213,1,168.750003755093,0|0,0:0|0:0,0:0:0:0:
|
||||
383,255,111874,22,0,B|422:273|422:273|476:273,1,74.999998807907,8|0,3:0|3:0,0:0:0:0:
|
||||
209,219,112096,2,0,B|169:221|169:221|131:206,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||
403,147,112318,2,0,B|352:114|352:114|337:43|337:43|295:109|295:109|234:115,1,269.999987468719,8|0,3:0|0:0,0:0:0:0:
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.IO;
|
||||
@@ -18,9 +19,23 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
public class StackingTest
|
||||
{
|
||||
[Test]
|
||||
public void TestStackingEdgeCaseOne()
|
||||
public void TestStacking()
|
||||
{
|
||||
using (var stream = new MemoryStream(@"
|
||||
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(beatmap_data)))
|
||||
using (var reader = new LineBufferedReader(stream))
|
||||
{
|
||||
var beatmap = Decoder.GetDecoder<Beatmap>(reader).Decode(reader);
|
||||
var converted = new TestWorkingBeatmap(beatmap).GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Array.Empty<Mod>());
|
||||
|
||||
var objects = converted.HitObjects.ToList();
|
||||
|
||||
// The last hitobject triggers the stacking
|
||||
for (int i = 0; i < objects.Count - 1; i++)
|
||||
Assert.AreEqual(0, ((OsuHitObject)objects[i]).StackHeight);
|
||||
}
|
||||
}
|
||||
|
||||
private const string beatmap_data = @"
|
||||
osu file format v14
|
||||
|
||||
[General]
|
||||
@@ -47,65 +62,6 @@ SliderTickRate:0.5
|
||||
311,185,218471,2,0,L|325:209,1,25
|
||||
311,185,218671,2,0,L|304:212,1,25
|
||||
311,185,240271,5,0,0:0:0:0:
|
||||
"u8.ToArray()))
|
||||
using (var reader = new LineBufferedReader(stream))
|
||||
{
|
||||
var beatmap = Decoder.GetDecoder<Beatmap>(reader).Decode(reader);
|
||||
var converted = new TestWorkingBeatmap(beatmap).GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Array.Empty<Mod>());
|
||||
|
||||
var objects = converted.HitObjects.ToList();
|
||||
|
||||
// The last hitobject triggers the stacking
|
||||
for (int i = 0; i < objects.Count - 1; i++)
|
||||
Assert.AreEqual(0, ((OsuHitObject)objects[i]).StackHeight);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestStackingEdgeCaseTwo()
|
||||
{
|
||||
using (var stream = new MemoryStream(@"
|
||||
osu file format v14
|
||||
// extracted from https://osu.ppy.sh/beatmapsets/365006#osu/801165
|
||||
|
||||
[General]
|
||||
StackLeniency: 0.2
|
||||
|
||||
[Difficulty]
|
||||
HPDrainRate:6
|
||||
CircleSize:4
|
||||
OverallDifficulty:8
|
||||
ApproachRate:9.3
|
||||
SliderMultiplier:2
|
||||
SliderTickRate:1
|
||||
|
||||
[TimingPoints]
|
||||
5338,444.444444444444,4,2,0,50,1,0
|
||||
82893,-76.9230769230769,4,2,8,50,0,0
|
||||
85115,-76.9230769230769,4,2,0,50,0,0
|
||||
85337,-100,4,2,8,60,0,0
|
||||
85893,-100,4,2,7,60,0,0
|
||||
86226,-100,4,2,8,60,0,0
|
||||
88893,-58.8235294117647,4,1,8,70,0,1
|
||||
|
||||
[HitObjects]
|
||||
427,124,84226,1,0,3:0:0:0:
|
||||
427,124,84337,1,0,3:0:0:0:
|
||||
427,124,84449,1,8,0:0:0:0:
|
||||
"u8.ToArray()))
|
||||
using (var reader = new LineBufferedReader(stream))
|
||||
{
|
||||
var beatmap = Decoder.GetDecoder<Beatmap>(reader).Decode(reader);
|
||||
var converted = new TestWorkingBeatmap(beatmap).GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Array.Empty<Mod>());
|
||||
|
||||
var objects = converted.HitObjects.ToList();
|
||||
|
||||
Assert.That(objects, Has.Count.EqualTo(3));
|
||||
|
||||
// The last hitobject triggers the stacking
|
||||
for (int i = 0; i < objects.Count - 1; i++)
|
||||
Assert.AreEqual(0, ((OsuHitObject)objects[i]).StackHeight);
|
||||
}
|
||||
}
|
||||
";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
// 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 System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Replays;
|
||||
using osu.Game.Rulesets.Replays;
|
||||
using osu.Game.Tests.Visual;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
[HeadlessTest]
|
||||
public partial class TestSceneAutoGeneration : OsuTestScene
|
||||
{
|
||||
[TestCase(-1, true)]
|
||||
[TestCase(0, false)]
|
||||
[TestCase(1, false)]
|
||||
public void TestAlternating(double offset, bool shouldAlternate)
|
||||
{
|
||||
const double first_object_time = 1000;
|
||||
double secondObjectTime = first_object_time + AutoGenerator.KEY_UP_DELAY + OsuAutoGenerator.MIN_FRAME_SEPARATION_FOR_ALTERNATING + offset;
|
||||
|
||||
var beatmap = new OsuBeatmap();
|
||||
beatmap.HitObjects.Add(new HitCircle { StartTime = first_object_time });
|
||||
beatmap.HitObjects.Add(new HitCircle { StartTime = secondObjectTime });
|
||||
|
||||
var generated = new OsuAutoGenerator(beatmap, []).Generate();
|
||||
var frames = generated.Frames.OfType<OsuReplayFrame>().ToList();
|
||||
|
||||
Assert.That(frames.Exists(f => f.Time == first_object_time && f.Actions.SingleOrDefault() == OsuAction.LeftButton));
|
||||
Assert.That(frames.Exists(f => f.Time == first_object_time + AutoGenerator.KEY_UP_DELAY && !f.Actions.Any()));
|
||||
|
||||
Assert.That(frames.Exists(f => f.Time == secondObjectTime && f.Actions.SingleOrDefault() == (shouldAlternate ? OsuAction.RightButton : OsuAction.LeftButton)));
|
||||
Assert.That(frames.Exists(f => f.Time == secondObjectTime + AutoGenerator.KEY_UP_DELAY && !f.Actions.Any()));
|
||||
}
|
||||
|
||||
[TestCase(300)]
|
||||
[TestCase(600)]
|
||||
[TestCase(1200)]
|
||||
public void TestAlternatingSpecificBPM(double bpm)
|
||||
{
|
||||
const double first_object_time = 1000;
|
||||
double secondObjectTime = first_object_time + 60000 / bpm;
|
||||
|
||||
var beatmap = new OsuBeatmap();
|
||||
beatmap.HitObjects.Add(new HitCircle { StartTime = first_object_time });
|
||||
beatmap.HitObjects.Add(new HitCircle { StartTime = secondObjectTime });
|
||||
|
||||
var generated = new OsuAutoGenerator(beatmap, []).Generate();
|
||||
var frames = generated.Frames.OfType<OsuReplayFrame>().ToList();
|
||||
|
||||
Assert.That(frames.Exists(f => f.Time == first_object_time && f.Actions.SingleOrDefault() == OsuAction.LeftButton));
|
||||
Assert.That(frames.Exists(f => f.Time == first_object_time + AutoGenerator.KEY_UP_DELAY && !f.Actions.Any()));
|
||||
|
||||
Assert.That(frames.Exists(f => f.Time == secondObjectTime && f.Actions.SingleOrDefault() == OsuAction.RightButton));
|
||||
Assert.That(frames.Exists(f => f.Time == secondObjectTime + AutoGenerator.KEY_UP_DELAY && !f.Actions.Any()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
Debug.Assert(drawableHitObject.HitObject.HitWindows != null);
|
||||
|
||||
double delay = drawableHitObject.HitObject.StartTime - (drawableHitObject.HitObject.HitWindows.WindowFor(HitResult.Miss) + RNG.Next(0, 300)) - Time.Current;
|
||||
scheduledTasks.Add(Scheduler.AddDelayed(drawableHitObject.TriggerJudgement, delay));
|
||||
scheduledTasks.Add(Scheduler.AddDelayed(() => drawableHitObject.TriggerJudgement(), delay));
|
||||
|
||||
return drawableHitObject;
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
||||
continue;
|
||||
|
||||
double endTime = stackBaseObject.GetEndTime();
|
||||
float stackThreshold = calculateStackThreshold(beatmap, objectN);
|
||||
double stackThreshold = objectN.TimePreempt * beatmap.StackLeniency;
|
||||
|
||||
if (objectN.StartTime - endTime > stackThreshold)
|
||||
// We are no longer within stacking range of the next object.
|
||||
@@ -136,7 +136,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
||||
OsuHitObject objectI = hitObjects[i];
|
||||
if (objectI.StackHeight != 0 || objectI is Spinner) continue;
|
||||
|
||||
float stackThreshold = calculateStackThreshold(beatmap, objectI);
|
||||
double stackThreshold = objectI.TimePreempt * beatmap.StackLeniency;
|
||||
|
||||
/* If this object is a hitcircle, then we enter this "special" case.
|
||||
* It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider.
|
||||
@@ -151,10 +151,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
||||
|
||||
double endTime = objectN.GetEndTime();
|
||||
|
||||
// truncation to integer is required to match stable
|
||||
// compare https://github.com/peppy/osu-stable-reference/blob/08e3dafd525934cf48880b08e91c24ce4ad8b761/osu!/GameplayElements/HitObjectManager.cs#L1725
|
||||
// - both quantities being subtracted there are integers
|
||||
if ((int)objectI.StartTime - (int)endTime > stackThreshold)
|
||||
if (objectI.StartTime - endTime > stackThreshold)
|
||||
// We are no longer within stacking range of the previous object.
|
||||
break;
|
||||
|
||||
@@ -235,7 +232,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
||||
|
||||
for (int j = i + 1; j < hitObjects.Count; j++)
|
||||
{
|
||||
float stackThreshold = calculateStackThreshold(beatmap, hitObjects[i]);
|
||||
double stackThreshold = hitObjects[i].TimePreempt * beatmap.StackLeniency;
|
||||
|
||||
if (hitObjects[j].StartTime - stackThreshold > startTime)
|
||||
break;
|
||||
@@ -267,17 +264,5 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Truncation of <see cref="OsuHitObject.TimePreempt"/> to <see cref="int"/>, as well as keeping the result as <see cref="float"/>, are both done
|
||||
/// <a href="https://github.com/peppy/osu-stable-reference/blob/08e3dafd525934cf48880b08e91c24ce4ad8b761/osu!/GameplayElements/HitObjectManager.cs#L1652">
|
||||
/// for the purposes of stable compatibility
|
||||
/// </a>.
|
||||
/// Note that for top-level objects <see cref="OsuHitObject.TimePreempt"/> is supposed to be integral anyway;
|
||||
/// see <see cref="OsuHitObject.ApplyDefaultsToSelf"/> using <see cref="IBeatmapDifficultyInfo.DifficultyRangeInt"/> when calculating it.
|
||||
/// Slider ticks and end circles are the exception to that, but they do not matter for stacking.
|
||||
/// </remarks>
|
||||
private static float calculateStackThreshold(IBeatmap beatmap, OsuHitObject hitObject)
|
||||
=> (int)hitObject.TimePreempt * beatmap.StackLeniency;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Utils;
|
||||
@@ -38,16 +37,13 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
[Resolved]
|
||||
private IEditorChangeHandler? changeHandler { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private EditorBeatmap editorBeatmap { get; set; } = null!;
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private IDistanceSnapProvider? snapProvider { get; set; }
|
||||
|
||||
private BindableList<HitObject> selectedItems { get; } = new BindableList<HitObject>();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
private void load(EditorBeatmap editorBeatmap)
|
||||
{
|
||||
selectedItems.BindTo(editorBeatmap.SelectedHitObjects);
|
||||
}
|
||||
@@ -57,22 +53,15 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
base.LoadComplete();
|
||||
|
||||
selectedItems.CollectionChanged += (_, __) => updateState();
|
||||
editorBeatmap.HitObjectUpdated += hitObjectUpdated;
|
||||
updateState();
|
||||
}
|
||||
|
||||
private void hitObjectUpdated(HitObject hitObject)
|
||||
{
|
||||
if (selectedMovableObjects.Contains(hitObject))
|
||||
updateState();
|
||||
}
|
||||
|
||||
private void updateState()
|
||||
{
|
||||
var quad = GeometryUtils.GetSurroundingQuad(selectedMovableObjects);
|
||||
|
||||
CanScaleX.Value = Precision.DefinitelyBigger(quad.Width, 0);
|
||||
CanScaleY.Value = Precision.DefinitelyBigger(quad.Height, 0);
|
||||
CanScaleX.Value = quad.Width > 0;
|
||||
CanScaleY.Value = quad.Height > 0;
|
||||
CanScaleDiagonally.Value = CanScaleX.Value && CanScaleY.Value;
|
||||
CanScaleFromPlayfieldOrigin.Value = selectedMovableObjects.Any();
|
||||
IsScalingSlider.Value = selectedMovableObjects.Count() == 1 && selectedMovableObjects.First() is Slider;
|
||||
@@ -350,13 +339,5 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
PathControlPointTypes = (hitObject as IHasPath)?.Path.ControlPoints.Select(p => p.Type).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (editorBeatmap.IsNotNull())
|
||||
editorBeatmap.HitObjectUpdated -= hitObjectUpdated;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,10 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
public partial class PolygonGenerationPopover : OsuPopover
|
||||
{
|
||||
private FormSliderBar<double> distanceSnapInput { get; set; } = null!;
|
||||
private FormSliderBar<int> offsetAngleInput { get; set; } = null!;
|
||||
private FormSliderBar<int> repeatCountInput { get; set; } = null!;
|
||||
private FormSliderBar<int> pointInput { get; set; } = null!;
|
||||
private SliderWithTextBoxInput<double> distanceSnapInput = null!;
|
||||
private SliderWithTextBoxInput<int> offsetAngleInput = null!;
|
||||
private SliderWithTextBoxInput<int> repeatCountInput = null!;
|
||||
private SliderWithTextBoxInput<int> pointInput = null!;
|
||||
private RoundedButton commitButton = null!;
|
||||
|
||||
private readonly List<HitCircle> insertedCircles = new List<HitCircle>();
|
||||
@@ -64,12 +64,11 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
Width = 220,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Spacing = new Vector2(5),
|
||||
Spacing = new Vector2(20),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
distanceSnapInput = new FormSliderBar<double>
|
||||
distanceSnapInput = new SliderWithTextBoxInput<double>("Distance snap:")
|
||||
{
|
||||
Caption = "Distance snap",
|
||||
Current = new BindableNumber<double>(1)
|
||||
{
|
||||
MinValue = 0.1,
|
||||
@@ -77,40 +76,37 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
Precision = 0.1,
|
||||
Value = ((OsuHitObjectComposer)composer).DistanceSnapProvider.DistanceSpacingMultiplier.Value,
|
||||
},
|
||||
TabbableContentContainer = this
|
||||
Instantaneous = true
|
||||
},
|
||||
offsetAngleInput = new FormSliderBar<int>
|
||||
offsetAngleInput = new SliderWithTextBoxInput<int>("Offset angle:")
|
||||
{
|
||||
Caption = "Offset angle",
|
||||
Current = new BindableNumber<int>
|
||||
{
|
||||
MinValue = 0,
|
||||
MaxValue = 180,
|
||||
Precision = 1
|
||||
},
|
||||
TabbableContentContainer = this
|
||||
Instantaneous = true
|
||||
},
|
||||
repeatCountInput = new FormSliderBar<int>
|
||||
repeatCountInput = new SliderWithTextBoxInput<int>("Repeats:")
|
||||
{
|
||||
Caption = "Repeats",
|
||||
Current = new BindableNumber<int>(1)
|
||||
{
|
||||
MinValue = 1,
|
||||
MaxValue = 10,
|
||||
Precision = 1
|
||||
},
|
||||
TabbableContentContainer = this
|
||||
Instantaneous = true
|
||||
},
|
||||
pointInput = new FormSliderBar<int>
|
||||
pointInput = new SliderWithTextBoxInput<int>("Vertices:")
|
||||
{
|
||||
Caption = "Vertices",
|
||||
Current = new BindableNumber<int>(3)
|
||||
{
|
||||
MinValue = 3,
|
||||
MaxValue = 32,
|
||||
Precision = 1,
|
||||
},
|
||||
TabbableContentContainer = this
|
||||
Instantaneous = true
|
||||
},
|
||||
commitButton = new RoundedButton
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
private BindableNumber<float> xBindable = null!;
|
||||
private BindableNumber<float> yBindable = null!;
|
||||
|
||||
private FormSliderBar<float> xInput { get; set; } = null!;
|
||||
private SliderWithTextBoxInput<float> xInput = null!;
|
||||
private OsuCheckbox relativeCheckbox = null!;
|
||||
|
||||
public PreciseMovementPopover()
|
||||
@@ -52,31 +52,31 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
Width = 220,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Spacing = new Vector2(5),
|
||||
Spacing = new Vector2(20),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
xInput = new FormSliderBar<float>
|
||||
xInput = new SliderWithTextBoxInput<float>("X:")
|
||||
{
|
||||
Caption = "X",
|
||||
Current = xBindable = new BindableNumber<float>
|
||||
{
|
||||
Precision = 1,
|
||||
},
|
||||
TabbableContentContainer = this
|
||||
Instantaneous = true,
|
||||
TabbableContentContainer = this,
|
||||
},
|
||||
new FormSliderBar<float>
|
||||
new SliderWithTextBoxInput<float>("Y:")
|
||||
{
|
||||
Caption = "Y",
|
||||
Current = yBindable = new BindableNumber<float>
|
||||
{
|
||||
Precision = 1,
|
||||
},
|
||||
TabbableContentContainer = this
|
||||
Instantaneous = true,
|
||||
TabbableContentContainer = this,
|
||||
},
|
||||
relativeCheckbox = new OsuCheckbox(false)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
LabelText = "Relative movement"
|
||||
LabelText = "Relative movement",
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
|
||||
private readonly Bindable<PreciseRotationInfo> rotationInfo = new Bindable<PreciseRotationInfo>(new PreciseRotationInfo(0, EditorOrigin.GridCentre));
|
||||
|
||||
private FormSliderBar<float> angleInput { get; set; } = null!;
|
||||
private SliderWithTextBoxInput<float> angleInput = null!;
|
||||
private EditorRadioButtonCollection rotationOrigin = null!;
|
||||
|
||||
private RadioButton gridCentreButton = null!;
|
||||
@@ -54,12 +54,11 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
Width = 220,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Spacing = new Vector2(5),
|
||||
Spacing = new Vector2(20),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
angleInput = new FormSliderBar<float>
|
||||
angleInput = new SliderWithTextBoxInput<float>("Angle (degrees):")
|
||||
{
|
||||
Caption = "Angle (degrees)",
|
||||
Current = new BindableNumber<float>
|
||||
{
|
||||
MinValue = -360,
|
||||
@@ -67,7 +66,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
Precision = 1
|
||||
},
|
||||
KeyboardStep = 1f,
|
||||
TabbableContentContainer = this
|
||||
Instantaneous = true
|
||||
},
|
||||
rotationOrigin = new EditorRadioButtonCollection
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
|
||||
private readonly Bindable<PreciseScaleInfo> scaleInfo = new Bindable<PreciseScaleInfo>(new PreciseScaleInfo(1, EditorOrigin.GridCentre, true, true));
|
||||
|
||||
private FormSliderBar<float> scaleInput { get; set; } = null!;
|
||||
private SliderWithTextBoxInput<float> scaleInput = null!;
|
||||
private BindableNumber<float> scaleInputBindable = null!;
|
||||
private EditorRadioButtonCollection scaleOrigin = null!;
|
||||
|
||||
@@ -66,12 +66,11 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
Width = 220,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Spacing = new Vector2(5),
|
||||
Spacing = new Vector2(20),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
scaleInput = new FormSliderBar<float>
|
||||
scaleInput = new SliderWithTextBoxInput<float>("Scale:")
|
||||
{
|
||||
Caption = "Scale",
|
||||
Current = scaleInputBindable = new BindableNumber<float>
|
||||
{
|
||||
MinValue = 0.05f,
|
||||
@@ -81,7 +80,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
Default = 1,
|
||||
},
|
||||
KeyboardStep = 0.01f,
|
||||
TabbableContentContainer = this
|
||||
Instantaneous = true
|
||||
},
|
||||
scaleOrigin = new EditorRadioButtonCollection
|
||||
{
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
[SettingSource(
|
||||
"Max size at combo",
|
||||
"The combo count at which the cursor reaches its maximum size",
|
||||
SettingControlType = typeof(SettingsSlider<int, MaxSizeComboSlider>)
|
||||
SettingControlType = typeof(SettingsSlider<int, RoundedSliderBar<int>>)
|
||||
)]
|
||||
public BindableInt MaxSizeComboCount { get; } = new BindableInt(50)
|
||||
{
|
||||
@@ -85,12 +85,4 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
cursor.ModScaleAdjust.Value = (float)Interpolation.Lerp(cursor.ModScaleAdjust.Value, currentSize, Math.Clamp(cursor.Time.Elapsed / TRANSITION_DURATION, 0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
public partial class MaxSizeComboSlider : RoundedSliderBar<int>
|
||||
{
|
||||
public MaxSizeComboSlider()
|
||||
{
|
||||
KeyboardStep = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
// 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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
@@ -84,8 +82,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
}
|
||||
}
|
||||
|
||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModTargetPractice)).ToArray();
|
||||
|
||||
protected override void ApplySettings(BeatmapDifficulty difficulty)
|
||||
{
|
||||
base.ApplySettings(difficulty);
|
||||
|
||||
@@ -27,10 +27,8 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
|
||||
public override LocalisableString Description => "Burn the notes into your memory.";
|
||||
|
||||
/// <remarks>
|
||||
/// Incompatible with all mods that directly modify or indirectly depend on <see cref="OsuHitObject.TimePreempt"/>, or alter the behaviour of approach circles.
|
||||
/// </remarks>
|
||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModApproachDifferent), typeof(OsuModTransform), typeof(OsuModDepth), typeof(OsuModHidden) }).ToArray();
|
||||
//Alters the transforms of the approach circles, breaking the effects of these mods.
|
||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModApproachDifferent), typeof(OsuModTransform), typeof(OsuModDepth) }).ToArray();
|
||||
|
||||
public override ModType Type => ModType.Fun;
|
||||
|
||||
@@ -59,25 +57,16 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
|
||||
void applyFadeInAdjustment(OsuHitObject osuObject)
|
||||
{
|
||||
if (osuObject is not Spinner)
|
||||
osuObject.TimePreempt += osuObject.StartTime - lastNewComboTime;
|
||||
|
||||
int repeatCount = 0;
|
||||
osuObject.TimePreempt += osuObject.StartTime - lastNewComboTime;
|
||||
|
||||
foreach (var nested in osuObject.NestedHitObjects.OfType<OsuHitObject>())
|
||||
{
|
||||
switch (nested)
|
||||
{
|
||||
// Freezing the SliderTicks doesnt play well with snaking sliders
|
||||
//Freezing the SliderTicks doesnt play well with snaking sliders
|
||||
case SliderTick:
|
||||
break;
|
||||
|
||||
//SliderRepeat wont layer correctly if preempt is changed.
|
||||
case SliderRepeat:
|
||||
if (repeatCount > 2)
|
||||
break;
|
||||
|
||||
applyFadeInAdjustment(nested);
|
||||
repeatCount++;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
public override LocalisableString Description => @"Play with no approach circles and fading circles/sliders.";
|
||||
public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.06 : 1;
|
||||
|
||||
public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn), typeof(OsuModDepth), typeof(OsuModFreezeFrame) };
|
||||
public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn), typeof(OsuModDepth) };
|
||||
|
||||
public const double FADE_IN_DURATION_MULTIPLIER = 0.4;
|
||||
public const double FADE_OUT_DURATION_MULTIPLIER = 0.3;
|
||||
|
||||
@@ -48,8 +48,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
typeof(OsuModSpunOut),
|
||||
typeof(OsuModStrictTracking),
|
||||
typeof(OsuModSuddenDeath),
|
||||
typeof(OsuModDepth),
|
||||
typeof(OsuModDifficultyAdjust),
|
||||
typeof(OsuModDepth)
|
||||
}).ToArray();
|
||||
|
||||
[SettingSource("Seed", "Use a custom seed instead of a random one", SettingControlType = typeof(SettingsNumberBox))]
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
public override string Name => "Traceable";
|
||||
public override string Acronym => "TC";
|
||||
public override IconUsage? Icon => OsuIcon.ModTraceable;
|
||||
public override ModType Type => ModType.DifficultyIncrease;
|
||||
public override ModType Type => ModType.Fun;
|
||||
public override LocalisableString Description => "Put your faith in the approach circles...";
|
||||
public override double ScoreMultiplier => 1;
|
||||
public override bool Ranked => true;
|
||||
|
||||
@@ -171,7 +171,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
{
|
||||
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
||||
|
||||
TimePreempt = IBeatmapDifficultyInfo.DifficultyRangeInt(difficulty.ApproachRate, PREEMPT_RANGE);
|
||||
TimePreempt = (float)IBeatmapDifficultyInfo.DifficultyRange(difficulty.ApproachRate, PREEMPT_RANGE);
|
||||
|
||||
// Preempt time can go below 450ms. Normally, this is achieved via the DT mod which uniformly speeds up all animations game wide regardless of AR.
|
||||
// This uniform speedup is hard to match 1:1, however we can at least make AR>10 (via mods) feel good by extending the upper linear function above.
|
||||
|
||||
@@ -175,7 +175,7 @@ namespace osu.Game.Rulesets.Osu
|
||||
new OsuModHardRock(),
|
||||
new MultiMod(new OsuModSuddenDeath(), new OsuModPerfect()),
|
||||
new MultiMod(new OsuModDoubleTime(), new OsuModNightcore()),
|
||||
new MultiMod(new OsuModHidden(), new OsuModTraceable()),
|
||||
new OsuModHidden(),
|
||||
new MultiMod(new OsuModFlashlight(), new OsuModBlinds()),
|
||||
new OsuModStrictTracking(),
|
||||
new OsuModAccuracyChallenge(),
|
||||
@@ -209,6 +209,7 @@ namespace osu.Game.Rulesets.Osu
|
||||
new OsuModSpinIn(),
|
||||
new MultiMod(new OsuModGrow(), new OsuModDeflate()),
|
||||
new MultiMod(new ModWindUp(), new ModWindDown()),
|
||||
new OsuModTraceable(),
|
||||
new OsuModBarrelRoll(),
|
||||
new OsuModApproachDifferent(),
|
||||
new OsuModMuted(),
|
||||
@@ -286,24 +287,19 @@ namespace osu.Game.Rulesets.Osu
|
||||
|
||||
public override IRulesetConfigManager CreateConfig(SettingsStore? settings) => new OsuRulesetConfigManager(settings, RulesetInfo);
|
||||
|
||||
public override IEnumerable<HitResult> GetValidHitResults()
|
||||
protected override IEnumerable<HitResult> GetValidHitResults()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
HitResult.Great,
|
||||
HitResult.Ok,
|
||||
HitResult.Meh,
|
||||
HitResult.Miss,
|
||||
|
||||
HitResult.LargeTickHit,
|
||||
HitResult.LargeTickMiss,
|
||||
HitResult.SmallTickHit,
|
||||
HitResult.SmallTickMiss,
|
||||
HitResult.SliderTailHit,
|
||||
HitResult.SmallBonus,
|
||||
HitResult.LargeBonus,
|
||||
HitResult.IgnoreHit,
|
||||
HitResult.IgnoreMiss,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -425,8 +421,7 @@ namespace osu.Game.Rulesets.Osu
|
||||
Description = "Affects how early objects appear on screen relative to their hit time.",
|
||||
AdditionalMetrics =
|
||||
[
|
||||
new RulesetBeatmapAttribute.AdditionalMetric("Approach time",
|
||||
LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRangeInt(effectiveDifficulty.ApproachRate, OsuHitObject.PREEMPT_RANGE):#,0.##} ms"))
|
||||
new RulesetBeatmapAttribute.AdditionalMetric("Approach time", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRange(effectiveDifficulty.ApproachRate, OsuHitObject.PREEMPT_RANGE):#,0.##} ms"))
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@ namespace osu.Game.Rulesets.Osu.Replays
|
||||
{
|
||||
public class OsuAutoGenerator : OsuAutoGeneratorBase
|
||||
{
|
||||
public const double MIN_FRAME_SEPARATION_FOR_ALTERNATING = 266;
|
||||
|
||||
public new OsuBeatmap Beatmap => (OsuBeatmap)base.Beatmap;
|
||||
|
||||
#region Parameters
|
||||
@@ -247,7 +245,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
||||
double timeDifference = ApplyModsToTimeDelta(lastFrame.Time, h.StartTime);
|
||||
OsuReplayFrame? lastLastFrame = Frames.Count >= 2 ? (OsuReplayFrame)Frames[^2] : null;
|
||||
|
||||
if (timeDifference >= 0)
|
||||
if (timeDifference > 0)
|
||||
{
|
||||
// If the last frame is a key-up frame and there has been no wait period, adjust the last frame's position such that it begins eased movement instantaneously.
|
||||
if (lastLastFrame != null && lastFrame is OsuKeyUpReplayFrame && !hasWaited)
|
||||
@@ -268,7 +266,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
||||
}
|
||||
|
||||
// Start alternating once the time separation is too small (faster than ~225BPM).
|
||||
if (timeDifference >= 0 && timeDifference < MIN_FRAME_SEPARATION_FOR_ALTERNATING)
|
||||
if (timeDifference > 0 && timeDifference < 266)
|
||||
buttonIndex++;
|
||||
else
|
||||
buttonIndex = 0;
|
||||
|
||||
@@ -103,9 +103,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
leaderboard.Origin = Anchor.BottomLeft;
|
||||
leaderboard.Position = pos;
|
||||
}
|
||||
|
||||
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||
d.UsesFixedAnchor = true;
|
||||
})
|
||||
{
|
||||
Children = new Drawable[]
|
||||
|
||||
@@ -49,18 +49,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
/// </summary>
|
||||
protected bool AllowPartRotation { get; set; }
|
||||
|
||||
private Vector2 cursorScale = Vector2.One;
|
||||
|
||||
public Vector2 CursorScale
|
||||
{
|
||||
get => cursorScale;
|
||||
set
|
||||
{
|
||||
cursorScale = value;
|
||||
Invalidate(Invalidation.DrawNode);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The trail part texture origin.
|
||||
/// </summary>
|
||||
@@ -198,7 +186,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
float distance = diff.Length;
|
||||
Vector2 direction = diff / distance;
|
||||
|
||||
float interval = Texture.DisplayWidth * CursorScale.X / 2.5f * IntervalMultiplier;
|
||||
float interval = Texture.DisplayWidth / 2.5f * IntervalMultiplier;
|
||||
float stopAt = distance - (AvoidDrawingNearCursor ? interval : 0);
|
||||
|
||||
for (float d = interval; d < stopAt; d += interval)
|
||||
@@ -245,7 +233,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
private float time;
|
||||
private float fadeExponent;
|
||||
private float angle;
|
||||
private Vector2 cursorScale;
|
||||
|
||||
private readonly TrailPart[] parts = new TrailPart[max_sprites];
|
||||
private Vector2 originPosition;
|
||||
@@ -266,7 +253,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
time = Source.time;
|
||||
fadeExponent = Source.FadeExponent;
|
||||
angle = Source.AllowPartRotation ? float.DegreesToRadians(Source.PartRotation) : 0;
|
||||
cursorScale = Source.cursorScale;
|
||||
|
||||
originPosition = Vector2.Zero;
|
||||
|
||||
@@ -321,9 +307,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
vertexBatch.Add(new TexturedTrailVertex
|
||||
{
|
||||
Position = rotateAround(
|
||||
new Vector2(
|
||||
part.Position.X - texture.DisplayWidth * originPosition.X * part.Scale.X * cursorScale.X,
|
||||
part.Position.Y + texture.DisplayHeight * (1 - originPosition.Y) * part.Scale.Y * cursorScale.Y),
|
||||
new Vector2(part.Position.X - texture.DisplayWidth * originPosition.X * part.Scale.X, part.Position.Y + texture.DisplayHeight * (1 - originPosition.Y) * part.Scale.Y),
|
||||
part.Position, sin, cos),
|
||||
TexturePosition = textureRect.BottomLeft,
|
||||
TextureRect = new Vector4(0, 0, 1, 1),
|
||||
@@ -334,10 +318,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
vertexBatch.Add(new TexturedTrailVertex
|
||||
{
|
||||
Position = rotateAround(
|
||||
new Vector2(
|
||||
part.Position.X + texture.DisplayWidth * (1 - originPosition.X) * part.Scale.X * cursorScale.X,
|
||||
part.Position.Y + texture.DisplayHeight * (1 - originPosition.Y) * part.Scale.Y * cursorScale.Y),
|
||||
part.Position, sin, cos),
|
||||
new Vector2(part.Position.X + texture.DisplayWidth * (1 - originPosition.X) * part.Scale.X,
|
||||
part.Position.Y + texture.DisplayHeight * (1 - originPosition.Y) * part.Scale.Y), part.Position, sin, cos),
|
||||
TexturePosition = textureRect.BottomRight,
|
||||
TextureRect = new Vector4(0, 0, 1, 1),
|
||||
Colour = DrawColourInfo.Colour.BottomRight.Linear,
|
||||
@@ -347,9 +329,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
vertexBatch.Add(new TexturedTrailVertex
|
||||
{
|
||||
Position = rotateAround(
|
||||
new Vector2(
|
||||
part.Position.X + texture.DisplayWidth * (1 - originPosition.X) * part.Scale.X * cursorScale.X,
|
||||
part.Position.Y - texture.DisplayHeight * originPosition.Y * part.Scale.Y * cursorScale.Y),
|
||||
new Vector2(part.Position.X + texture.DisplayWidth * (1 - originPosition.X) * part.Scale.X, part.Position.Y - texture.DisplayHeight * originPosition.Y * part.Scale.Y),
|
||||
part.Position, sin, cos),
|
||||
TexturePosition = textureRect.TopRight,
|
||||
TextureRect = new Vector4(0, 0, 1, 1),
|
||||
@@ -360,9 +340,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
vertexBatch.Add(new TexturedTrailVertex
|
||||
{
|
||||
Position = rotateAround(
|
||||
new Vector2(
|
||||
part.Position.X - texture.DisplayWidth * originPosition.X * part.Scale.X * cursorScale.X,
|
||||
part.Position.Y - texture.DisplayHeight * originPosition.Y * part.Scale.Y * cursorScale.Y),
|
||||
new Vector2(part.Position.X - texture.DisplayWidth * originPosition.X * part.Scale.X, part.Position.Y - texture.DisplayHeight * originPosition.Y * part.Scale.Y),
|
||||
part.Position, sin, cos),
|
||||
TexturePosition = textureRect.TopLeft,
|
||||
TextureRect = new Vector4(0, 0, 1, 1),
|
||||
|
||||
@@ -64,14 +64,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
var newScale = new Vector2(e.NewValue);
|
||||
|
||||
rippleVisualiser.CursorScale = newScale;
|
||||
updateTrailScale();
|
||||
cursorTrail.Scale = newScale;
|
||||
}, true);
|
||||
cursorTrail.OnSkinChanged += updateTrailScale;
|
||||
}
|
||||
|
||||
private void updateTrailScale()
|
||||
{
|
||||
if (cursorTrail.Drawable is CursorTrail trail) trail.CursorScale = new Vector2(ActiveCursor.CursorScale.Value);
|
||||
}
|
||||
|
||||
private int downCount;
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Graphics.UserInterfaceV2;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Overlays.Settings;
|
||||
using osu.Game.Rulesets.Osu.Configuration;
|
||||
@@ -29,34 +27,32 @@ namespace osu.Game.Rulesets.Osu.UI
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SettingsItemV2(new FormCheckBox
|
||||
new SettingsCheckbox
|
||||
{
|
||||
Caption = RulesetSettingsStrings.SnakingInSliders,
|
||||
LabelText = RulesetSettingsStrings.SnakingInSliders,
|
||||
Current = config.GetBindable<bool>(OsuRulesetSetting.SnakingInSliders)
|
||||
}),
|
||||
new SettingsItemV2(new FormCheckBox
|
||||
{
|
||||
Caption = RulesetSettingsStrings.SnakingOutSliders,
|
||||
Current = config.GetBindable<bool>(OsuRulesetSetting.SnakingOutSliders)
|
||||
})
|
||||
{
|
||||
ApplyClassicDefault = c => ((IHasCurrentValue<bool>)c).Current.Value = false,
|
||||
},
|
||||
new SettingsItemV2(new FormCheckBox
|
||||
new SettingsCheckbox
|
||||
{
|
||||
Caption = RulesetSettingsStrings.CursorTrail,
|
||||
ClassicDefault = false,
|
||||
LabelText = RulesetSettingsStrings.SnakingOutSliders,
|
||||
Current = config.GetBindable<bool>(OsuRulesetSetting.SnakingOutSliders)
|
||||
},
|
||||
new SettingsCheckbox
|
||||
{
|
||||
LabelText = RulesetSettingsStrings.CursorTrail,
|
||||
Current = config.GetBindable<bool>(OsuRulesetSetting.ShowCursorTrail)
|
||||
}),
|
||||
new SettingsItemV2(new FormCheckBox
|
||||
},
|
||||
new SettingsCheckbox
|
||||
{
|
||||
Caption = RulesetSettingsStrings.CursorRipples,
|
||||
LabelText = RulesetSettingsStrings.CursorRipples,
|
||||
Current = config.GetBindable<bool>(OsuRulesetSetting.ShowCursorRipples)
|
||||
}),
|
||||
new SettingsItemV2(new FormEnumDropdown<PlayfieldBorderStyle>
|
||||
},
|
||||
new SettingsEnumDropdown<PlayfieldBorderStyle>
|
||||
{
|
||||
Caption = RulesetSettingsStrings.PlayfieldBorderStyle,
|
||||
LabelText = RulesetSettingsStrings.PlayfieldBorderStyle,
|
||||
Current = config.GetBindable<PlayfieldBorderStyle>(OsuRulesetSetting.PlayfieldBorderStyle),
|
||||
}),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,9 +35,11 @@
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
</array>
|
||||
<key>XSAppIconAssets</key>
|
||||
<string>Assets.xcassets/AppIcon.appiconset</string>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
</plist>
|
||||
@@ -51,9 +51,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon
|
||||
spectatorList.Anchor = Anchor.BottomLeft;
|
||||
spectatorList.Origin = Anchor.TopLeft;
|
||||
}
|
||||
|
||||
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||
d.UsesFixedAnchor = true;
|
||||
})
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
|
||||
@@ -51,9 +51,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
|
||||
spectatorList.Origin = Anchor.TopLeft;
|
||||
spectatorList.Position = new Vector2(320, -280);
|
||||
}
|
||||
|
||||
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||
d.UsesFixedAnchor = true;
|
||||
})
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
|
||||
@@ -79,9 +79,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
|
||||
spectatorList.Origin = Anchor.TopLeft;
|
||||
spectatorList.Position = pos;
|
||||
}
|
||||
|
||||
foreach (var d in container.OfType<ISerialisableDrawable>())
|
||||
d.UsesFixedAnchor = true;
|
||||
})
|
||||
{
|
||||
new LegacyDefaultComboCounter(),
|
||||
|
||||
@@ -222,18 +222,15 @@ namespace osu.Game.Rulesets.Taiko
|
||||
|
||||
public override RulesetSettingsSubsection CreateSettings() => new TaikoSettingsSubsection(this);
|
||||
|
||||
public override IEnumerable<HitResult> GetValidHitResults()
|
||||
protected override IEnumerable<HitResult> GetValidHitResults()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
HitResult.Great,
|
||||
HitResult.Ok,
|
||||
HitResult.Miss,
|
||||
|
||||
HitResult.SmallBonus,
|
||||
HitResult.LargeBonus,
|
||||
HitResult.IgnoreHit,
|
||||
HitResult.IgnoreMiss,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Graphics.UserInterfaceV2;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Overlays.Settings;
|
||||
using osu.Game.Rulesets.Taiko.Configuration;
|
||||
@@ -27,11 +26,11 @@ namespace osu.Game.Rulesets.Taiko
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SettingsItemV2(new FormEnumDropdown<TaikoTouchControlScheme>
|
||||
new SettingsEnumDropdown<TaikoTouchControlScheme>
|
||||
{
|
||||
Caption = RulesetSettingsStrings.TouchControlScheme,
|
||||
LabelText = RulesetSettingsStrings.TouchControlScheme,
|
||||
Current = config.GetBindable<TaikoTouchControlScheme>(TaikoRulesetSetting.TouchControlScheme)
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
|
||||
var hitWindows = new TaikoHitWindows();
|
||||
|
||||
HitResult[] usableHitResults = Enum.GetValues<HitResult>().Where(hitWindows.IsHitResultAllowed).ToArray();
|
||||
HitResult[] usableHitResults = Enum.GetValues<HitResult>().Where(r => hitWindows.IsHitResultAllowed(r)).ToArray();
|
||||
|
||||
AddInternal(judgementPooler = new JudgementPooler<DrawableTaikoJudgement>(usableHitResults));
|
||||
|
||||
|
||||
@@ -35,31 +35,8 @@
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
</array>
|
||||
<key>CFBundleIcons~ipad</key>
|
||||
<dict>
|
||||
<key>CFBundlePrimaryIcon</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>AppIcon60x60</string>
|
||||
</array>
|
||||
<key>CFBundleIconName</key>
|
||||
<string>AppIcon</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>CFBundleIcons</key>
|
||||
<dict>
|
||||
<key>CFBundlePrimaryIcon</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>AppIcon60x60</string>
|
||||
<string>AppIcon76x76</string>
|
||||
</array>
|
||||
<key>CFBundleIconName</key>
|
||||
<string>AppIcon</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>XSAppIconAssets</key>
|
||||
<string>Assets.xcassets/AppIcon.appiconset</string>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -16,7 +15,6 @@ using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Tests.Beatmaps.IO;
|
||||
using osu.Game.Tests.Visual;
|
||||
@@ -36,12 +34,6 @@ namespace osu.Game.Tests.Beatmaps
|
||||
|
||||
private IBindable<StarDifficulty> starDifficultyBindable;
|
||||
|
||||
[Resolved]
|
||||
private BeatmapManager beatmapManager { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private BeatmapDifficultyCache actualDifficultyCache { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase osu)
|
||||
{
|
||||
@@ -63,36 +55,6 @@ namespace osu.Game.Tests.Beatmaps
|
||||
AddUntilStep($"star difficulty -> {BASE_STARS}", () => starDifficultyBindable.Value.Stars == BASE_STARS);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestInvalidationFlow()
|
||||
{
|
||||
BeatmapInfo postEditBeatmapInfo = null;
|
||||
BeatmapInfo preEditBeatmapInfo = null;
|
||||
|
||||
IBindable<StarDifficulty> bindableDifficulty = null;
|
||||
|
||||
AddStep("get bindable stars", () =>
|
||||
{
|
||||
preEditBeatmapInfo = importedSet.Beatmaps.First();
|
||||
bindableDifficulty = actualDifficultyCache.GetBindableDifficulty(preEditBeatmapInfo);
|
||||
});
|
||||
|
||||
AddUntilStep("wait for stars retrieved", () => bindableDifficulty.Value.Stars, () => Is.GreaterThan(0));
|
||||
|
||||
AddStep("remove all hitobjects", () =>
|
||||
{
|
||||
var working = beatmapManager.GetWorkingBeatmap(preEditBeatmapInfo);
|
||||
|
||||
((IList<HitObject>)working.Beatmap.HitObjects).Clear();
|
||||
|
||||
beatmapManager.Save(working.BeatmapInfo, working.Beatmap);
|
||||
postEditBeatmapInfo = working.BeatmapInfo;
|
||||
});
|
||||
|
||||
AddAssert("stars is now zero", () => actualDifficultyCache.GetDifficultyAsync(postEditBeatmapInfo).GetResultSafely()!.Value.Stars, () => Is.Zero);
|
||||
AddUntilStep("bindable stars is now zero", () => bindableDifficulty.Value.Stars, () => Is.Zero);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestStarDifficultyChangesOnModSettings()
|
||||
{
|
||||
@@ -114,30 +76,6 @@ namespace osu.Game.Tests.Beatmaps
|
||||
AddUntilStep($"star difficulty -> {BASE_STARS + 1.75}", () => starDifficultyBindable.Value.Stars == BASE_STARS + 1.75);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestStarDifficultyChangesOnModSettingsCorrectlyTrackAcrossReferenceChanges()
|
||||
{
|
||||
OsuModDoubleTime dt = null;
|
||||
|
||||
AddStep("set computation function", () => difficultyCache.ComputeDifficulty = lookup =>
|
||||
{
|
||||
var modRateAdjust = (ModRateAdjust)lookup.OrderedMods.SingleOrDefault(mod => mod is ModRateAdjust);
|
||||
return new StarDifficulty(BASE_STARS + modRateAdjust?.SpeedChange.Value ?? 0, 0);
|
||||
});
|
||||
|
||||
AddStep("change selected mod to DT", () => SelectedMods.Value = new[] { dt = new OsuModDoubleTime { SpeedChange = { Value = 1.5 } } });
|
||||
AddUntilStep($"star difficulty -> {BASE_STARS + 1.5}", () => starDifficultyBindable.Value.Stars == BASE_STARS + 1.5);
|
||||
|
||||
AddStep("change DT speed to 1.25", () => dt.SpeedChange.Value = 1.25);
|
||||
AddUntilStep($"star difficulty -> {BASE_STARS + 1.25}", () => starDifficultyBindable.Value.Stars == BASE_STARS + 1.25);
|
||||
|
||||
AddStep("reconstruct DT mod with same settings", () => SelectedMods.Value = new[] { dt = (OsuModDoubleTime)dt.DeepClone() });
|
||||
AddUntilStep($"star difficulty -> {BASE_STARS + 1.25}", () => starDifficultyBindable.Value.Stars == BASE_STARS + 1.25);
|
||||
|
||||
AddStep("change DT speed to 1.25", () => dt.SpeedChange.Value = 2);
|
||||
AddUntilStep($"star difficulty -> {BASE_STARS + 2}", () => starDifficultyBindable.Value.Stars == BASE_STARS + 2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestStarDifficultyAdjustHashCodeConflict()
|
||||
{
|
||||
@@ -184,10 +122,8 @@ namespace osu.Game.Tests.Beatmaps
|
||||
[Test]
|
||||
public void TestKeyDoesntEqualWithDifferentModSettings()
|
||||
{
|
||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 },
|
||||
new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.1 } } });
|
||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 },
|
||||
new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.9 } } });
|
||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.1 } } });
|
||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.9 } } });
|
||||
|
||||
Assert.That(key1, Is.Not.EqualTo(key2));
|
||||
Assert.That(key1.GetHashCode(), Is.Not.EqualTo(key2.GetHashCode()));
|
||||
@@ -196,10 +132,8 @@ namespace osu.Game.Tests.Beatmaps
|
||||
[Test]
|
||||
public void TestKeyEqualWithMatchingModSettings()
|
||||
{
|
||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 },
|
||||
new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 },
|
||||
new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
||||
|
||||
Assert.That(key1, Is.EqualTo(key2));
|
||||
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
||||
|
||||
@@ -247,7 +247,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
|
||||
AddStep("change all start times", () =>
|
||||
{
|
||||
editorBeatmap.HitObjectUpdated += updatedObjects.Add;
|
||||
editorBeatmap.HitObjectUpdated += h => updatedObjects.Add(h);
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
allHitObjects[i].StartTime += 10;
|
||||
@@ -282,7 +282,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
|
||||
AddStep("change start time twice", () =>
|
||||
{
|
||||
editorBeatmap.HitObjectUpdated += updatedObjects.Add;
|
||||
editorBeatmap.HitObjectUpdated += h => updatedObjects.Add(h);
|
||||
|
||||
editorBeatmap.HitObjects[0].StartTime = 10;
|
||||
editorBeatmap.HitObjects[0].StartTime = 20;
|
||||
|
||||
@@ -104,7 +104,10 @@ namespace osu.Game.Tests.Database
|
||||
Assert.AreNotEqual(detachedBeatmapSet.Status, BeatmapOnlineStatus.Ranked);
|
||||
detachedBeatmapSet.Status = BeatmapOnlineStatus.Ranked;
|
||||
|
||||
beatmapSet.PerformWrite(detachedBeatmapSet.CopyChangesToRealm);
|
||||
beatmapSet.PerformWrite(s =>
|
||||
{
|
||||
detachedBeatmapSet.CopyChangesToRealm(s);
|
||||
});
|
||||
|
||||
beatmapSet.PerformRead(s =>
|
||||
{
|
||||
|
||||
@@ -7,7 +7,6 @@ using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Catch;
|
||||
using osu.Game.Rulesets.Difficulty;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
@@ -117,69 +116,6 @@ namespace osu.Game.Tests.Database
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFakedRulesetIdIsDetected()
|
||||
{
|
||||
RunTestWithRealm((realm, storage) =>
|
||||
{
|
||||
LoadTestRuleset.HasImplementations = true;
|
||||
LoadTestRuleset.Version = Ruleset.CURRENT_RULESET_API_VERSION;
|
||||
|
||||
var ruleset = new LoadTestRuleset();
|
||||
string rulesetShortName = ruleset.RulesetInfo.ShortName;
|
||||
|
||||
realm.Write(r => r.Add(new RulesetInfo(rulesetShortName, ruleset.RulesetInfo.Name, ruleset.RulesetInfo.InstantiationInfo, 0)
|
||||
{
|
||||
Available = true,
|
||||
}));
|
||||
|
||||
Assert.That(realm.Run(r => r.Find<RulesetInfo>(rulesetShortName)!.Available), Is.True);
|
||||
|
||||
// Availability is updated on construction of a RealmRulesetStore
|
||||
using var _ = new RealmRulesetStore(realm, storage);
|
||||
|
||||
Assert.That(realm.Run(r => r.Find<RulesetInfo>(rulesetShortName)!.Available), Is.False);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMultipleRulesetWithSameOnlineIdsAreDetected()
|
||||
{
|
||||
RunTestWithRealm((realm, storage) =>
|
||||
{
|
||||
LoadTestRuleset.HasImplementations = true;
|
||||
LoadTestRuleset.Version = Ruleset.CURRENT_RULESET_API_VERSION;
|
||||
LoadTestRuleset.OnlineID = 2;
|
||||
|
||||
var first = new LoadTestRuleset();
|
||||
var second = new CatchRuleset();
|
||||
|
||||
realm.Write(r => r.Add(new RulesetInfo(first.ShortName, first.RulesetInfo.Name, first.RulesetInfo.InstantiationInfo, first.RulesetInfo.OnlineID)
|
||||
{
|
||||
Available = true,
|
||||
}));
|
||||
realm.Write(r => r.Add(new RulesetInfo(second.ShortName, second.RulesetInfo.Name, second.RulesetInfo.InstantiationInfo, second.RulesetInfo.OnlineID)
|
||||
{
|
||||
Available = true,
|
||||
}));
|
||||
|
||||
Assert.That(realm.Run(r => r.Find<RulesetInfo>(first.ShortName)!.Available), Is.True);
|
||||
Assert.That(realm.Run(r => r.Find<RulesetInfo>(second.ShortName)!.Available), Is.True);
|
||||
|
||||
// Availability is updated on construction of a RealmRulesetStore
|
||||
using var _ = new RealmRulesetStore(realm, storage);
|
||||
|
||||
Assert.That(realm.Run(r => r.Find<RulesetInfo>(first.ShortName)!.Available), Is.False);
|
||||
Assert.That(realm.Run(r => r.Find<RulesetInfo>(second.ShortName)!.Available), Is.False);
|
||||
|
||||
realm.Write(r => r.Remove(r.Find<RulesetInfo>(first.ShortName)!));
|
||||
|
||||
using var __ = new RealmRulesetStore(realm, storage);
|
||||
|
||||
Assert.That(realm.Run(r => r.Find<RulesetInfo>(second.ShortName)!.Available), Is.True);
|
||||
});
|
||||
}
|
||||
|
||||
private class LoadTestRuleset : Ruleset
|
||||
{
|
||||
public override string RulesetAPIVersionSupported => Version;
|
||||
@@ -188,13 +124,6 @@ namespace osu.Game.Tests.Database
|
||||
|
||||
public static string Version { get; set; } = CURRENT_RULESET_API_VERSION;
|
||||
|
||||
public static int OnlineID { get; set; } = -1;
|
||||
|
||||
public LoadTestRuleset()
|
||||
{
|
||||
RulesetInfo.OnlineID = OnlineID;
|
||||
}
|
||||
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type)
|
||||
{
|
||||
if (!HasImplementations)
|
||||
|
||||
@@ -11,6 +11,7 @@ using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Filter;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Screens.Select.Carousel;
|
||||
using osu.Game.Screens.Select.Filter;
|
||||
|
||||
namespace osu.Game.Tests.NonVisual.Filtering
|
||||
@@ -587,26 +588,6 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
||||
Assert.That(visibleBeatmaps, Is.EqualTo(expectedBeatmapIndexes));
|
||||
}
|
||||
|
||||
// This is a temporary class that emulates what these tests originally used from song select v1.
|
||||
// If anyone ever ends up tidying up these test, here's a starting point:
|
||||
// https://gist.github.com/peppy/67fda38f6483fd1dd01ef845ed5bf932
|
||||
public class CarouselBeatmap
|
||||
{
|
||||
public readonly BeatmapInfo BeatmapInfo;
|
||||
|
||||
public BindableBool Filtered = new BindableBool();
|
||||
|
||||
public CarouselBeatmap(BeatmapInfo beatmapInfo)
|
||||
{
|
||||
BeatmapInfo = beatmapInfo;
|
||||
}
|
||||
|
||||
public void Filter(FilterCriteria criteria)
|
||||
{
|
||||
Filtered.Value = !BeatmapCarouselFilterMatching.CheckCriteriaMatch(BeatmapInfo, criteria);
|
||||
}
|
||||
}
|
||||
|
||||
private class CustomCriteria : IRulesetFilterCriteria
|
||||
{
|
||||
private readonly bool match;
|
||||
|
||||
@@ -10,6 +10,7 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Filter;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Screens.Select.Carousel;
|
||||
using osu.Game.Screens.Select.Filter;
|
||||
|
||||
namespace osu.Game.Tests.NonVisual.Filtering
|
||||
@@ -508,7 +509,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
||||
("Another One", "diff ]with [[ brackets]]]"),
|
||||
("Diff in title", "a"),
|
||||
("a", "Diff in diff"),
|
||||
}).Select(info => new FilterMatchingTest.CarouselBeatmap(new BeatmapInfo
|
||||
}).Select(info => new CarouselBeatmap(new BeatmapInfo
|
||||
{
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
|
||||
@@ -44,13 +44,7 @@ namespace osu.Game.Tests.Online
|
||||
availableBeatmap = importedSet.Beatmaps[0];
|
||||
unavailableBeatmap = importedSet.Beatmaps[1];
|
||||
|
||||
Realm.Write(r =>
|
||||
{
|
||||
BeatmapInfo available = r.Find<BeatmapInfo>(availableBeatmap.ID)!;
|
||||
available.OnlineMD5Hash = available.MD5Hash;
|
||||
|
||||
r.Remove(r.Find<BeatmapInfo>(unavailableBeatmap.ID)!);
|
||||
});
|
||||
Realm.Write(r => r.Remove(r.Find<BeatmapInfo>(unavailableBeatmap.ID)!));
|
||||
}
|
||||
|
||||
public override void SetUpSteps()
|
||||
|
||||
@@ -28,7 +28,6 @@ using osu.Game.Screens.OnlinePlay;
|
||||
using osu.Game.Screens.OnlinePlay.Playlists;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osu.Game.Tests.Visual;
|
||||
using Realms;
|
||||
|
||||
namespace osu.Game.Tests.Online
|
||||
{
|
||||
@@ -231,14 +230,6 @@ namespace osu.Game.Tests.Online
|
||||
|
||||
return testBeatmapManager.CurrentImport = base.ImportModel(item, archive, parameters, cancellationToken);
|
||||
}
|
||||
|
||||
protected override void PostImport(BeatmapSetInfo model, Realm realm, ImportParameters parameters)
|
||||
{
|
||||
foreach (var beatmap in model.Beatmaps)
|
||||
beatmap.OnlineMD5Hash = beatmap.MD5Hash;
|
||||
|
||||
base.PostImport(model, realm, parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -526,7 +526,7 @@ namespace osu.Game.Tests.Rulesets.Scoring
|
||||
// ReSharper disable once MemberHidesStaticFromOuterClass
|
||||
private class TestRuleset : Ruleset
|
||||
{
|
||||
public override IEnumerable<HitResult> GetValidHitResults() => new[] { HitResult.Great };
|
||||
protected override IEnumerable<HitResult> GetValidHitResults() => new[] { HitResult.Great };
|
||||
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type) => throw new NotImplementedException();
|
||||
|
||||
|
||||
@@ -79,8 +79,6 @@ namespace osu.Game.Tests.Skins
|
||||
"Archives/modified-argon-20250424.osk",
|
||||
// Covers "Argon" unstable rate counter
|
||||
"Archives/modified-argon-20250809.osk",
|
||||
// Covers legacy style performance points counter
|
||||
"Archives/modified-classic-20250827.osk",
|
||||
// Covers "Argon" judgement counter
|
||||
"Archives/modified-argon-20250308.osk",
|
||||
// Covers "Argon" clicks/s counter, longest combo counter, skinnable SR display and beatmap status pill
|
||||
|
||||
@@ -32,7 +32,7 @@ using osu.Game.Screens.Backgrounds;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Play.PlayerSettings;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Screens.SelectV2;
|
||||
using osu.Game.Storyboards.Drawables;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osuTK;
|
||||
|
||||
@@ -7,9 +7,7 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osuTK;
|
||||
@@ -33,7 +31,7 @@ namespace osu.Game.Tests.Visual.Colours
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5f),
|
||||
ChildrenEnumerable = Enumerable.Range(0, 15).Select(i => new FillFlowContainer
|
||||
ChildrenEnumerable = Enumerable.Range(0, 10).Select(i => new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
@@ -42,9 +40,7 @@ namespace osu.Game.Tests.Visual.Colours
|
||||
Spacing = new Vector2(10f),
|
||||
ChildrenEnumerable = Enumerable.Range(0, 10).Select(j =>
|
||||
{
|
||||
float difficulty = 1f * i + 0.1f * j;
|
||||
var colour = colours.ForStarDifficulty(difficulty);
|
||||
var textColour = colours.ForStarDifficultyText(difficulty);
|
||||
var colour = colours.ForStarDifficulty(1f * i + 0.1f * j);
|
||||
|
||||
return new FillFlowContainer
|
||||
{
|
||||
@@ -52,27 +48,36 @@ namespace osu.Game.Tests.Visual.Colours
|
||||
Origin = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0f, 5f),
|
||||
Spacing = new Vector2(0f, 10f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
new CircularContainer
|
||||
{
|
||||
Masking = true,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Font = FontUsage.Default.With(size: 10),
|
||||
Text = $"BG: {colour.ToHex()}",
|
||||
Size = new Vector2(75f, 25f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colour,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Colour = OsuColour.ForegroundTextColourFor(colour),
|
||||
Text = colour.ToHex(),
|
||||
},
|
||||
}
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Font = FontUsage.Default.With(size: 10),
|
||||
Text = $"Text: {textColour.ToHex()}",
|
||||
},
|
||||
new StarRatingDisplay(new StarDifficulty(difficulty, 0))
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = $"*{(1f * i + 0.1f * j):0.00}",
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ using osu.Game.Online.Rooms;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Screens.SelectV2;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osu.Game.Tests.Visual.Metadata;
|
||||
using osu.Game.Tests.Visual.OnlinePlay;
|
||||
|
||||
@@ -1,64 +1,45 @@
|
||||
// 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 System;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Screens;
|
||||
using osu.Game.Screens.Edit.Submission;
|
||||
using osu.Game.Screens.Footer;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
public partial class TestSceneBeatmapSubmissionOverlay : ScreenTestScene
|
||||
public partial class TestSceneBeatmapSubmissionOverlay : OsuTestScene
|
||||
{
|
||||
private TestBeatmapSubmissionOverlayScreen screen = null!;
|
||||
|
||||
[Cached]
|
||||
private readonly BeatmapSubmissionSettings beatmapSubmissionSettings = new BeatmapSubmissionSettings();
|
||||
private ScreenFooter footer = null!;
|
||||
|
||||
[SetUpSteps]
|
||||
public override void SetUpSteps()
|
||||
public void SetUpSteps()
|
||||
{
|
||||
base.SetUpSteps();
|
||||
|
||||
AddStep("push screen", () => LoadScreen(screen = new TestBeatmapSubmissionOverlayScreen()));
|
||||
AddUntilStep("wait until screen is loaded", () => screen.IsLoaded, () => Is.True);
|
||||
AddStep("show overlay", () => screen.Overlay.Show());
|
||||
}
|
||||
|
||||
private partial class TestBeatmapSubmissionOverlayScreen : OsuScreen
|
||||
{
|
||||
public override bool ShowFooter => true;
|
||||
|
||||
public BeatmapSubmissionOverlay Overlay = null!;
|
||||
|
||||
private IDisposable? overlayRegistration;
|
||||
|
||||
[Resolved]
|
||||
private IOverlayManager? overlayManager { get; set; }
|
||||
|
||||
[Cached]
|
||||
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
AddStep("add overlay", () =>
|
||||
{
|
||||
LoadComponent(Overlay = new BeatmapSubmissionOverlay());
|
||||
}
|
||||
var receptor = new ScreenFooter.BackReceptor();
|
||||
footer = new ScreenFooter(receptor);
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
overlayRegistration = overlayManager?.RegisterBlockingOverlay(Overlay);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
overlayRegistration?.Dispose();
|
||||
}
|
||||
Child = new DependencyProvidingContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
CachedDependencies = new[]
|
||||
{
|
||||
(typeof(ScreenFooter), (object)footer),
|
||||
(typeof(BeatmapSubmissionSettings), new BeatmapSubmissionSettings()),
|
||||
},
|
||||
Children = new Drawable[]
|
||||
{
|
||||
receptor,
|
||||
new BeatmapSubmissionOverlay
|
||||
{
|
||||
State = { Value = Visibility.Visible, },
|
||||
},
|
||||
footer,
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,6 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
AddStep("set unique difficulty name", () => EditorBeatmap.BeatmapInfo.DifficultyName = firstDifficultyName);
|
||||
AddStep("add timing point", () => EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }));
|
||||
AddStep("add effect point", () => EditorBeatmap.ControlPointInfo.Add(500, new EffectControlPoint { KiaiMode = true }));
|
||||
AddStep("add bookmarks", () => EditorBeatmap.Bookmarks.AddRange([500, 1000]));
|
||||
AddStep("add hitobjects", () => EditorBeatmap.AddRange(new[]
|
||||
{
|
||||
new HitCircle
|
||||
@@ -186,7 +185,6 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
var effectPoint = EditorBeatmap.ControlPointInfo.EffectPoints.Single();
|
||||
return effectPoint.Time == 500 && effectPoint.KiaiMode && effectPoint.ScrollSpeedBindable.IsDefault;
|
||||
});
|
||||
AddAssert("created difficulty has bookmarks", () => EditorBeatmap.Bookmarks.Count == 2);
|
||||
AddAssert("created difficulty has no objects", () => EditorBeatmap.HitObjects.Count == 0);
|
||||
|
||||
AddAssert("status is modified", () => EditorBeatmap.BeatmapInfo.Status == BeatmapOnlineStatus.LocallyModified);
|
||||
@@ -225,7 +223,6 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
|
||||
AddStep("set unique difficulty name", () => EditorBeatmap.BeatmapInfo.DifficultyName = previousDifficultyName = Guid.NewGuid().ToString());
|
||||
AddStep("add timing point", () => EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }));
|
||||
AddStep("add bookmarks", () => EditorBeatmap.Bookmarks.AddRange([500, 1000]));
|
||||
AddStep("add effect points", () =>
|
||||
{
|
||||
EditorBeatmap.ControlPointInfo.Add(250, new EffectControlPoint { KiaiMode = false, ScrollSpeed = 0.05 });
|
||||
@@ -256,8 +253,6 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
return timingPoint.Time == 0 && timingPoint.BeatLength == 1000;
|
||||
});
|
||||
|
||||
AddAssert("created difficulty has bookmarks", () => EditorBeatmap.Bookmarks.Count == 2);
|
||||
|
||||
AddAssert("created difficulty has effect points", () =>
|
||||
{
|
||||
return EditorBeatmap.ControlPointInfo.EffectPoints.SequenceEqual(new[]
|
||||
@@ -289,7 +284,6 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
|
||||
AddStep("set unique difficulty name", () => EditorBeatmap.BeatmapInfo.DifficultyName = firstDifficultyName);
|
||||
AddStep("add timing point", () => EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }));
|
||||
AddStep("add bookmarks", () => EditorBeatmap.Bookmarks.AddRange([500, 1000]));
|
||||
AddStep("add effect points", () =>
|
||||
{
|
||||
EditorBeatmap.ControlPointInfo.Add(250, new EffectControlPoint { KiaiMode = false, ScrollSpeed = 0.05 });
|
||||
@@ -317,8 +311,6 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
return timingPoint.Time == 0 && timingPoint.BeatLength == 1000;
|
||||
});
|
||||
|
||||
AddAssert("created difficulty has bookmarks", () => EditorBeatmap.Bookmarks.Count == 2);
|
||||
|
||||
AddAssert("created difficulty has effect points", () =>
|
||||
{
|
||||
// since this difficulty is on another ruleset, scroll speed specifications are completely reset,
|
||||
@@ -352,7 +344,6 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
StartTime = 1000
|
||||
}
|
||||
}));
|
||||
AddStep("add bookmarks", () => EditorBeatmap.Bookmarks.AddRange([500, 1000]));
|
||||
AddStep("set approach rate", () => EditorBeatmap.Difficulty.ApproachRate = 4);
|
||||
AddStep("set combo colours", () =>
|
||||
{
|
||||
@@ -403,7 +394,6 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
return timingPoint.Time == 0 && timingPoint.BeatLength == 1000;
|
||||
});
|
||||
AddAssert("created difficulty has objects", () => EditorBeatmap.HitObjects.Count == 2);
|
||||
AddAssert("created difficulty has bookmarks", () => EditorBeatmap.Bookmarks.Count == 2);
|
||||
AddAssert("approach rate correctly copied", () => EditorBeatmap.Difficulty.ApproachRate == 4);
|
||||
AddAssert("combo colours correctly copied", () => EditorBeatmap.BeatmapSkin.AsNonNull().ComboColours.Count == 2);
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Screens.SelectV2;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
// 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.Graphics;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Edit.Components;
|
||||
using osu.Game.Tests.Visual.UserInterface;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
public partial class TestSceneFormSampleSet : ThemeComparisonTestScene
|
||||
{
|
||||
public TestSceneFormSampleSet()
|
||||
: base(false)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Drawable CreateContent() => new PopoverContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = new OsuContextMenuContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = new FormSampleSet
|
||||
{
|
||||
Current =
|
||||
{
|
||||
Value = new EditorBeatmapSkin.SampleSet(3, "Custom set #3")
|
||||
{
|
||||
Filenames = ["normal-hitwhistle3.wav"]
|
||||
}
|
||||
},
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Width = 0.4f,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Humanizer;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Audio;
|
||||
@@ -19,7 +20,6 @@ using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.UI;
|
||||
using osu.Game.Screens.Edit.Components.TernaryButtons;
|
||||
using osu.Game.Screens.Edit.Compose.Components;
|
||||
using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
||||
using osu.Game.Screens.Edit.Timing;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
@@ -113,77 +113,6 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
hitObjectHasSampleBank(1, HitSampleInfo.BANK_DRUM);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAutoAdditionsBankMatchesNormalBankWhenChangedViaPopover()
|
||||
{
|
||||
clickSamplePiece(0);
|
||||
setBankViaPopover(HitSampleInfo.BANK_SOFT);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_SOFT);
|
||||
|
||||
toggleAdditionViaPopover(1);
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_FINISH);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_SOFT);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_SOFT);
|
||||
|
||||
setBankViaPopover(HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_DRUM);
|
||||
|
||||
setAdditionBankViaPopover(HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
|
||||
setAdditionBankViaPopover(EditorSelectionHandler.HIT_BANK_AUTO);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_DRUM);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAutoAdditionsBankMatchesNormalBankWhenChangedViaHotkeys()
|
||||
{
|
||||
AddStep("select first object", () => EditorBeatmap.SelectedHitObjects.Add(EditorBeatmap.HitObjects[0]));
|
||||
AddStep("set soft normal bank", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.ShiftLeft);
|
||||
InputManager.Key(Key.E);
|
||||
InputManager.ReleaseKey(Key.ShiftLeft);
|
||||
});
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_SOFT);
|
||||
|
||||
AddStep("toggle finish", () => InputManager.Key(Key.E));
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_FINISH);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_SOFT);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_SOFT);
|
||||
|
||||
AddStep("set drum normal bank", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.ShiftLeft);
|
||||
InputManager.Key(Key.R);
|
||||
InputManager.ReleaseKey(Key.ShiftLeft);
|
||||
});
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_DRUM);
|
||||
|
||||
AddStep("set normal addition bank", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.AltLeft);
|
||||
InputManager.Key(Key.W);
|
||||
InputManager.ReleaseKey(Key.AltLeft);
|
||||
});
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
|
||||
AddStep("set auto addition bank", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.AltLeft);
|
||||
InputManager.Key(Key.Q);
|
||||
InputManager.ReleaseKey(Key.AltLeft);
|
||||
});
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_DRUM);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUndo()
|
||||
{
|
||||
@@ -267,6 +196,11 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
clickSamplePiece(1);
|
||||
samplePopoverHasSingleBank(HitSampleInfo.BANK_SOFT);
|
||||
|
||||
setBankViaPopover(string.Empty);
|
||||
hitObjectHasSampleBank(0, HitSampleInfo.BANK_SOFT);
|
||||
hitObjectHasSampleBank(1, HitSampleInfo.BANK_SOFT);
|
||||
samplePopoverHasSingleBank(HitSampleInfo.BANK_SOFT);
|
||||
|
||||
setBankViaPopover(HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasSampleBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasSampleBank(1, HitSampleInfo.BANK_DRUM);
|
||||
@@ -285,6 +219,11 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
clickSamplePiece(1);
|
||||
samplePopoverHasIndeterminateBank();
|
||||
|
||||
setBankViaPopover(string.Empty);
|
||||
hitObjectHasSampleBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasSampleBank(1, HitSampleInfo.BANK_SOFT);
|
||||
samplePopoverHasIndeterminateBank();
|
||||
|
||||
setBankViaPopover(HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasSampleBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasSampleBank(1, HitSampleInfo.BANK_NORMAL);
|
||||
@@ -418,7 +357,7 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
for (int i = 0; i < h.Samples.Count; i++)
|
||||
{
|
||||
h.Samples[i] = h.Samples[i].With(newBank: HitSampleInfo.BANK_SOFT, newEditorAutoBank: false);
|
||||
h.Samples[i] = h.Samples[i].With(newBank: HitSampleInfo.BANK_SOFT);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -426,7 +365,7 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
AddStep("add whistle addition", () =>
|
||||
{
|
||||
foreach (var h in EditorBeatmap.HitObjects)
|
||||
h.Samples.Add(new HitSampleInfo(HitSampleInfo.HIT_WHISTLE, HitSampleInfo.BANK_SOFT, editorAutoBank: false));
|
||||
h.Samples.Add(new HitSampleInfo(HitSampleInfo.HIT_WHISTLE, HitSampleInfo.BANK_SOFT));
|
||||
});
|
||||
|
||||
AddStep("select both objects", () => EditorBeatmap.SelectedHitObjects.AddRange(EditorBeatmap.HitObjects));
|
||||
@@ -595,172 +534,6 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
() => EditorBeatmap.PlacementObject.Value.Samples.First(s => s.Name != HitSampleInfo.HIT_NORMAL).Bank, () => Is.EqualTo(expected));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNonAutoBankHotkeysDuringPlacementPersistAfterPlacement()
|
||||
{
|
||||
AddStep("Clear all objects", () => EditorBeatmap.Clear());
|
||||
AddStep("Enter placement mode", () => InputManager.Key(Key.Number2));
|
||||
AddStep("Move mouse to centre", () => InputManager.MoveMouseTo(Editor.ChildrenOfType<HitObjectComposer>().First().ScreenSpaceDrawQuad.Centre));
|
||||
|
||||
AddStep("Move to 3000", () => EditorClock.Seek(3000));
|
||||
|
||||
AddStep("Press drum bank shortcut", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.ShiftLeft);
|
||||
InputManager.Key(Key.R);
|
||||
InputManager.ReleaseKey(Key.ShiftLeft);
|
||||
});
|
||||
|
||||
AddAssert($"Placement sample is {HitSampleInfo.BANK_DRUM}",
|
||||
() => EditorBeatmap.PlacementObject.Value.Samples.First(s => s.Name == HitSampleInfo.HIT_NORMAL).Bank, () => Is.EqualTo(HitSampleInfo.BANK_DRUM));
|
||||
|
||||
AddStep("Press normal addition bank shortcut", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.AltLeft);
|
||||
InputManager.Key(Key.W);
|
||||
InputManager.ReleaseKey(Key.AltLeft);
|
||||
});
|
||||
|
||||
AddStep("Press finish sample shortcut", () =>
|
||||
{
|
||||
InputManager.Key(Key.E);
|
||||
});
|
||||
|
||||
AddAssert($"Placement sample addition is {HitSampleInfo.BANK_NORMAL}",
|
||||
() => EditorBeatmap.PlacementObject.Value.Samples.First(s => s.Name != HitSampleInfo.HIT_NORMAL).Bank, () => Is.EqualTo(HitSampleInfo.BANK_NORMAL));
|
||||
|
||||
AddStep("Finish placement", () => InputManager.Click(MouseButton.Left));
|
||||
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_FINISH);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasAutoNormalBankFlag(0, false);
|
||||
hitObjectHasAutoAdditionBankFlag(0, false);
|
||||
|
||||
clickSamplePiece(0);
|
||||
samplePopoverIsOpen();
|
||||
samplePopoverHasSingleAdditionBank(HitSampleInfo.BANK_NORMAL);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAutoAdditionBankHotkeyDuringPlacementPersistsAfterPlacement()
|
||||
{
|
||||
AddStep("Clear all objects", () => EditorBeatmap.Clear());
|
||||
AddStep("Enter placement mode", () => InputManager.Key(Key.Number2));
|
||||
AddStep("Move mouse to centre", () => InputManager.MoveMouseTo(Editor.ChildrenOfType<HitObjectComposer>().First().ScreenSpaceDrawQuad.Centre));
|
||||
|
||||
AddStep("Move to 3000", () => EditorClock.Seek(3000));
|
||||
|
||||
AddStep("Press drum bank shortcut", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.ShiftLeft);
|
||||
InputManager.Key(Key.R);
|
||||
InputManager.ReleaseKey(Key.ShiftLeft);
|
||||
});
|
||||
|
||||
AddAssert($"Placement sample is {HitSampleInfo.BANK_DRUM}",
|
||||
() => EditorBeatmap.PlacementObject.Value.Samples.First(s => s.Name == HitSampleInfo.HIT_NORMAL).Bank, () => Is.EqualTo(HitSampleInfo.BANK_DRUM));
|
||||
|
||||
AddStep("Press normal addition bank shortcut", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.AltLeft);
|
||||
InputManager.Key(Key.W);
|
||||
InputManager.ReleaseKey(Key.AltLeft);
|
||||
});
|
||||
|
||||
AddStep("Press finish sample shortcut", () =>
|
||||
{
|
||||
InputManager.Key(Key.E);
|
||||
});
|
||||
|
||||
AddStep("Press auto addition bank shortcut", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.AltLeft);
|
||||
InputManager.Key(Key.Q);
|
||||
InputManager.ReleaseKey(Key.AltLeft);
|
||||
});
|
||||
|
||||
AddAssert($"Placement sample addition is {HitSampleInfo.BANK_DRUM}",
|
||||
() => EditorBeatmap.PlacementObject.Value.Samples.First(s => s.Name != HitSampleInfo.HIT_NORMAL).Bank, () => Is.EqualTo(HitSampleInfo.BANK_DRUM));
|
||||
|
||||
AddStep("Finish placement", () => InputManager.Click(MouseButton.Left));
|
||||
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_FINISH);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasAutoNormalBankFlag(0, false);
|
||||
hitObjectHasAutoAdditionBankFlag(0, true);
|
||||
|
||||
clickSamplePiece(0);
|
||||
samplePopoverIsOpen();
|
||||
samplePopoverHasSingleAdditionBank(EditorSelectionHandler.HIT_BANK_AUTO);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFullAutoBankHotkeyDuringPlacementPersistsAfterPlacement()
|
||||
{
|
||||
AddStep("Clear all objects", () => EditorBeatmap.Clear());
|
||||
AddStep("Enter placement mode", () => InputManager.Key(Key.Number2));
|
||||
AddStep("Move mouse to centre", () => InputManager.MoveMouseTo(Editor.ChildrenOfType<HitObjectComposer>().First().ScreenSpaceDrawQuad.Centre));
|
||||
|
||||
AddStep("Move to 3000", () => EditorClock.Seek(3000));
|
||||
|
||||
AddStep("Press auto normal bank shortcut", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.ShiftLeft);
|
||||
InputManager.Key(Key.Q);
|
||||
InputManager.ReleaseKey(Key.ShiftLeft);
|
||||
});
|
||||
|
||||
AddAssert($"Placement sample is {HitSampleInfo.BANK_NORMAL}",
|
||||
() => EditorBeatmap.PlacementObject.Value.Samples.First(s => s.Name == HitSampleInfo.HIT_NORMAL).Bank, () => Is.EqualTo(HitSampleInfo.BANK_NORMAL));
|
||||
|
||||
AddStep("Press finish sample shortcut", () =>
|
||||
{
|
||||
InputManager.Key(Key.E);
|
||||
});
|
||||
|
||||
AddStep("Press auto addition bank shortcut", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.AltLeft);
|
||||
InputManager.Key(Key.Q);
|
||||
InputManager.ReleaseKey(Key.AltLeft);
|
||||
});
|
||||
|
||||
AddAssert($"Placement sample addition is {HitSampleInfo.BANK_NORMAL}",
|
||||
() => EditorBeatmap.PlacementObject.Value.Samples.First(s => s.Name != HitSampleInfo.HIT_NORMAL).Bank, () => Is.EqualTo(HitSampleInfo.BANK_NORMAL));
|
||||
|
||||
AddStep("Finish placement", () => InputManager.Click(MouseButton.Left));
|
||||
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_FINISH);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasAutoNormalBankFlag(0, false); // it's the first object - nothing to inherit bank from
|
||||
hitObjectHasAutoAdditionBankFlag(0, true);
|
||||
|
||||
clickSamplePiece(0);
|
||||
samplePopoverIsOpen();
|
||||
samplePopoverHasSingleBank(HitSampleInfo.BANK_NORMAL);
|
||||
samplePopoverHasSingleAdditionBank(EditorSelectionHandler.HIT_BANK_AUTO);
|
||||
dismissPopover();
|
||||
|
||||
AddStep("Move to 5000", () => EditorClock.Seek(5000));
|
||||
AddStep("Enter placement mode", () => InputManager.Key(Key.Number2));
|
||||
AddStep("Move mouse to centre", () => InputManager.MoveMouseTo(Editor.ChildrenOfType<HitObjectComposer>().First().ScreenSpaceDrawQuad.Centre));
|
||||
AddStep("Finish placement", () => InputManager.Click(MouseButton.Left));
|
||||
|
||||
hitObjectHasSamples(1, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_FINISH); // finish is still implied, continuing from first placement
|
||||
hitObjectHasSampleNormalBank(1, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasSampleAdditionBank(1, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasAutoNormalBankFlag(1, true);
|
||||
hitObjectHasAutoAdditionBankFlag(1, true);
|
||||
|
||||
clickSamplePiece(1);
|
||||
samplePopoverIsOpen();
|
||||
samplePopoverHasSingleBank(HitSampleInfo.BANK_NORMAL);
|
||||
samplePopoverHasSingleAdditionBank(EditorSelectionHandler.HIT_BANK_AUTO);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PopoverForMultipleSelectionChangesAllSamples()
|
||||
{
|
||||
@@ -837,19 +610,19 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
Path = new SliderPath(new[] { new PathControlPoint(Vector2.Zero), new PathControlPoint(new Vector2(250, 0)) }),
|
||||
Samples =
|
||||
{
|
||||
new HitSampleInfo(HitSampleInfo.HIT_NORMAL, editorAutoBank: false)
|
||||
new HitSampleInfo(HitSampleInfo.HIT_NORMAL)
|
||||
},
|
||||
NodeSamples = new List<IList<HitSampleInfo>>
|
||||
{
|
||||
new List<HitSampleInfo>
|
||||
{
|
||||
new HitSampleInfo(HitSampleInfo.HIT_NORMAL, bank: HitSampleInfo.BANK_DRUM, editorAutoBank: false),
|
||||
new HitSampleInfo(HitSampleInfo.HIT_CLAP, bank: HitSampleInfo.BANK_DRUM, editorAutoBank: false),
|
||||
new HitSampleInfo(HitSampleInfo.HIT_NORMAL, bank: HitSampleInfo.BANK_DRUM),
|
||||
new HitSampleInfo(HitSampleInfo.HIT_CLAP, bank: HitSampleInfo.BANK_DRUM),
|
||||
},
|
||||
new List<HitSampleInfo>
|
||||
{
|
||||
new HitSampleInfo(HitSampleInfo.HIT_NORMAL, bank: HitSampleInfo.BANK_SOFT, editorAutoBank: false),
|
||||
new HitSampleInfo(HitSampleInfo.HIT_WHISTLE, bank: HitSampleInfo.BANK_SOFT, editorAutoBank: false),
|
||||
new HitSampleInfo(HitSampleInfo.HIT_NORMAL, bank: HitSampleInfo.BANK_SOFT),
|
||||
new HitSampleInfo(HitSampleInfo.HIT_WHISTLE, bank: HitSampleInfo.BANK_SOFT),
|
||||
},
|
||||
}
|
||||
});
|
||||
@@ -1046,174 +819,6 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddSoundBeforeSettingNonAutoAdditionBankOnSelectedObject()
|
||||
{
|
||||
AddStep("select first object", () =>
|
||||
{
|
||||
EditorBeatmap.SelectedHitObjects.Clear();
|
||||
EditorBeatmap.SelectedHitObjects.Add(EditorBeatmap.HitObjects[0]);
|
||||
});
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
|
||||
AddStep("add finish sound", () => InputManager.Key(Key.E));
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_FINISH);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasAutoAdditionBankFlag(0, true);
|
||||
|
||||
AddStep("set drum addition bank", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.AltLeft);
|
||||
InputManager.Key(Key.R);
|
||||
InputManager.ReleaseKey(Key.AltLeft);
|
||||
});
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_FINISH);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasAutoAdditionBankFlag(0, false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddSoundAfterSettingNonAutoAdditionBankOnSelectedObject()
|
||||
{
|
||||
AddStep("select first object", () =>
|
||||
{
|
||||
EditorBeatmap.SelectedHitObjects.Clear();
|
||||
EditorBeatmap.SelectedHitObjects.Add(EditorBeatmap.HitObjects[0]);
|
||||
});
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
|
||||
AddStep("set drum addition bank", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.AltLeft);
|
||||
InputManager.Key(Key.R);
|
||||
InputManager.ReleaseKey(Key.AltLeft);
|
||||
});
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
|
||||
AddStep("add finish sound", () => InputManager.Key(Key.E));
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_FINISH);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasAutoAdditionBankFlag(0, false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSwitchSoundAfterSettingNonAutoAdditionBankOnSelectedObject()
|
||||
{
|
||||
AddStep("select first object", () =>
|
||||
{
|
||||
EditorBeatmap.SelectedHitObjects.Clear();
|
||||
EditorBeatmap.SelectedHitObjects.Add(EditorBeatmap.HitObjects[0]);
|
||||
});
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
|
||||
AddStep("set drum addition bank", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.AltLeft);
|
||||
InputManager.Key(Key.R);
|
||||
InputManager.ReleaseKey(Key.AltLeft);
|
||||
});
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
|
||||
AddStep("add finish sound", () => InputManager.Key(Key.E));
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_FINISH);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasAutoAdditionBankFlag(0, false);
|
||||
|
||||
AddStep("remove finish sound", () => InputManager.Key(Key.E));
|
||||
AddStep("add whistle sound", () => InputManager.Key(Key.W));
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_WHISTLE);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasAutoAdditionBankFlag(0, false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddSoundBeforeSettingAutoAdditionBankOnSelectedObject()
|
||||
{
|
||||
AddStep("select first object", () =>
|
||||
{
|
||||
EditorBeatmap.SelectedHitObjects.Clear();
|
||||
EditorBeatmap.SelectedHitObjects.Add(EditorBeatmap.HitObjects[0]);
|
||||
});
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
|
||||
AddStep("add finish sound", () => InputManager.Key(Key.E));
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_FINISH);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasAutoAdditionBankFlag(0, true);
|
||||
|
||||
AddStep("set auto addition bank", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.AltLeft);
|
||||
InputManager.Key(Key.Q);
|
||||
InputManager.ReleaseKey(Key.AltLeft);
|
||||
});
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_FINISH);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasAutoAdditionBankFlag(0, true);
|
||||
|
||||
AddStep("set drum normal bank", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.ShiftLeft);
|
||||
InputManager.Key(Key.R);
|
||||
InputManager.ReleaseKey(Key.ShiftLeft);
|
||||
});
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_FINISH);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasAutoAdditionBankFlag(0, true);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddSoundAfterSettingAutoAdditionBankOnSelectedObject()
|
||||
{
|
||||
AddStep("select first object", () =>
|
||||
{
|
||||
EditorBeatmap.SelectedHitObjects.Clear();
|
||||
EditorBeatmap.SelectedHitObjects.Add(EditorBeatmap.HitObjects[0]);
|
||||
});
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
|
||||
AddStep("set auto addition bank", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.AltLeft);
|
||||
InputManager.Key(Key.Q);
|
||||
InputManager.ReleaseKey(Key.AltLeft);
|
||||
});
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
|
||||
AddStep("add finish sound", () => InputManager.Key(Key.E));
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_FINISH);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_NORMAL);
|
||||
hitObjectHasAutoAdditionBankFlag(0, true);
|
||||
|
||||
AddStep("set drum normal bank", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.ShiftLeft);
|
||||
InputManager.Key(Key.R);
|
||||
InputManager.ReleaseKey(Key.ShiftLeft);
|
||||
});
|
||||
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_FINISH);
|
||||
hitObjectHasSampleNormalBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasSampleAdditionBank(0, HitSampleInfo.BANK_DRUM);
|
||||
hitObjectHasAutoAdditionBankFlag(0, true);
|
||||
}
|
||||
|
||||
private void clickSamplePiece(int objectIndex) => AddStep($"click {objectIndex.ToOrdinalWords()} sample piece", () =>
|
||||
{
|
||||
var samplePiece = this.ChildrenOfType<SamplePointPiece>().Single(piece => piece is not NodeSamplePointPiece && piece.HitObject == EditorBeatmap.HitObjects.ElementAt(objectIndex));
|
||||
@@ -1273,25 +878,17 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
private void samplePopoverHasSingleBank(string bank) => AddUntilStep($"sample popover has bank {bank}", () =>
|
||||
{
|
||||
var popover = this.ChildrenOfType<SamplePointPiece.SampleEditPopover>().SingleOrDefault();
|
||||
var dropdown = popover?.ChildrenOfType<LabelledDropdown<string>>().First();
|
||||
var textBox = popover?.ChildrenOfType<OsuTextBox>().First();
|
||||
|
||||
return dropdown?.Current.Value == bank;
|
||||
return textBox?.Current.Value == bank && string.IsNullOrEmpty(textBox.PlaceholderText.ToString());
|
||||
});
|
||||
|
||||
private void samplePopoverHasIndeterminateBank() => AddUntilStep("sample popover has indeterminate bank", () =>
|
||||
{
|
||||
var popover = this.ChildrenOfType<SamplePointPiece.SampleEditPopover>().SingleOrDefault();
|
||||
var dropdown = popover?.ChildrenOfType<LabelledDropdown<string>>().First();
|
||||
var textBox = popover?.ChildrenOfType<OsuTextBox>().First();
|
||||
|
||||
return dropdown?.Current.Value == "(multiple)";
|
||||
});
|
||||
|
||||
private void samplePopoverHasSingleAdditionBank(string bank) => AddUntilStep($"sample popover has bank {bank}", () =>
|
||||
{
|
||||
var popover = this.ChildrenOfType<SamplePointPiece.SampleEditPopover>().SingleOrDefault();
|
||||
var dropdown = popover?.ChildrenOfType<LabelledDropdown<string>>().ElementAt(1);
|
||||
|
||||
return dropdown?.Current.Value == bank;
|
||||
return textBox != null && string.IsNullOrEmpty(textBox.Current.Value) && !string.IsNullOrEmpty(textBox.PlaceholderText.ToString());
|
||||
});
|
||||
|
||||
private void dismissPopover()
|
||||
@@ -1323,15 +920,23 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
private void setBankViaPopover(string bank) => AddStep($"set bank {bank} via popover", () =>
|
||||
{
|
||||
var popover = this.ChildrenOfType<SamplePointPiece.SampleEditPopover>().Single();
|
||||
var textBox = popover.ChildrenOfType<LabelledDropdown<string>>().First();
|
||||
var textBox = popover.ChildrenOfType<LabelledTextBox>().First();
|
||||
textBox.Current.Value = bank;
|
||||
// force a commit via keyboard.
|
||||
// this is needed when testing attempting to set empty bank - which should revert to the previous value, but only on commit.
|
||||
((IFocusManager)InputManager).ChangeFocus(textBox);
|
||||
InputManager.Key(Key.Enter);
|
||||
});
|
||||
|
||||
private void setAdditionBankViaPopover(string bank) => AddStep($"set addition bank {bank} via popover", () =>
|
||||
{
|
||||
var popover = this.ChildrenOfType<SamplePointPiece.SampleEditPopover>().Single();
|
||||
var textBox = popover.ChildrenOfType<LabelledDropdown<string>>().ToArray()[1];
|
||||
var textBox = popover.ChildrenOfType<LabelledTextBox>().ToArray()[1];
|
||||
textBox.Current.Value = bank;
|
||||
// force a commit via keyboard.
|
||||
// this is needed when testing attempting to set empty bank - which should revert to the previous value, but only on commit.
|
||||
((IFocusManager)InputManager).ChangeFocus(textBox);
|
||||
InputManager.Key(Key.Enter);
|
||||
});
|
||||
|
||||
private void toggleAdditionViaPopover(int index) => AddStep($"toggle addition {index} via popover", () =>
|
||||
@@ -1367,18 +972,6 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
return h.Samples.Where(o => o.Name != HitSampleInfo.HIT_NORMAL).All(o => o.Bank == bank);
|
||||
});
|
||||
|
||||
private void hitObjectHasAutoNormalBankFlag(int objectIndex, bool autoBank) => AddAssert($"{objectIndex.ToOrdinalWords()} has auto normal bank {(autoBank ? "on" : "off")}", () =>
|
||||
{
|
||||
var h = EditorBeatmap.HitObjects.ElementAt(objectIndex);
|
||||
return h.Samples.Where(o => o.Name == HitSampleInfo.HIT_NORMAL).All(o => o.EditorAutoBank == autoBank);
|
||||
});
|
||||
|
||||
private void hitObjectHasAutoAdditionBankFlag(int objectIndex, bool autoBank) => AddAssert($"{objectIndex.ToOrdinalWords()} has auto addition bank {(autoBank ? "on" : "off")}", () =>
|
||||
{
|
||||
var h = EditorBeatmap.HitObjects.ElementAt(objectIndex);
|
||||
return h.Samples.Where(o => o.Name != HitSampleInfo.HIT_NORMAL).All(o => o.EditorAutoBank == autoBank);
|
||||
});
|
||||
|
||||
private void hitObjectNodeHasSamples(int objectIndex, int nodeIndex, params string[] samples) => AddAssert(
|
||||
$"{objectIndex.ToOrdinalWords()} object {nodeIndex.ToOrdinalWords()} node has samples {string.Join(',', samples)}", () =>
|
||||
{
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
SaveEditor();
|
||||
|
||||
ReloadEditorToSameBeatmap();
|
||||
AddUntilStep("beatmap marked as locally modified", () => EditorBeatmap.BeatmapInfo.Status, () => Is.EqualTo(BeatmapOnlineStatus.LocallyModified));
|
||||
AddAssert("beatmap marked as locally modified", () => EditorBeatmap.BeatmapInfo.Status, () => Is.EqualTo(BeatmapOnlineStatus.LocallyModified));
|
||||
AddAssert("beatmap hash changed", () => EditorBeatmap.BeatmapInfo.MD5Hash, () => Is.Not.EqualTo(initialHash));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Menu;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Screens.SelectV2;
|
||||
using osu.Game.Tests.Resources;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
|
||||
@@ -37,42 +37,6 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
|
||||
private GlobalActionContainer globalActionContainer => this.ChildrenOfType<GlobalActionContainer>().Single();
|
||||
|
||||
[Test]
|
||||
public void TestPlaceThenUndo()
|
||||
{
|
||||
AddStep("select circle placement tool", () => InputManager.Key(Key.Number2));
|
||||
AddStep("move mouse to center of playfield", () => InputManager.MoveMouseTo(this.ChildrenOfType<Playfield>().Single()));
|
||||
AddStep("place circle", () => InputManager.Click(MouseButton.Left));
|
||||
|
||||
AddAssert("one circle added", () => EditorBeatmap.HitObjects, () => Has.One.Items);
|
||||
|
||||
AddStep("undo", () => Editor.Undo());
|
||||
|
||||
AddAssert("circle removed", () => EditorBeatmap.HitObjects, () => Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestTimingLost()
|
||||
{
|
||||
AddStep("select circle placement tool", () => InputManager.Key(Key.Number2));
|
||||
AddStep("move mouse to center of playfield", () => InputManager.MoveMouseTo(this.ChildrenOfType<Playfield>().Single()));
|
||||
|
||||
AddAssert("placement ready", () => this.ChildrenOfType<ComposeBlueprintContainer>().Single().CurrentPlacement, () => Is.Not.Null);
|
||||
|
||||
AddStep("nuke timing", () => EditorBeatmap.ControlPointInfo.Clear());
|
||||
|
||||
AddAssert("placement not available", () => this.ChildrenOfType<ComposeBlueprintContainer>().Single().CurrentPlacement, () => Is.Null);
|
||||
|
||||
AddStep("select circle placement tool", () => InputManager.Key(Key.Number2));
|
||||
|
||||
AddAssert("placement not available", () => this.ChildrenOfType<ComposeBlueprintContainer>().Single().CurrentPlacement, () => Is.Null);
|
||||
|
||||
AddStep("add back timing", () => EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint()));
|
||||
AddStep("select circle placement tool", () => InputManager.Key(Key.Number2));
|
||||
|
||||
AddAssert("placement ready", () => this.ChildrenOfType<ComposeBlueprintContainer>().Single().CurrentPlacement, () => Is.Not.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDeleteUsingMiddleMouse()
|
||||
{
|
||||
@@ -272,8 +236,8 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
AddAssert("circle has 2 samples", () => EditorBeatmap.HitObjects[1].Samples, () => Has.Count.EqualTo(2));
|
||||
AddAssert("normal sample has soft bank", () => EditorBeatmap.HitObjects[1].Samples.Single(s => s.Name == HitSampleInfo.HIT_NORMAL).Bank,
|
||||
() => Is.EqualTo(HitSampleInfo.BANK_SOFT));
|
||||
AddAssert("clap sample has soft bank", () => EditorBeatmap.HitObjects[1].Samples.Single(s => s.Name == HitSampleInfo.HIT_CLAP).Bank,
|
||||
() => Is.EqualTo(HitSampleInfo.BANK_SOFT));
|
||||
AddAssert("clap sample has drum bank", () => EditorBeatmap.HitObjects[1].Samples.Single(s => s.Name == HitSampleInfo.HIT_CLAP).Bank,
|
||||
() => Is.EqualTo(HitSampleInfo.BANK_DRUM));
|
||||
AddAssert("circle inherited volume", () => EditorBeatmap.HitObjects[1].Samples.All(s => s.Volume == 70));
|
||||
|
||||
AddStep("seek to 1000", () => EditorClock.Seek(1000)); // previous object is the one at time 500, which has no additions
|
||||
|
||||
@@ -8,7 +8,7 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osu.Game.Screens.Play.Leaderboards;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
@@ -50,34 +50,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
sprites.All(sprite => sprite.ChildrenOfType<Sprite>().All(s => s.Texture == null)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSpriteFadeOverflowBehaviour()
|
||||
{
|
||||
AddStep("create sprite", () => SetContents(_ =>
|
||||
{
|
||||
var layer = storyboard.GetLayer("Background");
|
||||
|
||||
var sprite = new StoryboardSprite(lookup_name, Anchor.TopLeft, new Vector2(256, 192));
|
||||
sprite.Commands.AddAlpha(Easing.None, Time.Current, Time.Current + 2000, 0, 2);
|
||||
|
||||
layer.Elements.Clear();
|
||||
layer.Add(sprite);
|
||||
|
||||
return new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
storyboard.CreateDrawable()
|
||||
}
|
||||
};
|
||||
}));
|
||||
|
||||
AddUntilStep("sprite reached high opacity once", () => sprites.All(sprite => sprite.ChildrenOfType<Sprite>().All(s => s.Alpha > 0.8f)));
|
||||
AddUntilStep("sprite reset to low opacity", () => sprites.All(sprite => sprite.ChildrenOfType<Sprite>().All(s => s.Alpha < 0.2f)));
|
||||
AddUntilStep("sprite reached high opacity twice", () => sprites.All(sprite => sprite.ChildrenOfType<Sprite>().All(s => s.Alpha > 0.8f)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLookupFromStoryboard()
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@ using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osu.Game.Screens.Play.Leaderboards;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Tests.Gameplay;
|
||||
using osuTK.Graphics;
|
||||
|
||||
|
||||
@@ -270,7 +270,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
AddStep("create overlay", () =>
|
||||
{
|
||||
hudOverlay = new HUDOverlay(null, Array.Empty<Mod>(), new PlayerConfiguration());
|
||||
hudOverlay = new HUDOverlay(null, Array.Empty<Mod>());
|
||||
|
||||
// Add any key just to display the key counter visually.
|
||||
hudOverlay.InputCountController.Add(new KeyCounterKeyboardTrigger(Key.Space));
|
||||
|
||||
@@ -25,7 +25,7 @@ using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Play.Leaderboards;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Tests.Gameplay;
|
||||
using osu.Game.Tests.Visual.Spectator;
|
||||
@@ -119,7 +119,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
Children = new Drawable[]
|
||||
{
|
||||
drawableRuleset,
|
||||
new HUDOverlay(drawableRuleset, [], new PlayerConfiguration())
|
||||
new HUDOverlay(drawableRuleset, [])
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ using osu.Game.Rulesets.Osu.Scoring;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Skinning.Triangles;
|
||||
using osu.Game.Tests.Gameplay;
|
||||
|
||||
@@ -36,7 +35,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
protected override Drawable CreateDefaultImplementation() => new TrianglesPerformancePointsCounter();
|
||||
protected override Drawable CreateArgonImplementation() => new ArgonPerformancePointsCounter();
|
||||
protected override Drawable CreateLegacyImplementation() => new LegacyPerformancePointsCounter();
|
||||
protected override Drawable CreateLegacyImplementation() => Empty();
|
||||
|
||||
private Bindable<JudgementResult> lastJudgementResult => (Bindable<JudgementResult>)gameplayState.LastJudgementResult;
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions;
|
||||
@@ -151,7 +150,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
List<SkinBlueprint> blueprints = new List<SkinBlueprint>();
|
||||
|
||||
AddStep("clear list", blueprints.Clear);
|
||||
AddStep("clear list", () => blueprints.Clear());
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
@@ -379,23 +378,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
() => Is.EqualTo(3));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCopyPasteIdempotency()
|
||||
{
|
||||
string state = null!;
|
||||
AddStep("select everything", () => InputManager.Keys(PlatformAction.SelectAll));
|
||||
AddStep("dump state", () =>
|
||||
{
|
||||
state = JsonConvert.SerializeObject(skinEditor.SelectedComponents.Cast<Drawable>().Select(s => s.CreateSerialisedInfo()).ToArray());
|
||||
});
|
||||
AddStep("copy", () => InputManager.Keys(PlatformAction.Copy));
|
||||
AddStep("delete", () => InputManager.Keys(PlatformAction.Delete));
|
||||
AddStep("paste", () => InputManager.Keys(PlatformAction.Paste));
|
||||
AddAssert("pasted state equals dumped",
|
||||
() => JsonConvert.SerializeObject(skinEditor.SelectedComponents.Cast<Drawable>().Select(s => s.CreateSerialisedInfo()).ToArray()),
|
||||
() => Is.EqualTo(state));
|
||||
}
|
||||
|
||||
private SkinnableContainer globalHUDTarget => Player.ChildrenOfType<SkinnableContainer>()
|
||||
.Single(c => c.Lookup.Lookup == GlobalSkinnableContainers.MainHUDComponents && c.Lookup.Ruleset == null);
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osu.Game.Screens.Play.Leaderboards;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Tests.Gameplay;
|
||||
using osuTK.Input;
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
var drawableRuleset = ruleset.CreateDrawableRulesetWith(beatmap, mods);
|
||||
|
||||
var hudOverlay = new HUDOverlay(drawableRuleset, mods, new PlayerConfiguration())
|
||||
var hudOverlay = new HUDOverlay(drawableRuleset, mods)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
|
||||
@@ -21,7 +21,7 @@ using osu.Game.Rulesets.Osu.UI;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osu.Game.Screens.Play.Leaderboards;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Tests.Gameplay;
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
SetContents(_ =>
|
||||
{
|
||||
hudOverlay = new HUDOverlay(new DrawableOsuRuleset(new OsuRuleset(), new OsuBeatmap()), Array.Empty<Mod>(), new PlayerConfiguration());
|
||||
hudOverlay = new HUDOverlay(new DrawableOsuRuleset(new OsuRuleset(), new OsuBeatmap()), Array.Empty<Mod>());
|
||||
|
||||
action?.Invoke(hudOverlay);
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ using osu.Game.Online.Leaderboards;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Play.Leaderboards;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
using osu.Game.Tests.Gameplay;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
@@ -5,7 +5,6 @@ using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
@@ -46,46 +45,10 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
|
||||
AddStep("add panel", () =>
|
||||
{
|
||||
var beatmap = CreateAPIBeatmap();
|
||||
|
||||
beatmap.TopTags =
|
||||
[
|
||||
new APIBeatmapTag { TagId = 4, VoteCount = 1 },
|
||||
new APIBeatmapTag { TagId = 2, VoteCount = 1 },
|
||||
new APIBeatmapTag { TagId = 23, VoteCount = 5 },
|
||||
];
|
||||
|
||||
beatmap.BeatmapSet!.HasExplicitContent = true;
|
||||
beatmap.BeatmapSet!.HasVideo = true;
|
||||
beatmap.BeatmapSet!.HasStoryboard = true;
|
||||
beatmap.BeatmapSet.FeaturedInSpotlight = true;
|
||||
beatmap.BeatmapSet.TrackId = 1;
|
||||
beatmap.BeatmapSet!.RelatedTags =
|
||||
[
|
||||
new APITag
|
||||
{
|
||||
Id = 2,
|
||||
Name = "song representation/simple",
|
||||
Description = "Accessible and straightforward map design."
|
||||
},
|
||||
new APITag
|
||||
{
|
||||
Id = 4,
|
||||
Name = "style/clean",
|
||||
Description = "Visually uncluttered and organised patterns, often involving few overlaps and equal visual spacing between objects."
|
||||
},
|
||||
new APITag
|
||||
{
|
||||
Id = 23,
|
||||
Name = "aim/aim control",
|
||||
Description = "Patterns with velocity or direction changes which strongly go against a player's natural movement pattern."
|
||||
}
|
||||
];
|
||||
|
||||
Child = new OsuContextMenuContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = panel = new MatchmakingSelectPanelBeatmap(new MatchmakingPlaylistItem(new MultiplayerPlaylistItem(), beatmap, []))
|
||||
Child = panel = new MatchmakingSelectPanelBeatmap(new MatchmakingPlaylistItem(new MultiplayerPlaylistItem(), CreateAPIBeatmap(), []))
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
@@ -133,12 +96,6 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
};
|
||||
});
|
||||
|
||||
AddStep("add peppy", () => panel!.AddUser(new APIUser
|
||||
{
|
||||
Id = 2,
|
||||
Username = "peppy",
|
||||
}));
|
||||
|
||||
AddToggleStep("allow selection", value => panel!.AllowSelection = value);
|
||||
|
||||
AddStep("reveal beatmap", () => panel!.PresentAsChosenBeatmap(new MatchmakingPlaylistItem(new MultiplayerPlaylistItem(), CreateAPIBeatmap(), [])));
|
||||
|
||||
@@ -7,7 +7,6 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Matchmaking;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Intro;
|
||||
using osu.Game.Screens.OnlinePlay.Matchmaking.Queue;
|
||||
using osu.Game.Tests.Visual.Multiplayer;
|
||||
@@ -27,7 +26,7 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
{
|
||||
base.SetUpSteps();
|
||||
|
||||
AddStep("load screen", () => LoadScreen(new ScreenIntro(MatchmakingPoolType.QuickPlay)));
|
||||
AddStep("load screen", () => LoadScreen(new ScreenIntro()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -122,51 +122,5 @@ namespace osu.Game.Tests.Visual.Matchmaking
|
||||
AddStep("set download progress 90%", () => MultiplayerClient.ChangeUserBeatmapAvailability(2, BeatmapAvailability.Downloading(0.9f)));
|
||||
AddStep("set locally available", () => MultiplayerClient.ChangeUserBeatmapAvailability(2, BeatmapAvailability.LocallyAvailable()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLongUsername()
|
||||
{
|
||||
AddStep("set long username", () =>
|
||||
{
|
||||
MultiplayerClient.ChangeMatchRoomState(new MatchmakingRoomState
|
||||
{
|
||||
Users =
|
||||
{
|
||||
UserDictionary =
|
||||
{
|
||||
{
|
||||
2, new MatchmakingUser
|
||||
{
|
||||
UserId = 2,
|
||||
Placement = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).WaitSafely();
|
||||
|
||||
Child = panel = new PlayerPanel(new MultiplayerRoomUser(2)
|
||||
{
|
||||
User = new APIUser
|
||||
{
|
||||
Username = @"ThisIsALongUsername",
|
||||
Id = 2,
|
||||
Colour = "99EB47",
|
||||
CountryCode = CountryCode.AU,
|
||||
CoverUrl = @"https://assets.ppy.sh/user-profile-covers/2/baba245ef60834b769694178f8f6d4f6166c5188c740de084656ad2b80f1eea7.jpeg",
|
||||
Statistics = new UserStatistics { GlobalRank = null, CountryRank = null }
|
||||
}
|
||||
})
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
};
|
||||
});
|
||||
|
||||
foreach (var layout in Enum.GetValues<PlayerPanelDisplayMode>())
|
||||
{
|
||||
AddStep($"set layout to {layout}", () => panel.DisplayMode = layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ using osu.Game.Online.Spectator;
|
||||
using osu.Game.Replays.Legacy;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osu.Game.Screens.Play.Leaderboards;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// 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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
@@ -17,7 +15,6 @@ using osu.Game.Database;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.OnlinePlay;
|
||||
using osu.Game.Screens.OnlinePlay.Lounge;
|
||||
@@ -25,7 +22,6 @@ using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||
using osu.Game.Screens.OnlinePlay.Multiplayer.Match;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
@@ -39,8 +35,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
protected IScreen CurrentScreen => multiplayerComponents.CurrentScreen;
|
||||
protected IScreen CurrentSubScreen => multiplayerComponents.MultiplayerScreen.CurrentSubScreen;
|
||||
|
||||
protected BeatmapManager Beatmaps { get; private set; } = null!;
|
||||
|
||||
private BeatmapManager beatmaps = null!;
|
||||
private BeatmapSetInfo importedSet = null!;
|
||||
private RulesetStore rulesets = null!;
|
||||
|
||||
@@ -54,7 +49,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
BeatmapStore beatmapStore;
|
||||
|
||||
Dependencies.Cache(rulesets = new RealmRulesetStore(Realm));
|
||||
Dependencies.Cache(Beatmaps = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
|
||||
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default));
|
||||
Dependencies.CacheAs(beatmapStore = new RealmDetachedBeatmapStore());
|
||||
Dependencies.Cache(Realm);
|
||||
|
||||
@@ -67,13 +62,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
AddStep("import beatmap", () =>
|
||||
{
|
||||
Beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
|
||||
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
|
||||
Realm.Write(r =>
|
||||
{
|
||||
foreach (var beatmapInfo in r.All<BeatmapInfo>())
|
||||
beatmapInfo.OnlineMD5Hash = beatmapInfo.MD5Hash;
|
||||
});
|
||||
importedSet = Beatmaps.GetAllUsableBeatmapSets().First();
|
||||
importedSet = beatmaps.GetAllUsableBeatmapSets().First();
|
||||
InitialBeatmap = importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0);
|
||||
OtherBeatmap = importedSet.Beatmaps.Last(b => b.Ruleset.OnlineID == 0);
|
||||
});
|
||||
@@ -123,30 +118,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddStep("exit player", () => multiplayerComponents.MultiplayerScreen.MakeCurrent());
|
||||
}
|
||||
|
||||
protected void AddBeatmapFromSongSelect(Func<BeatmapInfo> beatmap, RulesetInfo? ruleset = null, IReadOnlyList<Mod>? mods = null)
|
||||
{
|
||||
Screens.Select.SongSelect? songSelect = null;
|
||||
|
||||
AddStep("click add button", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSubScreen.AddItemButton>().Single());
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddUntilStep("wait for song select", () => (songSelect = CurrentSubScreen as Screens.Select.SongSelect) != null);
|
||||
AddUntilStep("wait for loaded", () => songSelect.IsCurrentScreen() && !songSelect.AsNonNull().IsFiltering);
|
||||
|
||||
if (ruleset != null)
|
||||
AddStep($"set {ruleset.Name} ruleset", () => songSelect.AsNonNull().Ruleset.Value = ruleset);
|
||||
|
||||
if (mods != null)
|
||||
AddStep($"set mods to {string.Join(",", mods.Select(m => m.Acronym))}", () => songSelect.AsNonNull().Mods.Value = mods);
|
||||
|
||||
AddStep("select other beatmap", () => songSelect.AsNonNull().Beatmap.Value = Beatmaps.GetWorkingBeatmap(beatmap()));
|
||||
AddStep("confirm selection", () => InputManager.Key(Key.Enter));
|
||||
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
// 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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Catch;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||
using osu.Game.Screens.OnlinePlay.Multiplayer.Match;
|
||||
using osu.Game.Screens.Play;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
@@ -37,10 +45,10 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
[Test]
|
||||
public void TestItemAddedToTheEndOfQueue()
|
||||
{
|
||||
AddBeatmapFromSongSelect(() => OtherBeatmap);
|
||||
addItem(() => OtherBeatmap);
|
||||
AddUntilStep("playlist has 2 items", () => MultiplayerClient.ClientAPIRoom?.Playlist.Count == 2);
|
||||
|
||||
AddBeatmapFromSongSelect(() => InitialBeatmap);
|
||||
addItem(() => InitialBeatmap);
|
||||
AddUntilStep("playlist has 3 items", () => MultiplayerClient.ClientAPIRoom?.Playlist.Count == 3);
|
||||
|
||||
AddUntilStep("first item still selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID);
|
||||
@@ -49,8 +57,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
[Test]
|
||||
public void TestNextItemSelectedAfterGameplayFinish()
|
||||
{
|
||||
AddBeatmapFromSongSelect(() => OtherBeatmap);
|
||||
AddBeatmapFromSongSelect(() => InitialBeatmap);
|
||||
addItem(() => OtherBeatmap);
|
||||
addItem(() => InitialBeatmap);
|
||||
|
||||
RunGameplay();
|
||||
|
||||
@@ -66,8 +74,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
[Test]
|
||||
public void TestItemsNotClearedWhenSwitchToHostOnlyMode()
|
||||
{
|
||||
AddBeatmapFromSongSelect(() => OtherBeatmap);
|
||||
AddBeatmapFromSongSelect(() => InitialBeatmap);
|
||||
addItem(() => OtherBeatmap);
|
||||
addItem(() => InitialBeatmap);
|
||||
|
||||
// Move to the "other" beatmap.
|
||||
RunGameplay();
|
||||
@@ -81,14 +89,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
[Test]
|
||||
public void TestCorrectItemSelectedAfterNewItemAdded()
|
||||
{
|
||||
AddBeatmapFromSongSelect(() => OtherBeatmap);
|
||||
addItem(() => OtherBeatmap);
|
||||
AddUntilStep("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCorrectRulesetSelectedAfterNewItemAdded()
|
||||
{
|
||||
AddBeatmapFromSongSelect(() => OtherBeatmap, new CatchRuleset().RulesetInfo);
|
||||
addItem(() => OtherBeatmap, new CatchRuleset().RulesetInfo);
|
||||
AddUntilStep("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID);
|
||||
|
||||
AddUntilStep("wait for idle", () => MultiplayerClient.LocalUser?.State == MultiplayerUserState.Idle);
|
||||
@@ -105,7 +113,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
[Test]
|
||||
public void TestCorrectModsSelectedAfterNewItemAdded()
|
||||
{
|
||||
AddBeatmapFromSongSelect(() => OtherBeatmap, mods: new Mod[] { new OsuModDoubleTime() });
|
||||
addItem(() => OtherBeatmap, mods: new Mod[] { new OsuModDoubleTime() });
|
||||
AddUntilStep("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID);
|
||||
|
||||
AddUntilStep("wait for idle", () => MultiplayerClient.LocalUser?.State == MultiplayerUserState.Idle);
|
||||
@@ -118,5 +126,28 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddAssert("mods are correct", () => !((Player)CurrentScreen).Mods.Value.Any());
|
||||
AddStep("exit player", () => CurrentScreen.Exit());
|
||||
}
|
||||
|
||||
private void addItem(Func<BeatmapInfo> beatmap, RulesetInfo? ruleset = null, IReadOnlyList<Mod>? mods = null)
|
||||
{
|
||||
Screens.Select.SongSelect? songSelect = null;
|
||||
|
||||
AddStep("click add button", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSubScreen.AddItemButton>().Single());
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddUntilStep("wait for song select", () => (songSelect = CurrentSubScreen as Screens.Select.SongSelect) != null);
|
||||
AddUntilStep("wait for loaded", () => songSelect.AsNonNull().BeatmapSetsLoaded);
|
||||
|
||||
if (ruleset != null)
|
||||
AddStep($"set {ruleset.Name} ruleset", () => songSelect.AsNonNull().Ruleset.Value = ruleset);
|
||||
|
||||
if (mods != null)
|
||||
AddStep($"set mods to {string.Join(",", mods.Select(m => m.Acronym))}", () => songSelect.AsNonNull().Mods.Value = mods);
|
||||
|
||||
AddStep("select other beatmap", () => songSelect.AsNonNull().FinaliseSelection(beatmap()));
|
||||
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,13 +7,14 @@ using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Mods;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Screens;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.Footer;
|
||||
using osu.Game.Screens.OnlinePlay;
|
||||
using osu.Game.Utils;
|
||||
@@ -21,13 +22,12 @@ using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public partial class TestSceneFreeModSelectOverlay : ScreenTestScene
|
||||
public partial class TestSceneFreeModSelectOverlay : MultiplayerTestScene
|
||||
{
|
||||
private TestFreeModSelectOverlayScreen screen = null!;
|
||||
private FreeModSelectOverlay freeModSelectOverlay = null!;
|
||||
private FooterButtonFreeMods footerButtonFreeMods = null!;
|
||||
private ScreenFooter footer = null!;
|
||||
private readonly Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> availableMods = new Bindable<Dictionary<ModType, IReadOnlyList<Mod>>>();
|
||||
private readonly Bindable<IReadOnlyList<Mod>> freeMods = new Bindable<IReadOnlyList<Mod>>([]);
|
||||
|
||||
private FreeModSelectOverlay freeModSelectOverlay => screen.Overlay;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase osuGameBase)
|
||||
@@ -35,14 +35,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
availableMods.BindTo(osuGameBase.AvailableMods);
|
||||
}
|
||||
|
||||
[SetUpSteps]
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
base.SetUpSteps();
|
||||
|
||||
AddStep("reset selected mods", () => freeMods.Value = []);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFreeModSelect()
|
||||
{
|
||||
@@ -52,6 +44,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
() => this.ChildrenOfType<ModPanel>()
|
||||
.Where(panel => panel.IsPresent)
|
||||
.All(panel => panel.Mod.HasImplementation && panel.Mod.UserPlayable));
|
||||
|
||||
AddToggleStep("toggle visibility", visible =>
|
||||
{
|
||||
freeModSelectOverlay.State.Value = visible ? Visibility.Visible : Visibility.Hidden;
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -75,16 +72,18 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
AddAssert("select all button enabled", () => this.ChildrenOfType<SelectAllModsButton>().Single().Enabled.Value);
|
||||
|
||||
AddStep("click select all button", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(this.ChildrenOfType<SelectAllModsButton>().Single());
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
AddStep("click select all button", navigateAndClick<SelectAllModsButton>);
|
||||
AddAssert("select all button disabled", () => !this.ChildrenOfType<SelectAllModsButton>().Single().Enabled.Value);
|
||||
|
||||
AddStep("change search term", () => freeModSelectOverlay.SearchTerm = "e");
|
||||
|
||||
AddAssert("select all button enabled", () => this.ChildrenOfType<SelectAllModsButton>().Single().Enabled.Value);
|
||||
|
||||
void navigateAndClick<T>() where T : Drawable
|
||||
{
|
||||
InputManager.MoveMouseTo(this.ChildrenOfType<T>().Single());
|
||||
InputManager.Click(MouseButton.Left);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -125,14 +124,55 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddAssert("select all button enabled", () => this.ChildrenOfType<SelectAllModsButton>().Single().Enabled.Value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSelectAllViaFooterButtonThenDeselectFromOverlay()
|
||||
{
|
||||
createFreeModSelect();
|
||||
|
||||
AddAssert("overlay select all button enabled", () => this.ChildrenOfType<SelectAllModsButton>().Single().Enabled.Value);
|
||||
AddAssert("footer button displays off", () => footerButtonFreeMods.ChildrenOfType<IHasText>().Any(t => t.Text == "off"));
|
||||
|
||||
AddStep("click footer select all button", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(footerButtonFreeMods);
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddUntilStep("all mods selected", assertAllAvailableModsSelected);
|
||||
AddAssert("footer button displays all", () => footerButtonFreeMods.ChildrenOfType<IHasText>().Any(t => t.Text == "all"));
|
||||
|
||||
AddStep("click deselect all button", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(this.ChildrenOfType<DeselectAllModsButton>().Single());
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
AddUntilStep("all mods deselected", () => !freeModSelectOverlay.SelectedMods.Value.Any());
|
||||
AddAssert("footer button displays off", () => footerButtonFreeMods.ChildrenOfType<IHasText>().Any(t => t.Text == "off"));
|
||||
}
|
||||
|
||||
private void createFreeModSelect()
|
||||
{
|
||||
AddStep("create free mod select screen", () => LoadScreen(screen = new TestFreeModSelectOverlayScreen
|
||||
AddStep("create free mod select screen", () => Child = new DependencyProvidingContainer
|
||||
{
|
||||
FreeMods = { BindTarget = freeMods },
|
||||
}));
|
||||
AddUntilStep("wait until screen is loaded", () => screen.IsLoaded, () => Is.True);
|
||||
AddStep("show overlay", () => freeModSelectOverlay.Show());
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
freeModSelectOverlay = new FreeModSelectOverlay
|
||||
{
|
||||
State = { Value = Visibility.Visible }
|
||||
},
|
||||
footerButtonFreeMods = new FooterButtonFreeMods(freeModSelectOverlay)
|
||||
{
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
Y = -ScreenFooter.HEIGHT,
|
||||
FreeMods = { BindTarget = freeModSelectOverlay.SelectedMods },
|
||||
},
|
||||
footer = new ScreenFooter(),
|
||||
},
|
||||
CachedDependencies = new (Type, object)[] { (typeof(ScreenFooter), footer) },
|
||||
});
|
||||
|
||||
AddUntilStep("all column content loaded",
|
||||
() => freeModSelectOverlay.ChildrenOfType<ModColumn>().Any()
|
||||
&& freeModSelectOverlay.ChildrenOfType<ModColumn>().All(column => column.IsLoaded && column.ItemsLoaded));
|
||||
@@ -157,50 +197,5 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private partial class TestFreeModSelectOverlayScreen : OsuScreen
|
||||
{
|
||||
public override bool ShowFooter => true;
|
||||
|
||||
public FreeModSelectOverlay Overlay = null!;
|
||||
private IDisposable? overlayRegistration;
|
||||
|
||||
public readonly Bindable<IReadOnlyList<Mod>> FreeMods = new Bindable<IReadOnlyList<Mod>>([]);
|
||||
|
||||
[Resolved]
|
||||
private IOverlayManager? overlayManager { get; set; }
|
||||
|
||||
[Cached]
|
||||
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
LoadComponent(Overlay = new FreeModSelectOverlay
|
||||
{
|
||||
SelectedMods = { BindTarget = FreeMods }
|
||||
});
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
overlayRegistration = overlayManager?.RegisterBlockingOverlay(Overlay);
|
||||
}
|
||||
|
||||
public override IReadOnlyList<ScreenFooterButton> CreateFooterButtons() =>
|
||||
[
|
||||
new FooterButtonFreeMods(Overlay)
|
||||
{
|
||||
FreeMods = { BindTarget = FreeMods },
|
||||
},
|
||||
];
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
overlayRegistration?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ using System;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
@@ -38,14 +36,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddUntilStep("second playlist item selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[1].ID);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestItemStillSelectedAfterChangeToSameBeatmap()
|
||||
{
|
||||
selectNewItem(() => InitialBeatmap);
|
||||
|
||||
AddUntilStep("playlist item still selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSettingsUpdatedWhenChangingQueueMode()
|
||||
{
|
||||
@@ -57,6 +47,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddUntilStep("api room updated", () => MultiplayerClient.ClientAPIRoom?.QueueMode == QueueMode.AllPlayers);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestItemStillSelectedAfterChangeToSameBeatmap()
|
||||
{
|
||||
selectNewItem(() => InitialBeatmap);
|
||||
|
||||
AddUntilStep("playlist item still selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestItemStillSelectedAfterChangeToOtherBeatmap()
|
||||
{
|
||||
@@ -82,15 +80,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
[Test]
|
||||
public void TestAddItemsAsHost()
|
||||
{
|
||||
AddBeatmapFromSongSelect(() => OtherBeatmap);
|
||||
addItem(() => OtherBeatmap);
|
||||
|
||||
AddUntilStep("playlist contains two items", () => MultiplayerClient.ClientAPIRoom?.Playlist.Count == 2);
|
||||
}
|
||||
|
||||
private void selectNewItem(Func<BeatmapInfo> beatmap)
|
||||
{
|
||||
Screens.Select.SongSelect? songSelect = null;
|
||||
|
||||
AddUntilStep("wait for playlist panels to load", () =>
|
||||
{
|
||||
var queueList = this.ChildrenOfType<MultiplayerQueueList>().Single();
|
||||
@@ -103,15 +99,26 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddUntilStep("wait for song select", () => (songSelect = CurrentSubScreen as Screens.Select.SongSelect) != null);
|
||||
AddUntilStep("wait for loaded", () => songSelect.IsCurrentScreen() && !songSelect.AsNonNull().IsFiltering);
|
||||
AddUntilStep("wait for song select", () => CurrentSubScreen is Screens.Select.SongSelect select && select.BeatmapSetsLoaded);
|
||||
|
||||
BeatmapInfo otherBeatmap = null!;
|
||||
AddStep("select other beatmap", () => songSelect.AsNonNull().Beatmap.Value = Beatmaps.GetWorkingBeatmap(otherBeatmap = beatmap()));
|
||||
AddStep("confirm selection", () => InputManager.Key(Key.Enter));
|
||||
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);
|
||||
AddStep("select other beatmap", () => ((Screens.Select.SongSelect)CurrentSubScreen).FinaliseSelection(otherBeatmap = beatmap()));
|
||||
|
||||
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);
|
||||
AddUntilStep("selected item is new beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == otherBeatmap.OnlineID);
|
||||
}
|
||||
|
||||
private void addItem(Func<BeatmapInfo> beatmap)
|
||||
{
|
||||
AddStep("click add button", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSubScreen.AddItemButton>().Single());
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddUntilStep("wait for song select", () => CurrentSubScreen is Screens.Select.SongSelect select && select.BeatmapSetsLoaded);
|
||||
AddStep("select other beatmap", () => ((Screens.Select.SongSelect)CurrentSubScreen).FinaliseSelection(beatmap()));
|
||||
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// 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 System.Linq;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Screens.OnlinePlay.Components;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osu.Game.Tests.Visual.OnlinePlay;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public partial class TestSceneMatchBeatmapDetailArea : OnlinePlayTestScene
|
||||
{
|
||||
private Room room = null!;
|
||||
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
base.SetUpSteps();
|
||||
|
||||
AddStep("create area", () =>
|
||||
{
|
||||
Child = new MatchBeatmapDetailArea(room = new Room())
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(500),
|
||||
CreateNewItem = createNewItem
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private void createNewItem()
|
||||
{
|
||||
room.Playlist = room.Playlist.Append(new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo)
|
||||
{
|
||||
ID = room.Playlist.Count,
|
||||
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
|
||||
RequiredMods = new[]
|
||||
{
|
||||
new APIMod(new OsuModHardRock()),
|
||||
new APIMod(new OsuModDoubleTime()),
|
||||
new APIMod(new OsuModAutoplay())
|
||||
}
|
||||
}).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ using osu.Framework.Timing;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osu.Game.Screens.Play.Leaderboards;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
|
||||
@@ -228,7 +228,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
// edit playlist item
|
||||
AddStep("Press select", () => InputManager.Key(Key.Enter));
|
||||
waitForSongSelect();
|
||||
AddUntilStep("wait for song select", () => InputManager.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);
|
||||
|
||||
// select beatmap
|
||||
AddStep("Press select", () => InputManager.Key(Key.Enter));
|
||||
@@ -451,7 +451,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
((MultiplayerMatchSubScreen)currentSubScreen).ShowSongSelect(item);
|
||||
});
|
||||
|
||||
waitForSongSelect();
|
||||
AddUntilStep("wait for song select", () => this.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);
|
||||
|
||||
AddUntilStep("Beatmap matches current item", () => Beatmap.Value.BeatmapInfo.OnlineID == multiplayerClient.ClientRoom?.Playlist.First().BeatmapID);
|
||||
|
||||
@@ -492,7 +492,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
((MultiplayerMatchSubScreen)currentSubScreen).ShowSongSelect(item);
|
||||
});
|
||||
|
||||
waitForSongSelect();
|
||||
AddUntilStep("wait for song select", () => this.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);
|
||||
|
||||
AddUntilStep("Ruleset matches current item", () => Ruleset.Value.OnlineID == multiplayerClient.ClientRoom?.Playlist.First().RulesetID);
|
||||
|
||||
@@ -533,7 +533,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
((MultiplayerMatchSubScreen)currentSubScreen).ShowSongSelect(item);
|
||||
});
|
||||
|
||||
waitForSongSelect();
|
||||
AddUntilStep("wait for song select", () => this.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);
|
||||
|
||||
AddUntilStep("Mods match current item",
|
||||
() => SelectedMods.Value.Select(m => m.Acronym).SequenceEqual(multiplayerClient.ClientRoom.AsNonNull().Playlist.First().RequiredMods.Select(m => m.Acronym)));
|
||||
@@ -1051,7 +1051,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddStep("press edit on second item", () => this.ChildrenOfType<DrawableRoomPlaylistItem>().Single(i => i.Item.RulesetID == 1)
|
||||
.ChildrenOfType<DrawableRoomPlaylistItem.PlaylistEditButton>().Single().TriggerClick());
|
||||
|
||||
waitForSongSelect();
|
||||
AddUntilStep("wait for song select", () => InputManager.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);
|
||||
AddAssert("ruleset is taiko", () => Ruleset.Value.OnlineID == 1);
|
||||
|
||||
AddStep("start match", () => multiplayerClient.StartMatch().WaitSafely());
|
||||
@@ -1249,15 +1249,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddUntilStep("wait for join", () => multiplayerClient.RoomJoined);
|
||||
}
|
||||
|
||||
private void waitForSongSelect()
|
||||
{
|
||||
AddUntilStep("wait for song select", () =>
|
||||
{
|
||||
var songSelect = InputManager.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault();
|
||||
return songSelect != null && songSelect.IsCurrentScreen() && !songSelect.IsFiltering;
|
||||
});
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
@@ -9,7 +9,7 @@ using osu.Game.Online.API;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Screens.Play.Leaderboards;
|
||||
using osu.Game.Screens.Select.Leaderboards;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user