diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index acdd0a420c..438d17dbc5 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -59,8 +59,8 @@ namespace osu.Game.Rulesets.Catch.Mods { base.ApplySettings(difficulty); - difficulty.CircleSize = CircleSize.Value; - difficulty.ApproachRate = ApproachRate.Value; + ApplySetting(CircleSize, cs => difficulty.CircleSize = cs); + ApplySetting(ApproachRate, ar => difficulty.ApproachRate = ar); } } } diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs index 49c1fe8540..db8546c71b 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs @@ -1,13 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Framework.Utils; +using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Tests.Mods @@ -18,8 +22,23 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods public void TestNoAdjustment() => CreateModTest(new ModTestData { Mod = new OsuModDifficultyAdjust(), + Beatmap = new Beatmap + { + BeatmapInfo = new BeatmapInfo + { + BaseDifficulty = new BeatmapDifficulty + { + CircleSize = 8 + } + }, + HitObjects = new List + { + new HitCircle { StartTime = 1000 }, + new HitCircle { StartTime = 2000 } + } + }, Autoplay = true, - PassCondition = checkSomeHit + PassCondition = () => checkSomeHit() && checkObjectsScale(0.29f) }); [Test] diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index ff995e38ce..a638234dbd 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -59,8 +59,8 @@ namespace osu.Game.Rulesets.Osu.Mods { base.ApplySettings(difficulty); - difficulty.CircleSize = CircleSize.Value; - difficulty.ApproachRate = ApproachRate.Value; + ApplySetting(CircleSize, cs => difficulty.CircleSize = cs); + ApplySetting(ApproachRate, ar => difficulty.ApproachRate = ar); } } } diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs index 3d3517ada4..40b2f66d74 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs @@ -11,6 +11,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Mods; using osu.Game.Screens.Select.Details; using osuTK.Graphics; @@ -141,16 +142,12 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep("select changed Difficulty Adjust mod", () => { var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance(); - var difficultyAdjustMod = ruleset.GetAllMods().OfType().Single(); + var difficultyAdjustMod = ruleset.GetAllMods().OfType().Single(); var originalDifficulty = advancedStats.Beatmap.BaseDifficulty; - var adjustedDifficulty = new BeatmapDifficulty - { - CircleSize = originalDifficulty.CircleSize, - DrainRate = originalDifficulty.DrainRate - 0.5f, - OverallDifficulty = originalDifficulty.OverallDifficulty, - ApproachRate = originalDifficulty.ApproachRate + 2.2f, - }; - difficultyAdjustMod.ReadFromDifficulty(adjustedDifficulty); + + difficultyAdjustMod.ReadFromDifficulty(originalDifficulty); + difficultyAdjustMod.DrainRate.Value = originalDifficulty.DrainRate - 0.5f; + difficultyAdjustMod.ApproachRate.Value = originalDifficulty.ApproachRate + 2.2f; SelectedMods.Value = new[] { difficultyAdjustMod }; }); diff --git a/osu.Game.Tournament/JsonPointConverter.cs b/osu.Game.Tournament/JsonPointConverter.cs new file mode 100644 index 0000000000..9c82f8ac06 --- /dev/null +++ b/osu.Game.Tournament/JsonPointConverter.cs @@ -0,0 +1,65 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Diagnostics; +using System.Drawing; +using Newtonsoft.Json; + +namespace osu.Game.Tournament +{ + /// + /// We made a change from using SixLabors.ImageSharp.Point to System.Drawing.Point at some stage. + /// This handles converting to a standardised format on json serialize/deserialize operations. + /// + internal class JsonPointConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, Point value, JsonSerializer serializer) + { + // use the format of LaborSharp's Point since it is nicer. + serializer.Serialize(writer, new { value.X, value.Y }); + } + + public override Point ReadJson(JsonReader reader, Type objectType, Point existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.TokenType != JsonToken.StartObject) + { + // if there's no object present then this is using string representation (System.Drawing.Point serializes to "x,y") + string str = (string)reader.Value; + + Debug.Assert(str != null); + + return new PointConverter().ConvertFromString(str) as Point? ?? new Point(); + } + + var point = new Point(); + + while (reader.Read()) + { + if (reader.TokenType == JsonToken.EndObject) break; + + if (reader.TokenType == JsonToken.PropertyName) + { + var name = reader.Value?.ToString(); + int? val = reader.ReadAsInt32(); + + if (val == null) + continue; + + switch (name) + { + case "X": + point.X = val.Value; + break; + + case "Y": + point.Y = val.Value; + break; + } + } + } + + return point; + } + } +} diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs index dbda6aa023..bc36f27e5b 100644 --- a/osu.Game.Tournament/TournamentGameBase.cs +++ b/osu.Game.Tournament/TournamentGameBase.cs @@ -8,12 +8,12 @@ using Newtonsoft.Json; using osu.Framework.Allocation; using osu.Framework.Graphics.Textures; using osu.Framework.Input; -using osu.Framework.Platform; using osu.Framework.IO.Stores; +using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Online.API.Requests; -using osu.Game.Tournament.IPC; using osu.Game.Tournament.IO; +using osu.Game.Tournament.IPC; using osu.Game.Tournament.Models; using osu.Game.Users; using osuTK.Input; @@ -60,7 +60,7 @@ namespace osu.Game.Tournament { using (Stream stream = storage.GetStream(bracket_filename, FileAccess.Read, FileMode.Open)) using (var sr = new StreamReader(stream)) - ladder = JsonConvert.DeserializeObject(sr.ReadToEnd()); + ladder = JsonConvert.DeserializeObject(sr.ReadToEnd(), new JsonPointConverter()); } ladder ??= new LadderInfo(); @@ -251,6 +251,7 @@ namespace osu.Game.Tournament Formatting = Formatting.Indented, NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore, + Converters = new JsonConverter[] { new JsonPointConverter() } })); } } diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index 72a4bb297f..a531e885db 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -116,18 +116,30 @@ namespace osu.Game.Rulesets.Mods internal override void CopyAdjustedSetting(IBindable target, object source) { - userChangedSettings[target] = true; + // if the value is non-bindable, it's presumably coming from an external source (like the API) - therefore presume it is not default. + // if the value is bindable, defer to the source's IsDefault to be able to tell. + userChangedSettings[target] = !(source is IBindable bindableSource) || !bindableSource.IsDefault; base.CopyAdjustedSetting(target, source); } + /// + /// Applies a setting from a configuration bindable using , if it has been changed by the user. + /// + protected void ApplySetting(BindableNumber setting, Action applyFunc) + where T : struct, IComparable, IConvertible, IEquatable + { + if (userChangedSettings.TryGetValue(setting, out bool userChangedSetting) && userChangedSetting) + applyFunc.Invoke(setting.Value); + } + /// /// Apply all custom settings to the provided beatmap. /// /// The beatmap to have settings applied. protected virtual void ApplySettings(BeatmapDifficulty difficulty) { - difficulty.DrainRate = DrainRate.Value; - difficulty.OverallDifficulty = OverallDifficulty.Value; + ApplySetting(DrainRate, dr => difficulty.DrainRate = dr); + ApplySetting(OverallDifficulty, od => difficulty.OverallDifficulty = od); } } }