1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-26 18:03:11 +08:00

Merge branch 'master' into fix-accuracy-formatting

This commit is contained in:
Bartłomiej Dach 2021-03-26 21:24:04 +01:00 committed by GitHub
commit e9289853fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 183 additions and 86 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,2 +1,6 @@
[General]
Version: 1.0
Version: 1.0
[Fonts]
HitCircleOverlap: 3
ScoreOverlap: 3

View File

@ -33,12 +33,18 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public SpinnerSpmCounter SpmCounter { get; private set; }
private Container<DrawableSpinnerTick> ticks;
private SpinnerBonusDisplay bonusDisplay;
private PausableSkinnableSound spinningSample;
private Bindable<bool> isSpinning;
private bool spinnerFrequencyModulate;
/// <summary>
/// The amount of bonus score gained from spinning after the required number of spins, for display purposes.
/// </summary>
public IBindable<double> GainedBonus => gainedBonus;
private readonly Bindable<double> gainedBonus = new Bindable<double>();
private const double fade_out_duration = 160;
public DrawableSpinner()
@ -67,7 +73,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
RelativeSizeAxes = Axes.Y,
Children = new Drawable[]
{
new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinnerDisc()),
new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinner()),
RotationTracker = new SpinnerRotationTracker(this)
}
},
@ -78,12 +84,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Y = 120,
Alpha = 0
},
bonusDisplay = new SpinnerBonusDisplay
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Y = -120,
},
spinningSample = new PausableSkinnableSound
{
Volume = { Value = 0 },
@ -298,6 +298,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
private void fadeInCounter() => SpmCounter.FadeIn(HitObject.TimeFadeIn);
private static readonly int score_per_tick = new SpinnerBonusTick.OsuSpinnerBonusTickJudgement().MaxNumericResult;
private int wholeSpins;
private void updateBonusScore()
@ -322,8 +324,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
if (tick != null)
{
tick.TriggerResult(true);
if (tick is DrawableSpinnerBonusTick)
bonusDisplay.SetBonusCount(spins - HitObject.SpinsRequired);
gainedBonus.Value = score_per_tick * (spins - HitObject.SpinsRequired);
}
wholeSpins++;

View File

@ -18,6 +18,6 @@ namespace osu.Game.Rulesets.Osu
SliderFollowCircle,
SliderBall,
SliderBody,
SpinnerBody
SpinnerBody,
}
}

View File

@ -0,0 +1,68 @@
// 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.Globalization;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects.Drawables;
namespace osu.Game.Rulesets.Osu.Skinning.Default
{
public class DefaultSpinner : CompositeDrawable
{
private DrawableSpinner drawableSpinner;
private OsuSpriteText bonusCounter;
public DefaultSpinner()
{
RelativeSizeAxes = Axes.Both;
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
}
[BackgroundDependencyLoader]
private void load(DrawableHitObject drawableHitObject)
{
drawableSpinner = (DrawableSpinner)drawableHitObject;
AddRangeInternal(new Drawable[]
{
new DefaultSpinnerDisc
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
bonusCounter = new OsuSpriteText
{
Alpha = 0,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = OsuFont.Numeric.With(size: 24),
Y = -120,
}
});
}
private IBindable<double> gainedBonus;
protected override void LoadComplete()
{
base.LoadComplete();
gainedBonus = drawableSpinner.GainedBonus.GetBoundCopy();
gainedBonus.BindValueChanged(bonus =>
{
bonusCounter.Text = bonus.NewValue.ToString(NumberFormatInfo.InvariantInfo);
bonusCounter.FadeOutFromOne(1500);
bonusCounter.ScaleTo(1.5f).Then().ScaleTo(1f, 1000, Easing.OutQuint);
});
}
}
}

View File

@ -40,14 +40,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
public DefaultSpinnerDisc()
{
RelativeSizeAxes = Axes.Both;
// we are slightly bigger than our parent, to clip the top and bottom of the circle
// this should probably be revisited when scaled spinners are a thing.
Scale = new Vector2(initial_scale);
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
}
[BackgroundDependencyLoader]

View File

@ -1,47 +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.Containers;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Osu.Objects;
namespace osu.Game.Rulesets.Osu.Skinning.Default
{
/// <summary>
/// Shows incremental bonus score achieved for a spinner.
/// </summary>
public class SpinnerBonusDisplay : CompositeDrawable
{
private static readonly int score_per_tick = new SpinnerBonusTick().CreateJudgement().MaxNumericResult;
private readonly OsuSpriteText bonusCounter;
public SpinnerBonusDisplay()
{
AutoSizeAxes = Axes.Both;
InternalChild = bonusCounter = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = OsuFont.Numeric.With(size: 24),
Alpha = 0,
};
}
private int displayedCount;
public void SetBonusCount(int count)
{
if (displayedCount == count)
return;
displayedCount = count;
bonusCounter.Text = $"{score_per_tick * count}";
bonusCounter.FadeOutFromOne(1500);
bonusCounter.ScaleTo(1.5f).Then().ScaleTo(1f, 1000, Easing.OutQuint);
}
}
}

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Globalization;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@ -32,6 +33,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
private Sprite spin;
private Sprite clear;
private LegacySpriteText bonusCounter;
[BackgroundDependencyLoader]
private void load(DrawableHitObject drawableHitObject, ISkinSource source)
{
@ -45,36 +48,67 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
DrawableSpinner = (DrawableSpinner)drawableHitObject;
AddRangeInternal(new[]
Container overlayContainer;
AddInternal(overlayContainer = new Container
{
spin = new Sprite
Depth = float.MinValue,
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
Anchor = Anchor.TopCentre,
Origin = Anchor.Centre,
Depth = float.MinValue,
Texture = source.GetTexture("spinner-spin"),
Scale = new Vector2(SPRITE_SCALE),
Y = SPINNER_TOP_OFFSET + 335,
},
clear = new Sprite
{
Alpha = 0,
Anchor = Anchor.TopCentre,
Origin = Anchor.Centre,
Depth = float.MinValue,
Texture = source.GetTexture("spinner-clear"),
Scale = new Vector2(SPRITE_SCALE),
Y = SPINNER_TOP_OFFSET + 115,
},
spin = new Sprite
{
Anchor = Anchor.TopCentre,
Origin = Anchor.Centre,
Texture = source.GetTexture("spinner-spin"),
Scale = new Vector2(SPRITE_SCALE),
Y = SPINNER_TOP_OFFSET + 335,
},
clear = new Sprite
{
Alpha = 0,
Anchor = Anchor.TopCentre,
Origin = Anchor.Centre,
Texture = source.GetTexture("spinner-clear"),
Scale = new Vector2(SPRITE_SCALE),
Y = SPINNER_TOP_OFFSET + 115,
},
}
});
bonusCounter = (source.GetDrawableComponent(new HUDSkinComponent(HUDSkinComponents.ScoreText)) as LegacySpriteText)?.With(c =>
{
c.Alpha = 0f;
c.Anchor = Anchor.TopCentre;
c.Origin = Anchor.Centre;
c.Font = c.Font.With(fixedWidth: false);
c.Scale = new Vector2(SPRITE_SCALE);
c.Y = SPINNER_TOP_OFFSET + 299;
});
if (bonusCounter != null)
overlayContainer.Add(bonusCounter);
}
private IBindable<double> gainedBonus;
private readonly Bindable<bool> completed = new Bindable<bool>();
protected override void LoadComplete()
{
base.LoadComplete();
if (bonusCounter != null)
{
gainedBonus = DrawableSpinner.GainedBonus.GetBoundCopy();
gainedBonus.BindValueChanged(bonus =>
{
bonusCounter.Text = bonus.NewValue.ToString(NumberFormatInfo.InvariantInfo);
bonusCounter.FadeOutFromOne(800, Easing.Out);
bonusCounter.ScaleTo(SPRITE_SCALE * 2f).Then().ScaleTo(SPRITE_SCALE * 1.28f, 800, Easing.Out);
});
}
completed.BindValueChanged(onCompletedChanged, true);
DrawableSpinner.ApplyCustomUpdateState += UpdateStateTransforms;

View File

@ -34,6 +34,7 @@ namespace osu.Game.Tests.Visual.UserInterface
public void SetUp() => Schedule(() =>
{
OsuSpriteText query;
OsuSpriteText general;
OsuSpriteText ruleset;
OsuSpriteText category;
OsuSpriteText genre;
@ -58,6 +59,7 @@ namespace osu.Game.Tests.Visual.UserInterface
Children = new Drawable[]
{
query = new OsuSpriteText(),
general = new OsuSpriteText(),
ruleset = new OsuSpriteText(),
category = new OsuSpriteText(),
genre = new OsuSpriteText(),
@ -71,6 +73,7 @@ namespace osu.Game.Tests.Visual.UserInterface
};
control.Query.BindValueChanged(q => query.Text = $"Query: {q.NewValue}", true);
control.General.BindCollectionChanged((u, v) => general.Text = $"General: {(control.General.Any() ? string.Join('.', control.General.Select(i => i.ToString().ToLowerInvariant())) : "")}", true);
control.Ruleset.BindValueChanged(r => ruleset.Text = $"Ruleset: {r.NewValue}", true);
control.Category.BindValueChanged(c => category.Text = $"Category: {c.NewValue}", true);
control.Genre.BindValueChanged(g => genre.Text = $"Genre: {g.NewValue}", true);

View File

@ -15,6 +15,9 @@ namespace osu.Game.Online.API.Requests
{
public class SearchBeatmapSetsRequest : APIRequest<SearchBeatmapSetsResponse>
{
[CanBeNull]
public IReadOnlyCollection<SearchGeneral> General { get; }
public SearchCategory SearchCategory { get; }
public SortCriteria SortCriteria { get; }
@ -45,6 +48,7 @@ namespace osu.Game.Online.API.Requests
string query,
RulesetInfo ruleset,
Cursor cursor = null,
IReadOnlyCollection<SearchGeneral> general = null,
SearchCategory searchCategory = SearchCategory.Any,
SortCriteria sortCriteria = SortCriteria.Ranked,
SortDirection sortDirection = SortDirection.Descending,
@ -59,6 +63,7 @@ namespace osu.Game.Online.API.Requests
this.ruleset = ruleset;
this.cursor = cursor;
General = general;
SearchCategory = searchCategory;
SortCriteria = sortCriteria;
SortDirection = sortDirection;
@ -75,6 +80,9 @@ namespace osu.Game.Online.API.Requests
var req = base.CreateWebRequest();
req.AddParameter("q", query);
if (General != null && General.Any())
req.AddParameter("c", string.Join('.', General.Select(e => e.ToString().ToLowerInvariant())));
if (ruleset.ID.HasValue)
req.AddParameter("m", ruleset.ID.Value.ToString());

View File

@ -123,13 +123,13 @@ namespace osu.Game.Online
{
if (attachedRequest.Progress == 1)
{
State.Value = DownloadState.Importing;
Progress.Value = 1;
State.Value = DownloadState.Importing;
}
else
{
State.Value = DownloadState.Downloading;
Progress.Value = attachedRequest.Progress;
State.Value = DownloadState.Downloading;
attachedRequest.Failure += onRequestFailure;
attachedRequest.DownloadProgressed += onRequestProgress;

View File

@ -45,6 +45,9 @@ namespace osu.Game.Online.Rooms
Progress.BindValueChanged(_ =>
{
if (State.Value != DownloadState.Downloading)
return;
// incoming progress changes are going to be at a very high rate.
// we don't want to flood the network with this, so rate limit how often we send progress updates.
if (progressUpdate?.Completed != false)

View File

@ -134,6 +134,7 @@ namespace osu.Game.Overlays.BeatmapListing
queueUpdateSearch(true);
});
searchControl.General.CollectionChanged += (_, __) => queueUpdateSearch();
searchControl.Ruleset.BindValueChanged(_ => queueUpdateSearch());
searchControl.Category.BindValueChanged(_ => queueUpdateSearch());
searchControl.Genre.BindValueChanged(_ => queueUpdateSearch());
@ -187,6 +188,7 @@ namespace osu.Game.Overlays.BeatmapListing
searchControl.Query.Value,
searchControl.Ruleset.Value,
lastResponse?.Cursor,
searchControl.General,
searchControl.Category.Value,
sortControl.Current.Value,
sortControl.SortDirection.Value,

View File

@ -29,6 +29,8 @@ namespace osu.Game.Overlays.BeatmapListing
public Bindable<string> Query => textBox.Current;
public BindableList<SearchGeneral> General => generalFilter.Current;
public Bindable<RulesetInfo> Ruleset => modeFilter.Current;
public Bindable<SearchCategory> Category => categoryFilter.Current;
@ -61,6 +63,7 @@ namespace osu.Game.Overlays.BeatmapListing
}
private readonly BeatmapSearchTextBox textBox;
private readonly BeatmapSearchMultipleSelectionFilterRow<SearchGeneral> generalFilter;
private readonly BeatmapSearchRulesetFilterRow modeFilter;
private readonly BeatmapSearchFilterRow<SearchCategory> categoryFilter;
private readonly BeatmapSearchFilterRow<SearchGenre> genreFilter;
@ -123,6 +126,7 @@ namespace osu.Game.Overlays.BeatmapListing
Padding = new MarginPadding { Horizontal = 10 },
Children = new Drawable[]
{
generalFilter = new BeatmapSearchMultipleSelectionFilterRow<SearchGeneral>(@"General"),
modeFilter = new BeatmapSearchRulesetFilterRow(),
categoryFilter = new BeatmapSearchFilterRow<SearchCategory>(@"Categories"),
genreFilter = new BeatmapSearchFilterRow<SearchGenre>(@"Genre"),

View File

@ -0,0 +1,19 @@
// 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.ComponentModel;
namespace osu.Game.Overlays.BeatmapListing
{
public enum SearchGeneral
{
[Description("Recommended difficulty")]
Recommended,
[Description("Include converted beatmaps")]
Converts,
[Description("Subscribed mappers")]
Follows
}
}

View File

@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Diagnostics;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
@ -170,7 +169,9 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
private void joinRequested(Room room)
{
Debug.Assert(joiningRoomOperation == null);
if (joiningRoomOperation != null)
return;
joiningRoomOperation = ongoingOperationTracker?.BeginOperation();
RoomManager?.JoinRoom(room, r =>