mirror of
https://github.com/ppy/osu.git
synced 2025-03-06 05:12:55 +08:00
Merge branch 'master' into improve-drag-selection
This commit is contained in:
commit
ab24e87013
@ -52,7 +52,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.1008.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.1008.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.1005.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.1011.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Transitive Dependencies">
|
<ItemGroup Label="Transitive Dependencies">
|
||||||
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
||||||
|
@ -36,5 +36,7 @@ namespace osu.Game.Rulesets.Catch.Edit
|
|||||||
|
|
||||||
return base.CreateHitObjectBlueprintFor(hitObject);
|
return base.CreateHitObjectBlueprintFor(hitObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected sealed override DragBox CreateDragBox() => new ScrollingDragBox(Composer.Playfield);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Catch.Mods
|
|||||||
{
|
{
|
||||||
this.playfield = playfield;
|
this.playfield = playfield;
|
||||||
|
|
||||||
FlashlightSize = new Vector2(0, GetSizeFor(0));
|
FlashlightSize = new Vector2(0, GetSize());
|
||||||
FlashlightSmoothness = 1.4f;
|
FlashlightSmoothness = 1.4f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,9 +66,9 @@ namespace osu.Game.Rulesets.Catch.Mods
|
|||||||
FlashlightPosition = playfield.CatcherArea.ToSpaceOfOtherDrawable(playfield.Catcher.DrawPosition, this);
|
FlashlightPosition = playfield.CatcherArea.ToSpaceOfOtherDrawable(playfield.Catcher.DrawPosition, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnComboChange(ValueChangedEvent<int> e)
|
protected override void UpdateFlashlightSize(float size)
|
||||||
{
|
{
|
||||||
this.TransformTo(nameof(FlashlightSize), new Vector2(0, GetSizeFor(e.NewValue)), FLASHLIGHT_FADE_DURATION);
|
this.TransformTo(nameof(FlashlightSize), new Vector2(0, size), FLASHLIGHT_FADE_DURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string FragmentShader => "CircularFlashlight";
|
protected override string FragmentShader => "CircularFlashlight";
|
||||||
|
@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
|||||||
countOk = score.Statistics.GetValueOrDefault(HitResult.Ok);
|
countOk = score.Statistics.GetValueOrDefault(HitResult.Ok);
|
||||||
countMeh = score.Statistics.GetValueOrDefault(HitResult.Meh);
|
countMeh = score.Statistics.GetValueOrDefault(HitResult.Meh);
|
||||||
countMiss = score.Statistics.GetValueOrDefault(HitResult.Miss);
|
countMiss = score.Statistics.GetValueOrDefault(HitResult.Miss);
|
||||||
scoreAccuracy = customAccuracy;
|
scoreAccuracy = calculateCustomAccuracy();
|
||||||
|
|
||||||
// Arbitrary initial value for scaling pp in order to standardize distributions across game modes.
|
// Arbitrary initial value for scaling pp in order to standardize distributions across game modes.
|
||||||
// The specific number has no intrinsic meaning and can be adjusted as needed.
|
// The specific number has no intrinsic meaning and can be adjusted as needed.
|
||||||
@ -73,6 +73,12 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Accuracy used to weight judgements independently from the score's actual accuracy.
|
/// Accuracy used to weight judgements independently from the score's actual accuracy.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private double customAccuracy => (countPerfect * 320 + countGreat * 300 + countGood * 200 + countOk * 100 + countMeh * 50) / (totalHits * 320);
|
private double calculateCustomAccuracy()
|
||||||
|
{
|
||||||
|
if (totalHits == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (countPerfect * 320 + countGreat * 300 + countGood * 200 + countOk * 100 + countMeh * 50) / (totalHits * 320);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,5 +33,7 @@ namespace osu.Game.Rulesets.Mania.Edit
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override SelectionHandler<HitObject> CreateSelectionHandler() => new ManiaSelectionHandler();
|
protected override SelectionHandler<HitObject> CreateSelectionHandler() => new ManiaSelectionHandler();
|
||||||
|
|
||||||
|
protected sealed override DragBox CreateDragBox() => new ScrollingDragBox(Composer.Playfield);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public ManiaFlashlight(ManiaModFlashlight modFlashlight)
|
public ManiaFlashlight(ManiaModFlashlight modFlashlight)
|
||||||
: base(modFlashlight)
|
: base(modFlashlight)
|
||||||
{
|
{
|
||||||
FlashlightSize = new Vector2(DrawWidth, GetSizeFor(0));
|
FlashlightSize = new Vector2(DrawWidth, GetSize());
|
||||||
|
|
||||||
AddLayout(flashlightProperties);
|
AddLayout(flashlightProperties);
|
||||||
}
|
}
|
||||||
@ -54,9 +54,9 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnComboChange(ValueChangedEvent<int> e)
|
protected override void UpdateFlashlightSize(float size)
|
||||||
{
|
{
|
||||||
this.TransformTo(nameof(FlashlightSize), new Vector2(DrawWidth, GetSizeFor(e.NewValue)), FLASHLIGHT_FADE_DURATION);
|
this.TransformTo(nameof(FlashlightSize), new Vector2(DrawWidth, size), FLASHLIGHT_FADE_DURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string FragmentShader => "RectangularFlashlight";
|
protected override string FragmentShader => "RectangularFlashlight";
|
||||||
|
@ -4,12 +4,14 @@
|
|||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Audio;
|
||||||
using osu.Game.Rulesets.Mania.Skinning.Default;
|
using osu.Game.Rulesets.Mania.Skinning.Default;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
@ -38,6 +40,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
private Container<DrawableHoldNoteTail> tailContainer;
|
private Container<DrawableHoldNoteTail> tailContainer;
|
||||||
private Container<DrawableHoldNoteTick> tickContainer;
|
private Container<DrawableHoldNoteTick> tickContainer;
|
||||||
|
|
||||||
|
private PausableSkinnableSound slidingSample;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains the size of the hold note covering the whole head/tail bounds. The size of this container changes as the hold note is being pressed.
|
/// Contains the size of the hold note covering the whole head/tail bounds. The size of this container changes as the hold note is being pressed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -108,6 +112,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
},
|
},
|
||||||
tickContainer = new Container<DrawableHoldNoteTick> { RelativeSizeAxes = Axes.Both },
|
tickContainer = new Container<DrawableHoldNoteTick> { RelativeSizeAxes = Axes.Both },
|
||||||
tailContainer = new Container<DrawableHoldNoteTail> { RelativeSizeAxes = Axes.Both },
|
tailContainer = new Container<DrawableHoldNoteTail> { RelativeSizeAxes = Axes.Both },
|
||||||
|
slidingSample = new PausableSkinnableSound { Looping = true }
|
||||||
});
|
});
|
||||||
|
|
||||||
maskedContents.AddRange(new[]
|
maskedContents.AddRange(new[]
|
||||||
@ -118,6 +123,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
isHitting.BindValueChanged(updateSlidingSample, true);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnApply()
|
protected override void OnApply()
|
||||||
{
|
{
|
||||||
base.OnApply();
|
base.OnApply();
|
||||||
@ -322,5 +334,38 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
HoldStartTime = null;
|
HoldStartTime = null;
|
||||||
isHitting.Value = false;
|
isHitting.Value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadSamples()
|
||||||
|
{
|
||||||
|
// Note: base.LoadSamples() isn't called since the slider plays the tail's hitsounds for the time being.
|
||||||
|
|
||||||
|
if (HitObject.SampleControlPoint == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}."
|
||||||
|
+ $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
slidingSample.Samples = HitObject.CreateSlidingSamples().Select(s => HitObject.SampleControlPoint.ApplyTo(s)).Cast<ISampleInfo>().ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void StopAllSamples()
|
||||||
|
{
|
||||||
|
base.StopAllSamples();
|
||||||
|
slidingSample?.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateSlidingSample(ValueChangedEvent<bool> tracking)
|
||||||
|
{
|
||||||
|
if (tracking.NewValue)
|
||||||
|
slidingSample?.Play();
|
||||||
|
else
|
||||||
|
slidingSample?.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFree()
|
||||||
|
{
|
||||||
|
slidingSample.Samples = null;
|
||||||
|
base.OnFree();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -89,13 +90,15 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
|||||||
|
|
||||||
Color4 colour;
|
Color4 colour;
|
||||||
|
|
||||||
|
const int total_colours = 7;
|
||||||
|
|
||||||
if (stage.IsSpecialColumn(column))
|
if (stage.IsSpecialColumn(column))
|
||||||
colour = new Color4(159, 101, 255, 255);
|
colour = new Color4(159, 101, 255, 255);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (column % 8)
|
switch (column % total_colours)
|
||||||
{
|
{
|
||||||
default:
|
case 0:
|
||||||
colour = new Color4(240, 216, 0, 255);
|
colour = new Color4(240, 216, 0, 255);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -112,20 +115,19 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
colour = new Color4(178, 0, 240, 255);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
colour = new Color4(0, 96, 240, 255);
|
colour = new Color4(0, 96, 240, 255);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case 5:
|
||||||
colour = new Color4(0, 226, 240, 255);
|
colour = new Color4(0, 226, 240, 255);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 6:
|
||||||
colour = new Color4(0, 240, 96, 255);
|
colour = new Color4(0, 240, 96, 255);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
followDelay = modFlashlight.FollowDelay.Value;
|
followDelay = modFlashlight.FollowDelay.Value;
|
||||||
|
|
||||||
FlashlightSize = new Vector2(0, GetSizeFor(0));
|
FlashlightSize = new Vector2(0, GetSize());
|
||||||
FlashlightSmoothness = 1.4f;
|
FlashlightSmoothness = 1.4f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,9 +83,9 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
return base.OnMouseMove(e);
|
return base.OnMouseMove(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnComboChange(ValueChangedEvent<int> e)
|
protected override void UpdateFlashlightSize(float size)
|
||||||
{
|
{
|
||||||
this.TransformTo(nameof(FlashlightSize), new Vector2(0, GetSizeFor(e.NewValue)), FLASHLIGHT_FADE_DURATION);
|
this.TransformTo(nameof(FlashlightSize), new Vector2(0, size), FLASHLIGHT_FADE_DURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string FragmentShader => "CircularFlashlight";
|
protected override string FragmentShader => "CircularFlashlight";
|
||||||
|
@ -186,17 +186,22 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
private Vector2? lastPosition;
|
private Vector2? lastPosition;
|
||||||
|
|
||||||
|
private bool rewinding;
|
||||||
|
|
||||||
public void UpdateProgress(double completionProgress)
|
public void UpdateProgress(double completionProgress)
|
||||||
{
|
{
|
||||||
Position = drawableSlider.HitObject.CurvePositionAt(completionProgress);
|
Position = drawableSlider.HitObject.CurvePositionAt(completionProgress);
|
||||||
|
|
||||||
var diff = lastPosition.HasValue ? lastPosition.Value - Position : Position - drawableSlider.HitObject.CurvePositionAt(completionProgress + 0.01f);
|
var diff = lastPosition.HasValue ? lastPosition.Value - Position : Position - drawableSlider.HitObject.CurvePositionAt(completionProgress + 0.01f);
|
||||||
|
|
||||||
|
if (Clock.ElapsedFrameTime != 0)
|
||||||
|
rewinding = Clock.ElapsedFrameTime < 0;
|
||||||
|
|
||||||
// Ensure the value is substantially high enough to allow for Atan2 to get a valid angle.
|
// Ensure the value is substantially high enough to allow for Atan2 to get a valid angle.
|
||||||
if (diff.LengthFast < 0.01f)
|
if (diff.LengthFast < 0.01f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ball.Rotation = -90 + (float)(-Math.Atan2(diff.X, diff.Y) * 180 / Math.PI);
|
ball.Rotation = -90 + (float)(-Math.Atan2(diff.X, diff.Y) * 180 / Math.PI) + (rewinding ? 180 : 0);
|
||||||
lastPosition = Position;
|
lastPosition = Position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,21 +34,6 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
|
|
||||||
public override IList<HitSampleInfo> AuxiliarySamples => CreateSlidingSamples().Concat(TailSamples).ToArray();
|
public override IList<HitSampleInfo> AuxiliarySamples => CreateSlidingSamples().Concat(TailSamples).ToArray();
|
||||||
|
|
||||||
public IList<HitSampleInfo> CreateSlidingSamples()
|
|
||||||
{
|
|
||||||
var slidingSamples = new List<HitSampleInfo>();
|
|
||||||
|
|
||||||
var normalSample = Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL);
|
|
||||||
if (normalSample != null)
|
|
||||||
slidingSamples.Add(normalSample.With("sliderslide"));
|
|
||||||
|
|
||||||
var whistleSample = Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_WHISTLE);
|
|
||||||
if (whistleSample != null)
|
|
||||||
slidingSamples.Add(whistleSample.With("sliderwhistle"));
|
|
||||||
|
|
||||||
return slidingSamples;
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly Cached<Vector2> endPositionCache = new Cached<Vector2>();
|
private readonly Cached<Vector2> endPositionCache = new Cached<Vector2>();
|
||||||
|
|
||||||
public override Vector2 EndPosition => endPositionCache.IsValid ? endPositionCache.Value : endPositionCache.Value = Position + this.CurvePositionAt(1);
|
public override Vector2 EndPosition => endPositionCache.IsValid ? endPositionCache.Value : endPositionCache.Value = Position + this.CurvePositionAt(1);
|
||||||
|
@ -47,21 +47,21 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
|||||||
{
|
{
|
||||||
this.taikoPlayfield = taikoPlayfield;
|
this.taikoPlayfield = taikoPlayfield;
|
||||||
|
|
||||||
FlashlightSize = getSizeFor(0);
|
FlashlightSize = adjustSize(GetSize());
|
||||||
FlashlightSmoothness = 1.4f;
|
FlashlightSmoothness = 1.4f;
|
||||||
|
|
||||||
AddLayout(flashlightProperties);
|
AddLayout(flashlightProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector2 getSizeFor(int combo)
|
private Vector2 adjustSize(float size)
|
||||||
{
|
{
|
||||||
// Preserve flashlight size through the playfield's aspect adjustment.
|
// Preserve flashlight size through the playfield's aspect adjustment.
|
||||||
return new Vector2(0, GetSizeFor(combo) * taikoPlayfield.DrawHeight / TaikoPlayfield.DEFAULT_HEIGHT);
|
return new Vector2(0, size * taikoPlayfield.DrawHeight / TaikoPlayfield.DEFAULT_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnComboChange(ValueChangedEvent<int> e)
|
protected override void UpdateFlashlightSize(float size)
|
||||||
{
|
{
|
||||||
this.TransformTo(nameof(FlashlightSize), getSizeFor(e.NewValue), FLASHLIGHT_FADE_DURATION);
|
this.TransformTo(nameof(FlashlightSize), adjustSize(size), FLASHLIGHT_FADE_DURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string FragmentShader => "CircularFlashlight";
|
protected override string FragmentShader => "CircularFlashlight";
|
||||||
@ -75,7 +75,7 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
|||||||
FlashlightPosition = ToLocalSpace(taikoPlayfield.HitTarget.ScreenSpaceDrawQuad.Centre);
|
FlashlightPosition = ToLocalSpace(taikoPlayfield.HitTarget.ScreenSpaceDrawQuad.Centre);
|
||||||
|
|
||||||
ClearTransforms(targetMember: nameof(FlashlightSize));
|
ClearTransforms(targetMember: nameof(FlashlightSize));
|
||||||
FlashlightSize = getSizeFor(Combo.Value);
|
FlashlightSize = adjustSize(Combo.Value);
|
||||||
|
|
||||||
flashlightProperties.Validate();
|
flashlightProperties.Validate();
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ using osu.Game.Rulesets.Mods;
|
|||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Screens.Play.HUD;
|
||||||
using osu.Game.Screens.Play.HUD.HitErrorMeters;
|
using osu.Game.Screens.Play.HUD.HitErrorMeters;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osu.Game.Tests.Gameplay;
|
using osu.Game.Tests.Gameplay;
|
||||||
@ -148,6 +149,42 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddAssert("key counters still hidden", () => !keyCounterFlow.IsPresent);
|
AddAssert("key counters still hidden", () => !keyCounterFlow.IsPresent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestInputDoesntWorkWhenHUDHidden()
|
||||||
|
{
|
||||||
|
SongProgressBar getSongProgress() => hudOverlay.ChildrenOfType<SongProgressBar>().Single();
|
||||||
|
|
||||||
|
bool seeked = false;
|
||||||
|
|
||||||
|
createNew();
|
||||||
|
|
||||||
|
AddStep("bind seek", () =>
|
||||||
|
{
|
||||||
|
seeked = false;
|
||||||
|
|
||||||
|
var progress = getSongProgress();
|
||||||
|
|
||||||
|
progress.ShowHandle = true;
|
||||||
|
progress.OnSeek += _ => seeked = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false);
|
||||||
|
AddUntilStep("hidetarget is hidden", () => !hideTarget.IsPresent);
|
||||||
|
|
||||||
|
AddStep("attempt seek", () =>
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(getSongProgress());
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("seek not performed", () => !seeked);
|
||||||
|
|
||||||
|
AddStep("set showhud true", () => hudOverlay.ShowHud.Value = true);
|
||||||
|
|
||||||
|
AddStep("attempt seek", () => InputManager.Click(MouseButton.Left));
|
||||||
|
AddAssert("seek performed", () => seeked);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestHiddenHUDDoesntBlockComponentUpdates()
|
public void TestHiddenHUDDoesntBlockComponentUpdates()
|
||||||
{
|
{
|
||||||
|
@ -189,6 +189,16 @@ Line after image";
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestFlag()
|
||||||
|
{
|
||||||
|
AddStep("Add flag", () =>
|
||||||
|
{
|
||||||
|
markdownContainer.CurrentPath = @"https://dev.ppy.sh";
|
||||||
|
markdownContainer.Text = "::{flag=\"AU\"}:: ::{flag=\"ZZ\"}::";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private class TestMarkdownContainer : WikiMarkdownContainer
|
private class TestMarkdownContainer : WikiMarkdownContainer
|
||||||
{
|
{
|
||||||
public LinkInline Link;
|
public LinkInline Link;
|
||||||
|
File diff suppressed because one or more lines are too long
@ -45,7 +45,7 @@ namespace osu.Game.Database
|
|||||||
|
|
||||||
public bool Download(T model, bool minimiseDownloadSize = false) => Download(model, minimiseDownloadSize, null);
|
public bool Download(T model, bool minimiseDownloadSize = false) => Download(model, minimiseDownloadSize, null);
|
||||||
|
|
||||||
public void DownloadAsUpdate(TModel originalModel) => Download(originalModel, false, originalModel);
|
public void DownloadAsUpdate(TModel originalModel, bool minimiseDownloadSize) => Download(originalModel, minimiseDownloadSize, originalModel);
|
||||||
|
|
||||||
protected bool Download(T model, bool minimiseDownloadSize, TModel? originalModel)
|
protected bool Download(T model, bool minimiseDownloadSize, TModel? originalModel)
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
using Markdig;
|
using Markdig;
|
||||||
using Markdig.Extensions.AutoLinks;
|
using Markdig.Extensions.AutoLinks;
|
||||||
|
using Markdig.Extensions.CustomContainers;
|
||||||
using Markdig.Extensions.EmphasisExtras;
|
using Markdig.Extensions.EmphasisExtras;
|
||||||
using Markdig.Extensions.Footnotes;
|
using Markdig.Extensions.Footnotes;
|
||||||
using Markdig.Extensions.Tables;
|
using Markdig.Extensions.Tables;
|
||||||
@ -32,6 +33,12 @@ namespace osu.Game.Graphics.Containers.Markdown
|
|||||||
/// <seealso cref="AutoLinkExtension"/>
|
/// <seealso cref="AutoLinkExtension"/>
|
||||||
protected virtual bool Autolinks => false;
|
protected virtual bool Autolinks => false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Allows this markdown container to parse custom containers (used for flags and infoboxes).
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="CustomContainerExtension"/>
|
||||||
|
protected virtual bool CustomContainers => false;
|
||||||
|
|
||||||
public OsuMarkdownContainer()
|
public OsuMarkdownContainer()
|
||||||
{
|
{
|
||||||
LineSpacing = 21;
|
LineSpacing = 21;
|
||||||
@ -107,6 +114,9 @@ namespace osu.Game.Graphics.Containers.Markdown
|
|||||||
if (Autolinks)
|
if (Autolinks)
|
||||||
pipeline = pipeline.UseAutoLinks();
|
pipeline = pipeline.UseAutoLinks();
|
||||||
|
|
||||||
|
if (CustomContainers)
|
||||||
|
pipeline.UseCustomContainers();
|
||||||
|
|
||||||
return pipeline.Build();
|
return pipeline.Build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Markdig.Extensions.CustomContainers;
|
||||||
using Markdig.Syntax.Inlines;
|
using Markdig.Syntax.Inlines;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -11,6 +14,9 @@ using osu.Framework.Graphics.Containers.Markdown;
|
|||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using osu.Game.Users.Drawables;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.Containers.Markdown
|
namespace osu.Game.Graphics.Containers.Markdown
|
||||||
{
|
{
|
||||||
@ -33,6 +39,31 @@ namespace osu.Game.Graphics.Containers.Markdown
|
|||||||
protected override SpriteText CreateEmphasisedSpriteText(bool bold, bool italic)
|
protected override SpriteText CreateEmphasisedSpriteText(bool bold, bool italic)
|
||||||
=> CreateSpriteText().With(t => t.Font = t.Font.With(weight: bold ? FontWeight.Bold : FontWeight.Regular, italics: italic));
|
=> CreateSpriteText().With(t => t.Font = t.Font.With(weight: bold ? FontWeight.Bold : FontWeight.Regular, italics: italic));
|
||||||
|
|
||||||
|
protected override void AddCustomComponent(CustomContainerInline inline)
|
||||||
|
{
|
||||||
|
if (!(inline.FirstChild is LiteralInline literal))
|
||||||
|
{
|
||||||
|
base.AddCustomComponent(inline);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] attributes = literal.Content.ToString().Trim(' ', '{', '}').Split();
|
||||||
|
string flagAttribute = attributes.SingleOrDefault(a => a.StartsWith(@"flag", StringComparison.Ordinal));
|
||||||
|
|
||||||
|
if (flagAttribute == null)
|
||||||
|
{
|
||||||
|
base.AddCustomComponent(inline);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string flag = flagAttribute.Split('=').Last().Trim('"');
|
||||||
|
|
||||||
|
if (!Enum.TryParse<CountryCode>(flag, out var countryCode))
|
||||||
|
countryCode = CountryCode.Unknown;
|
||||||
|
|
||||||
|
AddDrawable(new DrawableFlag(countryCode) { Size = new Vector2(20, 15) });
|
||||||
|
}
|
||||||
|
|
||||||
private class OsuMarkdownInlineCode : Container
|
private class OsuMarkdownInlineCode : Container
|
||||||
{
|
{
|
||||||
[Resolved]
|
[Resolved]
|
||||||
|
@ -563,6 +563,15 @@ namespace osu.Game
|
|||||||
|
|
||||||
// This should be able to be performed from song select, but that is disabled for now
|
// This should be able to be performed from song select, but that is disabled for now
|
||||||
// due to the weird decoupled ruleset logic (which can cause a crash in certain filter scenarios).
|
// due to the weird decoupled ruleset logic (which can cause a crash in certain filter scenarios).
|
||||||
|
//
|
||||||
|
// As a special case, if the beatmap and ruleset already match, allow immediately displaying the score from song select.
|
||||||
|
// This is guaranteed to not crash, and feels better from a user's perspective (ie. if they are clicking a score in the
|
||||||
|
// song select leaderboard).
|
||||||
|
IEnumerable<Type> validScreens =
|
||||||
|
Beatmap.Value.BeatmapInfo.Equals(databasedBeatmap) && Ruleset.Value.Equals(databasedScore.ScoreInfo.Ruleset)
|
||||||
|
? new[] { typeof(SongSelect) }
|
||||||
|
: Array.Empty<Type>();
|
||||||
|
|
||||||
PerformFromScreen(screen =>
|
PerformFromScreen(screen =>
|
||||||
{
|
{
|
||||||
Logger.Log($"{nameof(PresentScore)} updating beatmap ({databasedBeatmap}) and ruleset ({databasedScore.ScoreInfo.Ruleset}) to match score");
|
Logger.Log($"{nameof(PresentScore)} updating beatmap ({databasedBeatmap}) and ruleset ({databasedScore.ScoreInfo.Ruleset}) to match score");
|
||||||
@ -580,7 +589,7 @@ namespace osu.Game
|
|||||||
screen.Push(new SoloResultsScreen(databasedScore.ScoreInfo, false));
|
screen.Push(new SoloResultsScreen(databasedScore.ScoreInfo, false));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
}, validScreens: validScreens);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task Import(params ImportTask[] imports)
|
public override Task Import(params ImportTask[] imports)
|
||||||
|
@ -387,14 +387,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
if (bindTarget != null) bindTarget.IsBinding = true;
|
if (bindTarget != null) bindTarget.IsBinding = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateStoreFromButton(KeyButton button)
|
private void updateStoreFromButton(KeyButton button) =>
|
||||||
{
|
realm.WriteAsync(r => r.Find<RealmKeyBinding>(button.KeyBinding.ID).KeyCombinationString = button.KeyBinding.KeyCombinationString);
|
||||||
realm.Run(r =>
|
|
||||||
{
|
|
||||||
var binding = r.Find<RealmKeyBinding>(((IHasGuidPrimaryKey)button.KeyBinding).ID);
|
|
||||||
r.Write(() => binding.KeyCombinationString = button.KeyBinding.KeyCombinationString);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateIsDefaultValue()
|
private void updateIsDefaultValue()
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Markdig.Extensions.CustomContainers;
|
||||||
using Markdig.Extensions.Yaml;
|
using Markdig.Extensions.Yaml;
|
||||||
using Markdig.Syntax;
|
using Markdig.Syntax;
|
||||||
using Markdig.Syntax.Inlines;
|
using Markdig.Syntax.Inlines;
|
||||||
@ -16,6 +17,7 @@ namespace osu.Game.Overlays.Wiki.Markdown
|
|||||||
public class WikiMarkdownContainer : OsuMarkdownContainer
|
public class WikiMarkdownContainer : OsuMarkdownContainer
|
||||||
{
|
{
|
||||||
protected override bool Footnotes => true;
|
protected override bool Footnotes => true;
|
||||||
|
protected override bool CustomContainers => true;
|
||||||
|
|
||||||
public string CurrentPath
|
public string CurrentPath
|
||||||
{
|
{
|
||||||
@ -26,6 +28,11 @@ namespace osu.Game.Overlays.Wiki.Markdown
|
|||||||
{
|
{
|
||||||
switch (markdownObject)
|
switch (markdownObject)
|
||||||
{
|
{
|
||||||
|
case CustomContainer:
|
||||||
|
// infoboxes are parsed into CustomContainer objects, but we don't have support for infoboxes yet.
|
||||||
|
// todo: add support for infobox.
|
||||||
|
break;
|
||||||
|
|
||||||
case YamlFrontMatterBlock yamlFrontMatterBlock:
|
case YamlFrontMatterBlock yamlFrontMatterBlock:
|
||||||
container.Add(new WikiNoticeContainer(yamlFrontMatterBlock));
|
container.Add(new WikiNoticeContainer(yamlFrontMatterBlock));
|
||||||
break;
|
break;
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -12,7 +11,6 @@ using osu.Framework.Graphics.Rendering.Vertices;
|
|||||||
using osu.Framework.Graphics.Shaders;
|
using osu.Framework.Graphics.Shaders;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Beatmaps.Timing;
|
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.OpenGL.Vertices;
|
using osu.Game.Graphics.OpenGL.Vertices;
|
||||||
@ -20,6 +18,7 @@ using osu.Game.Rulesets.Objects;
|
|||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
@ -84,8 +83,6 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
|
|
||||||
flashlight.Combo.BindTo(Combo);
|
flashlight.Combo.BindTo(Combo);
|
||||||
drawableRuleset.KeyBindingInputManager.Add(flashlight);
|
drawableRuleset.KeyBindingInputManager.Add(flashlight);
|
||||||
|
|
||||||
flashlight.Breaks = drawableRuleset.Beatmap.Breaks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract Flashlight CreateFlashlight();
|
protected abstract Flashlight CreateFlashlight();
|
||||||
@ -100,8 +97,6 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
|
|
||||||
public override bool RemoveCompletedTransforms => false;
|
public override bool RemoveCompletedTransforms => false;
|
||||||
|
|
||||||
public List<BreakPeriod> Breaks = new List<BreakPeriod>();
|
|
||||||
|
|
||||||
private readonly float defaultFlashlightSize;
|
private readonly float defaultFlashlightSize;
|
||||||
private readonly float sizeMultiplier;
|
private readonly float sizeMultiplier;
|
||||||
private readonly bool comboBasedSize;
|
private readonly bool comboBasedSize;
|
||||||
@ -119,37 +114,36 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
shader = shaderManager.Load("PositionAndColour", FragmentShader);
|
shader = shaderManager.Load("PositionAndColour", FragmentShader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private Player? player { get; set; }
|
||||||
|
|
||||||
|
private readonly IBindable<bool> isBreakTime = new BindableBool();
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
Combo.ValueChanged += OnComboChange;
|
Combo.ValueChanged += _ => UpdateFlashlightSize(GetSize());
|
||||||
|
|
||||||
using (BeginAbsoluteSequence(0))
|
if (player != null)
|
||||||
{
|
{
|
||||||
foreach (var breakPeriod in Breaks)
|
isBreakTime.BindTo(player.IsBreakTime);
|
||||||
{
|
isBreakTime.BindValueChanged(_ => UpdateFlashlightSize(GetSize()), true);
|
||||||
if (!breakPeriod.HasEffect)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (breakPeriod.Duration < FLASHLIGHT_FADE_DURATION * 2) continue;
|
|
||||||
|
|
||||||
this.Delay(breakPeriod.StartTime + FLASHLIGHT_FADE_DURATION).FadeOutFromOne(FLASHLIGHT_FADE_DURATION);
|
|
||||||
this.Delay(breakPeriod.EndTime - FLASHLIGHT_FADE_DURATION).FadeInFromZero(FLASHLIGHT_FADE_DURATION);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void OnComboChange(ValueChangedEvent<int> e);
|
protected abstract void UpdateFlashlightSize(float size);
|
||||||
|
|
||||||
protected abstract string FragmentShader { get; }
|
protected abstract string FragmentShader { get; }
|
||||||
|
|
||||||
protected float GetSizeFor(int combo)
|
protected float GetSize()
|
||||||
{
|
{
|
||||||
float size = defaultFlashlightSize * sizeMultiplier;
|
float size = defaultFlashlightSize * sizeMultiplier;
|
||||||
|
|
||||||
if (comboBasedSize)
|
if (isBreakTime.Value)
|
||||||
size *= GetComboScaleFor(combo);
|
size *= 2.5f;
|
||||||
|
else if (comboBasedSize)
|
||||||
|
size *= GetComboScaleFor(Combo.Value);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@ -198,6 +199,21 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[NotNull]
|
[NotNull]
|
||||||
protected virtual HitWindows CreateHitWindows() => new HitWindows();
|
protected virtual HitWindows CreateHitWindows() => new HitWindows();
|
||||||
|
|
||||||
|
public IList<HitSampleInfo> CreateSlidingSamples()
|
||||||
|
{
|
||||||
|
var slidingSamples = new List<HitSampleInfo>();
|
||||||
|
|
||||||
|
var normalSample = Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL);
|
||||||
|
if (normalSample != null)
|
||||||
|
slidingSamples.Add(normalSample.With("sliderslide"));
|
||||||
|
|
||||||
|
var whistleSample = Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_WHISTLE);
|
||||||
|
if (whistleSample != null)
|
||||||
|
slidingSamples.Add(whistleSample.With("sliderwhistle"));
|
||||||
|
|
||||||
|
return slidingSamples;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class HitObjectExtensions
|
public static class HitObjectExtensions
|
||||||
|
64
osu.Game/Screens/Edit/Compose/Components/ScrollingDragBox.cs
Normal file
64
osu.Game/Screens/Edit/Compose/Components/ScrollingDragBox.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// 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.UI;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Edit.Compose.Components
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="DragBox"/> that scrolls along with the scrolling playfield.
|
||||||
|
/// </summary>
|
||||||
|
public class ScrollingDragBox : DragBox
|
||||||
|
{
|
||||||
|
public double MinTime { get; private set; }
|
||||||
|
|
||||||
|
public double MaxTime { get; private set; }
|
||||||
|
|
||||||
|
private double? startTime;
|
||||||
|
|
||||||
|
private readonly ScrollingPlayfield playfield;
|
||||||
|
|
||||||
|
public ScrollingDragBox(Playfield playfield)
|
||||||
|
{
|
||||||
|
this.playfield = playfield as ScrollingPlayfield ?? throw new ArgumentException("Playfield must be of type {nameof(ScrollingPlayfield)} to use this class.", nameof(playfield));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void HandleDrag(MouseButtonEvent e)
|
||||||
|
{
|
||||||
|
base.HandleDrag(e);
|
||||||
|
|
||||||
|
startTime ??= playfield.TimeAtScreenSpacePosition(e.ScreenSpaceMouseDownPosition);
|
||||||
|
double endTime = playfield.TimeAtScreenSpacePosition(e.ScreenSpaceMousePosition);
|
||||||
|
|
||||||
|
MinTime = Math.Min(startTime.Value, endTime);
|
||||||
|
MaxTime = Math.Max(startTime.Value, endTime);
|
||||||
|
|
||||||
|
var startPos = ToLocalSpace(playfield.ScreenSpacePositionAtTime(startTime.Value));
|
||||||
|
var endPos = ToLocalSpace(playfield.ScreenSpacePositionAtTime(endTime));
|
||||||
|
|
||||||
|
switch (playfield.ScrollingInfo.Direction.Value)
|
||||||
|
{
|
||||||
|
case ScrollingDirection.Up:
|
||||||
|
case ScrollingDirection.Down:
|
||||||
|
Box.Y = Math.Min(startPos.Y, endPos.Y);
|
||||||
|
Box.Height = Math.Max(startPos.Y, endPos.Y) - Box.Y;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScrollingDirection.Left:
|
||||||
|
case ScrollingDirection.Right:
|
||||||
|
Box.X = Math.Min(startPos.X, endPos.X);
|
||||||
|
Box.Width = Math.Max(startPos.X, endPos.X) - Box.X;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Hide()
|
||||||
|
{
|
||||||
|
base.Hide();
|
||||||
|
startTime = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -39,6 +39,10 @@ namespace osu.Game.Screens.Play
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public float BottomScoringElementsHeight { get; private set; }
|
public float BottomScoringElementsHeight { get; private set; }
|
||||||
|
|
||||||
|
// HUD uses AlwaysVisible on child components so they can be in an updated state for next display.
|
||||||
|
// Without blocking input, this would also allow them to be interacted with in such a state.
|
||||||
|
public override bool PropagatePositionalInputSubTree => ShowHud.Value;
|
||||||
|
|
||||||
public readonly KeyCounterDisplay KeyCounter;
|
public readonly KeyCounterDisplay KeyCounter;
|
||||||
public readonly ModDisplay ModDisplay;
|
public readonly ModDisplay ModDisplay;
|
||||||
public readonly HoldForMenuButton HoldToQuit;
|
public readonly HoldForMenuButton HoldToQuit;
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
@ -43,11 +45,15 @@ namespace osu.Game.Screens.Select.Carousel
|
|||||||
Origin = Anchor.CentreLeft;
|
Origin = Anchor.CentreLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Bindable<bool> preferNoVideo = null!;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load(OsuConfigManager config)
|
||||||
{
|
{
|
||||||
const float icon_size = 14;
|
const float icon_size = 14;
|
||||||
|
|
||||||
|
preferNoVideo = config.GetBindable<bool>(OsuSetting.PreferNoVideo);
|
||||||
|
|
||||||
Content.Anchor = Anchor.CentreLeft;
|
Content.Anchor = Anchor.CentreLeft;
|
||||||
Content.Origin = Anchor.CentreLeft;
|
Content.Origin = Anchor.CentreLeft;
|
||||||
|
|
||||||
@ -104,7 +110,7 @@ namespace osu.Game.Screens.Select.Carousel
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
beatmapDownloader.DownloadAsUpdate(beatmapSetInfo);
|
beatmapDownloader.DownloadAsUpdate(beatmapSetInfo, preferNoVideo.Value);
|
||||||
attachExistingDownload();
|
attachExistingDownload();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,10 @@ namespace osu.Game.Storyboards
|
|||||||
public void Add(Easing easing, double startTime, double endTime, T startValue, T endValue)
|
public void Add(Easing easing, double startTime, double endTime, T startValue, T endValue)
|
||||||
{
|
{
|
||||||
if (endTime < startTime)
|
if (endTime < startTime)
|
||||||
return;
|
{
|
||||||
|
(startTime, endTime) = (endTime, startTime);
|
||||||
|
(startValue, endValue) = (endValue, startValue);
|
||||||
|
}
|
||||||
|
|
||||||
commands.Add(new TypedCommand { Easing = easing, StartTime = startTime, EndTime = endTime, StartValue = startValue, EndValue = endValue });
|
commands.Add(new TypedCommand { Easing = easing, StartTime = startTime, EndTime = endTime, StartValue = startValue, EndValue = endValue });
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Realm" Version="10.17.0" />
|
<PackageReference Include="Realm" Version="10.17.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2022.1005.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2022.1011.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.1008.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.1008.0" />
|
||||||
<PackageReference Include="Sentry" Version="3.22.0" />
|
<PackageReference Include="Sentry" Version="3.22.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.32.2" />
|
<PackageReference Include="SharpCompress" Version="0.32.2" />
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.1008.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.1008.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2022.1005.0" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2022.1011.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net6.0) -->
|
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net6.0) -->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
@ -82,7 +82,7 @@
|
|||||||
<PackageReference Include="DiffPlex" Version="1.7.1" />
|
<PackageReference Include="DiffPlex" Version="1.7.1" />
|
||||||
<PackageReference Include="Humanizer" Version="2.14.1" />
|
<PackageReference Include="Humanizer" Version="2.14.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2022.1005.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2022.1011.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.32.2" />
|
<PackageReference Include="SharpCompress" Version="0.32.2" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||||
|
Loading…
Reference in New Issue
Block a user