1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 01:52:55 +08:00

Merge branch 'master' into fl-skill

This commit is contained in:
MBmasher 2021-09-15 11:50:25 +10:00 committed by GitHub
commit 31baac5879
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 115 additions and 57 deletions

View File

@ -15,13 +15,13 @@ namespace osu.Game.Rulesets.Osu.Tests
{
protected override string ResourceAssembly => "osu.Game.Rulesets.Osu";
[TestCase(6.7568168283591499d, "diffcalc-test")]
[TestCase(1.0348244046058293d, "zero-length-sliders")]
[TestCase(6.6634445062299665d, "diffcalc-test")]
[TestCase(1.0414203870195022d, "zero-length-sliders")]
public void Test(double expected, string name)
=> base.Test(expected, name);
[TestCase(8.4783236764532557d, "diffcalc-test")]
[TestCase(1.2708532136987165d, "zero-length-sliders")]
[TestCase(8.3858089051603368d, "diffcalc-test")]
[TestCase(1.2723279173428435d, "zero-length-sliders")]
public void TestClockRateAdjusted(double expected, string name)
=> Test(expected, name, new OsuModDoubleTime());

View File

@ -35,7 +35,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
double flashlightRating = Math.Sqrt(skills[2].DifficultyValue()) * difficulty_multiplier;
double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2;
double baseAimPerformance = Math.Pow(5 * Math.Max(1, aimRating / 0.0675) - 4, 3) / 100000;
double baseSpeedPerformance = Math.Pow(5 * Math.Max(1, speedRating / 0.0675) - 4, 3) / 100000;
double basePerformance = Math.Pow(Math.Pow(baseAimPerformance, 1.1) + Math.Pow(baseSpeedPerformance, 1.1), 1 / 1.1);
double starRating = basePerformance > 0.00001 ? Math.Cbrt(1.12) * 0.027 * (Math.Cbrt(100000 / Math.Pow(2, 1 / 1.1) * basePerformance) + 4) : 0;
HitWindows hitWindows = new OsuHitWindows();
hitWindows.SetDifficulty(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty);

View File

@ -3,6 +3,7 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -82,7 +83,23 @@ namespace osu.Game.Tests.Visual.Multiplayer
}
[Test]
public void TestJoinRoomWithPassword()
public void TestJoinRoomWithIncorrectPassword()
{
DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null;
AddStep("add room", () => RoomManager.AddRooms(1, withPassword: true));
AddStep("select room", () => InputManager.Key(Key.Down));
AddStep("attempt join room", () => InputManager.Key(Key.Enter));
AddUntilStep("password prompt appeared", () => (passwordEntryPopover = InputManager.ChildrenOfType<DrawableLoungeRoom.PasswordEntryPopover>().FirstOrDefault()) != null);
AddStep("enter password in text box", () => passwordEntryPopover.ChildrenOfType<TextBox>().First().Text = "wrong");
AddStep("press join room button", () => passwordEntryPopover.ChildrenOfType<OsuButton>().First().TriggerClick());
AddAssert("room not joined", () => loungeScreen.IsCurrentScreen());
AddUntilStep("password prompt still visible", () => passwordEntryPopover.State.Value == Visibility.Visible);
}
[Test]
public void TestJoinRoomWithCorrectPassword()
{
DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null;

View File

@ -38,6 +38,33 @@ namespace osu.Game.Extensions
return repeatDelegate;
}
/// <summary>
/// Shakes this drawable.
/// </summary>
/// <param name="target">The target to shake.</param>
/// <param name="shakeDuration">The length of a single shake.</param>
/// <param name="shakeMagnitude">Pixels of displacement per shake.</param>
/// <param name="maximumLength">The maximum length the shake should last.</param>
public static void Shake(this Drawable target, double shakeDuration = 80, float shakeMagnitude = 8, double? maximumLength = null)
{
// if we don't have enough time, don't bother shaking.
if (maximumLength < shakeDuration * 2)
return;
var sequence = target.MoveToX(shakeMagnitude, shakeDuration / 2, Easing.OutSine).Then()
.MoveToX(-shakeMagnitude, shakeDuration, Easing.InOutSine).Then();
// if we don't have enough time for the second shake, skip it.
if (!maximumLength.HasValue || maximumLength >= shakeDuration * 4)
{
sequence = sequence
.MoveToX(shakeMagnitude, shakeDuration, Easing.InOutSine).Then()
.MoveToX(-shakeMagnitude, shakeDuration, Easing.InOutSine).Then();
}
sequence.MoveToX(0, shakeDuration / 2, Easing.InSine);
}
/// <summary>
/// Accepts a delta vector in screen-space coordinates and converts it to one which can be applied to this drawable's position.
/// </summary>

View File

@ -1,8 +1,8 @@
// 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.Containers;
using osu.Game.Extensions;
namespace osu.Game.Graphics.Containers
{
@ -16,40 +16,10 @@ namespace osu.Game.Graphics.Containers
/// </summary>
public float ShakeDuration = 80;
/// <summary>
/// Total number of shakes. May be shortened if possible.
/// </summary>
public float TotalShakes = 4;
/// <summary>
/// Pixels of displacement per shake.
/// </summary>
public float ShakeMagnitude = 8;
/// <summary>
/// Shake the contents of this container.
/// </summary>
/// <param name="maximumLength">The maximum length the shake should last.</param>
public void Shake(double? maximumLength = null)
{
const float shake_amount = 8;
// if we don't have enough time, don't bother shaking.
if (maximumLength < ShakeDuration * 2)
return;
var sequence = this.MoveToX(shake_amount, ShakeDuration / 2, Easing.OutSine).Then()
.MoveToX(-shake_amount, ShakeDuration, Easing.InOutSine).Then();
// if we don't have enough time for the second shake, skip it.
if (!maximumLength.HasValue || maximumLength >= ShakeDuration * 4)
{
sequence = sequence
.MoveToX(shake_amount, ShakeDuration, Easing.InOutSine).Then()
.MoveToX(-shake_amount, ShakeDuration, Easing.InOutSine).Then();
}
sequence.MoveToX(0, ShakeDuration / 2, Easing.InSine);
}
public void Shake(double? maximumLength = null) => this.Shake(ShakeDuration, maximumLength: maximumLength);
}
}

View File

@ -87,9 +87,10 @@ namespace osu.Game.Screens.OnlinePlay.Components
currentJoinRoomRequest.Failure += exception =>
{
if (!(exception is OperationCanceledException))
Logger.Log($"Failed to join room: {exception}", level: LogLevel.Important);
onError?.Invoke(exception.ToString());
if (exception is OperationCanceledException)
return;
onError?.Invoke(exception.Message);
};
api.Queue(currentJoinRoomRequest);

View File

@ -1,7 +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 osu.Framework.Allocation;
using osu.Framework.Audio;
@ -15,6 +14,9 @@ using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Extensions;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Input.Bindings;
@ -120,7 +122,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
}
}
public Popover GetPopover() => new PasswordEntryPopover(Room) { JoinRequested = lounge.Join };
public Popover GetPopover() => new PasswordEntryPopover(Room);
public MenuItem[] ContextMenuItems => new MenuItem[]
{
@ -176,7 +178,8 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
{
private readonly Room room;
public Action<Room, string> JoinRequested;
[Resolved(canBeNull: true)]
private LoungeSubScreen lounge { get; set; }
public PasswordEntryPopover(Room room)
{
@ -184,30 +187,61 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
}
private OsuPasswordTextBox passwordTextbox;
private TriangleButton joinButton;
private OsuSpriteText errorText;
[BackgroundDependencyLoader]
private void load()
private void load(OsuColour colours)
{
Child = new FillFlowContainer
{
Margin = new MarginPadding(10),
Spacing = new Vector2(5),
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
passwordTextbox = new OsuPasswordTextBox
new FillFlowContainer
{
Width = 200,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5),
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
passwordTextbox = new OsuPasswordTextBox
{
Width = 200,
PlaceholderText = "password",
},
joinButton = new TriangleButton
{
Width = 80,
Text = "Join Room",
}
}
},
new TriangleButton
errorText = new OsuSpriteText
{
Width = 80,
Text = "Join Room",
Action = () => JoinRequested?.Invoke(room, passwordTextbox.Text)
}
Colour = colours.Red,
},
}
};
joinButton.Action = () => lounge?.Join(room, passwordTextbox.Text, null, joinFailed);
}
private void joinFailed(string error)
{
passwordTextbox.Text = string.Empty;
errorText.Text = error;
errorText
.FadeIn()
.FlashColour(Color4.White, 200)
.Delay(1000)
.FadeOutFromOne(1000, Easing.In);
Body.Shake();
}
protected override void LoadComplete()
@ -215,7 +249,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
base.LoadComplete();
Schedule(() => GetContainingInputManager().ChangeFocus(passwordTextbox));
passwordTextbox.OnCommit += (_, __) => JoinRequested?.Invoke(room, passwordTextbox.Text);
passwordTextbox.OnCommit += (_, __) => lounge?.Join(room, passwordTextbox.Text, null, joinFailed);
}
}
}

View File

@ -290,7 +290,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
popoverContainer.HidePopover();
}
public void Join(Room room, string password) => Schedule(() =>
public void Join(Room room, string password, Action<Room> onSuccess = null, Action<string> onFailure = null) => Schedule(() =>
{
if (joiningRoomOperation != null)
return;
@ -302,10 +302,12 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
Open(room);
joiningRoomOperation?.Dispose();
joiningRoomOperation = null;
}, _ =>
onSuccess?.Invoke(room);
}, error =>
{
joiningRoomOperation?.Dispose();
joiningRoomOperation = null;
onFailure?.Invoke(error);
});
});

View File

@ -23,7 +23,10 @@ namespace osu.Game.Tests.Beatmaps
protected abstract string ResourceAssembly { get; }
protected void Test(double expected, string name, params Mod[] mods)
=> Assert.AreEqual(expected, CreateDifficultyCalculator(getBeatmap(name)).Calculate(mods).StarRating);
{
// Platform-dependent math functions (Pow, Cbrt, Exp, etc) may result in minute differences.
Assert.That(CreateDifficultyCalculator(getBeatmap(name)).Calculate(mods).StarRating, Is.EqualTo(expected).Within(0.00001));
}
private WorkingBeatmap getBeatmap(string name)
{