1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 13:37:25 +08:00

Merge branch 'master' into results-screen-scaling

This commit is contained in:
Salman Ahmed 2022-05-09 11:11:55 +03:00 committed by GitHub
commit 1677f1d696
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 135 additions and 36 deletions

View File

@ -55,7 +55,10 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
AddMoveStep(end_time, 0);
AddClickStep(MouseButton.Left);
AddMoveStep(start_time, 0);
AddAssert("duration is positive", () => ((BananaShower)CurrentBlueprint.HitObject).Duration > 0);
AddClickStep(MouseButton.Right);
AddAssert("start time is correct", () => Precision.AlmostEquals(LastObject.HitObject.StartTime, start_time));
AddAssert("end time is correct", () => Precision.AlmostEquals(LastObject.HitObject.GetEndTime(), end_time));

View File

@ -1,6 +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 osu.Framework.Input.Events;
using osu.Game.Rulesets.Catch.Edit.Blueprints.Components;
using osu.Game.Rulesets.Catch.Objects;
@ -13,11 +14,21 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
{
private readonly TimeSpanOutline outline;
private double placementStartTime;
private double placementEndTime;
public BananaShowerPlacementBlueprint()
{
InternalChild = outline = new TimeSpanOutline();
}
protected override void LoadComplete()
{
base.LoadComplete();
BeginPlacement();
}
protected override void Update()
{
base.Update();
@ -38,13 +49,6 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
case PlacementState.Active:
if (e.Button != MouseButton.Right) break;
// If the duration is negative, swap the start and the end time to make the duration positive.
if (HitObject.Duration < 0)
{
HitObject.StartTime = HitObject.EndTime;
HitObject.Duration = -HitObject.Duration;
}
EndPlacement(HitObject.Duration > 0);
return true;
}
@ -61,13 +65,16 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
switch (PlacementActive)
{
case PlacementState.Waiting:
HitObject.StartTime = time;
placementStartTime = placementEndTime = time;
break;
case PlacementState.Active:
HitObject.EndTime = time;
placementEndTime = time;
break;
}
HitObject.StartTime = Math.Min(placementStartTime, placementEndTime);
HitObject.EndTime = Math.Max(placementStartTime, placementEndTime);
}
}
}

View File

@ -47,6 +47,8 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
base.LoadComplete();
inputManager = GetContainingInputManager();
BeginPlacement();
}
protected override bool OnMouseDown(MouseDownEvent e)

View File

@ -451,6 +451,36 @@ namespace osu.Game.Tests.Visual.UserInterface
AddAssert("mod select hidden", () => modSelectScreen.State.Value == Visibility.Hidden);
}
[Test]
public void TestColumnHiding()
{
AddStep("create screen", () => Child = modSelectScreen = new UserModSelectScreen
{
RelativeSizeAxes = Axes.Both,
State = { Value = Visibility.Visible },
SelectedMods = { BindTarget = SelectedMods },
IsValidMod = mod => mod.Type == ModType.DifficultyIncrease || mod.Type == ModType.Conversion
});
waitForColumnLoad();
changeRuleset(0);
AddAssert("two columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 2);
AddStep("unset filter", () => modSelectScreen.IsValidMod = _ => true);
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
AddStep("filter out everything", () => modSelectScreen.IsValidMod = _ => false);
AddAssert("no columns visible", () => this.ChildrenOfType<ModColumn>().All(col => !col.IsPresent));
AddStep("hide", () => modSelectScreen.Hide());
AddStep("set filter for 3 columns", () => modSelectScreen.IsValidMod = mod => mod.Type == ModType.DifficultyReduction
|| mod.Type == ModType.Automation
|| mod.Type == ModType.Conversion);
AddStep("show", () => modSelectScreen.Show());
AddUntilStep("3 columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 3);
}
private void waitForColumnLoad() => AddUntilStep("all column content loaded",
() => modSelectScreen.ChildrenOfType<ModColumn>().Any() && modSelectScreen.ChildrenOfType<ModColumn>().All(column => column.IsLoaded && column.ItemsLoaded));

View File

@ -153,7 +153,17 @@ namespace osu.Game.Beatmaps
}
};
Task.Run(() => cacheDownloadRequest.PerformAsync());
Task.Run(async () =>
{
try
{
await cacheDownloadRequest.PerformAsync();
}
catch
{
// Prevent throwing unobserved exceptions, as they will be logged from the network request to the log file anyway.
}
});
}
private bool checkLocalCache(BeatmapSetInfo set, BeatmapInfo beatmapInfo)

View File

@ -431,9 +431,10 @@ namespace osu.Game.Beatmaps.Formats
OmitFirstBarLine = omitFirstBarSignature,
};
bool isOsuRuleset = beatmap.BeatmapInfo.Ruleset.OnlineID == 0;
// scrolling rulesets use effect points rather than difficulty points for scroll speed adjustments.
if (!isOsuRuleset)
int onlineRulesetID = beatmap.BeatmapInfo.Ruleset.OnlineID;
// osu!taiko and osu!mania use effect points rather than difficulty points for scroll speed adjustments.
if (onlineRulesetID == 1 || onlineRulesetID == 3)
effectPoint.ScrollSpeed = speedMultiplier;
addControlPoint(time, effectPoint, timingChange);

View File

@ -183,15 +183,15 @@ namespace osu.Game.Beatmaps.Formats
SampleControlPoint lastRelevantSamplePoint = null;
DifficultyControlPoint lastRelevantDifficultyPoint = null;
bool isOsuRuleset = onlineRulesetID == 0;
// In osu!taiko and osu!mania, a scroll speed is stored as "slider velocity" in legacy formats.
// In that case, a scrolling speed change is a global effect and per-hit object difficulty control points are ignored.
bool scrollSpeedEncodedAsSliderVelocity = onlineRulesetID == 1 || onlineRulesetID == 3;
// iterate over hitobjects and pull out all required sample and difficulty changes
extractDifficultyControlPoints(beatmap.HitObjects);
extractSampleControlPoints(beatmap.HitObjects);
// handle scroll speed, which is stored as "slider velocity" in legacy formats.
// this is relevant for scrolling ruleset beatmaps.
if (!isOsuRuleset)
if (scrollSpeedEncodedAsSliderVelocity)
{
foreach (var point in legacyControlPoints.EffectPoints)
legacyControlPoints.Add(point.Time, new DifficultyControlPoint { SliderVelocity = point.ScrollSpeed });
@ -242,7 +242,7 @@ namespace osu.Game.Beatmaps.Formats
IEnumerable<DifficultyControlPoint> collectDifficultyControlPoints(IEnumerable<HitObject> hitObjects)
{
if (!isOsuRuleset)
if (scrollSpeedEncodedAsSliderVelocity)
yield break;
foreach (var hitObject in hitObjects)

View File

@ -55,8 +55,18 @@ namespace osu.Game.Overlays.Mods
}
}
/// <summary>
/// Determines whether this column should accept user input.
/// </summary>
public Bindable<bool> Active = new BindableBool(true);
private readonly Bindable<bool> allFiltered = new BindableBool();
/// <summary>
/// True if all of the panels in this column have been filtered out by the current <see cref="Filter"/>.
/// </summary>
public IBindable<bool> AllFiltered => allFiltered;
/// <summary>
/// List of mods marked as selected in this column.
/// </summary>
@ -339,6 +349,8 @@ namespace osu.Game.Overlays.Mods
panel.ApplyFilter(Filter);
}
allFiltered.Value = panelFlow.All(panel => panel.Filtered.Value);
if (toggleAllCheckbox != null && !SelectionAnimationRunning)
{
toggleAllCheckbox.Alpha = panelFlow.Any(panel => !panel.Filtered.Value) ? 1 : 0;

View File

@ -129,7 +129,6 @@ namespace osu.Game.Overlays.Mods
Shear = new Vector2(SHEAR, 0),
RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X,
Spacing = new Vector2(10, 0),
Margin = new MarginPadding { Horizontal = 70 },
Children = new[]
{
@ -237,12 +236,21 @@ namespace osu.Game.Overlays.Mods
}
private ColumnDimContainer createModColumnContent(ModType modType, Key[]? toggleKeys = null)
=> new ColumnDimContainer(CreateModColumn(modType, toggleKeys))
{
var column = CreateModColumn(modType, toggleKeys).With(column =>
{
column.Filter = IsValidMod;
// spacing applied here rather than via `columnFlow.Spacing` to avoid uneven gaps when some of the columns are hidden.
column.Margin = new MarginPadding { Right = 10 };
});
return new ColumnDimContainer(column)
{
AutoSizeAxes = Axes.X,
RelativeSizeAxes = Axes.Y,
RequestScroll = column => columnScroll.ScrollIntoView(column, extraScroll: 140)
RequestScroll = col => columnScroll.ScrollIntoView(col, extraScroll: 140),
};
}
private ShearedButton[] createDefaultFooterButtons()
=> new[]
@ -351,6 +359,8 @@ namespace osu.Game.Overlays.Mods
#region Transition handling
private const float distance = 700;
protected override void PopIn()
{
const double fade_in_duration = 400;
@ -362,13 +372,26 @@ namespace osu.Game.Overlays.Mods
.FadeIn(fade_in_duration / 2, Easing.OutQuint)
.ScaleTo(1, fade_in_duration, Easing.OutElastic);
int nonFilteredColumnCount = 0;
for (int i = 0; i < columnFlow.Count; i++)
{
columnFlow[i].Column
.TopLevelContent
.Delay(i * 30)
.MoveToY(0, fade_in_duration, Easing.OutQuint)
.FadeIn(fade_in_duration, Easing.OutQuint);
var column = columnFlow[i].Column;
double delay = column.AllFiltered.Value ? 0 : nonFilteredColumnCount * 30;
double duration = column.AllFiltered.Value ? 0 : fade_in_duration;
float startingYPosition = 0;
if (!column.AllFiltered.Value)
startingYPosition = nonFilteredColumnCount % 2 == 0 ? -distance : distance;
column.TopLevelContent
.MoveToY(startingYPosition)
.Delay(delay)
.MoveToY(0, duration, Easing.OutQuint)
.FadeIn(duration, Easing.OutQuint);
if (!column.AllFiltered.Value)
nonFilteredColumnCount += 1;
}
}
@ -382,16 +405,24 @@ namespace osu.Game.Overlays.Mods
.FadeOut(fade_out_duration / 2, Easing.OutQuint)
.ScaleTo(0.75f, fade_out_duration, Easing.OutQuint);
int nonFilteredColumnCount = 0;
for (int i = 0; i < columnFlow.Count; i++)
{
const float distance = 700;
var column = columnFlow[i].Column;
double duration = column.AllFiltered.Value ? 0 : fade_out_duration;
float newYPosition = 0;
if (!column.AllFiltered.Value)
newYPosition = nonFilteredColumnCount % 2 == 0 ? -distance : distance;
column.FlushPendingSelections();
column.TopLevelContent
.MoveToY(i % 2 == 0 ? -distance : distance, fade_out_duration, Easing.OutQuint)
.FadeOut(fade_out_duration, Easing.OutQuint);
.MoveToY(newYPosition, duration, Easing.OutQuint)
.FadeOut(duration, Easing.OutQuint);
if (!column.AllFiltered.Value)
nonFilteredColumnCount += 1;
}
}
@ -557,17 +588,20 @@ namespace osu.Game.Overlays.Mods
protected override void LoadComplete()
{
base.LoadComplete();
Active.BindValueChanged(_ => updateDim(), true);
Active.BindValueChanged(_ => updateState());
Column.AllFiltered.BindValueChanged(_ => updateState(), true);
FinishTransforms();
}
protected override bool RequiresChildrenUpdate => base.RequiresChildrenUpdate || Column.SelectionAnimationRunning;
private void updateDim()
private void updateState()
{
Colour4 targetColour;
if (Active.Value)
Column.Alpha = Column.AllFiltered.Value ? 0 : 1;
if (Column.Active.Value)
targetColour = Colour4.White;
else
targetColour = IsHovered ? colours.GrayC : colours.Gray8;
@ -586,14 +620,14 @@ namespace osu.Game.Overlays.Mods
protected override bool OnHover(HoverEvent e)
{
base.OnHover(e);
updateDim();
updateState();
return Active.Value;
}
protected override void OnHoverLost(HoverLostEvent e)
{
base.OnHoverLost(e);
updateDim();
updateState();
}
}

View File

@ -24,7 +24,7 @@ namespace osu.Game.Utils
var options = new SentryOptions
{
Dsn = "https://5e342cd55f294edebdc9ad604d28bbd3@sentry.io/1255255",
Dsn = "https://ad9f78529cef40ac874afb95a9aca04e@sentry.ppy.sh/2",
Release = game.Version
};