mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 16:27:26 +08:00
Merge remote-tracking branch 'upstream/master' into pause-logic-simplification
This commit is contained in:
commit
5b6ac7abdc
@ -23,16 +23,9 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
|
||||
protected override int SectionLength => 750;
|
||||
|
||||
private readonly float halfCatchWidth;
|
||||
|
||||
public CatchDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||
: base(ruleset, beatmap)
|
||||
{
|
||||
var catcher = new CatcherArea.Catcher(beatmap.BeatmapInfo.BaseDifficulty);
|
||||
halfCatchWidth = catcher.CatchWidth * 0.5f;
|
||||
|
||||
// We're only using 80% of the catcher's width to simulate imperfect gameplay.
|
||||
halfCatchWidth *= 0.8f;
|
||||
}
|
||||
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
@ -54,6 +47,14 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
|
||||
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate)
|
||||
{
|
||||
float halfCatchWidth;
|
||||
|
||||
using (var catcher = new CatcherArea.Catcher(beatmap.BeatmapInfo.BaseDifficulty))
|
||||
{
|
||||
halfCatchWidth = catcher.CatchWidth * 0.5f;
|
||||
halfCatchWidth *= 0.8f; // We're only using 80% of the catcher's width to simulate imperfect gameplay.
|
||||
}
|
||||
|
||||
CatchHitObject lastObject = null;
|
||||
|
||||
foreach (var hitObject in beatmap.HitObjects.OfType<CatchHitObject>())
|
||||
|
@ -15,77 +15,100 @@ namespace osu.Game.Rulesets.Catch.Mods
|
||||
public override double ScoreMultiplier => 1.12;
|
||||
public override bool Ranked => true;
|
||||
|
||||
private float lastStartX;
|
||||
private int lastStartTime;
|
||||
private float? lastPosition;
|
||||
private double lastStartTime;
|
||||
|
||||
public void ApplyToHitObject(HitObject hitObject)
|
||||
{
|
||||
if (!(hitObject is Fruit))
|
||||
return;
|
||||
|
||||
var catchObject = (CatchHitObject)hitObject;
|
||||
|
||||
float position = catchObject.X;
|
||||
int startTime = (int)hitObject.StartTime;
|
||||
double startTime = hitObject.StartTime;
|
||||
|
||||
if (lastStartX == 0)
|
||||
if (lastPosition == null)
|
||||
{
|
||||
lastStartX = position;
|
||||
lastPosition = position;
|
||||
lastStartTime = startTime;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
float diff = lastStartX - position;
|
||||
int timeDiff = startTime - lastStartTime;
|
||||
float positionDiff = position - lastPosition.Value;
|
||||
double timeDiff = startTime - lastStartTime;
|
||||
|
||||
if (timeDiff > 1000)
|
||||
{
|
||||
lastStartX = position;
|
||||
lastPosition = position;
|
||||
lastStartTime = startTime;
|
||||
return;
|
||||
}
|
||||
|
||||
if (diff == 0)
|
||||
if (positionDiff == 0)
|
||||
{
|
||||
bool right = RNG.NextBool();
|
||||
|
||||
float rand = Math.Min(20, (float)RNG.NextDouble(0, timeDiff / 4d)) / CatchPlayfield.BASE_WIDTH;
|
||||
|
||||
if (right)
|
||||
{
|
||||
if (position + rand <= 1)
|
||||
position += rand;
|
||||
else
|
||||
position -= rand;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (position - rand >= 0)
|
||||
position -= rand;
|
||||
else
|
||||
position += rand;
|
||||
}
|
||||
|
||||
applyRandomOffset(ref position, timeDiff / 4d);
|
||||
catchObject.X = position;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Math.Abs(diff) < timeDiff / 3d)
|
||||
{
|
||||
if (diff > 0)
|
||||
{
|
||||
if (position - diff > 0)
|
||||
position -= diff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (position - diff < 1)
|
||||
position -= diff;
|
||||
}
|
||||
}
|
||||
if (Math.Abs(positionDiff * CatchPlayfield.BASE_WIDTH) < timeDiff / 3d)
|
||||
applyOffset(ref position, positionDiff);
|
||||
|
||||
catchObject.X = position;
|
||||
|
||||
lastStartX = position;
|
||||
lastPosition = position;
|
||||
lastStartTime = startTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a random offset in a random direction to a position, ensuring that the final position remains within the boundary of the playfield.
|
||||
/// </summary>
|
||||
/// <param name="position">The position which the offset should be applied to.</param>
|
||||
/// <param name="maxOffset">The maximum offset, cannot exceed 20px.</param>
|
||||
private void applyRandomOffset(ref float position, double maxOffset)
|
||||
{
|
||||
bool right = RNG.NextBool();
|
||||
float rand = Math.Min(20, (float)RNG.NextDouble(0, maxOffset)) / CatchPlayfield.BASE_WIDTH;
|
||||
|
||||
if (right)
|
||||
{
|
||||
// Clamp to the right bound
|
||||
if (position + rand <= 1)
|
||||
position += rand;
|
||||
else
|
||||
position -= rand;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clamp to the left bound
|
||||
if (position - rand >= 0)
|
||||
position -= rand;
|
||||
else
|
||||
position += rand;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies an offset to a position, ensuring that the final position remains within the boundary of the playfield.
|
||||
/// </summary>
|
||||
/// <param name="position">The position which the offset should be applied to.</param>
|
||||
/// <param name="amount">The amount to offset by.</param>
|
||||
private void applyOffset(ref float position, float amount)
|
||||
{
|
||||
if (amount > 0)
|
||||
{
|
||||
// Clamp to the right bound
|
||||
if (position + amount < 1)
|
||||
position += amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clamp to the left bound
|
||||
if (position + amount > 0)
|
||||
position += amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -354,9 +354,9 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
judgementResults = new List<JudgementResult>();
|
||||
});
|
||||
|
||||
AddUntilStep(() => Beatmap.Value.Track.CurrentTime == 0, "Beatmap at 0");
|
||||
AddUntilStep(() => currentPlayer.IsCurrentScreen(), "Wait until player is loaded");
|
||||
AddUntilStep(() => allJudgedFired, "Wait for all judged");
|
||||
AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0);
|
||||
AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen());
|
||||
AddUntilStep("Wait for all judged", () => allJudgedFired);
|
||||
}
|
||||
|
||||
private class ScoreAccessibleReplayPlayer : ReplayPlayer
|
||||
|
@ -25,8 +25,8 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
protected override void AddCheckSteps()
|
||||
{
|
||||
AddUntilStep(() => ((ScoreAccessiblePlayer)Player).ScoreProcessor.TotalScore.Value > 0, "score above zero");
|
||||
AddUntilStep(() => ((ScoreAccessiblePlayer)Player).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0), "key counter counted keys");
|
||||
AddUntilStep("score above zero", () => ((ScoreAccessiblePlayer)Player).ScoreProcessor.TotalScore.Value > 0);
|
||||
AddUntilStep("key counter counted keys", () => ((ScoreAccessiblePlayer)Player).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0));
|
||||
}
|
||||
|
||||
private class ScoreAccessiblePlayer : Player
|
||||
|
@ -98,7 +98,7 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
setupUserSettings();
|
||||
AddStep("Start player loader", () => songSelect.Push(playerLoader = new DimAccessiblePlayerLoader(player = new DimAccessiblePlayer())));
|
||||
AddUntilStep(() => playerLoader?.IsLoaded ?? false, "Wait for Player Loader to load");
|
||||
AddUntilStep("Wait for Player Loader to load", () => playerLoader?.IsLoaded ?? false);
|
||||
AddAssert("Background retained from song select", () => songSelect.IsBackgroundCurrent());
|
||||
AddStep("Trigger background preview", () =>
|
||||
{
|
||||
@ -220,7 +220,7 @@ namespace osu.Game.Tests.Visual
|
||||
AddAssert("Screen is undimmed", () => songSelect.IsBackgroundUndimmed());
|
||||
}
|
||||
|
||||
private void waitForDim() => AddWaitStep(5, "Wait for dim");
|
||||
private void waitForDim() => AddWaitStep("Wait for dim", 5);
|
||||
|
||||
private void createFakeStoryboard() => AddStep("Create storyboard", () =>
|
||||
{
|
||||
@ -249,14 +249,14 @@ namespace osu.Game.Tests.Visual
|
||||
Ready = true,
|
||||
}));
|
||||
});
|
||||
AddUntilStep(() => playerLoader.IsLoaded, "Wait for Player Loader to load");
|
||||
AddUntilStep("Wait for Player Loader to load", () => playerLoader.IsLoaded);
|
||||
AddStep("Move mouse to center of screen", () => InputManager.MoveMouseTo(playerLoader.ScreenPos));
|
||||
AddUntilStep(() => player.IsLoaded, "Wait for player to load");
|
||||
AddUntilStep("Wait for player to load", () => player.IsLoaded);
|
||||
}
|
||||
|
||||
private void setupUserSettings()
|
||||
{
|
||||
AddUntilStep(() => songSelect.Carousel.SelectedBeatmap != null, "Song select has selection");
|
||||
AddUntilStep("Song select has selection", () => songSelect.Carousel.SelectedBeatmap != null);
|
||||
AddStep("Set default user settings", () =>
|
||||
{
|
||||
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { new OsuModNoFail() });
|
||||
|
@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual
|
||||
carousel.BeatmapSetsChanged = () => changed = true;
|
||||
carousel.BeatmapSets = beatmapSets;
|
||||
});
|
||||
AddUntilStep(() => changed, "Wait for load");
|
||||
AddUntilStep("Wait for load", () => changed);
|
||||
}
|
||||
|
||||
private void ensureRandomFetchSuccess() =>
|
||||
@ -214,7 +214,7 @@ namespace osu.Game.Tests.Visual
|
||||
checkSelected(3, 2);
|
||||
|
||||
AddStep("Un-filter (debounce)", () => carousel.Filter(new FilterCriteria()));
|
||||
AddUntilStep(() => !carousel.PendingFilterTask, "Wait for debounce");
|
||||
AddUntilStep("Wait for debounce", () => !carousel.PendingFilterTask);
|
||||
checkVisibleItemCount(diff: false, count: set_count);
|
||||
checkVisibleItemCount(diff: true, count: 3);
|
||||
|
||||
@ -327,13 +327,13 @@ namespace osu.Game.Tests.Visual
|
||||
AddStep("Remove first", () => carousel.RemoveBeatmapSet(carousel.BeatmapSets.First()));
|
||||
checkSelected(1);
|
||||
|
||||
AddUntilStep(() =>
|
||||
AddUntilStep("Remove all", () =>
|
||||
{
|
||||
if (!carousel.BeatmapSets.Any()) return true;
|
||||
|
||||
carousel.RemoveBeatmapSet(carousel.BeatmapSets.Last());
|
||||
return false;
|
||||
}, "Remove all");
|
||||
});
|
||||
|
||||
checkNoSelection();
|
||||
}
|
||||
|
@ -56,11 +56,11 @@ namespace osu.Game.Tests.Visual
|
||||
// select part is redundant, but wait for load isn't
|
||||
selectBeatmap(Beatmap.Value.Beatmap);
|
||||
|
||||
AddWaitStep(3);
|
||||
AddWaitStep("wait for select", 3);
|
||||
|
||||
AddStep("hide", () => { infoWedge.State = Visibility.Hidden; });
|
||||
|
||||
AddWaitStep(3);
|
||||
AddWaitStep("wait for hide", 3);
|
||||
|
||||
AddStep("show", () => { infoWedge.State = Visibility.Visible; });
|
||||
|
||||
@ -135,7 +135,7 @@ namespace osu.Game.Tests.Visual
|
||||
infoWedge.Beatmap = Beatmap.Value = b == null ? Beatmap.Default : new TestWorkingBeatmap(b);
|
||||
});
|
||||
|
||||
AddUntilStep(() => infoWedge.Info != infoBefore, "wait for async load");
|
||||
AddUntilStep("wait for async load", () => infoWedge.Info != infoBefore);
|
||||
}
|
||||
|
||||
private IBeatmap createTestBeatmap(RulesetInfo ruleset)
|
||||
|
@ -90,7 +90,7 @@ namespace osu.Game.Tests.Visual
|
||||
AddStep("set second channel", () => channelTabControl.Current.Value = channelTabControl.Items.Skip(1).First());
|
||||
AddAssert("selector tab is inactive", () => !channelTabControl.ChannelSelectorActive.Value);
|
||||
|
||||
AddUntilStep(() =>
|
||||
AddUntilStep("remove all channels", () =>
|
||||
{
|
||||
var first = channelTabControl.Items.First();
|
||||
if (first.Name == "+")
|
||||
@ -98,7 +98,7 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
channelTabControl.RemoveChannel(first);
|
||||
return false;
|
||||
}, "remove all channels");
|
||||
});
|
||||
|
||||
AddAssert("selector tab is active", () => channelTabControl.ChannelSelectorActive.Value);
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ namespace osu.Game.Tests.Visual
|
||||
Scheduler.AddDelayed(() => newLine.Message = new DummyMessage(completeText ?? text), delay);
|
||||
});
|
||||
|
||||
AddUntilStep(() => textContainer.All(line => line.Message is DummyMessage), $"wait for msg #{echoCounter}");
|
||||
AddUntilStep($"wait for msg #{echoCounter}", () => textContainer.All(line => line.Message is DummyMessage));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,16 +2,31 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Screens.Menu;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseDisclaimer : ScreenTestCase
|
||||
{
|
||||
[Cached(typeof(IAPIProvider))]
|
||||
private readonly DummyAPIAccess api = new DummyAPIAccess();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
LoadScreen(new Disclaimer());
|
||||
AddStep("load disclaimer", () => LoadScreen(new Disclaimer()));
|
||||
|
||||
AddStep("toggle support", () =>
|
||||
{
|
||||
api.LocalUser.Value = new User
|
||||
{
|
||||
Username = api.LocalUser.Value.Username,
|
||||
Id = api.LocalUser.Value.Id,
|
||||
IsSupporter = !api.LocalUser.Value.IsSupporter,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,9 +32,9 @@ namespace osu.Game.Tests.Visual
|
||||
var text = holdForMenuButton.Children.OfType<SpriteText>().First();
|
||||
|
||||
AddStep("Trigger text fade in", () => InputManager.MoveMouseTo(holdForMenuButton));
|
||||
AddUntilStep(() => text.IsPresent && !exitAction, "Text visible");
|
||||
AddUntilStep("Text visible", () => text.IsPresent && !exitAction);
|
||||
AddStep("Trigger text fade out", () => InputManager.MoveMouseTo(Vector2.One));
|
||||
AddUntilStep(() => !text.IsPresent && !exitAction, "Text is not visible");
|
||||
AddUntilStep("Text is not visible", () => !text.IsPresent && !exitAction);
|
||||
|
||||
AddStep("Trigger exit action", () =>
|
||||
{
|
||||
@ -47,7 +47,7 @@ namespace osu.Game.Tests.Visual
|
||||
AddAssert("action not triggered", () => !exitAction);
|
||||
|
||||
AddStep("Trigger exit action", () => InputManager.PressButton(MouseButton.Left));
|
||||
AddUntilStep(() => exitAction, $"{nameof(holdForMenuButton.Action)} was triggered");
|
||||
AddUntilStep($"{nameof(holdForMenuButton.Action)} was triggered", () => exitAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
AddStep("start confirming", () => overlay.Begin());
|
||||
|
||||
AddUntilStep(() => fired, "wait until confirmed");
|
||||
AddUntilStep("wait until confirmed", () => fired);
|
||||
}
|
||||
|
||||
private class TestHoldToConfirmOverlay : ExitConfirmOverlay
|
||||
|
@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
AddStep("move mouse to top left", () => InputManager.MoveMouseTo(box1.ScreenSpaceDrawQuad.Centre));
|
||||
|
||||
AddUntilStep(() => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle, "Wait for all idle");
|
||||
AddUntilStep("Wait for all idle", () => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle);
|
||||
|
||||
AddStep("nudge mouse", () => InputManager.MoveMouseTo(box1.ScreenSpaceDrawQuad.Centre + new Vector2(1)));
|
||||
|
||||
@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual
|
||||
AddAssert("check idle", () => !box3.IsIdle);
|
||||
AddAssert("check idle", () => !box4.IsIdle);
|
||||
|
||||
AddUntilStep(() => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle, "Wait for all idle");
|
||||
AddUntilStep("Wait for all idle", () => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -96,13 +96,13 @@ namespace osu.Game.Tests.Visual
|
||||
AddStep("move mouse", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre));
|
||||
|
||||
AddAssert("check not idle", () => !box1.IsIdle && !box2.IsIdle && !box3.IsIdle && !box4.IsIdle);
|
||||
AddUntilStep(() => box1.IsIdle, "Wait for idle");
|
||||
AddUntilStep("Wait for idle", () => box1.IsIdle);
|
||||
AddAssert("check not idle", () => !box2.IsIdle && !box3.IsIdle && !box4.IsIdle);
|
||||
AddUntilStep(() => box2.IsIdle, "Wait for idle");
|
||||
AddUntilStep("Wait for idle", () => box2.IsIdle);
|
||||
AddAssert("check not idle", () => !box3.IsIdle && !box4.IsIdle);
|
||||
AddUntilStep(() => box3.IsIdle, "Wait for idle");
|
||||
AddUntilStep("Wait for idle", () => box3.IsIdle);
|
||||
|
||||
AddUntilStep(() => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle, "Wait for all idle");
|
||||
AddUntilStep("Wait for all idle", () => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle);
|
||||
}
|
||||
|
||||
private class IdleTrackingBox : CompositeDrawable
|
||||
|
@ -25,30 +25,30 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
bool logoVisible = false;
|
||||
AddStep("almost instant display", () => Child = loader = new TestLoader(250));
|
||||
AddUntilStep(() =>
|
||||
AddUntilStep("loaded", () =>
|
||||
{
|
||||
logoVisible = loader.Logo?.Alpha > 0;
|
||||
return loader.Logo != null && loader.ScreenLoaded;
|
||||
}, "loaded");
|
||||
});
|
||||
AddAssert("logo not visible", () => !logoVisible);
|
||||
|
||||
AddStep("short load", () => Child = loader = new TestLoader(800));
|
||||
AddUntilStep(() =>
|
||||
AddUntilStep("loaded", () =>
|
||||
{
|
||||
logoVisible = loader.Logo?.Alpha > 0;
|
||||
return loader.Logo != null && loader.ScreenLoaded;
|
||||
}, "loaded");
|
||||
});
|
||||
AddAssert("logo visible", () => logoVisible);
|
||||
AddUntilStep(() => loader.Logo?.Alpha == 0, "logo gone");
|
||||
AddUntilStep("logo gone", () => loader.Logo?.Alpha == 0);
|
||||
|
||||
AddStep("longer load", () => Child = loader = new TestLoader(1400));
|
||||
AddUntilStep(() =>
|
||||
AddUntilStep("loaded", () =>
|
||||
{
|
||||
logoVisible = loader.Logo?.Alpha > 0;
|
||||
return loader.Logo != null && loader.ScreenLoaded;
|
||||
}, "loaded");
|
||||
});
|
||||
AddAssert("logo visible", () => logoVisible);
|
||||
AddUntilStep(() => loader.Logo?.Alpha == 0, "logo gone");
|
||||
AddUntilStep("logo gone", () => loader.Logo?.Alpha == 0);
|
||||
}
|
||||
|
||||
private class TestLoader : Loader
|
||||
|
@ -111,7 +111,7 @@ namespace osu.Game.Tests.Visual
|
||||
settings.ApplyButton.Action.Invoke();
|
||||
});
|
||||
|
||||
AddUntilStep(() => !settings.ErrorText.IsPresent, "error not displayed");
|
||||
AddUntilStep("error not displayed", () => !settings.ErrorText.IsPresent);
|
||||
}
|
||||
|
||||
private class TestRoomSettings : MatchSettingsOverlay
|
||||
|
@ -208,22 +208,22 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
checkLabelColor(Color4.White);
|
||||
selectNext(mod);
|
||||
AddWaitStep(1, "wait for changing colour");
|
||||
AddWaitStep("wait for changing colour", 1);
|
||||
checkLabelColor(colour);
|
||||
selectPrevious(mod);
|
||||
AddWaitStep(1, "wait for changing colour");
|
||||
AddWaitStep("wait for changing colour", 1);
|
||||
checkLabelColor(Color4.White);
|
||||
}
|
||||
|
||||
private void testRankedText(Mod mod)
|
||||
{
|
||||
AddWaitStep(1, "wait for fade");
|
||||
AddWaitStep("wait for fade", 1);
|
||||
AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0);
|
||||
selectNext(mod);
|
||||
AddWaitStep(1, "wait for fade");
|
||||
AddWaitStep("wait for fade", 1);
|
||||
AddAssert("check for unranked", () => modSelect.UnrankedLabel.Alpha != 0);
|
||||
selectPrevious(mod);
|
||||
AddWaitStep(1, "wait for fade");
|
||||
AddWaitStep("wait for fade", 1);
|
||||
AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0);
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ namespace osu.Game.Tests.Visual
|
||||
setState(Visibility.Hidden);
|
||||
|
||||
AddRepeatStep(@"add many simple", sendManyNotifications, 3);
|
||||
AddWaitStep(5);
|
||||
AddWaitStep("wait some", 5);
|
||||
|
||||
checkProgressingCount(0);
|
||||
|
||||
@ -70,7 +70,7 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
AddAssert("Displayed count is 33", () => manager.UnreadCount.Value == 33);
|
||||
|
||||
AddWaitStep(10);
|
||||
AddWaitStep("wait some", 10);
|
||||
|
||||
checkProgressingCount(0);
|
||||
|
||||
|
@ -46,7 +46,7 @@ namespace osu.Game.Tests.Visual
|
||||
[Test]
|
||||
public void TestPauseAfterFail()
|
||||
{
|
||||
AddUntilStep(() => Player.HasFailed, "wait for fail");
|
||||
AddUntilStep("wait for fail", () => Player.HasFailed);
|
||||
|
||||
AddAssert("fail overlay shown", () => Player.FailOverlayVisible);
|
||||
|
||||
@ -59,14 +59,14 @@ namespace osu.Game.Tests.Visual
|
||||
[Test]
|
||||
public void TestExitFromPause()
|
||||
{
|
||||
AddUntilStep(() =>
|
||||
AddUntilStep("keep trying to pause", () =>
|
||||
{
|
||||
Player.Pause();
|
||||
return Player.PauseOverlayVisible;
|
||||
}, "keep trying to pause");
|
||||
});
|
||||
|
||||
AddStep("exit", () => Player.Exit());
|
||||
AddUntilStep(() => !Player.IsCurrentScreen(), "player exited");
|
||||
AddUntilStep("player exited", () => !Player.IsCurrentScreen());
|
||||
}
|
||||
|
||||
protected override bool AllowFail => true;
|
||||
|
@ -112,10 +112,10 @@ namespace osu.Game.Tests.Visual
|
||||
createSongSelect();
|
||||
AddAssert("dummy selected", () => songSelect.CurrentBeatmap == defaultBeatmap);
|
||||
|
||||
AddUntilStep(() => songSelect.CurrentBeatmapDetailsBeatmap == defaultBeatmap, "dummy shown on wedge");
|
||||
AddUntilStep("dummy shown on wedge", () => songSelect.CurrentBeatmapDetailsBeatmap == defaultBeatmap);
|
||||
|
||||
addManyTestMaps();
|
||||
AddWaitStep(3);
|
||||
AddWaitStep("wait for select", 3);
|
||||
|
||||
AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap);
|
||||
}
|
||||
@ -125,7 +125,7 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
createSongSelect();
|
||||
addManyTestMaps();
|
||||
AddWaitStep(3);
|
||||
AddWaitStep("wait for add", 3);
|
||||
|
||||
AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap);
|
||||
|
||||
@ -142,7 +142,7 @@ namespace osu.Game.Tests.Visual
|
||||
createSongSelect();
|
||||
changeRuleset(2);
|
||||
importForRuleset(0);
|
||||
AddUntilStep(() => songSelect.Carousel.SelectedBeatmap == null, "no selection");
|
||||
AddUntilStep("no selection", () => songSelect.Carousel.SelectedBeatmap == null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -152,13 +152,13 @@ namespace osu.Game.Tests.Visual
|
||||
changeRuleset(2);
|
||||
importForRuleset(2);
|
||||
importForRuleset(1);
|
||||
AddUntilStep(() => songSelect.Carousel.SelectedBeatmap.RulesetID == 2, "has selection");
|
||||
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap.RulesetID == 2);
|
||||
|
||||
changeRuleset(1);
|
||||
AddUntilStep(() => songSelect.Carousel.SelectedBeatmap.RulesetID == 1, "has selection");
|
||||
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap.RulesetID == 1);
|
||||
|
||||
changeRuleset(0);
|
||||
AddUntilStep(() => songSelect.Carousel.SelectedBeatmap == null, "no selection");
|
||||
AddUntilStep("no selection", () => songSelect.Carousel.SelectedBeatmap == null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -196,7 +196,7 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
createSongSelect();
|
||||
addManyTestMaps();
|
||||
AddUntilStep(() => songSelect.Carousel.SelectedBeatmap != null, "has selection");
|
||||
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap != null);
|
||||
|
||||
bool startRequested = false;
|
||||
|
||||
@ -225,7 +225,7 @@ namespace osu.Game.Tests.Visual
|
||||
private void createSongSelect()
|
||||
{
|
||||
AddStep("create song select", () => LoadScreen(songSelect = new TestSongSelect()));
|
||||
AddUntilStep(() => songSelect.IsCurrentScreen(), "wait for present");
|
||||
AddUntilStep("wait for present", () => songSelect.IsCurrentScreen());
|
||||
}
|
||||
|
||||
private void addManyTestMaps()
|
||||
|
@ -37,15 +37,15 @@ namespace osu.Game.Tests.Visual
|
||||
AllowResults = false,
|
||||
})));
|
||||
|
||||
AddUntilStep(() => loader.IsCurrentScreen(), "wait for current");
|
||||
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
|
||||
|
||||
AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre));
|
||||
|
||||
AddUntilStep(() => !loader.IsCurrentScreen(), "wait for no longer current");
|
||||
AddUntilStep("wait for no longer current", () => !loader.IsCurrentScreen());
|
||||
|
||||
AddStep("exit loader", () => loader.Exit());
|
||||
|
||||
AddUntilStep(() => !loader.IsAlive, "wait for no longer alive");
|
||||
AddUntilStep("wait for no longer alive", () => !loader.IsAlive);
|
||||
|
||||
AddStep("load slow dummy beatmap", () =>
|
||||
{
|
||||
@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual
|
||||
Scheduler.AddDelayed(() => slow.Ready = true, 5000);
|
||||
});
|
||||
|
||||
AddUntilStep(() => !loader.IsCurrentScreen(), "wait for no longer current");
|
||||
AddUntilStep("wait for no longer current", () => !loader.IsCurrentScreen());
|
||||
}
|
||||
|
||||
protected class SlowLoadPlayer : Player
|
||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
protected override void AddCheckSteps()
|
||||
{
|
||||
AddUntilStep(() =>
|
||||
AddUntilStep("no leaked beatmaps", () =>
|
||||
{
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
@ -26,9 +26,9 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
workingWeakReferences.ForEachAlive(_ => count++);
|
||||
return count == 1;
|
||||
}, "no leaked beatmaps");
|
||||
});
|
||||
|
||||
AddUntilStep(() =>
|
||||
AddUntilStep("no leaked players", () =>
|
||||
{
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
@ -36,7 +36,7 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
playerWeakReferences.ForEachAlive(_ => count++);
|
||||
return count == 1;
|
||||
}, "no leaked players");
|
||||
});
|
||||
}
|
||||
|
||||
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock clock)
|
||||
|
@ -22,8 +22,8 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
protected override void AddCheckSteps()
|
||||
{
|
||||
AddUntilStep(() => ((ScoreAccessibleReplayPlayer)Player).ScoreProcessor.TotalScore.Value > 0, "score above zero");
|
||||
AddUntilStep(() => ((ScoreAccessibleReplayPlayer)Player).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0), "key counter counted keys");
|
||||
AddUntilStep("score above zero", () => ((ScoreAccessibleReplayPlayer)Player).ScoreProcessor.TotalScore.Value > 0);
|
||||
AddUntilStep("key counter counted keys", () => ((ScoreAccessibleReplayPlayer)Player).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0));
|
||||
}
|
||||
|
||||
private class ScoreAccessibleReplayPlayer : ReplayPlayer
|
||||
|
@ -74,7 +74,7 @@ namespace osu.Game.Tests.Visual
|
||||
}
|
||||
|
||||
private void pushNext() => AddStep(@"push next screen", () => ((TestScreen)screenStack.CurrentScreen).PushNext());
|
||||
private void waitForCurrent() => AddUntilStep(() => screenStack.CurrentScreen.IsCurrentScreen(), "current screen");
|
||||
private void waitForCurrent() => AddUntilStep("current screen", () => screenStack.CurrentScreen.IsCurrentScreen());
|
||||
|
||||
private abstract class TestScreen : OsuScreen
|
||||
{
|
||||
|
@ -46,23 +46,23 @@ namespace osu.Game.Tests.Visual
|
||||
Origin = Anchor.TopLeft,
|
||||
});
|
||||
|
||||
AddWaitStep(5);
|
||||
AddWaitStep("wait some", 5);
|
||||
AddAssert("ensure not created", () => graph.CreationCount == 0);
|
||||
|
||||
AddStep("display values", displayNewValues);
|
||||
AddWaitStep(5);
|
||||
AddUntilStep(() => graph.CreationCount == 1, "wait for creation count");
|
||||
AddWaitStep("wait some", 5);
|
||||
AddUntilStep("wait for creation count", () => graph.CreationCount == 1);
|
||||
|
||||
AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking);
|
||||
AddWaitStep(5);
|
||||
AddUntilStep(() => graph.CreationCount == 1, "wait for creation count");
|
||||
AddWaitStep("wait some", 5);
|
||||
AddUntilStep("wait for creation count", () => graph.CreationCount == 1);
|
||||
|
||||
AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking);
|
||||
AddWaitStep(5);
|
||||
AddUntilStep(() => graph.CreationCount == 1, "wait for creation count");
|
||||
AddWaitStep("wait some", 5);
|
||||
AddUntilStep("wait for creation count", () => graph.CreationCount == 1);
|
||||
AddRepeatStep("New Values", displayNewValues, 5);
|
||||
|
||||
AddWaitStep(5);
|
||||
AddWaitStep("wait some", 5);
|
||||
AddAssert("ensure debounced", () => graph.CreationCount == 2);
|
||||
}
|
||||
|
||||
|
@ -36,18 +36,18 @@ namespace osu.Game.Tests.Visual
|
||||
api.Queue(req);
|
||||
|
||||
AddStep("load null beatmap", () => beatmapBindable.Value = null);
|
||||
AddUntilStep(() => backgroundSprite.ChildCount == 1, "wait for cleanup...");
|
||||
AddUntilStep("wait for cleanup...", () => backgroundSprite.ChildCount == 1);
|
||||
AddStep("load imported beatmap", () => beatmapBindable.Value = imported.Beatmaps.First());
|
||||
AddUntilStep(() => backgroundSprite.ChildCount == 1, "wait for cleanup...");
|
||||
AddUntilStep("wait for cleanup...", () => backgroundSprite.ChildCount == 1);
|
||||
|
||||
if (api.IsLoggedIn)
|
||||
{
|
||||
AddUntilStep(() => req.Result != null, "wait for api response");
|
||||
AddUntilStep("wait for api response", () => req.Result != null);
|
||||
AddStep("load online beatmap", () => beatmapBindable.Value = new BeatmapInfo
|
||||
{
|
||||
BeatmapSet = req.Result?.ToBeatmapSet(rulesets)
|
||||
});
|
||||
AddUntilStep(() => backgroundSprite.ChildCount == 1, "wait for cleanup...");
|
||||
AddUntilStep("wait for cleanup...", () => backgroundSprite.ChildCount == 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -108,7 +108,7 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
private void checkSupporterTag(bool isSupporter)
|
||||
{
|
||||
AddUntilStep(() => profile.Header.User != null, "wait for load");
|
||||
AddUntilStep("wait for load", () => profile.Header.User != null);
|
||||
if (isSupporter)
|
||||
AddAssert("is supporter", () => profile.Header.SupporterTag.Alpha == 1);
|
||||
else
|
||||
|
@ -1,12 +1,13 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Graphics;
|
||||
@ -25,16 +26,17 @@ namespace osu.Game.Screens.Menu
|
||||
private SpriteIcon icon;
|
||||
private Color4 iconColour;
|
||||
private LinkFlowContainer textFlow;
|
||||
private LinkFlowContainer supportFlow;
|
||||
|
||||
public override bool HideOverlaysOnEnter => true;
|
||||
public override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled;
|
||||
|
||||
public override bool CursorVisible => false;
|
||||
|
||||
private readonly List<Drawable> supporterDrawables = new List<Drawable>();
|
||||
private Drawable heart;
|
||||
|
||||
private const float icon_y = -85;
|
||||
private const float icon_size = 30;
|
||||
|
||||
private readonly Bindable<User> currentUser = new Bindable<User>();
|
||||
|
||||
@ -53,19 +55,39 @@ namespace osu.Game.Screens.Menu
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Icon = FontAwesome.fa_warning,
|
||||
Size = new Vector2(30),
|
||||
Size = new Vector2(icon_size),
|
||||
Y = icon_y,
|
||||
},
|
||||
textFlow = new LinkFlowContainer
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding(50),
|
||||
TextAnchor = Anchor.TopCentre,
|
||||
Y = -110,
|
||||
Direction = FillDirection.Vertical,
|
||||
Y = icon_y + icon_size,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Spacing = new Vector2(0, 2),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
textFlow = new LinkFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
TextAnchor = Anchor.TopCentre,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Spacing = new Vector2(0, 2),
|
||||
},
|
||||
supportFlow = new LinkFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
TextAnchor = Anchor.TopCentre,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Alpha = 0,
|
||||
Spacing = new Vector2(0, 2),
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -88,28 +110,45 @@ namespace osu.Game.Screens.Menu
|
||||
textFlow.NewParagraph();
|
||||
textFlow.NewParagraph();
|
||||
|
||||
supporterDrawables.AddRange(textFlow.AddText("Consider becoming an ", format));
|
||||
supporterDrawables.AddRange(textFlow.AddLink("osu!supporter", "https://osu.ppy.sh/home/support", creationParameters: format));
|
||||
supporterDrawables.AddRange(textFlow.AddText(" to help support the game", format));
|
||||
|
||||
supporterDrawables.Add(heart = textFlow.AddIcon(FontAwesome.fa_heart, t =>
|
||||
{
|
||||
t.Padding = new MarginPadding { Left = 5 };
|
||||
t.Font = t.Font.With(size: 12);
|
||||
t.Colour = colours.Pink;
|
||||
t.Origin = Anchor.Centre;
|
||||
}).First());
|
||||
|
||||
iconColour = colours.Yellow;
|
||||
|
||||
currentUser.BindTo(api.LocalUser);
|
||||
currentUser.BindValueChanged(e =>
|
||||
{
|
||||
supportFlow.Children.ForEach(d => d.FadeOut().Expire());
|
||||
|
||||
if (e.NewValue.IsSupporter)
|
||||
supporterDrawables.ForEach(d => d.FadeOut(500, Easing.OutQuint).Expire());
|
||||
{
|
||||
supportFlow.AddText("Thank you for supporting osu!", format);
|
||||
}
|
||||
else
|
||||
{
|
||||
supportFlow.AddText("Consider becoming an ", format);
|
||||
supportFlow.AddLink("osu!supporter", "https://osu.ppy.sh/home/support", creationParameters: format);
|
||||
supportFlow.AddText(" to help support the game", format);
|
||||
}
|
||||
|
||||
heart = supportFlow.AddIcon(FontAwesome.fa_heart, t =>
|
||||
{
|
||||
t.Padding = new MarginPadding { Left = 5 };
|
||||
t.Font = t.Font.With(size: 12);
|
||||
t.Origin = Anchor.Centre;
|
||||
t.Colour = colours.Pink;
|
||||
}).First();
|
||||
|
||||
if (IsLoaded)
|
||||
animateHeart();
|
||||
|
||||
if (supportFlow.IsPresent)
|
||||
supportFlow.FadeInFromZero(500);
|
||||
}, true);
|
||||
}
|
||||
|
||||
private void animateHeart()
|
||||
{
|
||||
heart.FlashColour(Color4.White, 750, Easing.OutQuint).Loop();
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
@ -128,7 +167,9 @@ namespace osu.Game.Screens.Menu
|
||||
.MoveToY(icon_y, 160, Easing.InCirc)
|
||||
.RotateTo(0, 160, Easing.InCirc);
|
||||
|
||||
supporterDrawables.ForEach(d => d.FadeOut().Delay(2000).FadeIn(500));
|
||||
supportFlow.FadeOut().Delay(2000).FadeIn(500);
|
||||
|
||||
animateHeart();
|
||||
|
||||
this
|
||||
.FadeInFromZero(500)
|
||||
@ -136,8 +177,6 @@ namespace osu.Game.Screens.Menu
|
||||
.FadeOut(250)
|
||||
.ScaleTo(0.9f, 250, Easing.InQuint)
|
||||
.Finally(d => this.Push(intro));
|
||||
|
||||
heart.FlashColour(Color4.White, 750, Easing.OutQuint).Loop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.Screens.Play;
|
||||
|
||||
namespace osu.Game.Storyboards.Drawables
|
||||
{
|
||||
@ -55,9 +56,12 @@ namespace osu.Game.Storyboards.Drawables
|
||||
});
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(FileStore fileStore)
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(FileStore fileStore, GameplayClock clock)
|
||||
{
|
||||
if (clock != null)
|
||||
Clock = clock;
|
||||
|
||||
dependencies.Cache(new TextureStore(new TextureLoaderStore(fileStore.Store), false, scaleAdjust: 1));
|
||||
|
||||
foreach (var layer in Storyboard.Layers)
|
||||
|
@ -16,7 +16,7 @@
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.128.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2019.315.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2019.319.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||
|
@ -105,8 +105,8 @@
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.128.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2019.315.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.315.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2019.319.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.319.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||
|
Loading…
Reference in New Issue
Block a user