mirror of
https://github.com/ppy/osu.git
synced 2025-03-23 01:37:31 +08:00
Merge branch 'master' into match-subscreen-redesign
This commit is contained in:
commit
19d61c1255
@ -9,6 +9,7 @@ using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Replays;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using static osu.Game.Input.Handlers.ReplayInputHandler;
|
||||
|
||||
@ -24,6 +25,21 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
/// </summary>
|
||||
private const float relax_leniency = 3;
|
||||
|
||||
private bool isDownState;
|
||||
private bool wasLeft;
|
||||
|
||||
private OsuInputManager osuInputManager;
|
||||
|
||||
private ReplayState<OsuAction> state;
|
||||
private double lastStateChangeTime;
|
||||
|
||||
public void ApplyToDrawableRuleset(DrawableRuleset<OsuHitObject> drawableRuleset)
|
||||
{
|
||||
// grab the input manager for future use.
|
||||
osuInputManager = (OsuInputManager)drawableRuleset.KeyBindingInputManager;
|
||||
osuInputManager.AllowUserPresses = false;
|
||||
}
|
||||
|
||||
public void Update(Playfield playfield)
|
||||
{
|
||||
bool requiresHold = false;
|
||||
@ -63,11 +79,14 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
|
||||
if (requiresHit)
|
||||
{
|
||||
addAction(false);
|
||||
addAction(true);
|
||||
changeState(false);
|
||||
changeState(true);
|
||||
}
|
||||
|
||||
addAction(requiresHold);
|
||||
if (requiresHold)
|
||||
changeState(true);
|
||||
else if (isDownState && time - lastStateChangeTime > AutoGenerator.KEY_UP_DELAY)
|
||||
changeState(false);
|
||||
|
||||
void handleHitCircle(DrawableHitCircle circle)
|
||||
{
|
||||
@ -77,39 +96,28 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
Debug.Assert(circle.HitObject.HitWindows != null);
|
||||
requiresHit |= circle.HitObject.HitWindows.CanBeHit(time - circle.HitObject.StartTime);
|
||||
}
|
||||
}
|
||||
|
||||
private bool wasHit;
|
||||
private bool wasLeft;
|
||||
|
||||
private OsuInputManager osuInputManager;
|
||||
|
||||
private void addAction(bool hitting)
|
||||
{
|
||||
if (wasHit == hitting)
|
||||
return;
|
||||
|
||||
wasHit = hitting;
|
||||
|
||||
var state = new ReplayState<OsuAction>
|
||||
void changeState(bool down)
|
||||
{
|
||||
PressedActions = new List<OsuAction>()
|
||||
};
|
||||
if (isDownState == down)
|
||||
return;
|
||||
|
||||
if (hitting)
|
||||
{
|
||||
state.PressedActions.Add(wasLeft ? OsuAction.LeftButton : OsuAction.RightButton);
|
||||
wasLeft = !wasLeft;
|
||||
isDownState = down;
|
||||
lastStateChangeTime = time;
|
||||
|
||||
state = new ReplayState<OsuAction>
|
||||
{
|
||||
PressedActions = new List<OsuAction>()
|
||||
};
|
||||
|
||||
if (down)
|
||||
{
|
||||
state.PressedActions.Add(wasLeft ? OsuAction.LeftButton : OsuAction.RightButton);
|
||||
wasLeft = !wasLeft;
|
||||
}
|
||||
|
||||
state?.Apply(osuInputManager.CurrentState, osuInputManager);
|
||||
}
|
||||
|
||||
state.Apply(osuInputManager.CurrentState, osuInputManager);
|
||||
}
|
||||
|
||||
public void ApplyToDrawableRuleset(DrawableRuleset<OsuHitObject> drawableRuleset)
|
||||
{
|
||||
// grab the input manager for future use.
|
||||
osuInputManager = (OsuInputManager)drawableRuleset.KeyBindingInputManager;
|
||||
osuInputManager.AllowUserPresses = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,9 +91,44 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
AddStep("load dummy beatmap", () => ResetPlayer(false));
|
||||
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
|
||||
AddRepeatStep("move mouse", () => InputManager.MoveMouseTo(loader.VisualSettings.ScreenSpaceDrawQuad.TopLeft + (loader.VisualSettings.ScreenSpaceDrawQuad.BottomRight - loader.VisualSettings.ScreenSpaceDrawQuad.TopLeft) * RNG.NextSingle()), 20);
|
||||
|
||||
AddUntilStep("wait for load ready", () =>
|
||||
{
|
||||
moveMouse();
|
||||
return player.LoadState == LoadState.Ready;
|
||||
});
|
||||
AddRepeatStep("move mouse", moveMouse, 20);
|
||||
|
||||
AddAssert("loader still active", () => loader.IsCurrentScreen());
|
||||
AddUntilStep("loads after idle", () => !loader.IsCurrentScreen());
|
||||
|
||||
void moveMouse()
|
||||
{
|
||||
InputManager.MoveMouseTo(
|
||||
loader.VisualSettings.ScreenSpaceDrawQuad.TopLeft
|
||||
+ (loader.VisualSettings.ScreenSpaceDrawQuad.BottomRight - loader.VisualSettings.ScreenSpaceDrawQuad.TopLeft)
|
||||
* RNG.NextSingle());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBlockLoadViaFocus()
|
||||
{
|
||||
OsuFocusedOverlayContainer overlay = null;
|
||||
|
||||
AddStep("load dummy beatmap", () => ResetPlayer(false));
|
||||
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
|
||||
|
||||
AddStep("show focused overlay", () => { container.Add(overlay = new ChangelogOverlay { State = { Value = Visibility.Visible } }); });
|
||||
AddUntilStep("overlay visible", () => overlay.IsPresent);
|
||||
|
||||
AddUntilStep("wait for load ready", () => player.LoadState == LoadState.Ready);
|
||||
AddRepeatStep("twiddle thumbs", () => { }, 20);
|
||||
|
||||
AddAssert("loader still active", () => loader.IsCurrentScreen());
|
||||
|
||||
AddStep("hide overlay", () => overlay.Hide());
|
||||
AddUntilStep("loads after idle", () => !loader.IsCurrentScreen());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -159,13 +194,22 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMutedNotificationMasterVolume() => addVolumeSteps("master volume", () => audioManager.Volume.Value = 0, null, () => audioManager.Volume.IsDefault);
|
||||
public void TestMutedNotificationMasterVolume()
|
||||
{
|
||||
addVolumeSteps("master volume", () => audioManager.Volume.Value = 0, null, () => audioManager.Volume.IsDefault);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMutedNotificationTrackVolume() => addVolumeSteps("music volume", () => audioManager.VolumeTrack.Value = 0, null, () => audioManager.VolumeTrack.IsDefault);
|
||||
public void TestMutedNotificationTrackVolume()
|
||||
{
|
||||
addVolumeSteps("music volume", () => audioManager.VolumeTrack.Value = 0, null, () => audioManager.VolumeTrack.IsDefault);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMutedNotificationMuteButton() => addVolumeSteps("mute button", null, () => container.VolumeOverlay.IsMuted.Value = true, () => !container.VolumeOverlay.IsMuted.Value);
|
||||
public void TestMutedNotificationMuteButton()
|
||||
{
|
||||
addVolumeSteps("mute button", null, () => container.VolumeOverlay.IsMuted.Value = true, () => !container.VolumeOverlay.IsMuted.Value);
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Created for avoiding copy pasting code for the same steps.
|
||||
@ -179,7 +223,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddStep("reset notification lock", () => sessionStatics.GetBindable<bool>(Static.MutedAudioNotificationShownOnce).Value = false);
|
||||
|
||||
AddStep("load player", () => ResetPlayer(false, beforeLoad, afterLoad));
|
||||
AddUntilStep("wait for player", () => player.IsLoaded);
|
||||
AddUntilStep("wait for player", () => player.LoadState == LoadState.Ready);
|
||||
|
||||
AddAssert("check for notification", () => container.NotificationOverlay.UnreadCount.Value == 1);
|
||||
AddStep("click notification", () =>
|
||||
@ -193,6 +237,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
});
|
||||
|
||||
AddAssert("check " + volumeName, assert);
|
||||
|
||||
AddUntilStep("wait for player load", () => player.IsLoaded);
|
||||
}
|
||||
|
||||
private class TestPlayerLoaderContainer : Container
|
||||
|
@ -1,16 +1,16 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Screens.Multi.Components;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
@ -21,7 +21,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
private BeatmapManager beatmapManager { get; set; }
|
||||
|
||||
[Resolved]
|
||||
|
||||
private RulesetStore rulesetStore { get; set; }
|
||||
|
||||
[SetUp]
|
||||
@ -40,19 +39,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
private void createNewItem()
|
||||
{
|
||||
var set = beatmapManager.GetAllUsableBeatmapSetsEnumerable().First();
|
||||
var rulesets = rulesetStore.AvailableRulesets.ToList();
|
||||
|
||||
var beatmap = set.Beatmaps[RNG.Next(0, set.Beatmaps.Count)];
|
||||
|
||||
beatmap.BeatmapSet = set;
|
||||
beatmap.Metadata = set.Metadata;
|
||||
|
||||
Room.Playlist.Add(new PlaylistItem
|
||||
{
|
||||
ID = Room.Playlist.Count,
|
||||
Beatmap = { Value = beatmap },
|
||||
Ruleset = { Value = rulesets[RNG.Next(0, rulesets.Count)] },
|
||||
Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo },
|
||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||
RequiredMods =
|
||||
{
|
||||
new OsuModHardRock(),
|
||||
|
@ -117,6 +117,8 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
{
|
||||
base.LoadComplete();
|
||||
API.Login("Rhythm Champion", "osu!");
|
||||
|
||||
Dependencies.Get<SessionStatics>().Set(Static.MutedAudioNotificationShownOnce, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Replays
|
||||
#region Constants
|
||||
|
||||
// Shared amongst all modes
|
||||
protected const double KEY_UP_DELAY = 50;
|
||||
public const double KEY_UP_DELAY = 50;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -181,7 +181,7 @@ namespace osu.Game.Screens.Multi.Match
|
||||
}
|
||||
}, true);
|
||||
|
||||
SelectedItem.BindValueChanged(selectedItemChanged);
|
||||
SelectedItem.BindValueChanged(_ => Scheduler.AddOnce(selectedItemChanged));
|
||||
SelectedItem.Value = playlist.FirstOrDefault();
|
||||
|
||||
beatmapManager.ItemAdded += beatmapAdded;
|
||||
@ -195,14 +195,16 @@ namespace osu.Game.Screens.Multi.Match
|
||||
return base.OnExiting(next);
|
||||
}
|
||||
|
||||
private void selectedItemChanged(ValueChangedEvent<PlaylistItem> e)
|
||||
private void selectedItemChanged()
|
||||
{
|
||||
updateWorkingBeatmap();
|
||||
|
||||
Mods.Value = e.NewValue?.RequiredMods?.ToArray() ?? Array.Empty<Mod>();
|
||||
var item = SelectedItem.Value;
|
||||
|
||||
if (e.NewValue?.Ruleset != null)
|
||||
Ruleset.Value = e.NewValue.Ruleset.Value;
|
||||
Mods.Value = item?.RequiredMods?.ToArray() ?? Array.Empty<Mod>();
|
||||
|
||||
if (item?.Ruleset != null)
|
||||
Ruleset.Value = item.Ruleset.Value;
|
||||
}
|
||||
|
||||
private void updateWorkingBeatmap()
|
||||
|
@ -67,7 +67,14 @@ namespace osu.Game.Screens.Play
|
||||
}
|
||||
|
||||
private bool readyForPush =>
|
||||
player.LoadState == LoadState.Ready && (IsHovered || idleTracker.IsIdle.Value) && inputManager?.DraggedDrawable == null;
|
||||
// don't push unless the player is completely loaded
|
||||
player.LoadState == LoadState.Ready
|
||||
// don't push if the user is hovering one of the panes, unless they are idle.
|
||||
&& (IsHovered || idleTracker.IsIdle.Value)
|
||||
// don't push if the user is dragging a slider or otherwise.
|
||||
&& inputManager?.DraggedDrawable == null
|
||||
// don't push if a focused overlay is visible, like settings.
|
||||
&& inputManager?.FocusedDrawable == null;
|
||||
|
||||
private readonly Func<Player> createPlayer;
|
||||
|
||||
|
@ -42,8 +42,16 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
protected override bool OnStart()
|
||||
{
|
||||
if (Playlist.Count == 0)
|
||||
createNewItem();
|
||||
switch (Playlist.Count)
|
||||
{
|
||||
case 0:
|
||||
createNewItem();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
populateItemFromCurrent(Playlist.Single());
|
||||
break;
|
||||
}
|
||||
|
||||
this.Exit();
|
||||
|
||||
@ -55,13 +63,20 @@ namespace osu.Game.Screens.Select
|
||||
PlaylistItem item = new PlaylistItem
|
||||
{
|
||||
ID = (Playlist.LastOrDefault()?.ID + 1) ?? 0,
|
||||
Beatmap = { Value = Beatmap.Value.BeatmapInfo },
|
||||
Ruleset = { Value = Ruleset.Value }
|
||||
};
|
||||
|
||||
item.RequiredMods.AddRange(Mods.Value);
|
||||
populateItemFromCurrent(item);
|
||||
|
||||
Playlist.Add(item);
|
||||
}
|
||||
|
||||
private void populateItemFromCurrent(PlaylistItem item)
|
||||
{
|
||||
item.Beatmap.Value = Beatmap.Value.BeatmapInfo;
|
||||
item.Ruleset.Value = Ruleset.Value;
|
||||
|
||||
item.RequiredMods.Clear();
|
||||
item.RequiredMods.AddRange(Mods.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user