mirror of
https://github.com/osukey/osukey.git
synced 2025-08-05 07:33:55 +09:00
Merge remote-tracking branch 'huoyaoyuan/master' into health-processor
# Conflicts: # osu.Game.Rulesets.Catch/CatchRuleset.cs # osu.Game.Rulesets.Mania/ManiaRuleset.cs # osu.Game.Rulesets.Taiko/TaikoRuleset.cs
This commit is contained in:
@ -4,6 +4,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
@ -25,7 +26,7 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
public IBeatmap Beatmap { get; }
|
||||
|
||||
protected BeatmapConverter(IBeatmap beatmap)
|
||||
protected BeatmapConverter(IBeatmap beatmap, Ruleset ruleset)
|
||||
{
|
||||
Beatmap = beatmap;
|
||||
}
|
||||
@ -33,7 +34,7 @@ namespace osu.Game.Beatmaps
|
||||
/// <summary>
|
||||
/// Whether <see cref="Beatmap"/> can be converted by this <see cref="BeatmapConverter{T}"/>.
|
||||
/// </summary>
|
||||
public bool CanConvert => !Beatmap.HitObjects.Any() || ValidConversionTypes.All(t => Beatmap.HitObjects.Any(t.IsInstanceOfType));
|
||||
public abstract bool CanConvert();
|
||||
|
||||
/// <summary>
|
||||
/// Converts <see cref="Beatmap"/>.
|
||||
@ -92,11 +93,6 @@ namespace osu.Game.Beatmaps
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The types of HitObjects that can be converted to be used for this Beatmap.
|
||||
/// </summary>
|
||||
protected abstract IEnumerable<Type> ValidConversionTypes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates the <see cref="Beatmap{T}"/> that will be returned by this <see cref="BeatmapProcessor"/>.
|
||||
/// </summary>
|
||||
|
@ -76,7 +76,7 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
public IBeatmap Beatmap { get; set; }
|
||||
|
||||
public bool CanConvert => true;
|
||||
public bool CanConvert() => true;
|
||||
|
||||
public IBeatmap Convert()
|
||||
{
|
||||
|
@ -8,6 +8,14 @@ namespace osu.Game.Beatmaps.Formats
|
||||
{
|
||||
public interface IHasComboColours
|
||||
{
|
||||
List<Color4> ComboColours { get; set; }
|
||||
/// <summary>
|
||||
/// Retrieves the list of combo colours for presentation only.
|
||||
/// </summary>
|
||||
IReadOnlyList<Color4> ComboColours { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds combo colours to the list.
|
||||
/// </summary>
|
||||
void AddComboColours(params Color4[] colours);
|
||||
}
|
||||
}
|
||||
|
@ -77,8 +77,6 @@ namespace osu.Game.Beatmaps.Formats
|
||||
return line;
|
||||
}
|
||||
|
||||
private bool hasComboColours;
|
||||
|
||||
private void handleColours(T output, string line)
|
||||
{
|
||||
var pair = SplitKeyVal(line);
|
||||
@ -105,14 +103,7 @@ namespace osu.Game.Beatmaps.Formats
|
||||
{
|
||||
if (!(output is IHasComboColours tHasComboColours)) return;
|
||||
|
||||
if (!hasComboColours)
|
||||
{
|
||||
// remove default colours.
|
||||
tHasComboColours.ComboColours.Clear();
|
||||
hasComboColours = true;
|
||||
}
|
||||
|
||||
tHasComboColours.ComboColours.Add(colour);
|
||||
tHasComboColours.AddComboColours(colour);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5,7 +5,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Extensions;
|
||||
@ -42,10 +41,6 @@ namespace osu.Game.Beatmaps.Formats
|
||||
{
|
||||
this.storyboard = storyboard;
|
||||
base.ParseStreamInto(stream, storyboard);
|
||||
|
||||
// OrderBy is used to guarantee that the parsing order of elements with equal start times is maintained (stably-sorted)
|
||||
foreach (StoryboardLayer layer in storyboard.Layers)
|
||||
layer.Elements = layer.Elements.OrderBy(h => h.StartTime).ToList();
|
||||
}
|
||||
|
||||
protected override void ParseLine(Storyboard storyboard, Section section, string line)
|
||||
|
@ -25,7 +25,7 @@ namespace osu.Game.Beatmaps
|
||||
/// <summary>
|
||||
/// Whether <see cref="Beatmap"/> can be converted by this <see cref="IBeatmapConverter"/>.
|
||||
/// </summary>
|
||||
bool CanConvert { get; }
|
||||
bool CanConvert();
|
||||
|
||||
/// <summary>
|
||||
/// Converts <see cref="Beatmap"/>.
|
||||
|
@ -108,7 +108,7 @@ namespace osu.Game.Beatmaps
|
||||
IBeatmapConverter converter = CreateBeatmapConverter(Beatmap, rulesetInstance);
|
||||
|
||||
// Check if the beatmap can be converted
|
||||
if (!converter.CanConvert)
|
||||
if (Beatmap.HitObjects.Count > 0 && !converter.CanConvert())
|
||||
throw new BeatmapInvalidForRulesetException($"{nameof(Beatmaps.Beatmap)} can not be converted for the ruleset (ruleset: {ruleset.InstantiationInfo}, converter: {converter}).");
|
||||
|
||||
// Apply conversion mods
|
||||
|
@ -52,7 +52,6 @@ namespace osu.Game.Graphics.UserInterface
|
||||
|
||||
public override bool HandleNonPositionalInput => State == Visibility.Visible;
|
||||
public override bool HandlePositionalInput => State == Visibility.Visible;
|
||||
public override bool IsRemovable => true;
|
||||
|
||||
private Visibility state;
|
||||
|
||||
|
@ -12,10 +12,12 @@ using osu.Framework.Input.Events;
|
||||
|
||||
namespace osu.Game.Graphics.UserInterface
|
||||
{
|
||||
public class OsuTextBox : TextBox
|
||||
public class OsuTextBox : BasicTextBox
|
||||
{
|
||||
protected override float LeftRightPadding => 10;
|
||||
|
||||
protected override float CaretWidth => 3;
|
||||
|
||||
protected override SpriteText CreatePlaceholder() => new OsuSpriteText
|
||||
{
|
||||
Font = OsuFont.GetFont(italics: true),
|
||||
@ -41,6 +43,8 @@ namespace osu.Game.Graphics.UserInterface
|
||||
BackgroundCommit = BorderColour = colour.Yellow;
|
||||
}
|
||||
|
||||
protected override Color4 SelectionColour => new Color4(249, 90, 255, 255);
|
||||
|
||||
protected override void OnFocus(FocusEvent e)
|
||||
{
|
||||
BorderThickness = 3;
|
||||
|
@ -171,6 +171,7 @@ namespace osu.Game.Overlays
|
||||
d.Origin = Anchor.BottomLeft;
|
||||
d.RelativeSizeAxes = Axes.Both;
|
||||
d.OnRequestLeave = channelManager.LeaveChannel;
|
||||
d.IsSwitchable = true;
|
||||
}),
|
||||
}
|
||||
},
|
||||
|
13
osu.Game/Overlays/Settings/ISettingsItem.cs
Normal file
13
osu.Game/Overlays/Settings/ISettingsItem.cs
Normal file
@ -0,0 +1,13 @@
|
||||
// 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.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Settings
|
||||
{
|
||||
public interface ISettingsItem : IDrawable, IDisposable
|
||||
{
|
||||
event Action SettingChanged;
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
@ -20,7 +21,7 @@ using osuTK;
|
||||
|
||||
namespace osu.Game.Overlays.Settings
|
||||
{
|
||||
public abstract class SettingsItem<T> : Container, IFilterable
|
||||
public abstract class SettingsItem<T> : Container, IFilterable, ISettingsItem
|
||||
{
|
||||
protected abstract Drawable CreateControl();
|
||||
|
||||
@ -34,8 +35,6 @@ namespace osu.Game.Overlays.Settings
|
||||
|
||||
private SpriteText text;
|
||||
|
||||
private readonly RestoreDefaultValueButton restoreDefaultButton;
|
||||
|
||||
public bool ShowsDefaultIndicator = true;
|
||||
|
||||
public virtual string LabelText
|
||||
@ -70,8 +69,12 @@ namespace osu.Game.Overlays.Settings
|
||||
|
||||
public bool FilteringActive { get; set; }
|
||||
|
||||
public event Action SettingChanged;
|
||||
|
||||
protected SettingsItem()
|
||||
{
|
||||
RestoreDefaultValueButton restoreDefaultButton;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
Padding = new MarginPadding { Right = SettingsPanel.CONTENT_MARGINS };
|
||||
@ -87,13 +90,12 @@ namespace osu.Game.Overlays.Settings
|
||||
Child = Control = CreateControl()
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
// all bindable logic is in constructor intentionally to support "CreateSettingsControls" being used in a context it is
|
||||
// never loaded, but requires bindable storage.
|
||||
if (controlWithCurrent != null)
|
||||
{
|
||||
controlWithCurrent.Current.ValueChanged += _ => SettingChanged?.Invoke();
|
||||
controlWithCurrent.Current.DisabledChanged += disabled => { Colour = disabled ? Color4.Gray : Color4.White; };
|
||||
|
||||
if (ShowsDefaultIndicator)
|
||||
@ -113,6 +115,7 @@ namespace osu.Game.Overlays.Settings
|
||||
bindable = value;
|
||||
bindable.ValueChanged += _ => UpdateState();
|
||||
bindable.DisabledChanged += _ => UpdateState();
|
||||
bindable.DefaultChanged += _ => UpdateState();
|
||||
UpdateState();
|
||||
}
|
||||
}
|
||||
|
13
osu.Game/Rulesets/ILegacyRuleset.cs
Normal file
13
osu.Game/Rulesets/ILegacyRuleset.cs
Normal file
@ -0,0 +1,13 @@
|
||||
// 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
|
||||
{
|
||||
public interface ILegacyRuleset
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifies the server-side ID of a legacy ruleset.
|
||||
/// </summary>
|
||||
int LegacyID { get; }
|
||||
}
|
||||
}
|
81
osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs
Normal file
81
osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs
Normal file
@ -0,0 +1,81 @@
|
||||
// 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.Beatmaps;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using System;
|
||||
using osu.Game.Configuration;
|
||||
|
||||
namespace osu.Game.Rulesets.Mods
|
||||
{
|
||||
public abstract class ModDifficultyAdjust : Mod, IApplicableToDifficulty
|
||||
{
|
||||
public override string Name => @"Difficulty Adjust";
|
||||
|
||||
public override string Description => @"Override a beatmap's difficulty settings.";
|
||||
|
||||
public override string Acronym => "DA";
|
||||
|
||||
public override ModType Type => ModType.Conversion;
|
||||
|
||||
public override IconUsage Icon => FontAwesome.Solid.Hammer;
|
||||
|
||||
public override double ScoreMultiplier => 1.0;
|
||||
|
||||
public override Type[] IncompatibleMods => new[] { typeof(ModEasy), typeof(ModHardRock) };
|
||||
|
||||
[SettingSource("Drain Rate", "Override a beatmap's set HP.")]
|
||||
public BindableNumber<float> DrainRate { get; } = new BindableFloat
|
||||
{
|
||||
Precision = 0.1f,
|
||||
MinValue = 1,
|
||||
MaxValue = 10,
|
||||
Default = 5,
|
||||
Value = 5,
|
||||
};
|
||||
|
||||
[SettingSource("Overall Difficulty", "Override a beatmap's set OD.")]
|
||||
public BindableNumber<float> OverallDifficulty { get; } = new BindableFloat
|
||||
{
|
||||
Precision = 0.1f,
|
||||
MinValue = 1,
|
||||
MaxValue = 10,
|
||||
Default = 5,
|
||||
Value = 5,
|
||||
};
|
||||
|
||||
private BeatmapDifficulty difficulty;
|
||||
|
||||
public void ApplyToDifficulty(BeatmapDifficulty difficulty)
|
||||
{
|
||||
if (this.difficulty == null || this.difficulty.ID != difficulty.ID)
|
||||
{
|
||||
this.difficulty = difficulty;
|
||||
TransferSettings(difficulty);
|
||||
}
|
||||
else
|
||||
ApplySettings(difficulty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transfer initial settings from the beatmap to settings.
|
||||
/// </summary>
|
||||
/// <param name="difficulty">The beatmap's initial values.</param>
|
||||
protected virtual void TransferSettings(BeatmapDifficulty difficulty)
|
||||
{
|
||||
DrainRate.Value = DrainRate.Default = difficulty.DrainRate;
|
||||
OverallDifficulty.Value = OverallDifficulty.Default = difficulty.OverallDifficulty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply all custom settings to the provided beatmap.
|
||||
/// </summary>
|
||||
/// <param name="difficulty">The beatmap to have settings applied.</param>
|
||||
protected virtual void ApplySettings(BeatmapDifficulty difficulty)
|
||||
{
|
||||
difficulty.DrainRate = DrainRate.Value;
|
||||
difficulty.OverallDifficulty = OverallDifficulty.Value;
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ using System;
|
||||
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;
|
||||
|
||||
@ -18,9 +19,16 @@ namespace osu.Game.Rulesets.Mods
|
||||
public override ModType Type => ModType.DifficultyReduction;
|
||||
public override double ScoreMultiplier => 0.5;
|
||||
public override bool Ranked => true;
|
||||
public override Type[] IncompatibleMods => new[] { typeof(ModHardRock) };
|
||||
public override Type[] IncompatibleMods => new[] { typeof(ModHardRock), typeof(ModDifficultyAdjust) };
|
||||
|
||||
private int retries = 2;
|
||||
[SettingSource("Extra Lives", "Number of extra lives")]
|
||||
public Bindable<int> Retries { get; } = new BindableInt(2)
|
||||
{
|
||||
MinValue = 0,
|
||||
MaxValue = 10
|
||||
};
|
||||
|
||||
private int retries;
|
||||
|
||||
private BindableNumber<double> health;
|
||||
|
||||
@ -31,6 +39,8 @@ namespace osu.Game.Rulesets.Mods
|
||||
difficulty.ApproachRate *= ratio;
|
||||
difficulty.DrainRate *= ratio;
|
||||
difficulty.OverallDifficulty *= ratio;
|
||||
|
||||
retries = Retries.Value;
|
||||
}
|
||||
|
||||
public bool AllowFail
|
||||
|
@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mods
|
||||
public override IconUsage Icon => OsuIcon.ModHardrock;
|
||||
public override ModType Type => ModType.DifficultyIncrease;
|
||||
public override string Description => "Everything just got a bit harder...";
|
||||
public override Type[] IncompatibleMods => new[] { typeof(ModEasy) };
|
||||
public override Type[] IncompatibleMods => new[] { typeof(ModEasy), typeof(ModDifficultyAdjust) };
|
||||
|
||||
public void ApplyToDifficulty(BeatmapDifficulty difficulty)
|
||||
{
|
||||
|
@ -356,7 +356,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
||||
{
|
||||
if (HitObject is IHasComboInformation combo)
|
||||
{
|
||||
var comboColours = CurrentSkin.GetConfig<GlobalSkinConfiguration, List<Color4>>(GlobalSkinConfiguration.ComboColours)?.Value;
|
||||
var comboColours = CurrentSkin.GetConfig<GlobalSkinConfiguration, IReadOnlyList<Color4>>(GlobalSkinConfiguration.ComboColours)?.Value;
|
||||
AccentColour.Value = comboColours?.Count > 0 ? comboColours[combo.ComboIndex % comboColours.Count] : Color4.White;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace osu.Game.Rulesets
|
||||
{
|
||||
public abstract class Ruleset
|
||||
{
|
||||
public readonly RulesetInfo RulesetInfo;
|
||||
public RulesetInfo RulesetInfo { get; internal set; }
|
||||
|
||||
public IEnumerable<Mod> GetAllMods() => Enum.GetValues(typeof(ModType)).Cast<ModType>()
|
||||
// Confine all mods of each mod type into a single IEnumerable<Mod>
|
||||
@ -51,7 +51,14 @@ namespace osu.Game.Rulesets
|
||||
|
||||
protected Ruleset()
|
||||
{
|
||||
RulesetInfo = createRulesetInfo();
|
||||
RulesetInfo = new RulesetInfo
|
||||
{
|
||||
Name = Description,
|
||||
ShortName = ShortName,
|
||||
ID = (this as ILegacyRuleset)?.LegacyID,
|
||||
InstantiationInfo = GetType().AssemblyQualifiedName,
|
||||
Available = true
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -109,11 +116,6 @@ namespace osu.Game.Rulesets
|
||||
/// <param name="settings">The <see cref="SettingsStore"/> to store the settings.</param>
|
||||
public virtual IRulesetConfigManager CreateConfig(SettingsStore settings) => null;
|
||||
|
||||
/// <summary>
|
||||
/// Do not override this unless you are a legacy mode.
|
||||
/// </summary>
|
||||
public virtual int? LegacyID => null;
|
||||
|
||||
/// <summary>
|
||||
/// A unique short name to reference this ruleset in online requests.
|
||||
/// </summary>
|
||||
@ -144,18 +146,5 @@ namespace osu.Game.Rulesets
|
||||
/// </summary>
|
||||
/// <returns>An empty frame for the current ruleset, or null if unsupported.</returns>
|
||||
public virtual IConvertibleReplayFrame CreateConvertibleReplayFrame() => null;
|
||||
|
||||
/// <summary>
|
||||
/// Create a ruleset info based on this ruleset.
|
||||
/// </summary>
|
||||
/// <returns>A filled <see cref="RulesetInfo"/>.</returns>
|
||||
private RulesetInfo createRulesetInfo() => new RulesetInfo
|
||||
{
|
||||
Name = Description,
|
||||
ShortName = ShortName,
|
||||
InstantiationInfo = GetType().AssemblyQualifiedName,
|
||||
ID = LegacyID,
|
||||
Available = true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -20,11 +20,17 @@ namespace osu.Game.Rulesets
|
||||
[JsonIgnore]
|
||||
public bool Available { get; set; }
|
||||
|
||||
// TODO: this should probably be moved to RulesetStore.
|
||||
public virtual Ruleset CreateInstance()
|
||||
{
|
||||
if (!Available) return null;
|
||||
|
||||
return (Ruleset)Activator.CreateInstance(Type.GetType(InstantiationInfo));
|
||||
var ruleset = (Ruleset)Activator.CreateInstance(Type.GetType(InstantiationInfo));
|
||||
|
||||
// overwrite the pre-populated RulesetInfo with a potentially database attached copy.
|
||||
ruleset.RulesetInfo = this;
|
||||
|
||||
return ruleset;
|
||||
}
|
||||
|
||||
public bool Equals(RulesetInfo other) => other != null && ID == other.ID && Available == other.Available && Name == other.Name && InstantiationInfo == other.InstantiationInfo;
|
||||
|
@ -58,17 +58,17 @@ namespace osu.Game.Rulesets
|
||||
|
||||
var instances = loadedAssemblies.Values.Select(r => (Ruleset)Activator.CreateInstance(r)).ToList();
|
||||
|
||||
//add all legacy modes in correct order
|
||||
foreach (var r in instances.Where(r => r.LegacyID != null).OrderBy(r => r.LegacyID))
|
||||
//add all legacy rulesets first to ensure they have exclusive choice of primary key.
|
||||
foreach (var r in instances.Where(r => r is ILegacyRuleset))
|
||||
{
|
||||
if (context.RulesetInfo.SingleOrDefault(rsi => rsi.ID == r.RulesetInfo.ID) == null)
|
||||
if (context.RulesetInfo.SingleOrDefault(dbRuleset => dbRuleset.ID == r.RulesetInfo.ID) == null)
|
||||
context.RulesetInfo.Add(r.RulesetInfo);
|
||||
}
|
||||
|
||||
context.SaveChanges();
|
||||
|
||||
//add any other modes
|
||||
foreach (var r in instances.Where(r => r.LegacyID == null))
|
||||
foreach (var r in instances.Where(r => !(r is ILegacyRuleset)))
|
||||
{
|
||||
if (context.RulesetInfo.FirstOrDefault(ri => ri.InstantiationInfo == r.RulesetInfo.InstantiationInfo) == null)
|
||||
context.RulesetInfo.Add(r.RulesetInfo);
|
||||
|
@ -159,7 +159,7 @@ namespace osu.Game.Rulesets.UI
|
||||
dependencies.Cache(textureStore);
|
||||
|
||||
localSampleStore = dependencies.Get<AudioManager>().GetSampleStore(new NamespacedResourceStore<byte[]>(resources, "Samples"));
|
||||
dependencies.CacheAs(new FallbackSampleStore(localSampleStore, dependencies.Get<ISampleStore>()));
|
||||
dependencies.CacheAs<ISampleStore>(new FallbackSampleStore(localSampleStore, dependencies.Get<ISampleStore>()));
|
||||
}
|
||||
|
||||
onScreenDisplay = dependencies.Get<OnScreenDisplay>();
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
@ -132,6 +133,8 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
private void confirmAndExit()
|
||||
{
|
||||
if (exitConfirmed) return;
|
||||
|
||||
exitConfirmed = true;
|
||||
this.Exit();
|
||||
}
|
||||
@ -244,10 +247,18 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
public override bool OnExiting(IScreen next)
|
||||
{
|
||||
if (!exitConfirmed && dialogOverlay != null && !(dialogOverlay.CurrentDialog is ConfirmExitDialog))
|
||||
if (!exitConfirmed && dialogOverlay != null)
|
||||
{
|
||||
dialogOverlay.Push(new ConfirmExitDialog(confirmAndExit, () => exitConfirmOverlay.Abort()));
|
||||
return true;
|
||||
if (dialogOverlay.CurrentDialog is ConfirmExitDialog exitDialog)
|
||||
{
|
||||
exitConfirmed = true;
|
||||
exitDialog.Buttons.First().Click();
|
||||
}
|
||||
else
|
||||
{
|
||||
dialogOverlay.Push(new ConfirmExitDialog(confirmAndExit, () => exitConfirmOverlay.Abort()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
buttons.State = ButtonSystemState.Exit;
|
||||
|
@ -43,6 +43,11 @@ namespace osu.Game.Screens.Play
|
||||
private void load(OsuConfigManager config)
|
||||
{
|
||||
config.BindWith(OsuSetting.KeyOverlay, configVisibility);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
Visible.BindValueChanged(_ => updateVisibility());
|
||||
configVisibility.BindValueChanged(_ => updateVisibility(), true);
|
||||
|
@ -580,7 +580,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
// GameplayClockContainer performs seeks / start / stop operations on the beatmap's track.
|
||||
// as we are no longer the current screen, we cannot guarantee the track is still usable.
|
||||
GameplayClockContainer.StopUsingBeatmapClock();
|
||||
GameplayClockContainer?.StopUsingBeatmapClock();
|
||||
|
||||
fadeOut();
|
||||
return base.OnExiting(next);
|
||||
|
@ -48,6 +48,7 @@ namespace osu.Game.Screens.Select
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
IsSwitchable = true,
|
||||
},
|
||||
},
|
||||
modsCheckbox = new OsuTabControlCheckbox
|
||||
|
@ -16,6 +16,9 @@ using osu.Framework.Bindables;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using System.Linq;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Overlays.Settings;
|
||||
|
||||
namespace osu.Game.Screens.Select.Details
|
||||
{
|
||||
@ -69,7 +72,37 @@ namespace osu.Game.Screens.Select.Details
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
mods.BindValueChanged(_ => updateStatistics(), true);
|
||||
mods.BindValueChanged(modsChanged, true);
|
||||
}
|
||||
|
||||
private readonly List<ISettingsItem> references = new List<ISettingsItem>();
|
||||
|
||||
private void modsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods)
|
||||
{
|
||||
// TODO: find a more permanent solution for this if/when it is needed in other components.
|
||||
// this is generating drawables for the only purpose of storing bindable references.
|
||||
foreach (var r in references)
|
||||
r.Dispose();
|
||||
|
||||
references.Clear();
|
||||
|
||||
ScheduledDelegate debounce = null;
|
||||
|
||||
foreach (var mod in mods.NewValue.OfType<IApplicableToDifficulty>())
|
||||
{
|
||||
foreach (var setting in mod.CreateSettingsControls().OfType<ISettingsItem>())
|
||||
{
|
||||
setting.SettingChanged += () =>
|
||||
{
|
||||
debounce?.Cancel();
|
||||
debounce = Scheduler.AddDelayed(updateStatistics, 100);
|
||||
};
|
||||
|
||||
references.Add(setting);
|
||||
}
|
||||
}
|
||||
|
||||
updateStatistics();
|
||||
}
|
||||
|
||||
private void updateStatistics()
|
||||
|
@ -13,13 +13,12 @@ namespace osu.Game.Skinning
|
||||
: base(Info, storage, audioManager, string.Empty)
|
||||
{
|
||||
Configuration.CustomColours["SliderBall"] = new Color4(2, 170, 255, 255);
|
||||
Configuration.ComboColours.AddRange(new[]
|
||||
{
|
||||
Configuration.AddComboColours(
|
||||
new Color4(255, 192, 0, 255),
|
||||
new Color4(0, 202, 0, 255),
|
||||
new Color4(18, 124, 255, 255),
|
||||
new Color4(242, 24, 57, 255),
|
||||
});
|
||||
new Color4(242, 24, 57, 255)
|
||||
);
|
||||
|
||||
Configuration.LegacyVersion = 2.0m;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ namespace osu.Game.Skinning
|
||||
switch (global)
|
||||
{
|
||||
case GlobalSkinConfiguration.ComboColours:
|
||||
return SkinUtils.As<TValue>(new Bindable<List<Color4>>(Configuration.ComboColours));
|
||||
return SkinUtils.As<TValue>(new Bindable<IReadOnlyList<Color4>>(Configuration.ComboColours));
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -1,8 +1,6 @@
|
||||
// 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 osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
/// <summary>
|
||||
@ -10,15 +8,5 @@ namespace osu.Game.Skinning
|
||||
/// </summary>
|
||||
public class DefaultSkinConfiguration : SkinConfiguration
|
||||
{
|
||||
public DefaultSkinConfiguration()
|
||||
{
|
||||
ComboColours.AddRange(new[]
|
||||
{
|
||||
new Color4(255, 192, 0, 255),
|
||||
new Color4(0, 202, 0, 255),
|
||||
new Color4(18, 124, 255, 255),
|
||||
new Color4(242, 24, 57, 255),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ namespace osu.Game.Skinning
|
||||
public LegacyBeatmapSkin(BeatmapInfo beatmap, IResourceStore<byte[]> storage, AudioManager audioManager)
|
||||
: base(createSkinInfo(beatmap), new LegacySkinResourceStore<BeatmapSetFileInfo>(beatmap.BeatmapSet, storage), audioManager, beatmap.Path)
|
||||
{
|
||||
// Disallow default colours fallback on beatmap skins to allow using parent skin combo colours. (via SkinProvidingContainer)
|
||||
Configuration.AllowDefaultComboColoursFallback = false;
|
||||
}
|
||||
|
||||
private static SkinInfo createSkinInfo(BeatmapInfo beatmap) =>
|
||||
|
@ -72,7 +72,11 @@ namespace osu.Game.Skinning
|
||||
switch (global)
|
||||
{
|
||||
case GlobalSkinConfiguration.ComboColours:
|
||||
return SkinUtils.As<TValue>(new Bindable<List<Color4>>(Configuration.ComboColours));
|
||||
var comboColours = Configuration.ComboColours;
|
||||
if (comboColours != null)
|
||||
return SkinUtils.As<TValue>(new Bindable<IReadOnlyList<Color4>>(comboColours));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
public class LegacySkinConfiguration : DefaultSkinConfiguration
|
||||
public class LegacySkinConfiguration : SkinConfiguration
|
||||
{
|
||||
public const decimal LATEST_VERSION = 2.7m;
|
||||
|
||||
|
@ -14,7 +14,36 @@ namespace osu.Game.Skinning
|
||||
{
|
||||
public readonly SkinInfo SkinInfo = new SkinInfo();
|
||||
|
||||
public List<Color4> ComboColours { get; set; } = new List<Color4>();
|
||||
/// <summary>
|
||||
/// Whether to allow <see cref="DefaultComboColours"/> as a fallback list for when no combo colours are provided.
|
||||
/// </summary>
|
||||
internal bool AllowDefaultComboColoursFallback = true;
|
||||
|
||||
public static List<Color4> DefaultComboColours { get; } = new List<Color4>
|
||||
{
|
||||
new Color4(255, 192, 0, 255),
|
||||
new Color4(0, 202, 0, 255),
|
||||
new Color4(18, 124, 255, 255),
|
||||
new Color4(242, 24, 57, 255),
|
||||
};
|
||||
|
||||
private readonly List<Color4> comboColours = new List<Color4>();
|
||||
|
||||
public IReadOnlyList<Color4> ComboColours
|
||||
{
|
||||
get
|
||||
{
|
||||
if (comboColours.Count > 0)
|
||||
return comboColours;
|
||||
|
||||
if (AllowDefaultComboColoursFallback)
|
||||
return DefaultComboColours;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddComboColours(params Color4[] colours) => comboColours.AddRange(colours);
|
||||
|
||||
public Dictionary<string, Color4> CustomColours { get; set; } = new Dictionary<string, Color4>();
|
||||
|
||||
|
@ -11,7 +11,10 @@ using osu.Game.Overlays.Notifications;
|
||||
|
||||
namespace osu.Game.Updater
|
||||
{
|
||||
public abstract class UpdateManager : CompositeDrawable
|
||||
/// <summary>
|
||||
/// An update manager which only shows notifications after an update completes.
|
||||
/// </summary>
|
||||
public class UpdateManager : CompositeDrawable
|
||||
{
|
||||
[Resolved]
|
||||
private OsuConfigManager config { get; set; }
|
||||
|
@ -23,7 +23,7 @@
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1215.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2019.1215.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2019.1225.0" />
|
||||
<PackageReference Include="Sentry" Version="1.2.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.24.0" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
|
Reference in New Issue
Block a user