Compare commits
12 Commits
2025.1111.
...
f5ca5083d6
| Author | SHA1 | Date | |
|---|---|---|---|
| f5ca5083d6 | |||
| 1d7c77d8d6 | |||
| 774e52fbd6 | |||
| a9d7a9d5d5 | |||
| f7069b1009 | |||
| c3ce5dc787 | |||
| 98076e2092 | |||
| b7d1092f90 | |||
| 08db90c278 | |||
| b7e36164c3 | |||
| 0f5f13858d | |||
| 89a0c75156 |
12
.github/ISSUE_TEMPLATE/config.yml
vendored
12
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,12 +1,6 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: true
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: Help
|
- name: Help
|
||||||
url: https://github.com/ppy/osu/discussions/categories/q-a
|
url: https://t.me/jvnkosu_chat
|
||||||
about: osu! not working or performing as you'd expect? Not sure it's a bug? Check the Q&A section!
|
about: Your jvnkosu! is not working right? Please contact us using our Telegram chat
|
||||||
- name: Suggestions or feature request
|
|
||||||
url: https://github.com/ppy/osu/discussions/categories/ideas
|
|
||||||
about: Got something you think should change or be added? Search for or start a new discussion!
|
|
||||||
- name: osu!stable issues
|
|
||||||
url: https://github.com/ppy/osu-stable-issues
|
|
||||||
about: For osu!(stable) - ie. the current "live" game version, check out the dedicated repository. Note that this is for serious bug reports only, not tech support.
|
|
||||||
|
|
||||||
|
|||||||
@@ -208,9 +208,10 @@ namespace osu.Desktop
|
|||||||
[SupportedOSPlatform("windows")]
|
[SupportedOSPlatform("windows")]
|
||||||
private static void configureWindows(VelopackApp app)
|
private static void configureWindows(VelopackApp app)
|
||||||
{
|
{
|
||||||
app.OnFirstRun(_ => WindowsAssociationManager.InstallAssociations());
|
// we do not want associations here, as that breaks official lazer's associations
|
||||||
app.OnAfterUpdateFastCallback(_ => WindowsAssociationManager.UpdateAssociations());
|
// app.OnFirstRun(_ => WindowsAssociationManager.InstallAssociations());
|
||||||
app.OnBeforeUninstallFastCallback(_ => WindowsAssociationManager.UninstallAssociations());
|
// app.OnAfterUpdateFastCallback(_ => WindowsAssociationManager.UpdateAssociations());
|
||||||
|
// app.OnBeforeUninstallFastCallback(_ => WindowsAssociationManager.UninstallAssociations());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
typeof(ManiaModFadeIn)
|
typeof(ManiaModFadeIn)
|
||||||
}).ToArray();
|
}).ToArray();
|
||||||
|
|
||||||
public override bool Ranked => false;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public override bool ValidForFreestyleAsRequiredMod => false;
|
public override bool ValidForFreestyleAsRequiredMod => false;
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public class ManiaModHardRock : ModHardRock, IApplicableToHitObject
|
public class ManiaModHardRock : ModHardRock, IApplicableToHitObject
|
||||||
{
|
{
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override bool Ranked => false;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public const double HIT_WINDOW_DIFFICULTY_MULTIPLIER = 1.4;
|
public const double HIT_WINDOW_DIFFICULTY_MULTIPLIER = 1.4;
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public class ManiaModMirror : ModMirror, IApplicableToBeatmap
|
public class ManiaModMirror : ModMirror, IApplicableToBeatmap
|
||||||
{
|
{
|
||||||
public override LocalisableString Description => "Notes are flipped horizontally.";
|
public override LocalisableString Description => "Notes are flipped horizontally.";
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public void ApplyToBeatmap(IBeatmap beatmap)
|
public void ApplyToBeatmap(IBeatmap beatmap)
|
||||||
{
|
{
|
||||||
|
|||||||
16
osu.Game.Rulesets.Osu/Mods/OsuModRateAdjustConcrete.cs
Normal file
16
osu.Game.Rulesets.Osu/Mods/OsuModRateAdjustConcrete.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Overlays.Settings;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
|
{
|
||||||
|
public class OsuModRateAdjustConcrete : ModRateAdjustConcrete
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override LocalisableString Description => @"Spinners will be automatically completed.";
|
public override LocalisableString Description => @"Spinners will be automatically completed.";
|
||||||
public override double ScoreMultiplier => 0.9;
|
public override double ScoreMultiplier => 0.9;
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot), typeof(OsuModTargetPractice) };
|
public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot), typeof(OsuModTargetPractice) };
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public void ApplyToDrawableHitObject(DrawableHitObject hitObject)
|
public void ApplyToDrawableHitObject(DrawableHitObject hitObject)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public class OsuModTouchDevice : ModTouchDevice
|
public class OsuModTouchDevice : ModTouchDevice
|
||||||
{
|
{
|
||||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot), typeof(OsuModBloom) }).ToArray();
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot), typeof(OsuModBloom) }).ToArray();
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -230,6 +230,14 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
new ModScoreV2(),
|
new ModScoreV2(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
case ModType.Special:
|
||||||
|
#if DEBUG
|
||||||
|
return new Mod[]
|
||||||
|
{
|
||||||
|
new OsuModRateAdjustConcrete(),
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return Array.Empty<Mod>();
|
return Array.Empty<Mod>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace osu.Game.Beatmaps
|
|||||||
LocallyModified = -4,
|
LocallyModified = -4,
|
||||||
|
|
||||||
[LocalisableDescription(typeof(SongSelectStrings), nameof(SongSelectStrings.StatusUnknown))]
|
[LocalisableDescription(typeof(SongSelectStrings), nameof(SongSelectStrings.StatusUnknown))]
|
||||||
[Description("Unknown")]
|
[Description("Offline")]
|
||||||
None = -3,
|
None = -3,
|
||||||
|
|
||||||
[LocalisableDescription(typeof(BeatmapsetsStrings), nameof(BeatmapsetsStrings.ShowStatusGraveyard))]
|
[LocalisableDescription(typeof(BeatmapsetsStrings), nameof(BeatmapsetsStrings.ShowStatusGraveyard))]
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ namespace osu.Game.Beatmaps.Drawables.Cards
|
|||||||
Status = beatmapSet.Status,
|
Status = beatmapSet.Status,
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
TextSize = 13f
|
TextSize = 13f,
|
||||||
|
ShowUnknownStatus = true
|
||||||
},
|
},
|
||||||
new DifficultySpectrumDisplay
|
new DifficultySpectrumDisplay
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ namespace osu.Game.Graphics
|
|||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case BeatmapOnlineStatus.None:
|
case BeatmapOnlineStatus.None:
|
||||||
return Color4.RosyBrown;
|
return Color4.AliceBlue;
|
||||||
|
|
||||||
case BeatmapOnlineStatus.LocallyModified:
|
case BeatmapOnlineStatus.LocallyModified:
|
||||||
return Color4.OrangeRed;
|
return Color4.OrangeRed;
|
||||||
@@ -183,6 +183,9 @@ namespace osu.Game.Graphics
|
|||||||
case ModType.System:
|
case ModType.System:
|
||||||
return Yellow;
|
return Yellow;
|
||||||
|
|
||||||
|
case ModType.Special:
|
||||||
|
return Orange2;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException(nameof(modType), modType, "Unknown mod type");
|
throw new ArgumentOutOfRangeException(nameof(modType), modType, "Unknown mod type");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ namespace osu.Game.Localisation
|
|||||||
public static LocalisableString LocallyModifiedTooltip => new TranslatableString(getKey(@"locally_modified_tooltip"), @"Has been locally modified");
|
public static LocalisableString LocallyModifiedTooltip => new TranslatableString(getKey(@"locally_modified_tooltip"), @"Has been locally modified");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Unknown"
|
/// "Offline"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString StatusUnknown => new TranslatableString(getKey(@"status_unknown"), @"Unknown");
|
public static LocalisableString StatusUnknown => new TranslatableString(getKey(@"status_unknown"), @"Offline");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Total Plays"
|
/// "Total Plays"
|
||||||
|
|||||||
@@ -191,7 +191,8 @@ namespace osu.Game.Overlays.BeatmapSet
|
|||||||
Anchor = Anchor.TopRight,
|
Anchor = Anchor.TopRight,
|
||||||
Origin = Anchor.TopRight,
|
Origin = Anchor.TopRight,
|
||||||
TextSize = 14,
|
TextSize = 14,
|
||||||
TextPadding = new MarginPadding { Horizontal = 35, Vertical = 10 }
|
TextPadding = new MarginPadding { Horizontal = 35, Vertical = 10 },
|
||||||
|
ShowUnknownStatus = true
|
||||||
},
|
},
|
||||||
storyboardIconPill = new StoryboardIconPill
|
storyboardIconPill = new StoryboardIconPill
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -329,6 +329,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
yield return createModColumnContent(ModType.Automation);
|
yield return createModColumnContent(ModType.Automation);
|
||||||
yield return createModColumnContent(ModType.Conversion);
|
yield return createModColumnContent(ModType.Conversion);
|
||||||
yield return createModColumnContent(ModType.Fun);
|
yield return createModColumnContent(ModType.Fun);
|
||||||
|
yield return createModColumnContent(ModType.Special);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ColumnDimContainer createModColumnContent(ModType modType)
|
private ColumnDimContainer createModColumnContent(ModType modType)
|
||||||
|
|||||||
22
osu.Game/Rulesets/Mods/IApplicableFailExit.cs
Normal file
22
osu.Game/Rulesets/Mods/IApplicableFailExit.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mods
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a mod which can override a fail and quit the game instead.
|
||||||
|
/// </summary>
|
||||||
|
public interface IApplicableFailExit : IApplicableMod
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Whether we should allow failing at the current point in time.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Whether the fail should be allowed to proceed. Return false to block.</returns>
|
||||||
|
bool PerformFail();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether we want to exit the game on fail. Only used if <see cref="PerformFail"/> returns true.
|
||||||
|
/// </summary>
|
||||||
|
bool ExitOnFail { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,19 +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.Game;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An interface for mods that apply changes to the <see cref="OsuGameBase"/>.
|
|
||||||
/// This is really stupid and f%%king dangerous, possibly disasterous even.
|
|
||||||
/// </summary>
|
|
||||||
public interface IApplicableToOsuGameBase : IApplicableMod
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Provide a <see cref="OsuGameBase"/>. Called once on initialisation of a play instance.
|
|
||||||
/// </summary>
|
|
||||||
void ApplyToOsuGameBase(OsuGameBase game);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -127,7 +127,9 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
/// The settings are returned in ascending key order as per <see cref="SettingsMap"/>.
|
/// The settings are returned in ascending key order as per <see cref="SettingsMap"/>.
|
||||||
/// The ordering is intentionally enforced manually, as ordering of <see cref="Dictionary{TKey,TValue}.Values"/> is unspecified.
|
/// The ordering is intentionally enforced manually, as ordering of <see cref="Dictionary{TKey,TValue}.Values"/> is unspecified.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
internal IEnumerable<IBindable> SettingsBindables => SettingsMap.OrderBy(pair => pair.Key).Select(pair => pair.Value);
|
internal IEnumerable<IBindable> SettingsBindables => SettingsMap.OrderBy(pair => pair.Key)
|
||||||
|
.Select(pair => pair.Value)
|
||||||
|
.Where(x => !x.GetType().GetCustomAttributes(typeof(JsonIgnoreAttribute)).Any());
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides mapping of names to <see cref="IBindable"/>s of all settings within this mod.
|
/// Provides mapping of names to <see cref="IBindable"/>s of all settings within this mod.
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
/// - Hit windows differ (https://github.com/ppy/osu/issues/11311).
|
/// - Hit windows differ (https://github.com/ppy/osu/issues/11311).
|
||||||
/// - Sliders always gives combo for slider end, even on miss (https://github.com/ppy/osu/issues/11769).
|
/// - Sliders always gives combo for slider end, even on miss (https://github.com/ppy/osu/issues/11769).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed override bool Ranked => false;
|
public sealed override bool Ranked => true;
|
||||||
|
|
||||||
public sealed override bool ValidForFreestyleAsRequiredMod => false;
|
public sealed override bool ValidForFreestyleAsRequiredMod => false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override IconUsage? Icon => OsuIcon.ModDaycore;
|
public override IconUsage? Icon => OsuIcon.ModDaycore;
|
||||||
public override ModType Type => ModType.DifficultyReduction;
|
public override ModType Type => ModType.DifficultyReduction;
|
||||||
public override LocalisableString Description => "Whoaaaaa...";
|
public override LocalisableString Description => "Whoaaaaa...";
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
[SettingSource("Speed decrease", "The actual decrease to apply", SettingControlType = typeof(MultiplierSettingsSlider))]
|
[SettingSource("Speed decrease", "The actual decrease to apply", SettingControlType = typeof(MultiplierSettingsSlider))]
|
||||||
public override BindableNumber<double> SpeedChange { get; } = new BindableDouble(0.75)
|
public override BindableNumber<double> SpeedChange { get; } = new BindableDouble(0.75)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override IconUsage? Icon => OsuIcon.ModDoubleTime;
|
public override IconUsage? Icon => OsuIcon.ModDoubleTime;
|
||||||
public override ModType Type => ModType.DifficultyIncrease;
|
public override ModType Type => ModType.DifficultyIncrease;
|
||||||
public override LocalisableString Description => "Zoooooooooom...";
|
public override LocalisableString Description => "Zoooooooooom...";
|
||||||
public override bool Ranked => SpeedChange.IsDefault;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
[SettingSource("Speed increase", "The actual increase to apply", SettingControlType = typeof(MultiplierSettingsSlider))]
|
[SettingSource("Speed increase", "The actual increase to apply", SettingControlType = typeof(MultiplierSettingsSlider))]
|
||||||
public override BindableNumber<double> SpeedChange { get; } = new BindableDouble(1.5)
|
public override BindableNumber<double> SpeedChange { get; } = new BindableDouble(1.5)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override ModType Type => ModType.DifficultyReduction;
|
public override ModType Type => ModType.DifficultyReduction;
|
||||||
public override double ScoreMultiplier => 0.5;
|
public override double ScoreMultiplier => 0.5;
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(ModHardRock), typeof(ModDifficultyAdjust) };
|
public override Type[] IncompatibleMods => new[] { typeof(ModHardRock), typeof(ModDifficultyAdjust) };
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
public override bool ValidForFreestyleAsRequiredMod => true;
|
public override bool ValidForFreestyleAsRequiredMod => true;
|
||||||
|
|
||||||
protected const float ADJUST_RATIO = 0.5f;
|
protected const float ADJUST_RATIO = 0.5f;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// 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 Newtonsoft.Json;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
@@ -9,17 +10,23 @@ using osu.Game.Rulesets.Scoring;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
public abstract class ModFailCondition : Mod, IApplicableToHealthProcessor, IApplicableFailOverride
|
public abstract class ModFailCondition : Mod, IApplicableToHealthProcessor, IApplicableFailOverride, IApplicableFailExit
|
||||||
{
|
{
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(ModNoFail), typeof(ModCinema) };
|
public override Type[] IncompatibleMods => new[] { typeof(ModNoFail), typeof(ModCinema) };
|
||||||
|
|
||||||
[SettingSource("Restart on fail", "Automatically restarts when failed.")]
|
[SettingSource("Restart on fail", "Automatically restarts when failed.")]
|
||||||
public BindableBool Restart { get; } = new BindableBool();
|
public BindableBool Restart { get; } = new BindableBool();
|
||||||
|
|
||||||
|
[SettingSource("Exit game on fail", "Automatically exits the game when failed."), JsonIgnore]
|
||||||
|
public BindableBool Exit { get; } = new BindableBool();
|
||||||
|
|
||||||
public virtual bool PerformFail() => true;
|
public virtual bool PerformFail() => true;
|
||||||
|
|
||||||
public virtual bool RestartOnFail => Restart.Value;
|
public virtual bool RestartOnFail => Restart.Value;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual bool ExitOnFail => Exit.Value;
|
||||||
|
|
||||||
private Action? triggerFailureDelegate;
|
private Action? triggerFailureDelegate;
|
||||||
|
|
||||||
public void ApplyToHealthProcessor(HealthProcessor healthProcessor)
|
public void ApplyToHealthProcessor(HealthProcessor healthProcessor)
|
||||||
@@ -39,7 +46,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="healthProcessor">The loaded <see cref="HealthProcessor"/>.</param>
|
/// <param name="healthProcessor">The loaded <see cref="HealthProcessor"/>.</param>
|
||||||
/// <param name="result">The latest <see cref="JudgementResult"/>.</param>
|
/// <param name="result">The latest <see cref="JudgementResult"/>.</param>
|
||||||
/// <returns>Whether the fail condition has been met.</returns>
|
/// <returns>Whether the fail condition has been met.</returns>z
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This method should only be used to trigger failures based on <paramref name="result"/>.
|
/// This method should only be used to trigger failures based on <paramref name="result"/>.
|
||||||
/// Using outside values to evaluate failure may introduce event ordering discrepancies, use
|
/// Using outside values to evaluate failure may introduce event ordering discrepancies, use
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override IconUsage? Icon => OsuIcon.ModFlashlight;
|
public override IconUsage? Icon => OsuIcon.ModFlashlight;
|
||||||
public override ModType Type => ModType.DifficultyIncrease;
|
public override ModType Type => ModType.DifficultyIncrease;
|
||||||
public override LocalisableString Description => "Restricted view area.";
|
public override LocalisableString Description => "Restricted view area.";
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
[SettingSource("Flashlight size", "Multiplier applied to the default flashlight size.")]
|
[SettingSource("Flashlight size", "Multiplier applied to the default flashlight size.")]
|
||||||
public abstract BindableFloat SizeMultiplier { get; }
|
public abstract BindableFloat SizeMultiplier { get; }
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override IconUsage? Icon => OsuIcon.ModHalfTime;
|
public override IconUsage? Icon => OsuIcon.ModHalfTime;
|
||||||
public override ModType Type => ModType.DifficultyReduction;
|
public override ModType Type => ModType.DifficultyReduction;
|
||||||
public override LocalisableString Description => "Less zoom...";
|
public override LocalisableString Description => "Less zoom...";
|
||||||
public override bool Ranked => SpeedChange.IsDefault;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
[SettingSource("Speed decrease", "The actual decrease to apply", SettingControlType = typeof(MultiplierSettingsSlider))]
|
[SettingSource("Speed decrease", "The actual decrease to apply", SettingControlType = typeof(MultiplierSettingsSlider))]
|
||||||
public override BindableNumber<double> SpeedChange { get; } = new BindableDouble(0.75)
|
public override BindableNumber<double> SpeedChange { get; } = new BindableDouble(0.75)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override ModType Type => ModType.DifficultyIncrease;
|
public override ModType Type => ModType.DifficultyIncrease;
|
||||||
public override LocalisableString Description => "Everything just got a bit harder...";
|
public override LocalisableString Description => "Everything just got a bit harder...";
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(ModEasy), typeof(ModDifficultyAdjust) };
|
public override Type[] IncompatibleMods => new[] { typeof(ModEasy), typeof(ModDifficultyAdjust) };
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
public override bool ValidForFreestyleAsRequiredMod => true;
|
public override bool ValidForFreestyleAsRequiredMod => true;
|
||||||
|
|
||||||
protected const float ADJUST_RATIO = 1.4f;
|
protected const float ADJUST_RATIO = 1.4f;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override string Acronym => "HD";
|
public override string Acronym => "HD";
|
||||||
public override IconUsage? Icon => OsuIcon.ModHidden;
|
public override IconUsage? Icon => OsuIcon.ModHidden;
|
||||||
public override ModType Type => ModType.DifficultyIncrease;
|
public override ModType Type => ModType.DifficultyIncrease;
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public virtual void ApplyToScoreProcessor(ScoreProcessor scoreProcessor)
|
public virtual void ApplyToScoreProcessor(ScoreProcessor scoreProcessor)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override IconUsage? Icon => OsuIcon.ModNightcore;
|
public override IconUsage? Icon => OsuIcon.ModNightcore;
|
||||||
public override ModType Type => ModType.DifficultyIncrease;
|
public override ModType Type => ModType.DifficultyIncrease;
|
||||||
public override LocalisableString Description => "Uguuuuuuuu...";
|
public override LocalisableString Description => "Uguuuuuuuu...";
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
[SettingSource("Speed increase", "The actual increase to apply", SettingControlType = typeof(MultiplierSettingsSlider))]
|
[SettingSource("Speed increase", "The actual increase to apply", SettingControlType = typeof(MultiplierSettingsSlider))]
|
||||||
public override BindableNumber<double> SpeedChange { get; } = new BindableDouble(1.5)
|
public override BindableNumber<double> SpeedChange { get; } = new BindableDouble(1.5)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override LocalisableString Description => "You can't fail, no matter what.";
|
public override LocalisableString Description => "You can't fail, no matter what.";
|
||||||
public override double ScoreMultiplier => 0.5;
|
public override double ScoreMultiplier => 0.5;
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(ModFailCondition), typeof(ModCinema) };
|
public override Type[] IncompatibleMods => new[] { typeof(ModFailCondition), typeof(ModCinema) };
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
public override bool ValidForFreestyleAsRequiredMod => true;
|
public override bool ValidForFreestyleAsRequiredMod => true;
|
||||||
|
|
||||||
private readonly Bindable<bool> showHealthBar = new Bindable<bool>();
|
private readonly Bindable<bool> showHealthBar = new Bindable<bool>();
|
||||||
|
|||||||
47
osu.Game/Rulesets/Mods/ModRateAdjustConcrete.cs
Normal file
47
osu.Game/Rulesets/Mods/ModRateAdjustConcrete.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Overlays.Settings;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mods
|
||||||
|
{
|
||||||
|
public abstract class ModRateAdjustConcrete : ModRateAdjust
|
||||||
|
{
|
||||||
|
public override string Name => "Rate Adjust";
|
||||||
|
public override LocalisableString Description => "[DEBUG BUILDS ONLY] Set any speed";
|
||||||
|
public override string Acronym => "_R";
|
||||||
|
private readonly RateAdjustModHelper rateAdjustHelper;
|
||||||
|
|
||||||
|
[SettingSource("Speed decrease", "The actual decrease to apply", SettingControlType = typeof(MultiplierSettingsSlider))]
|
||||||
|
public override BindableNumber<double> SpeedChange { get; } = new BindableDouble(0.75)
|
||||||
|
{
|
||||||
|
MinValue = 0.1, // BASS breaks at lower rates
|
||||||
|
MaxValue = 10,
|
||||||
|
Precision = 0.01
|
||||||
|
};
|
||||||
|
|
||||||
|
[SettingSource("Adjust pitch", "Should pitch be adjusted with speed")]
|
||||||
|
public virtual BindableBool AdjustPitch { get; } = new BindableBool();
|
||||||
|
|
||||||
|
|
||||||
|
protected ModRateAdjustConcrete()
|
||||||
|
{
|
||||||
|
rateAdjustHelper = new RateAdjustModHelper(SpeedChange);
|
||||||
|
rateAdjustHelper.HandleAudioAdjustments(AdjustPitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override double ScoreMultiplier => 1.0;
|
||||||
|
public override void ApplyToTrack(IAdjustableAudioComponent track)
|
||||||
|
{
|
||||||
|
rateAdjustHelper.ApplyToTrack(track);
|
||||||
|
}
|
||||||
|
public override bool Ranked => false;
|
||||||
|
public override ModType Type => ModType.Special;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
Conversion,
|
Conversion,
|
||||||
Automation,
|
Automation,
|
||||||
Fun,
|
Fun,
|
||||||
System
|
System,
|
||||||
|
Special
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public readonly string OriginalAcronym;
|
public readonly string OriginalAcronym;
|
||||||
|
|
||||||
public override string Name => $"Unknown mod ({OriginalAcronym})";
|
public override string Name => $"Unknown mod ({OriginalAcronym})";
|
||||||
public override string Acronym => $"{OriginalAcronym}??";
|
public override string Acronym => $"{OriginalAcronym}!";
|
||||||
public override LocalisableString Description => "This mod could not be resolved by the game.";
|
public override LocalisableString Description => "This mod could not be resolved by the game.";
|
||||||
public override double ScoreMultiplier => 0;
|
public override double ScoreMultiplier => 0;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
// 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@@ -32,6 +34,8 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
public readonly KeyBindingContainer<T> KeyBindingContainer;
|
public readonly KeyBindingContainer<T> KeyBindingContainer;
|
||||||
|
|
||||||
|
private readonly RulesetKeyBindingContainer rulesetKeyBindingContainer;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private ScoreProcessor? scoreProcessor { get; set; }
|
private ScoreProcessor? scoreProcessor { get; set; }
|
||||||
|
|
||||||
@@ -64,8 +68,10 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
protected RulesetInputManager(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique)
|
protected RulesetInputManager(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique)
|
||||||
{
|
{
|
||||||
|
rulesetKeyBindingContainer = createRulesetKeyBindingContainer(ruleset, variant, unique);
|
||||||
|
|
||||||
InternalChild = KeyBindingContainer =
|
InternalChild = KeyBindingContainer =
|
||||||
CreateKeyBindingContainer(ruleset, variant, unique)
|
rulesetKeyBindingContainer
|
||||||
.WithChild(content = new Container { RelativeSizeAxes = Axes.Both });
|
.WithChild(content = new Container { RelativeSizeAxes = Axes.Both });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,11 +180,10 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
public void Attach(InputCountController inputCountController)
|
public void Attach(InputCountController inputCountController)
|
||||||
{
|
{
|
||||||
var triggers = KeyBindingContainer.DefaultKeyBindings
|
var bindings = rulesetKeyBindingContainer.DefaultKeyBindings;
|
||||||
.Select(b => b.GetAction<T>())
|
var triggers = bindings.Select(b => new KeyCounterBindingTrigger<T>(b, b.GetAction<T>()))
|
||||||
.Distinct()
|
.DistinctBy(b => b.Action)
|
||||||
.Select(action => new KeyCounterActionTrigger<T>(action))
|
.ToArray();
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
KeyBindingContainer.AddRange(triggers);
|
KeyBindingContainer.AddRange(triggers);
|
||||||
inputCountController.AddRange(triggers);
|
inputCountController.AddRange(triggers);
|
||||||
@@ -215,6 +220,9 @@ namespace osu.Game.Rulesets.UI
|
|||||||
protected virtual KeyBindingContainer<T> CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique)
|
protected virtual KeyBindingContainer<T> CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique)
|
||||||
=> new RulesetKeyBindingContainer(ruleset, variant, unique);
|
=> new RulesetKeyBindingContainer(ruleset, variant, unique);
|
||||||
|
|
||||||
|
private RulesetKeyBindingContainer createRulesetKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique)
|
||||||
|
=> new RulesetKeyBindingContainer(ruleset, variant, unique);
|
||||||
|
|
||||||
public partial class RulesetKeyBindingContainer : DatabasedKeyBindingContainer<T>
|
public partial class RulesetKeyBindingContainer : DatabasedKeyBindingContainer<T>
|
||||||
{
|
{
|
||||||
protected override bool HandleRepeats => false;
|
protected override bool HandleRepeats => false;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace osu.Game.Screens.Play.Break
|
|||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Font = OsuFont.Numeric.With(size: 33),
|
Font = OsuFont.TorusAlternate.With(size: 64, weight: FontWeight.SemiBold),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
97
osu.Game/Screens/Play/HUD/ArgonLongestComboCounter.cs
Normal file
97
osu.Game/Screens/Play/HUD/ArgonLongestComboCounter.cs
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
// 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.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Extensions.LocalisationExtensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Localisation.SkinComponents;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Play.HUD
|
||||||
|
{
|
||||||
|
public partial class ArgonLongestComboCounter : ComboCounter
|
||||||
|
{
|
||||||
|
protected ArgonCounterTextComponent Text = null!;
|
||||||
|
|
||||||
|
protected override double RollingDuration => 250;
|
||||||
|
|
||||||
|
protected virtual bool DisplayXSymbol => true;
|
||||||
|
|
||||||
|
[SettingSource("Wireframe opacity", "Controls the opacity of the wireframes behind the digits.")]
|
||||||
|
public BindableFloat WireframeOpacity { get; } = new BindableFloat(0.25f)
|
||||||
|
{
|
||||||
|
Precision = 0.01f,
|
||||||
|
MinValue = 0,
|
||||||
|
MaxValue = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
[SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.ShowLabel))]
|
||||||
|
public Bindable<bool> ShowLabel { get; } = new BindableBool(true);
|
||||||
|
|
||||||
|
[SettingSource("Show animation on increase", "Shows a bouncing animation when the combo increases")]
|
||||||
|
public Bindable<bool> ShowRolling { get; } = new BindableBool(true);
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(ScoreProcessor scoreProcessor)
|
||||||
|
{
|
||||||
|
Current.BindTo(scoreProcessor.HighestCombo);
|
||||||
|
Current.BindValueChanged(combo =>
|
||||||
|
{
|
||||||
|
bool wasIncrease = combo.NewValue > combo.OldValue;
|
||||||
|
bool wasMiss = combo.OldValue > 1 && combo.NewValue == 0;
|
||||||
|
|
||||||
|
float newScale = Math.Clamp(Text.NumberContainer.Scale.X * (wasIncrease ? 1.1f : 0.8f), 0.6f, 1.4f);
|
||||||
|
|
||||||
|
float duration = ShowRolling.Value ? 500 : 0;
|
||||||
|
|
||||||
|
Text.NumberContainer
|
||||||
|
.ScaleTo(new Vector2(newScale))
|
||||||
|
.ScaleTo(Vector2.One, duration, Easing.OutQuint);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int DisplayedCount
|
||||||
|
{
|
||||||
|
get => base.DisplayedCount;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.DisplayedCount = value;
|
||||||
|
updateWireframe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateWireframe()
|
||||||
|
{
|
||||||
|
int digitsRequiredForDisplayCount = getDigitsRequiredForDisplayCount();
|
||||||
|
|
||||||
|
if (digitsRequiredForDisplayCount != Text.WireframeTemplate.Length)
|
||||||
|
Text.WireframeTemplate = new string('#', digitsRequiredForDisplayCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getDigitsRequiredForDisplayCount()
|
||||||
|
{
|
||||||
|
// one for the single presumed starting digit, one for the "x" at the end (unless disabled).
|
||||||
|
int digitsRequired = DisplayXSymbol ? 2 : 1;
|
||||||
|
long c = DisplayedCount;
|
||||||
|
while ((c /= 10) > 0)
|
||||||
|
digitsRequired++;
|
||||||
|
return digitsRequired;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override LocalisableString FormatCount(int count) => DisplayXSymbol ? $@"{count}x" : count.ToString();
|
||||||
|
|
||||||
|
protected override IHasText CreateText() => Text = new ArgonCounterTextComponent(Anchor.TopLeft, "MAX COMBO")
|
||||||
|
{
|
||||||
|
WireframeOpacity = { BindTarget = WireframeOpacity },
|
||||||
|
ShowLabel = { BindTarget = ShowLabel },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
// 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.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Localisation.SkinComponents;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Play.HUD.ClicksPerSecond
|
||||||
|
{
|
||||||
|
public partial class ArgonClicksPerSecondCounter : RollingCounter<int>, ISerialisableDrawable
|
||||||
|
{
|
||||||
|
[Resolved]
|
||||||
|
private ClicksPerSecondController controller { get; set; } = null!;
|
||||||
|
|
||||||
|
protected override double RollingDuration => 175;
|
||||||
|
|
||||||
|
[SettingSource("Wireframe opacity", "Controls the opacity of the wireframes behind the digits.")]
|
||||||
|
public BindableFloat WireframeOpacity { get; } = new BindableFloat(0.25f)
|
||||||
|
{
|
||||||
|
Precision = 0.01f,
|
||||||
|
MinValue = 0,
|
||||||
|
MaxValue = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
[SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.ShowLabel))]
|
||||||
|
public Bindable<bool> ShowLabel { get; } = new BindableBool(true);
|
||||||
|
|
||||||
|
public bool UsesFixedAnchor { get; set; }
|
||||||
|
|
||||||
|
public ArgonClicksPerSecondCounter()
|
||||||
|
{
|
||||||
|
Current.Value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
Current.Value = controller.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IHasText CreateText() => new TextComponent()
|
||||||
|
{
|
||||||
|
WireframeOpacity = { BindTarget = WireframeOpacity },
|
||||||
|
ShowLabel = { BindTarget = ShowLabel },
|
||||||
|
};
|
||||||
|
|
||||||
|
private partial class TextComponent : CompositeDrawable, IHasText
|
||||||
|
{
|
||||||
|
private readonly ArgonCounterTextComponent cpsValue;
|
||||||
|
|
||||||
|
public IBindable<float> WireframeOpacity { get; } = new BindableFloat();
|
||||||
|
|
||||||
|
public Bindable<bool> ShowLabel { get; } = new BindableBool();
|
||||||
|
|
||||||
|
public LocalisableString Text
|
||||||
|
{
|
||||||
|
get => cpsValue.Text;
|
||||||
|
set => cpsValue.Text = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextComponent()
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
InternalChild = new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Child = cpsValue = new ArgonCounterTextComponent(Anchor.TopLeft, "KEYS/SEC") // welp, not good
|
||||||
|
{
|
||||||
|
WireframeOpacity = { BindTarget = WireframeOpacity },
|
||||||
|
WireframeTemplate = @"##",
|
||||||
|
ShowLabel = { BindTarget = ShowLabel },
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
38
osu.Game/Screens/Play/HUD/KeyCounterBindingTrigger.cs
Normal file
38
osu.Game/Screens/Play/HUD/KeyCounterBindingTrigger.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using osu.Framework.Input.Bindings;
|
||||||
|
using osu.Framework.Input.Events;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Play.HUD
|
||||||
|
{
|
||||||
|
public partial class KeyCounterBindingTrigger<T> : InputTrigger, IKeyBindingHandler<T>
|
||||||
|
where T : struct
|
||||||
|
{
|
||||||
|
public T Action { get; }
|
||||||
|
|
||||||
|
public KeyCounterBindingTrigger(IKeyBinding key, T action)
|
||||||
|
: base(key?.KeyCombination.Keys[0].ToString() ?? $"B{(int)(object)action + 1}")
|
||||||
|
{
|
||||||
|
Action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnPressed(KeyBindingPressEvent<T> e)
|
||||||
|
{
|
||||||
|
if (!EqualityComparer<T>.Default.Equals(e.Action, Action))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Activate(Clock.Rate >= 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnReleased(KeyBindingReleaseEvent<T> e)
|
||||||
|
{
|
||||||
|
if (!EqualityComparer<T>.Default.Equals(e.Action, Action))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Deactivate(Clock.Rate >= 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Logging;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.Drawables;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Localisation.SkinComponents;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Play.HUD
|
||||||
|
{
|
||||||
|
public partial class SkinnableBeatmapSetOnlineStatusPill : CompositeDrawable, ISerialisableDrawable
|
||||||
|
{
|
||||||
|
private BeatmapSetOnlineStatusPill beatmapSetOnlineStatusPill { get; set; } = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IBindable<WorkingBeatmap> beatmap { get; set; } = null!;
|
||||||
|
|
||||||
|
public SkinnableBeatmapSetOnlineStatusPill() // WARNING: this is awful
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
beatmapSetOnlineStatusPill = new BeatmapSetOnlineStatusPill()
|
||||||
|
{
|
||||||
|
ShowUnknownStatus = true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
beatmap.BindValueChanged(b =>
|
||||||
|
{
|
||||||
|
beatmapSetOnlineStatusPill.Status = beatmap.Value.BeatmapSetInfo.Status;
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool UsesFixedAnchor { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
64
osu.Game/Screens/Play/HUD/SkinnableStarRatingDisplay.cs
Normal file
64
osu.Game/Screens/Play/HUD/SkinnableStarRatingDisplay.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.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Logging;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.Drawables;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Localisation.SkinComponents;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Play.HUD
|
||||||
|
{
|
||||||
|
public partial class SkinnableStarRatingDisplay : CompositeDrawable, ISerialisableDrawable
|
||||||
|
{
|
||||||
|
private StarRatingDisplay starRatingDisplay { get; set; } = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IBindable<WorkingBeatmap> beatmap { get; set; } = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private BeatmapDifficultyCache difficultyCache { get; set; } = null!;
|
||||||
|
|
||||||
|
private CancellationTokenSource? difficultyCancellationSource;
|
||||||
|
private IBindable<StarDifficulty>? difficultyBindable;
|
||||||
|
|
||||||
|
public SkinnableStarRatingDisplay() // WARNING: this is awful
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
starRatingDisplay = new StarRatingDisplay(new StarDifficulty(0.00, 0), animated: true)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
beatmap.BindValueChanged(b =>
|
||||||
|
{
|
||||||
|
difficultyCancellationSource?.Cancel();
|
||||||
|
difficultyCancellationSource = new CancellationTokenSource();
|
||||||
|
|
||||||
|
difficultyBindable?.UnbindAll();
|
||||||
|
difficultyBindable = difficultyCache.GetBindableDifficulty(b.NewValue.BeatmapInfo, difficultyCancellationSource.Token);
|
||||||
|
}, true);
|
||||||
|
starRatingDisplay.Current.BindTo((Bindable<StarDifficulty>)difficultyBindable!);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool UsesFixedAnchor { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -200,6 +200,8 @@ namespace osu.Game.Screens.Play
|
|||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
=> dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
=> dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
|
private OsuConfigManager config;
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
@@ -226,12 +228,13 @@ namespace osu.Game.Screens.Play
|
|||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(OsuConfigManager config, OsuGameBase game, CancellationToken cancellationToken)
|
private void load(OsuConfigManager config, OsuGameBase game, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
this.config = config;
|
||||||
var gameplayMods = Mods.Value.Select(m => m.DeepClone()).ToArray();
|
var gameplayMods = Mods.Value.Select(m => m.DeepClone()).ToArray();
|
||||||
|
|
||||||
if (gameplayMods.Any(m => m is UnknownMod))
|
if (gameplayMods.Any(m => m is UnknownMod))
|
||||||
{
|
{
|
||||||
Logger.Log("Gameplay was started with an unknown mod applied.", level: LogLevel.Important);
|
Logger.Log("Gameplay was started with an unknown mod applied.", level: LogLevel.Important);
|
||||||
return;
|
// return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Beatmap.Value is DummyWorkingBeatmap)
|
if (Beatmap.Value is DummyWorkingBeatmap)
|
||||||
@@ -983,6 +986,15 @@ namespace osu.Game.Screens.Play
|
|||||||
if (PauseOverlay.State.Value == Visibility.Visible)
|
if (PauseOverlay.State.Value == Visibility.Visible)
|
||||||
PauseOverlay.Hide();
|
PauseOverlay.Hide();
|
||||||
|
|
||||||
|
bool exitOnFail = GameplayState.Mods.OfType<IApplicableFailExit>().Any(m => m.ExitOnFail)
|
||||||
|
&& Score.ScoreInfo.User.Username == config.Get<string>(OsuSetting.Username); // TODO: do more concrete checks
|
||||||
|
if (exitOnFail)
|
||||||
|
{
|
||||||
|
// game.AttemptExit();
|
||||||
|
game.Exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool restartOnFail = GameplayState.Mods.OfType<IApplicableFailOverride>().Any(m => m.RestartOnFail);
|
bool restartOnFail = GameplayState.Mods.OfType<IApplicableFailOverride>().Any(m => m.RestartOnFail);
|
||||||
if (!restartOnFail)
|
if (!restartOnFail)
|
||||||
failAnimationContainer.Start();
|
failAnimationContainer.Start();
|
||||||
|
|||||||
@@ -215,6 +215,9 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
|
|||||||
|
|
||||||
this.ScaleTo(0).Then().ScaleTo(1, APPEAR_DURATION, Easing.OutQuint);
|
this.ScaleTo(0).Then().ScaleTo(1, APPEAR_DURATION, Easing.OutQuint);
|
||||||
|
|
||||||
|
if (!withFlair)
|
||||||
|
accuracyCircle.Colour = OsuColour.ForRank(score.Rank);
|
||||||
|
|
||||||
if (withFlair)
|
if (withFlair)
|
||||||
{
|
{
|
||||||
const double swoosh_pre_delay = 443f;
|
const double swoosh_pre_delay = 443f;
|
||||||
@@ -307,6 +310,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
|
|||||||
{
|
{
|
||||||
var dink = badgeNum < badges.Count - 1 ? badgeTickSound : badgeMaxSound;
|
var dink = badgeNum < badges.Count - 1 ? badgeTickSound : badgeMaxSound;
|
||||||
|
|
||||||
|
accuracyCircle.FadeColour(OsuColour.ForRank(badge.Rank), 100, Easing.InOutSine); // TODO: nicer animations
|
||||||
dink!.FrequencyTo(1 + badgeNum++ * 0.05);
|
dink!.FrequencyTo(1 + badgeNum++ * 0.05);
|
||||||
dink!.Play();
|
dink!.Play();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Extensions.LocalisationExtensions;
|
using osu.Framework.Extensions.LocalisationExtensions;
|
||||||
|
using osu.Framework.Extensions.ObjectExtensions;
|
||||||
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;
|
||||||
@@ -43,45 +44,63 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics
|
|||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Direction = FillDirection.Vertical,
|
Direction = FillDirection.Vertical,
|
||||||
Children = new[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new CircularContainer
|
new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Height = 12,
|
AutoSizeAxes = Axes.Y,
|
||||||
Masking = true,
|
Masking = true,
|
||||||
|
CornerRadius = 8f,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new Box
|
new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = Color4Extensions.FromHex("#222")
|
Colour = Color4Extensions.FromHex("#2222229f"),
|
||||||
},
|
},
|
||||||
HeaderText = new OsuSpriteText
|
new FillFlowContainer
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.TopLeft,
|
||||||
Origin = Anchor.Centre,
|
RelativeSizeAxes = Axes.X,
|
||||||
Font = OsuFont.Torus.With(size: 12, weight: FontWeight.SemiBold),
|
AutoSizeAxes = Axes.Y,
|
||||||
Text = header.ToUpper(),
|
Direction = FillDirection.Vertical,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
HeaderText = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Font = OsuFont.Torus.With(size: 12, weight: FontWeight.SemiBold),
|
||||||
|
Text = header.ToUpper(),
|
||||||
|
},
|
||||||
|
content = CreateContent().With(d =>
|
||||||
|
{
|
||||||
|
d.Origin = Anchor.TopCentre;
|
||||||
|
d.Anchor = Anchor.TopCentre;
|
||||||
|
d.Alpha = 0;
|
||||||
|
d.AlwaysPresent = true;
|
||||||
|
}),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Container
|
// new Container
|
||||||
{
|
// {
|
||||||
Anchor = Anchor.TopCentre,
|
// Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre,
|
// Origin = Anchor.TopCentre,
|
||||||
AutoSizeAxes = Axes.Both,
|
// AutoSizeAxes = Axes.Both,
|
||||||
Children = new[]
|
// Children = new[]
|
||||||
{
|
// {
|
||||||
content = CreateContent().With(d =>
|
// content = CreateContent().With(d =>
|
||||||
{
|
// {
|
||||||
d.Anchor = Anchor.TopCentre;
|
// d.Anchor = Anchor.TopCentre;
|
||||||
d.Origin = Anchor.TopCentre;
|
// d.Origin = Anchor.TopCentre;
|
||||||
d.Alpha = 0;
|
// d.Alpha = 0;
|
||||||
d.AlwaysPresent = true;
|
// d.AlwaysPresent = true;
|
||||||
}),
|
// }),
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Extensions.ImageExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Audio;
|
using osu.Framework.Graphics.Audio;
|
||||||
using osu.Framework.Graphics.Colour;
|
using osu.Framework.Graphics.Colour;
|
||||||
@@ -14,12 +15,14 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Ranking.Contracted;
|
using osu.Game.Screens.Ranking.Contracted;
|
||||||
using osu.Game.Screens.Ranking.Expanded;
|
using osu.Game.Screens.Ranking.Expanded;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
using ZstdSharp.Unsafe;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Ranking
|
namespace osu.Game.Screens.Ranking
|
||||||
{
|
{
|
||||||
@@ -96,6 +99,7 @@ namespace osu.Game.Screens.Ranking
|
|||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuGameBase game { get; set; } = null!;
|
private OsuGameBase game { get; set; } = null!;
|
||||||
|
private OsuColour colour { get; set; } = null!;
|
||||||
|
|
||||||
private AudioContainer audioContent = null!;
|
private AudioContainer audioContent = null!;
|
||||||
|
|
||||||
@@ -124,12 +128,14 @@ namespace osu.Game.Screens.Ranking
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(AudioManager audio)
|
private void load(AudioManager audio, OsuColour colour)
|
||||||
{
|
{
|
||||||
// ScorePanel doesn't include the top extruding area in its own size.
|
// ScorePanel doesn't include the top extruding area in its own size.
|
||||||
// Adding a manual offset here allows the expanded version to take on an "acceptable" vertical centre when at 100% UI scale.
|
// Adding a manual offset here allows the expanded version to take on an "acceptable" vertical centre when at 100% UI scale.
|
||||||
const float vertical_fudge = 20;
|
const float vertical_fudge = 20;
|
||||||
|
|
||||||
|
this.colour = colour;
|
||||||
|
|
||||||
InternalChild = audioContent = new AudioContainer
|
InternalChild = audioContent = new AudioContainer
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
@@ -239,6 +245,15 @@ namespace osu.Game.Screens.Ranking
|
|||||||
|
|
||||||
private void updateState()
|
private void updateState()
|
||||||
{
|
{
|
||||||
|
ColourInfo getColour(ColourInfo info)
|
||||||
|
{
|
||||||
|
var ci = info.AverageColour;
|
||||||
|
var rank = (ColourInfo)OsuColour.ForRank(Score.Rank);
|
||||||
|
(float _, float _, float v) = Color4Extensions.ToHSV(ci);
|
||||||
|
(float rh, float rs, _) = Color4Extensions.ToHSV(rank);
|
||||||
|
return Color4Extensions.FromHSV(rh, rs * 0.3f, v * 1.1f);
|
||||||
|
}
|
||||||
|
|
||||||
topLayerContent?.FadeOut(content_fade_duration).Expire();
|
topLayerContent?.FadeOut(content_fade_duration).Expire();
|
||||||
middleLayerContent?.FadeOut(content_fade_duration).Expire();
|
middleLayerContent?.FadeOut(content_fade_duration).Expire();
|
||||||
|
|
||||||
@@ -247,8 +262,8 @@ namespace osu.Game.Screens.Ranking
|
|||||||
case PanelState.Expanded:
|
case PanelState.Expanded:
|
||||||
Size = new Vector2(EXPANDED_WIDTH, expanded_height);
|
Size = new Vector2(EXPANDED_WIDTH, expanded_height);
|
||||||
|
|
||||||
topLayerBackground.FadeColour(expanded_top_layer_colour, RESIZE_DURATION, Easing.OutQuint);
|
topLayerBackground.FadeColour(getColour(expanded_top_layer_colour), RESIZE_DURATION, Easing.OutQuint);
|
||||||
middleLayerBackground.FadeColour(expanded_middle_layer_colour, RESIZE_DURATION, Easing.OutQuint);
|
middleLayerBackground.FadeColour(getColour(expanded_middle_layer_colour), RESIZE_DURATION, Easing.OutQuint);
|
||||||
|
|
||||||
bool firstLoad = topLayerContent == null;
|
bool firstLoad = topLayerContent == null;
|
||||||
topLayerContentContainer.Add(topLayerContent = new ExpandedPanelTopContent(Score.User, firstLoad) { Alpha = 0 });
|
topLayerContentContainer.Add(topLayerContent = new ExpandedPanelTopContent(Score.User, firstLoad) { Alpha = 0 });
|
||||||
@@ -261,8 +276,8 @@ namespace osu.Game.Screens.Ranking
|
|||||||
case PanelState.Contracted:
|
case PanelState.Contracted:
|
||||||
Size = new Vector2(CONTRACTED_WIDTH, contracted_height);
|
Size = new Vector2(CONTRACTED_WIDTH, contracted_height);
|
||||||
|
|
||||||
topLayerBackground.FadeColour(contracted_top_layer_colour, RESIZE_DURATION, Easing.OutQuint);
|
topLayerBackground.FadeColour(getColour(contracted_top_layer_colour), RESIZE_DURATION, Easing.OutQuint);
|
||||||
middleLayerBackground.FadeColour(contracted_middle_layer_colour, RESIZE_DURATION, Easing.OutQuint);
|
middleLayerBackground.FadeColour(getColour(contracted_middle_layer_colour), RESIZE_DURATION, Easing.OutQuint);
|
||||||
|
|
||||||
topLayerContentContainer.Add(topLayerContent = new ContractedPanelTopContent
|
topLayerContentContainer.Add(topLayerContent = new ContractedPanelTopContent
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ namespace osu.Game.Screens.Select
|
|||||||
private FillFlowContainer infoLabelContainer;
|
private FillFlowContainer infoLabelContainer;
|
||||||
private Container bpmLabelContainer;
|
private Container bpmLabelContainer;
|
||||||
private Container lengthLabelContainer;
|
private Container lengthLabelContainer;
|
||||||
|
private Container performanceLabelContainer;
|
||||||
|
|
||||||
private readonly WorkingBeatmap working;
|
private readonly WorkingBeatmap working;
|
||||||
private readonly RulesetInfo ruleset;
|
private readonly RulesetInfo ruleset;
|
||||||
@@ -269,6 +270,7 @@ namespace osu.Game.Screens.Select
|
|||||||
TextSize = 11,
|
TextSize = 11,
|
||||||
TextPadding = new MarginPadding { Horizontal = 8, Vertical = 2 },
|
TextPadding = new MarginPadding { Horizontal = 8, Vertical = 2 },
|
||||||
Status = beatmapInfo.Status,
|
Status = beatmapInfo.Status,
|
||||||
|
ShowUnknownStatus = true,
|
||||||
Alpha = string.IsNullOrEmpty(beatmapInfo.DifficultyName) ? 0 : 1
|
Alpha = string.IsNullOrEmpty(beatmapInfo.DifficultyName) ? 0 : 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -343,9 +345,11 @@ namespace osu.Game.Screens.Select
|
|||||||
settingChangeTracker?.Dispose();
|
settingChangeTracker?.Dispose();
|
||||||
|
|
||||||
refreshBPMAndLengthLabel();
|
refreshBPMAndLengthLabel();
|
||||||
|
refreshPerformanceLabel();
|
||||||
|
|
||||||
settingChangeTracker = new ModSettingChangeTracker(m.NewValue);
|
settingChangeTracker = new ModSettingChangeTracker(m.NewValue);
|
||||||
settingChangeTracker.SettingChanged += _ => refreshBPMAndLengthLabel();
|
settingChangeTracker.SettingChanged += _ => refreshBPMAndLengthLabel();
|
||||||
|
settingChangeTracker.SettingChanged += _ => refreshPerformanceLabel();
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,7 +388,11 @@ namespace osu.Game.Screens.Select
|
|||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Spacing = new Vector2(20, 0),
|
Spacing = new Vector2(20, 0),
|
||||||
Children = playableBeatmap.GetStatistics().Select(s => new InfoLabel(s)).ToArray()
|
Children = playableBeatmap.GetStatistics().Select(s => new InfoLabel(s)).ToArray()
|
||||||
}
|
},
|
||||||
|
performanceLabelContainer = new Container
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -428,6 +436,27 @@ namespace osu.Game.Screens.Select
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void refreshPerformanceLabel()
|
||||||
|
{
|
||||||
|
var beatmap = working.Beatmap;
|
||||||
|
|
||||||
|
if (beatmap == null || performanceLabelContainer == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var diff = difficultyCache.GetBindableDifficulty(beatmap.BeatmapInfo);
|
||||||
|
diff.BindValueChanged(d =>
|
||||||
|
{
|
||||||
|
float perf = (float?)d.NewValue.PerformanceAttributes?.Total ?? 0.0f;
|
||||||
|
string disp = $"{Math.Round(perf, 1)} pp";
|
||||||
|
performanceLabelContainer.Child = new InfoLabel(new BeatmapStatistic
|
||||||
|
{
|
||||||
|
Name = "Max PP",
|
||||||
|
CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Accuracy),
|
||||||
|
Content = disp
|
||||||
|
});
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
private Drawable getMapper(BeatmapMetadata metadata)
|
private Drawable getMapper(BeatmapMetadata metadata)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(metadata.Author.Username))
|
if (string.IsNullOrEmpty(metadata.Author.Username))
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ namespace osu.Game.Screens.Select.Carousel
|
|||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
TextSize = 11,
|
TextSize = 11,
|
||||||
TextPadding = new MarginPadding { Horizontal = 8, Vertical = 2 },
|
TextPadding = new MarginPadding { Horizontal = 8, Vertical = 2 },
|
||||||
|
ShowUnknownStatus = true,
|
||||||
Status = beatmapSet.Status
|
Status = beatmapSet.Status
|
||||||
},
|
},
|
||||||
iconFlow = new FillFlowContainer<DifficultyIcon>
|
iconFlow = new FillFlowContainer<DifficultyIcon>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ using osu.Framework.Extensions.Color4Extensions;
|
|||||||
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.Logging;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.Drawables;
|
using osu.Game.Beatmaps.Drawables;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
@@ -233,6 +234,7 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
|
|
||||||
private void updateDisplay()
|
private void updateDisplay()
|
||||||
{
|
{
|
||||||
|
countStatisticsDisplay.ForceTiny = true;
|
||||||
cancellationSource?.Cancel();
|
cancellationSource?.Cancel();
|
||||||
cancellationSource = new CancellationTokenSource();
|
cancellationSource = new CancellationTokenSource();
|
||||||
|
|
||||||
@@ -293,8 +295,22 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
|
|
||||||
Ruleset rulesetInstance = ruleset.Value.CreateInstance();
|
Ruleset rulesetInstance = ruleset.Value.CreateInstance();
|
||||||
|
|
||||||
|
var workingBeatmap = beatmap.Value;
|
||||||
|
var diff = difficultyCache.GetBindableDifficulty(workingBeatmap.BeatmapInfo);
|
||||||
|
|
||||||
|
float perf = 0.0f;
|
||||||
var displayAttributes = rulesetInstance.GetBeatmapAttributesForDisplay(beatmap.Value.BeatmapInfo, mods.Value).ToList();
|
var displayAttributes = rulesetInstance.GetBeatmapAttributesForDisplay(beatmap.Value.BeatmapInfo, mods.Value).ToList();
|
||||||
difficultyStatisticsDisplay.Statistics = displayAttributes.Select(a => new StatisticDifficulty.Data(a)).ToList();
|
difficultyStatisticsDisplay.Statistics = displayAttributes.Select(a => new StatisticDifficulty.Data(a))
|
||||||
|
.Prepend(new StatisticDifficulty.Data("Max PP", perf, perf, perf));
|
||||||
|
|
||||||
|
// at first, performance points won't be available, so we'd have to update them later
|
||||||
|
diff.BindValueChanged(d =>
|
||||||
|
{
|
||||||
|
perf = (float)Math.Round((float?)d.NewValue.PerformanceAttributes?.Total ?? 0f, 1); // yikes
|
||||||
|
var arr = difficultyStatisticsDisplay.Statistics.ToArray();
|
||||||
|
arr[0] = new StatisticDifficulty.Data("Max PP", perf, perf, perf);
|
||||||
|
difficultyStatisticsDisplay.Statistics = arr.AsEnumerable();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
|
|||||||
@@ -27,9 +27,11 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
private readonly FillFlowContainer<StatisticDifficulty> statisticsFlow;
|
private readonly FillFlowContainer<StatisticDifficulty> statisticsFlow;
|
||||||
private readonly GridContainer tinyStatisticsGrid;
|
private readonly GridContainer tinyStatisticsGrid;
|
||||||
|
|
||||||
private IReadOnlyList<StatisticDifficulty.Data> statistics = Array.Empty<StatisticDifficulty.Data>();
|
public bool ForceTiny { get; set; } = false;
|
||||||
|
|
||||||
public IReadOnlyList<StatisticDifficulty.Data> Statistics
|
private IEnumerable<StatisticDifficulty.Data> statistics = Array.Empty<StatisticDifficulty.Data>();
|
||||||
|
|
||||||
|
public IEnumerable<StatisticDifficulty.Data> Statistics
|
||||||
{
|
{
|
||||||
get => statistics;
|
get => statistics;
|
||||||
set
|
set
|
||||||
@@ -137,7 +139,7 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
float flowWidth = statisticsFlow[0].Width * statisticsFlow.Count + statisticsFlow.Spacing.X * (statisticsFlow.Count - 1);
|
float flowWidth = statisticsFlow[0].Width * statisticsFlow.Count + statisticsFlow.Spacing.X * (statisticsFlow.Count - 1);
|
||||||
bool tiny = !autoSize && DrawWidth < flowWidth - 20;
|
bool tiny = !autoSize && DrawWidth < flowWidth - 20 || ForceTiny;
|
||||||
|
|
||||||
if (displayedTinyStatistics != tiny)
|
if (displayedTinyStatistics != tiny)
|
||||||
{
|
{
|
||||||
@@ -180,8 +182,8 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
if (statisticsFlow.Select(s => s.Value.Label)
|
if (statisticsFlow.Select(s => s.Value.Label)
|
||||||
.SequenceEqual(statistics.Select(s => s.Label)))
|
.SequenceEqual(statistics.Select(s => s.Label)))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < statistics.Count; i++)
|
for (int i = 0; i < statistics.Count(); i++)
|
||||||
statisticsFlow[i].Value = statistics[i];
|
statisticsFlow[i].Value = statistics.ToArray()[i];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
TextSize = OsuFont.Style.Caption2.Size,
|
TextSize = OsuFont.Style.Caption2.Size,
|
||||||
Margin = new MarginPadding { Right = 5f },
|
Margin = new MarginPadding { Right = 5f },
|
||||||
Animated = false,
|
Animated = false,
|
||||||
|
ShowUnknownStatus = true
|
||||||
},
|
},
|
||||||
updateButton = new PanelUpdateBeatmapButton
|
updateButton = new PanelUpdateBeatmapButton
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ namespace osu.Game.Screens.SelectV2
|
|||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
TextSize = OsuFont.Style.Caption2.Size,
|
TextSize = OsuFont.Style.Caption2.Size,
|
||||||
Margin = new MarginPadding { Right = 4f },
|
Margin = new MarginPadding { Right = 4f },
|
||||||
|
ShowUnknownStatus = true
|
||||||
},
|
},
|
||||||
updateButton = new PanelUpdateBeatmapButton
|
updateButton = new PanelUpdateBeatmapButton
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user