1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 06:42:56 +08:00

Merge branch 'master' into on-drawable-hitobject-added

This commit is contained in:
Dan Balasescu 2020-11-24 16:09:57 +09:00 committed by GitHub
commit 87ce8a53ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 299 additions and 139 deletions

View File

@ -5,7 +5,7 @@ using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Catch.Mods
{
public class CatchModEasy : ModEasy
public class CatchModEasy : ModEasyWithExtraLives
{
public override string Description => @"Larger fruits, more forgiving HP drain, less accuracy required, and three lives!";
}

View File

@ -5,7 +5,7 @@ using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Mods
{
public class ManiaModEasy : ModEasy
public class ManiaModEasy : ModEasyWithExtraLives
{
public override string Description => @"More forgiving HP drain, less accuracy required, and three lives!";
}

View File

@ -44,6 +44,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
[Resolved(CanBeNull = true)]
private IEditorChangeHandler changeHandler { get; set; }
private readonly BindableList<PathControlPoint> controlPoints = new BindableList<PathControlPoint>();
private readonly IBindable<int> pathVersion = new Bindable<int>();
public SliderSelectionBlueprint(DrawableSlider slider)
: base(slider)
{
@ -61,13 +64,13 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
};
}
private IBindable<int> pathVersion;
protected override void LoadComplete()
{
base.LoadComplete();
pathVersion = HitObject.Path.Version.GetBoundCopy();
controlPoints.BindTo(HitObject.Path.ControlPoints);
pathVersion.BindTo(HitObject.Path.Version);
pathVersion.BindValueChanged(_ => updatePath());
BodyPiece.UpdateFrom(HitObject);
@ -164,8 +167,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
}
}
private BindableList<PathControlPoint> controlPoints => HitObject.Path.ControlPoints;
private int addControlPoint(Vector2 position)
{
position -= HitObject.Position;

View File

@ -5,7 +5,7 @@ using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Osu.Mods
{
public class OsuModEasy : ModEasy
public class OsuModEasy : ModEasyWithExtraLives
{
public override string Description => @"Larger circles, more forgiving HP drain, less accuracy required, and three lives!";
}

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 osu.Framework.Bindables;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
@ -47,6 +48,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
});
}
public double AnimationStartTime { get; set; }
public Bindable<double> AnimationStartTime { get; } = new BindableDouble();
}
}

View File

@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
fp.Alpha = 0;
fp.Scale = new Vector2(1.5f * end.Scale);
fp.AnimationStartTime = fadeInTime;
fp.AnimationStartTime.Value = fadeInTime;
using (fp.BeginAbsoluteSequence(fadeInTime))
{

View File

@ -7,6 +7,6 @@ namespace osu.Game.Rulesets.Taiko.Mods
{
public class TaikoModEasy : ModEasy
{
public override string Description => @"Beats move slower, less accuracy required, and three lives!";
public override string Description => @"Beats move slower, and less accuracy required!";
}
}

View File

@ -0,0 +1,79 @@
// 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.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Animations;
using osu.Framework.Graphics.OpenGL.Textures;
using osu.Framework.Graphics.Textures;
using osu.Framework.Testing;
using osu.Framework.Timing;
using osu.Game.Audio;
using osu.Game.Skinning;
using osu.Game.Tests.Visual;
namespace osu.Game.Tests.NonVisual.Skinning
{
[HeadlessTest]
public class LegacySkinAnimationTest : OsuTestScene
{
private const string animation_name = "animation";
private const int frame_count = 6;
[Cached(typeof(IAnimationTimeReference))]
private TestAnimationTimeReference animationTimeReference = new TestAnimationTimeReference();
private TextureAnimation animation;
[Test]
public void TestAnimationTimeReferenceChange()
{
ISkin skin = new TestSkin();
AddStep("get animation", () => Add(animation = (TextureAnimation)skin.GetAnimation(animation_name, true, false)));
AddAssert("frame count correct", () => animation.FrameCount == frame_count);
assertPlaybackPosition(0);
AddStep("set start time to 1000", () => animationTimeReference.AnimationStartTime.Value = 1000);
assertPlaybackPosition(-1000);
AddStep("set current time to 500", () => animationTimeReference.ManualClock.CurrentTime = 500);
assertPlaybackPosition(-500);
}
private void assertPlaybackPosition(double expectedPosition)
=> AddAssert($"playback position is {expectedPosition}", () => animation.PlaybackPosition == expectedPosition);
private class TestSkin : ISkin
{
private static readonly string[] lookup_names = Enumerable.Range(0, frame_count).Select(frame => $"{animation_name}-{frame}").ToArray();
public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT)
{
return lookup_names.Contains(componentName) ? Texture.WhitePixel : null;
}
public Drawable GetDrawableComponent(ISkinComponent component) => throw new NotSupportedException();
public SampleChannel GetSample(ISampleInfo sampleInfo) => throw new NotSupportedException();
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => throw new NotSupportedException();
}
private class TestAnimationTimeReference : IAnimationTimeReference
{
public ManualClock ManualClock { get; }
public IFrameBasedClock Clock { get; }
public Bindable<double> AnimationStartTime { get; } = new BindableDouble();
public TestAnimationTimeReference()
{
ManualClock = new ManualClock();
Clock = new FramedClock(ManualClock);
}
}
}
}

View File

@ -318,7 +318,7 @@ namespace osu.Game.Tests.Visual.Background
private class FadeAccessibleResults : ResultsScreen
{
public FadeAccessibleResults(ScoreInfo score)
: base(score)
: base(score, true)
{
}

View File

@ -256,7 +256,7 @@ namespace osu.Game.Tests.Visual.Ranking
public HotkeyRetryOverlay RetryOverlay;
public TestResultsScreen(ScoreInfo score)
: base(score)
: base(score, true)
{
}
@ -326,7 +326,7 @@ namespace osu.Game.Tests.Visual.Ranking
public HotkeyRetryOverlay RetryOverlay;
public UnrankedSoloResultsScreen(ScoreInfo score)
: base(score)
: base(score, true)
{
Score.Beatmap.OnlineBeatmapID = 0;
Score.Beatmap.Status = BeatmapSetOnlineStatus.Pending;

View File

@ -11,12 +11,12 @@ using osu.Framework.Allocation;
namespace osu.Game.Tests.Visual.UserInterface
{
public class TestScenePaginatedContainerHeader : OsuTestScene
public class TestSceneProfileSubsectionHeader : OsuTestScene
{
[Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink);
private PaginatedContainerHeader header;
private ProfileSubsectionHeader header;
[Test]
public void TestHiddenCounter()
@ -69,7 +69,7 @@ namespace osu.Game.Tests.Visual.UserInterface
private void createHeader(string text, CounterVisibilityState state, int initialValue = 0)
{
Clear();
Add(header = new PaginatedContainerHeader(text, state)
Add(header = new ProfileSubsectionHeader(text, state)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,

View File

@ -196,7 +196,7 @@ namespace osu.Game.Configuration
public Func<int, string> LookupSkinName { private get; set; }
public Func<GlobalAction, string> LookupKeyBindings { private get; set; }
public Func<GlobalAction, string> LookupKeyBindings { get; set; }
}
public enum OsuSetting

View File

@ -420,7 +420,7 @@ namespace osu.Game
break;
case ScorePresentType.Results:
screen.Push(new SoloResultsScreen(databasedScore.ScoreInfo));
screen.Push(new SoloResultsScreen(databasedScore.ScoreInfo, false));
break;
}
}, validScreens: new[] { typeof(PlaySongSelect) });

View File

@ -6,6 +6,7 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Input.Bindings;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Input.Bindings;
using osu.Game.Overlays.OSD;
@ -37,11 +38,11 @@ namespace osu.Game.Overlays.Music
bool wasPlaying = musicController.IsPlaying;
if (musicController.TogglePause())
onScreenDisplay?.Display(new MusicActionToast(wasPlaying ? "Pause track" : "Play track"));
onScreenDisplay?.Display(new MusicActionToast(wasPlaying ? "Pause track" : "Play track", action));
return true;
case GlobalAction.MusicNext:
musicController.NextTrack(() => onScreenDisplay?.Display(new MusicActionToast("Next track")));
musicController.NextTrack(() => onScreenDisplay?.Display(new MusicActionToast("Next track", action)));
return true;
@ -51,11 +52,11 @@ namespace osu.Game.Overlays.Music
switch (res)
{
case PreviousTrackResult.Restart:
onScreenDisplay?.Display(new MusicActionToast("Restart track"));
onScreenDisplay?.Display(new MusicActionToast("Restart track", action));
break;
case PreviousTrackResult.Previous:
onScreenDisplay?.Display(new MusicActionToast("Previous track"));
onScreenDisplay?.Display(new MusicActionToast("Previous track", action));
break;
}
});
@ -72,9 +73,18 @@ namespace osu.Game.Overlays.Music
private class MusicActionToast : Toast
{
public MusicActionToast(string action)
: base("Music Playback", action, string.Empty)
private readonly GlobalAction action;
public MusicActionToast(string value, GlobalAction action)
: base("Music Playback", value, string.Empty)
{
this.action = action;
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
ShortcutText.Text = config.LookupKeyBindings(action).ToUpperInvariant();
}
}
}

View File

@ -16,10 +16,13 @@ namespace osu.Game.Overlays.OSD
private const int toast_minimum_width = 240;
private readonly Container content;
protected override Container<Drawable> Content => content;
protected readonly OsuSpriteText ValueText;
protected readonly OsuSpriteText ShortcutText;
protected Toast(string description, string value, string shortcut)
{
Anchor = Anchor.Centre;
@ -68,7 +71,7 @@ namespace osu.Game.Overlays.OSD
Origin = Anchor.Centre,
Text = value
},
new OsuSpriteText
ShortcutText = new OsuSpriteText
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,

View File

@ -14,7 +14,7 @@ using osuTK;
namespace osu.Game.Overlays.Profile.Sections.Beatmaps
{
public class PaginatedBeatmapContainer : PaginatedContainer<APIBeatmapSet>
public class PaginatedBeatmapContainer : PaginatedProfileSubsection<APIBeatmapSet>
{
private const float panel_padding = 10f;
private readonly BeatmapSetType type;

View File

@ -13,7 +13,7 @@ using osu.Game.Users;
namespace osu.Game.Overlays.Profile.Sections.Historical
{
public class PaginatedMostPlayedBeatmapContainer : PaginatedContainer<APIUserMostPlayedBeatmap>
public class PaginatedMostPlayedBeatmapContainer : PaginatedProfileSubsection<APIUserMostPlayedBeatmap>
{
public PaginatedMostPlayedBeatmapContainer(Bindable<User> user)
: base(user, "Most Played Beatmaps", "No records. :(", CounterVisibilityState.AlwaysVisible)

View File

@ -11,7 +11,7 @@ using System.Collections.Generic;
namespace osu.Game.Overlays.Profile.Sections.Kudosu
{
public class PaginatedKudosuHistoryContainer : PaginatedContainer<APIKudosuHistory>
public class PaginatedKudosuHistoryContainer : PaginatedProfileSubsection<APIKudosuHistory>
{
public PaginatedKudosuHistoryContainer(Bindable<User> user)
: base(user, missingText: "This user hasn't received any kudosu!")

View File

@ -6,62 +6,51 @@ 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.Online.API;
using osu.Game.Rulesets;
using osu.Game.Users;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics;
namespace osu.Game.Overlays.Profile.Sections
{
public abstract class PaginatedContainer<TModel> : FillFlowContainer
public abstract class PaginatedProfileSubsection<TModel> : ProfileSubsection
{
[Resolved]
private IAPIProvider api { get; set; }
[Resolved]
protected RulesetStore Rulesets { get; private set; }
protected int VisiblePages;
protected int ItemsPerPage;
protected readonly Bindable<User> User = new Bindable<User>();
protected FillFlowContainer ItemsContainer;
protected RulesetStore Rulesets;
protected FillFlowContainer ItemsContainer { get; private set; }
private APIRequest<List<TModel>> retrievalRequest;
private CancellationTokenSource loadCancellation;
private readonly string missingText;
private ShowMoreButton moreButton;
private OsuSpriteText missing;
private PaginatedContainerHeader header;
private readonly string missingText;
private readonly string headerText;
private readonly CounterVisibilityState counterVisibilityState;
protected PaginatedContainer(Bindable<User> user, string headerText = "", string missingText = "", CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden)
protected PaginatedProfileSubsection(Bindable<User> user, string headerText = "", string missingText = "", CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden)
: base(user, headerText, counterVisibilityState)
{
this.headerText = headerText;
this.missingText = missingText;
this.counterVisibilityState = counterVisibilityState;
User.BindTo(user);
}
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
protected override Drawable CreateContent() => new FillFlowContainer
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Direction = FillDirection.Vertical;
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
header = new PaginatedContainerHeader(headerText, counterVisibilityState)
{
Alpha = string.IsNullOrEmpty(headerText) ? 0 : 1
},
ItemsContainer = new FillFlowContainer
{
AutoSizeAxes = Axes.Y,
@ -81,13 +70,14 @@ namespace osu.Game.Overlays.Profile.Sections
Font = OsuFont.GetFont(size: 15),
Text = missingText,
Alpha = 0,
},
};
}
}
};
Rulesets = rulesets;
User.ValueChanged += onUserChanged;
User.TriggerChange();
protected override void LoadComplete()
{
base.LoadComplete();
User.BindValueChanged(onUserChanged, true);
}
private void onUserChanged(ValueChangedEvent<User> e)
@ -124,7 +114,7 @@ namespace osu.Game.Overlays.Profile.Sections
moreButton.Hide();
moreButton.IsLoading = false;
if (!string.IsNullOrEmpty(missing.Text))
if (!string.IsNullOrEmpty(missingText))
missing.Show();
return;
@ -142,8 +132,6 @@ namespace osu.Game.Overlays.Profile.Sections
protected virtual int GetCount(User user) => 0;
protected void SetCount(int value) => header.Current.Value = value;
protected virtual void OnItemsReceived(List<TModel> items)
{
}
@ -154,8 +142,9 @@ namespace osu.Game.Overlays.Profile.Sections
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
retrievalRequest?.Cancel();
loadCancellation?.Cancel();
base.Dispose(isDisposing);
}
}
}

View File

@ -0,0 +1,51 @@
// 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.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Users;
using JetBrains.Annotations;
namespace osu.Game.Overlays.Profile.Sections
{
public abstract class ProfileSubsection : FillFlowContainer
{
protected readonly Bindable<User> User = new Bindable<User>();
private readonly string headerText;
private readonly CounterVisibilityState counterVisibilityState;
private ProfileSubsectionHeader header;
protected ProfileSubsection(Bindable<User> user, string headerText = "", CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden)
{
this.headerText = headerText;
this.counterVisibilityState = counterVisibilityState;
User.BindTo(user);
}
[BackgroundDependencyLoader]
private void load()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Direction = FillDirection.Vertical;
Children = new[]
{
header = new ProfileSubsectionHeader(headerText, counterVisibilityState)
{
Alpha = string.IsNullOrEmpty(headerText) ? 0 : 1
},
CreateContent()
};
}
[NotNull]
protected abstract Drawable CreateContent();
protected void SetCount(int value) => header.Current.Value = value;
}
}

View File

@ -14,7 +14,7 @@ using osu.Game.Graphics;
namespace osu.Game.Overlays.Profile.Sections
{
public class PaginatedContainerHeader : CompositeDrawable, IHasCurrentValue<int>
public class ProfileSubsectionHeader : CompositeDrawable, IHasCurrentValue<int>
{
private readonly BindableWithCurrent<int> current = new BindableWithCurrent<int>();
@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Profile.Sections
private CounterPill counterPill;
public PaginatedContainerHeader(string text, CounterVisibilityState counterState)
public ProfileSubsectionHeader(string text, CounterVisibilityState counterState)
{
this.text = text;
this.counterState = counterState;

View File

@ -14,7 +14,7 @@ using osu.Framework.Allocation;
namespace osu.Game.Overlays.Profile.Sections.Ranks
{
public class PaginatedScoreContainer : PaginatedContainer<APILegacyScoreInfo>
public class PaginatedScoreContainer : PaginatedProfileSubsection<APILegacyScoreInfo>
{
private readonly ScoreType type;

View File

@ -13,7 +13,7 @@ using osu.Framework.Allocation;
namespace osu.Game.Overlays.Profile.Sections.Recent
{
public class PaginatedRecentActivityContainer : PaginatedContainer<APIRecentActivity>
public class PaginatedRecentActivityContainer : PaginatedProfileSubsection<APIRecentActivity>
{
public PaginatedRecentActivityContainer(Bindable<User> user)
: base(user, missingText: "This user hasn't done anything notable recently!")

View File

@ -149,7 +149,10 @@ namespace osu.Game.Rulesets.Judgements
private void runAnimation()
{
// undo any transforms applies in ApplyMissAnimations/ApplyHitAnimations to get a sane initial state.
ApplyTransformsAt(double.MinValue, true);
ClearTransforms(true);
LifetimeStart = Result.TimeAbsolute;
using (BeginAbsoluteSequence(Result.TimeAbsolute, true))

View File

@ -2,17 +2,13 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using Humanizer;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Mods
{
public abstract class ModEasy : Mod, IApplicableToDifficulty, IApplicableFailOverride, IApplicableToHealthProcessor
public abstract class ModEasy : Mod, IApplicableToDifficulty
{
public override string Name => "Easy";
public override string Acronym => "EZ";
@ -22,49 +18,17 @@ namespace osu.Game.Rulesets.Mods
public override bool Ranked => true;
public override Type[] IncompatibleMods => new[] { typeof(ModHardRock), typeof(ModDifficultyAdjust) };
[SettingSource("Extra Lives", "Number of extra lives")]
public Bindable<int> Retries { get; } = new BindableInt(2)
{
MinValue = 0,
MaxValue = 10
};
public override string SettingDescription => Retries.IsDefault ? string.Empty : $"{"lives".ToQuantity(Retries.Value)}";
private int retries;
private BindableNumber<double> health;
public void ReadFromDifficulty(BeatmapDifficulty difficulty)
public virtual void ReadFromDifficulty(BeatmapDifficulty difficulty)
{
}
public void ApplyToDifficulty(BeatmapDifficulty difficulty)
public virtual void ApplyToDifficulty(BeatmapDifficulty difficulty)
{
const float ratio = 0.5f;
difficulty.CircleSize *= ratio;
difficulty.ApproachRate *= ratio;
difficulty.DrainRate *= ratio;
difficulty.OverallDifficulty *= ratio;
retries = Retries.Value;
}
public bool PerformFail()
{
if (retries == 0) return true;
health.Value = health.MaxValue;
retries--;
return false;
}
public bool RestartOnFail => false;
public void ApplyToHealthProcessor(HealthProcessor healthProcessor)
{
health = healthProcessor.Health.GetBoundCopy();
}
}
}

View File

@ -0,0 +1,50 @@
// 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 Humanizer;
using osu.Framework.Bindables;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Mods
{
public abstract class ModEasyWithExtraLives : ModEasy, IApplicableFailOverride, IApplicableToHealthProcessor
{
[SettingSource("Extra Lives", "Number of extra lives")]
public Bindable<int> Retries { get; } = new BindableInt(2)
{
MinValue = 0,
MaxValue = 10
};
public override string SettingDescription => Retries.IsDefault ? string.Empty : $"{"lives".ToQuantity(Retries.Value)}";
private int retries;
private BindableNumber<double> health;
public override void ApplyToDifficulty(BeatmapDifficulty difficulty)
{
base.ApplyToDifficulty(difficulty);
retries = Retries.Value;
}
public bool PerformFail()
{
if (retries == 0) return true;
health.Value = health.MaxValue;
retries--;
return false;
}
public bool RestartOnFail => false;
public void ApplyToHealthProcessor(HealthProcessor healthProcessor)
{
health = healthProcessor.Health.GetBoundCopy();
}
}
}

View File

@ -454,6 +454,8 @@ namespace osu.Game.Rulesets.Objects.Drawables
private void clearExistingStateTransforms()
{
base.ApplyTransformsAt(double.MinValue, true);
// has to call this method directly (not ClearTransforms) to bypass the local ClearTransformsAfter override.
base.ClearTransformsAfter(double.MinValue, true);
}

View File

@ -113,8 +113,7 @@ namespace osu.Game.Screens.Menu
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Alpha = 0.5f,
AccentColour = Color4.DarkBlue,
Colour = Color4.DarkBlue,
Size = new Vector2(0.96f)
},
new Circle

View File

@ -11,7 +11,6 @@ using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Shaders;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
@ -20,13 +19,14 @@ using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Bindables;
using osu.Framework.Utils;
using osu.Framework.Extensions.Color4Extensions;
namespace osu.Game.Screens.Menu
{
/// <summary>
/// A visualiser that reacts to music coming from beatmaps.
/// </summary>
public class LogoVisualisation : Drawable, IHasAccentColour
public class LogoVisualisation : Drawable
{
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
@ -67,8 +67,6 @@ namespace osu.Game.Screens.Menu
private int indexOffset;
public Color4 AccentColour { get; set; }
/// <summary>
/// The relative movement of bars based on input amplification. Defaults to 1.
/// </summary>
@ -176,7 +174,8 @@ namespace osu.Game.Screens.Menu
// Assuming the logo is a circle, we don't need a second dimension.
private float size;
private Color4 colour;
private static readonly Color4 transparent_white = Color4.White.Opacity(0.2f);
private float[] audioData;
private readonly QuadBatch<TexturedVertex2D> vertexBatch = new QuadBatch<TexturedVertex2D>(100, 10);
@ -193,7 +192,6 @@ namespace osu.Game.Screens.Menu
shader = Source.shader;
texture = Source.texture;
size = Source.DrawSize.X;
colour = Source.AccentColour;
audioData = Source.frequencyAmplitudes;
}
@ -206,7 +204,7 @@ namespace osu.Game.Screens.Menu
Vector2 inflation = DrawInfo.MatrixInverse.ExtractScale().Xy;
ColourInfo colourInfo = DrawColourInfo.Colour;
colourInfo.ApplyChild(colour);
colourInfo.ApplyChild(transparent_white);
if (audioData != null)
{

View File

@ -7,7 +7,6 @@ using osu.Game.Online.API;
using osu.Game.Users;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
namespace osu.Game.Screens.Menu
{
@ -28,12 +27,10 @@ namespace osu.Game.Screens.Menu
private void updateColour()
{
Color4 defaultColour = Color4.White.Opacity(0.2f);
if (user.Value?.IsSupporter ?? false)
AccentColour = skin.Value.GetConfig<GlobalSkinColours, Color4>(GlobalSkinColours.MenuGlow)?.Value ?? defaultColour;
Colour = skin.Value.GetConfig<GlobalSkinColours, Color4>(GlobalSkinColours.MenuGlow)?.Value ?? Color4.White;
else
AccentColour = defaultColour;
Colour = Color4.White;
}
}
}

View File

@ -81,6 +81,8 @@ namespace osu.Game.Screens.Menu
set => rippleContainer.FadeTo(value ? 1 : 0, transition_length, Easing.OutQuint);
}
private const float visualizer_default_alpha = 0.5f;
private readonly Box flashLayer;
private readonly Container impactContainer;
@ -144,7 +146,7 @@ namespace osu.Game.Screens.Menu
RelativeSizeAxes = Axes.Both,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Alpha = 0.5f,
Alpha = visualizer_default_alpha,
Size = new Vector2(0.96f)
},
new Container
@ -282,8 +284,7 @@ namespace osu.Game.Screens.Menu
this.Delay(early_activation).Schedule(() => sampleBeat.Play());
logoBeatContainer
.ScaleTo(1 - 0.02f * amplitudeAdjust, early_activation, Easing.Out)
.Then()
.ScaleTo(1 - 0.02f * amplitudeAdjust, early_activation, Easing.Out).Then()
.ScaleTo(1, beatLength * 2, Easing.OutQuint);
ripple.ClearTransforms();
@ -296,15 +297,13 @@ namespace osu.Game.Screens.Menu
{
flashLayer.ClearTransforms();
flashLayer
.FadeTo(0.2f * amplitudeAdjust, early_activation, Easing.Out)
.Then()
.FadeTo(0.2f * amplitudeAdjust, early_activation, Easing.Out).Then()
.FadeOut(beatLength);
visualizer.ClearTransforms();
visualizer
.FadeTo(0.9f * amplitudeAdjust, early_activation, Easing.Out)
.Then()
.FadeTo(0.5f, beatLength);
.FadeTo(visualizer_default_alpha * 1.8f * amplitudeAdjust, early_activation, Easing.Out).Then()
.FadeTo(visualizer_default_alpha, beatLength);
}
}

View File

@ -92,7 +92,7 @@ namespace osu.Game.Screens.Multi.Play
protected override ResultsScreen CreateResults(ScoreInfo score)
{
Debug.Assert(roomId.Value != null);
return new TimeshiftResultsScreen(score, roomId.Value.Value, playlistItem);
return new TimeshiftResultsScreen(score, roomId.Value.Value, playlistItem, true);
}
protected override ScoreInfo CreateScore()

View File

@ -32,7 +32,7 @@ namespace osu.Game.Screens.Multi.Ranking
[Resolved]
private IAPIProvider api { get; set; }
public TimeshiftResultsScreen(ScoreInfo score, int roomId, PlaylistItem playlistItem, bool allowRetry = true)
public TimeshiftResultsScreen(ScoreInfo score, int roomId, PlaylistItem playlistItem, bool allowRetry)
: base(score, allowRetry)
{
this.roomId = roomId;

View File

@ -545,7 +545,7 @@ namespace osu.Game.Screens.Play
protected override bool OnScroll(ScrollEvent e) => mouseWheelDisabled.Value && !GameplayClockContainer.IsPaused.Value;
protected virtual ResultsScreen CreateResults(ScoreInfo score) => new SoloResultsScreen(score);
protected virtual ResultsScreen CreateResults(ScoreInfo score) => new SoloResultsScreen(score, true);
#region Fail Logic

View File

@ -12,7 +12,7 @@ namespace osu.Game.Screens.Play
public class SpectatorResultsScreen : SoloResultsScreen
{
public SpectatorResultsScreen(ScoreInfo score)
: base(score)
: base(score, false)
{
}

View File

@ -58,7 +58,7 @@ namespace osu.Game.Screens.Ranking
private readonly bool allowRetry;
protected ResultsScreen(ScoreInfo score, bool allowRetry = true)
protected ResultsScreen(ScoreInfo score, bool allowRetry)
{
Score = score;
this.allowRetry = allowRetry;

View File

@ -18,7 +18,7 @@ namespace osu.Game.Screens.Ranking
[Resolved]
private RulesetStore rulesets { get; set; }
public SoloResultsScreen(ScoreInfo score, bool allowRetry = true)
public SoloResultsScreen(ScoreInfo score, bool allowRetry)
: base(score, allowRetry)
{
}

View File

@ -38,7 +38,7 @@ namespace osu.Game.Screens.Select
}
protected void PresentScore(ScoreInfo score) =>
FinaliseSelection(score.Beatmap, score.Ruleset, () => this.Push(new SoloResultsScreen(score)));
FinaliseSelection(score.Beatmap, score.Ruleset, () => this.Push(new SoloResultsScreen(score, false)));
protected override BeatmapDetailArea CreateBeatmapDetailArea() => new PlayBeatmapDetailArea();

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics.OpenGL.Textures;
using osu.Framework.Timing;
@ -25,6 +26,6 @@ namespace osu.Game.Skinning
/// <summary>
/// The time which animations should be started from, relative to <see cref="Clock"/>.
/// </summary>
double AnimationStartTime { get; }
Bindable<double> AnimationStartTime { get; }
}
}

View File

@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Animations;
using osu.Framework.Graphics.OpenGL.Textures;
@ -70,6 +71,8 @@ namespace osu.Game.Skinning
[Resolved(canBeNull: true)]
private IAnimationTimeReference timeReference { get; set; }
private readonly Bindable<double> animationStartTime = new BindableDouble();
public SkinnableTextureAnimation(bool startAtCurrentTime = true)
: base(startAtCurrentTime)
{
@ -82,8 +85,18 @@ namespace osu.Game.Skinning
if (timeReference != null)
{
Clock = timeReference.Clock;
PlaybackPosition = timeReference.Clock.CurrentTime - timeReference.AnimationStartTime;
animationStartTime.BindTo(timeReference.AnimationStartTime);
}
animationStartTime.BindValueChanged(_ => updatePlaybackPosition(), true);
}
private void updatePlaybackPosition()
{
if (timeReference == null)
return;
PlaybackPosition = timeReference.Clock.CurrentTime - timeReference.AnimationStartTime.Value;
}
}