1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-14 10:22:41 +08:00

Compare commits

...

24 Commits

20 changed files with 213 additions and 104 deletions
+1 -1
View File
@@ -11,7 +11,7 @@
<AndroidManifestMerger>manifestmerger.jar</AndroidManifestMerger>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Framework.Android" Version="2023.531.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2023.608.0" />
</ItemGroup>
<ItemGroup>
<AndroidManifestOverlay Include="$(MSBuildThisFileDirectory)osu.Android\Properties\AndroidManifestOverlay.xml" />
@@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Mania.Configuration
speed => new SettingDescription(
rawValue: speed,
name: RulesetSettingsStrings.ScrollSpeed,
value: RulesetSettingsStrings.ScrollSpeedTooltip(DrawableManiaRuleset.ComputeScrollTime(speed), speed)
value: RulesetSettingsStrings.ScrollSpeedTooltip((int)DrawableManiaRuleset.ComputeScrollTime(speed), speed)
)
)
};
@@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Mania
private partial class ManiaScrollSlider : RoundedSliderBar<int>
{
public override LocalisableString TooltipText => RulesetSettingsStrings.ScrollSpeedTooltip(DrawableManiaRuleset.ComputeScrollTime(Current.Value), Current.Value);
public override LocalisableString TooltipText => RulesetSettingsStrings.ScrollSpeedTooltip((int)DrawableManiaRuleset.ComputeScrollTime(Current.Value), Current.Value);
}
}
}
@@ -18,8 +18,8 @@ namespace osu.Game.Rulesets.Mania.Scoring
protected override double ComputeTotalScore(double comboProgress, double accuracyProgress, double bonusPortion)
{
return 200000 * comboProgress
+ 800000 * Math.Pow(Accuracy.Value, 2 + 2 * Accuracy.Value) * accuracyProgress
return 10000 * comboProgress
+ 990000 * Math.Pow(Accuracy.Value, 2 + 2 * Accuracy.Value) * accuracyProgress
+ bonusPortion;
}
@@ -15,187 +15,175 @@ namespace osu.Game.Rulesets.Taiko.Tests.Judgements
[Test]
public void TestHitAllDrumRoll()
{
const double hit_time = 1000;
PerformTest(new List<ReplayFrame>
{
new TaikoReplayFrame(0),
new TaikoReplayFrame(1000, TaikoAction.LeftCentre),
new TaikoReplayFrame(1001),
new TaikoReplayFrame(1250, TaikoAction.LeftCentre),
new TaikoReplayFrame(1251),
new TaikoReplayFrame(1500, TaikoAction.LeftCentre),
new TaikoReplayFrame(1501),
new TaikoReplayFrame(1750, TaikoAction.LeftCentre),
new TaikoReplayFrame(1751),
new TaikoReplayFrame(2000, TaikoAction.LeftCentre),
new TaikoReplayFrame(2001),
}, CreateBeatmap(new DrumRoll
{
StartTime = hit_time,
Duration = 1000
}));
}, CreateBeatmap(createDrumRoll(false)));
AssertJudgementCount(3);
AssertJudgementCount(6);
AssertResult<DrumRollTick>(0, HitResult.SmallBonus);
AssertResult<DrumRollTick>(1, HitResult.SmallBonus);
AssertResult<DrumRollTick>(2, HitResult.SmallBonus);
AssertResult<DrumRollTick>(3, HitResult.SmallBonus);
AssertResult<DrumRollTick>(4, HitResult.SmallBonus);
AssertResult<DrumRoll>(0, HitResult.IgnoreHit);
}
[Test]
public void TestHitSomeDrumRoll()
{
const double hit_time = 1000;
PerformTest(new List<ReplayFrame>
{
new TaikoReplayFrame(0),
new TaikoReplayFrame(2000, TaikoAction.LeftCentre),
new TaikoReplayFrame(2001),
}, CreateBeatmap(new DrumRoll
{
StartTime = hit_time,
Duration = 1000
}));
}, CreateBeatmap(createDrumRoll(false)));
AssertJudgementCount(3);
AssertJudgementCount(6);
AssertResult<DrumRollTick>(0, HitResult.IgnoreMiss);
AssertResult<DrumRollTick>(1, HitResult.SmallBonus);
AssertResult<DrumRollTick>(1, HitResult.IgnoreMiss);
AssertResult<DrumRollTick>(2, HitResult.IgnoreMiss);
AssertResult<DrumRollTick>(3, HitResult.IgnoreMiss);
AssertResult<DrumRollTick>(4, HitResult.SmallBonus);
AssertResult<DrumRoll>(0, HitResult.IgnoreHit);
}
[Test]
public void TestHitNoneDrumRoll()
{
const double hit_time = 1000;
PerformTest(new List<ReplayFrame>
{
new TaikoReplayFrame(0),
}, CreateBeatmap(new DrumRoll
{
StartTime = hit_time,
Duration = 1000
}));
}, CreateBeatmap(createDrumRoll(false)));
AssertJudgementCount(3);
AssertJudgementCount(6);
AssertResult<DrumRollTick>(0, HitResult.IgnoreMiss);
AssertResult<DrumRollTick>(1, HitResult.IgnoreMiss);
AssertResult<DrumRollTick>(2, HitResult.IgnoreMiss);
AssertResult<DrumRollTick>(3, HitResult.IgnoreMiss);
AssertResult<DrumRollTick>(4, HitResult.IgnoreMiss);
AssertResult<DrumRoll>(0, HitResult.IgnoreHit);
}
[Test]
public void TestHitAllStrongDrumRollWithOneKey()
{
const double hit_time = 1000;
PerformTest(new List<ReplayFrame>
{
new TaikoReplayFrame(0),
new TaikoReplayFrame(1000, TaikoAction.LeftCentre),
new TaikoReplayFrame(1001),
new TaikoReplayFrame(1250, TaikoAction.LeftCentre),
new TaikoReplayFrame(1251),
new TaikoReplayFrame(1500, TaikoAction.LeftCentre),
new TaikoReplayFrame(1501),
new TaikoReplayFrame(1750, TaikoAction.LeftCentre),
new TaikoReplayFrame(1751),
new TaikoReplayFrame(2000, TaikoAction.LeftCentre),
new TaikoReplayFrame(2001),
}, CreateBeatmap(new DrumRoll
}, CreateBeatmap(createDrumRoll(true)));
AssertJudgementCount(12);
for (int i = 0; i < 5; i++)
{
StartTime = hit_time,
Duration = 1000,
IsStrong = true
}));
AssertJudgementCount(6);
AssertResult<DrumRollTick>(0, HitResult.SmallBonus);
AssertResult<StrongNestedHitObject>(0, HitResult.LargeBonus);
AssertResult<DrumRollTick>(1, HitResult.SmallBonus);
AssertResult<StrongNestedHitObject>(1, HitResult.LargeBonus);
AssertResult<DrumRollTick>(i, HitResult.SmallBonus);
AssertResult<StrongNestedHitObject>(i, HitResult.LargeBonus);
}
AssertResult<DrumRoll>(0, HitResult.IgnoreHit);
AssertResult<StrongNestedHitObject>(2, HitResult.IgnoreHit);
AssertResult<StrongNestedHitObject>(5, HitResult.IgnoreHit);
}
[Test]
public void TestHitSomeStrongDrumRollWithOneKey()
{
const double hit_time = 1000;
PerformTest(new List<ReplayFrame>
{
new TaikoReplayFrame(0),
new TaikoReplayFrame(2000, TaikoAction.LeftCentre),
new TaikoReplayFrame(2001),
}, CreateBeatmap(new DrumRoll
{
StartTime = hit_time,
Duration = 1000,
IsStrong = true
}));
}, CreateBeatmap(createDrumRoll(true)));
AssertJudgementCount(6);
AssertJudgementCount(12);
AssertResult<DrumRollTick>(0, HitResult.IgnoreMiss);
AssertResult<StrongNestedHitObject>(0, HitResult.IgnoreMiss);
AssertResult<DrumRollTick>(1, HitResult.SmallBonus);
AssertResult<StrongNestedHitObject>(1, HitResult.LargeBonus);
AssertResult<DrumRollTick>(4, HitResult.SmallBonus);
AssertResult<StrongNestedHitObject>(4, HitResult.LargeBonus);
AssertResult<DrumRoll>(0, HitResult.IgnoreHit);
AssertResult<StrongNestedHitObject>(2, HitResult.IgnoreHit);
AssertResult<StrongNestedHitObject>(5, HitResult.IgnoreHit);
}
[Test]
public void TestHitAllStrongDrumRollWithBothKeys()
{
const double hit_time = 1000;
PerformTest(new List<ReplayFrame>
{
new TaikoReplayFrame(0),
new TaikoReplayFrame(1000, TaikoAction.LeftCentre, TaikoAction.RightCentre),
new TaikoReplayFrame(1001),
new TaikoReplayFrame(1250, TaikoAction.LeftCentre, TaikoAction.RightCentre),
new TaikoReplayFrame(1251),
new TaikoReplayFrame(1500, TaikoAction.LeftCentre, TaikoAction.RightCentre),
new TaikoReplayFrame(1501),
new TaikoReplayFrame(1750, TaikoAction.LeftCentre, TaikoAction.RightCentre),
new TaikoReplayFrame(1751),
new TaikoReplayFrame(2000, TaikoAction.LeftCentre, TaikoAction.RightCentre),
new TaikoReplayFrame(2001),
}, CreateBeatmap(new DrumRoll
}, CreateBeatmap(createDrumRoll(true)));
AssertJudgementCount(12);
for (int i = 0; i < 5; i++)
{
StartTime = hit_time,
Duration = 1000,
IsStrong = true
}));
AssertJudgementCount(6);
AssertResult<DrumRollTick>(0, HitResult.SmallBonus);
AssertResult<StrongNestedHitObject>(0, HitResult.LargeBonus);
AssertResult<DrumRollTick>(1, HitResult.SmallBonus);
AssertResult<StrongNestedHitObject>(1, HitResult.LargeBonus);
AssertResult<DrumRollTick>(i, HitResult.SmallBonus);
AssertResult<StrongNestedHitObject>(i, HitResult.LargeBonus);
}
AssertResult<DrumRoll>(0, HitResult.IgnoreHit);
AssertResult<StrongNestedHitObject>(2, HitResult.IgnoreHit);
AssertResult<StrongNestedHitObject>(5, HitResult.IgnoreHit);
}
[Test]
public void TestHitSomeStrongDrumRollWithBothKeys()
{
const double hit_time = 1000;
PerformTest(new List<ReplayFrame>
{
new TaikoReplayFrame(0),
new TaikoReplayFrame(2000, TaikoAction.LeftCentre, TaikoAction.RightCentre),
new TaikoReplayFrame(2001),
}, CreateBeatmap(new DrumRoll
{
StartTime = hit_time,
Duration = 1000,
IsStrong = true
}));
}, CreateBeatmap(createDrumRoll(true)));
AssertJudgementCount(6);
AssertJudgementCount(12);
AssertResult<DrumRollTick>(0, HitResult.IgnoreMiss);
AssertResult<StrongNestedHitObject>(0, HitResult.IgnoreMiss);
AssertResult<DrumRollTick>(1, HitResult.SmallBonus);
AssertResult<StrongNestedHitObject>(1, HitResult.LargeBonus);
AssertResult<DrumRollTick>(4, HitResult.SmallBonus);
AssertResult<StrongNestedHitObject>(4, HitResult.LargeBonus);
AssertResult<DrumRoll>(0, HitResult.IgnoreHit);
AssertResult<StrongNestedHitObject>(2, HitResult.IgnoreHit);
AssertResult<StrongNestedHitObject>(5, HitResult.IgnoreHit);
}
private DrumRoll createDrumRoll(bool strong) => new DrumRoll
{
StartTime = 1000,
Duration = 1000,
IsStrong = strong
};
}
}
@@ -92,6 +92,14 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
}).ToList();
}
// TODO: stable makes the last tick of a drumroll non-required when the next object is too close.
// This probably needs to be reimplemented:
//
// List<HitObject> hitobjects = hitObjectManager.hitObjects;
// int ind = hitobjects.IndexOf(this);
// if (i < hitobjects.Count - 1 && hitobjects[i + 1].HittableStartTime - (EndTime + (int)TickSpacing) <= (int)TickSpacing)
// lastTickHittable = false;
return converted;
}
@@ -133,7 +141,6 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
StartTime = obj.StartTime,
Samples = obj.Samples,
Duration = taikoDuration,
TickRate = beatmap.Difficulty.SliderTickRate == 3 ? 3 : 4,
SliderVelocity = obj is IHasSliderVelocity velocityData ? velocityData.SliderVelocity : 1
};
}
+2 -2
View File
@@ -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.
#nullable disable
using osu.Game.Rulesets.Objects.Types;
using System.Threading;
using osu.Framework.Bindables;
@@ -69,6 +67,8 @@ namespace osu.Game.Rulesets.Taiko.Objects
double scoringDistance = base_distance * difficulty.SliderMultiplier * SliderVelocity;
Velocity = scoringDistance / timingPoint.BeatLength;
TickRate = difficulty.SliderTickRate == 3 ? 3 : 4;
tickSpacing = timingPoint.BeatLength / TickRate;
}
@@ -209,10 +209,14 @@ namespace osu.Game.Tests.Visual.Editing
public override void TearDownSteps()
{
base.TearDownSteps();
AddStep("delete imported", () =>
AddStep("delete imported", () => Realm.Write(r =>
{
beatmaps.Delete(importedBeatmapSet);
});
// delete from realm directly rather than via `BeatmapManager` to avoid cross-test pollution
// (`BeatmapManager.Delete()` uses soft deletion, which can lead to beatmap reuse between test cases).
r.RemoveAll<BeatmapMetadata>();
r.RemoveAll<BeatmapInfo>();
r.RemoveAll<BeatmapSetInfo>();
}));
}
}
}
@@ -40,7 +40,7 @@ namespace osu.Game.Tests.Visual.Navigation
AddStep("open editor", () => ((PlaySongSelect)Game.ScreenStack.CurrentScreen).Edit(beatmapSet.Beatmaps.First(beatmap => beatmap.Ruleset.OnlineID == 0)));
AddUntilStep("wait for editor open", () => Game.ScreenStack.CurrentScreen is Editor editor && editor.ReadyForUse);
AddStep("test gameplay", () => ((Editor)Game.ScreenStack.CurrentScreen).TestGameplay());
AddStep("test gameplay", () => getEditor().TestGameplay());
AddUntilStep("wait for player", () =>
{
@@ -141,6 +141,37 @@ namespace osu.Game.Tests.Visual.Navigation
AddUntilStep("wait for editor exit", () => Game.ScreenStack.CurrentScreen is not Editor);
}
private EditorBeatmap getEditorBeatmap() => ((Editor)Game.ScreenStack.CurrentScreen).ChildrenOfType<EditorBeatmap>().Single();
[Test]
public void TestLastTimestampRememberedOnExit()
{
BeatmapSetInfo beatmapSet = null!;
AddStep("import test beatmap", () => Game.BeatmapManager.Import(TestResources.GetTestBeatmapForImport()).WaitSafely());
AddStep("retrieve beatmap", () => beatmapSet = Game.BeatmapManager.QueryBeatmapSet(set => !set.Protected).AsNonNull().Value.Detach());
AddStep("present beatmap", () => Game.PresentBeatmap(beatmapSet));
AddUntilStep("wait for song select",
() => Game.Beatmap.Value.BeatmapSetInfo.Equals(beatmapSet)
&& Game.ScreenStack.CurrentScreen is PlaySongSelect songSelect
&& songSelect.IsLoaded);
AddStep("open editor", () => ((PlaySongSelect)Game.ScreenStack.CurrentScreen).Edit(beatmapSet.Beatmaps.First(beatmap => beatmap.Ruleset.OnlineID == 0)));
AddUntilStep("wait for editor open", () => Game.ScreenStack.CurrentScreen is Editor editor && editor.ReadyForUse);
AddStep("seek to arbitrary time", () => getEditor().ChildrenOfType<EditorClock>().First().Seek(1234));
AddUntilStep("time is correct", () => getEditor().ChildrenOfType<EditorClock>().First().CurrentTime, () => Is.EqualTo(1234));
AddStep("exit editor", () => InputManager.Key(Key.Escape));
AddUntilStep("wait for editor exit", () => Game.ScreenStack.CurrentScreen is not Editor);
AddStep("open editor", () => ((PlaySongSelect)Game.ScreenStack.CurrentScreen).Edit());
AddUntilStep("wait for editor open", () => Game.ScreenStack.CurrentScreen is Editor editor && editor.ReadyForUse);
AddUntilStep("time is correct", () => getEditor().ChildrenOfType<EditorClock>().First().CurrentTime, () => Is.EqualTo(1234));
}
private EditorBeatmap getEditorBeatmap() => getEditor().ChildrenOfType<EditorBeatmap>().Single();
private Editor getEditor() => (Editor)Game.ScreenStack.CurrentScreen;
}
}
+5
View File
@@ -171,6 +171,11 @@ namespace osu.Game.Beatmaps
public double TimelineZoom { get; set; } = 1.0;
/// <summary>
/// The time in milliseconds when last exiting the editor with this beatmap loaded.
/// </summary>
public double? EditorTimestamp { get; set; }
[Ignored]
public CountdownType Countdown { get; set; } = CountdownType.Normal;
+45 -1
View File
@@ -22,12 +22,15 @@ using osu.Framework.Statistics;
using osu.Framework.Threading;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Extensions;
using osu.Game.Input.Bindings;
using osu.Game.IO.Legacy;
using osu.Game.Models;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
using osu.Game.Scoring.Legacy;
using osu.Game.Skinning;
using Realms;
using Realms.Exceptions;
@@ -71,8 +74,10 @@ namespace osu.Game.Database
/// 24 2022-08-22 Added MaximumStatistics to ScoreInfo.
/// 25 2022-09-18 Remove skins to add with new naming.
/// 26 2023-02-05 Added BeatmapHash to ScoreInfo.
/// 27 2023-06-06 Added EditorTimestamp to BeatmapInfo.
/// 28 2023-06-08 Added IsLegacyScore to ScoreInfo, parsed from replay files.
/// </summary>
private const int schema_version = 26;
private const int schema_version = 28;
/// <summary>
/// Lock object which is held during <see cref="BlockAllOperations"/> sections, blocking realm retrieval during blocking periods.
@@ -879,6 +884,7 @@ namespace osu.Game.Database
break;
case 26:
{
// Add ScoreInfo.BeatmapHash property to ensure scores correspond to the correct version of beatmap.
var scores = migration.NewRealm.All<ScoreInfo>();
@@ -886,6 +892,44 @@ namespace osu.Game.Database
score.BeatmapHash = score.BeatmapInfo.Hash;
break;
}
case 28:
{
var files = new RealmFileStore(this, storage);
var scores = migration.NewRealm.All<ScoreInfo>();
foreach (var score in scores)
{
string? replayFilename = score.Files.FirstOrDefault(f => f.Filename.EndsWith(@".osr", StringComparison.InvariantCultureIgnoreCase))?.File.GetStoragePath();
if (replayFilename == null)
continue;
try
{
using (var stream = files.Store.GetStream(replayFilename))
{
if (stream == null)
continue;
// Trimmed down logic from LegacyScoreDecoder to extract the version from replays.
using (SerializationReader sr = new SerializationReader(stream))
{
sr.ReadByte(); // Ruleset.
int version = sr.ReadInt32();
if (version < LegacyScoreEncoder.FIRST_LAZER_VERSION)
score.IsLegacyScore = true;
}
}
}
catch (Exception e)
{
Logger.Error(e, $"Failed to read replay {replayFilename} during score migration", LoggingTarget.Database);
}
}
break;
}
}
}
@@ -82,7 +82,7 @@ namespace osu.Game.Localisation
/// <summary>
/// "{0}ms (speed {1})"
/// </summary>
public static LocalisableString ScrollSpeedTooltip(double scrollTime, int scrollSpeed) => new TranslatableString(getKey(@"ruleset"), @"{0:0}ms (speed {1})", scrollTime, scrollSpeed);
public static LocalisableString ScrollSpeedTooltip(int scrollTime, int scrollSpeed) => new TranslatableString(getKey(@"ruleset"), @"{0}ms (speed {1})", scrollTime, scrollSpeed);
private static string getKey(string key) => $@"{prefix}:{key}";
}
@@ -46,6 +46,9 @@ namespace osu.Game.Scoring.Legacy
score.ScoreInfo = scoreInfo;
int version = sr.ReadInt32();
scoreInfo.IsLegacyScore = version < LegacyScoreEncoder.FIRST_LAZER_VERSION;
string beatmapHash = sr.ReadString();
workingBeatmap = GetBeatmap(beatmapHash);
@@ -28,9 +28,10 @@ namespace osu.Game.Scoring.Legacy
/// <remarks>
/// <list type="bullet">
/// <item><description>30000001: Appends <see cref="LegacyReplaySoloScoreInfo"/> to the end of scores.</description></item>
/// <item><description>30000002: Score stored to replay calculated using the Score V2 algorithm.</description></item>
/// </list>
/// </remarks>
public const int LATEST_VERSION = 30000001;
public const int LATEST_VERSION = 30000002;
/// <summary>
/// The first stable-compatible YYYYMMDD format version given to lazer usage of replays.
@@ -16,7 +16,13 @@ namespace osu.Game.Scoring.Legacy
=> getDisplayScore(scoreProcessor.Ruleset.RulesetInfo.OnlineID, scoreProcessor.TotalScore.Value, mode, scoreProcessor.MaximumStatistics);
public static long GetDisplayScore(this ScoreInfo scoreInfo, ScoringMode mode)
=> getDisplayScore(scoreInfo.Ruleset.OnlineID, scoreInfo.TotalScore, mode, scoreInfo.MaximumStatistics);
{
// Temporary to not scale stable scores that are already in the XX-millions with the classic scoring mode.
if (scoreInfo.IsLegacyScore)
return scoreInfo.TotalScore;
return getDisplayScore(scoreInfo.Ruleset.OnlineID, scoreInfo.TotalScore, mode, scoreInfo.MaximumStatistics);
}
private static long getDisplayScore(int rulesetId, long score, ScoringMode mode, IReadOnlyDictionary<HitResult, int> maximumStatistics)
{
+1 -2
View File
@@ -181,8 +181,7 @@ namespace osu.Game.Scoring
/// <summary>
/// Whether this <see cref="ScoreInfo"/> represents a legacy (osu!stable) score.
/// </summary>
[Ignored]
public bool IsLegacyScore => Mods.OfType<ModClassic>().Any();
public bool IsLegacyScore { get; set; }
private Dictionary<HitResult, int>? statistics;
+16 -1
View File
@@ -28,6 +28,7 @@ using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Configuration;
using osu.Game.Database;
using osu.Game.Graphics.Cursor;
using osu.Game.Graphics.UserInterface;
using osu.Game.Input.Bindings;
@@ -92,6 +93,9 @@ namespace osu.Game.Screens.Edit
[Resolved(canBeNull: true)]
private INotificationOverlay notifications { get; set; }
[Resolved]
private RealmAccess realm { get; set; }
public readonly Bindable<EditorScreenMode> Mode = new Bindable<EditorScreenMode>();
public IBindable<bool> SamplePlaybackDisabled => samplePlaybackDisabled;
@@ -700,6 +704,13 @@ namespace osu.Game.Screens.Edit
}
}
realm.Write(r =>
{
var beatmap = r.Find<BeatmapInfo>(editorBeatmap.BeatmapInfo.ID);
if (beatmap != null)
beatmap.EditorTimestamp = clock.CurrentTime;
});
ApplyToBackground(b =>
{
b.DimWhenUserSettingsIgnored.Value = 0;
@@ -833,7 +844,11 @@ namespace osu.Game.Screens.Edit
{
double targetTime = 0;
if (Beatmap.Value.Beatmap.HitObjects.Count > 0)
if (editorBeatmap.BeatmapInfo.EditorTimestamp != null)
{
targetTime = editorBeatmap.BeatmapInfo.EditorTimestamp.Value;
}
else if (Beatmap.Value.Beatmap.HitObjects.Count > 0)
{
// seek to one beat length before the first hitobject
targetTime = Beatmap.Value.Beatmap.HitObjects[0].StartTime;
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Utils;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Localisation.HUD;
@@ -101,7 +102,12 @@ namespace osu.Game.Screens.Play.HUD
protected override void Update()
{
base.Update();
Height = bottom_bar_height + graph_height + handle_size.Y + info.Height - graph.Y;
// to prevent unnecessary invalidations of the song progress graph due to changes in size, apply tolerance when updating the height.
float newHeight = bottom_bar_height + graph_height + handle_size.Y + info.Height - graph.Y;
if (!Precision.AlmostEquals(Height, newHeight, 5f))
Height = newHeight;
}
private void updateBarVisibility()
+1 -1
View File
@@ -36,7 +36,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Realm" Version="10.20.0" />
<PackageReference Include="ppy.osu.Framework" Version="2023.531.0" />
<PackageReference Include="ppy.osu.Framework" Version="2023.608.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2023.510.0" />
<PackageReference Include="Sentry" Version="3.28.1" />
<PackageReference Include="SharpCompress" Version="0.32.2" />
+1 -1
View File
@@ -16,6 +16,6 @@
<RuntimeIdentifier>iossimulator-x64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Framework.iOS" Version="2023.531.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2023.608.0" />
</ItemGroup>
</Project>