mirror of
https://github.com/ppy/osu.git
synced 2025-01-15 10:42:55 +08:00
Merge branch 'master' into profile-recent-info
This commit is contained in:
commit
c9143275be
@ -44,6 +44,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
private const double time_during_slide_2 = 3000;
|
private const double time_during_slide_2 = 3000;
|
||||||
private const double time_during_slide_3 = 3500;
|
private const double time_during_slide_3 = 3500;
|
||||||
private const double time_during_slide_4 = 3800;
|
private const double time_during_slide_4 = 3800;
|
||||||
|
private const double time_slider_end = 4000;
|
||||||
|
|
||||||
private List<JudgementResult> judgementResults;
|
private List<JudgementResult> judgementResults;
|
||||||
private bool allJudgedFired;
|
private bool allJudgedFired;
|
||||||
@ -284,6 +285,48 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
AddAssert("Tracking acquired", assertMidSliderJudgements);
|
AddAssert("Tracking acquired", assertMidSliderJudgements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scenario:
|
||||||
|
/// - Press a key on the slider head
|
||||||
|
/// - While holding the key, move cursor close to the edge of tracking area
|
||||||
|
/// - Keep the cursor on the edge of tracking area until the slider ends
|
||||||
|
/// Expected Result:
|
||||||
|
/// A passing test case will have the slider track the cursor throughout the whole test.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestTrackingAreaEdge()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start },
|
||||||
|
new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 },
|
||||||
|
new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.199f), Actions = { OsuAction.LeftButton }, Time = time_slider_end },
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("Tracking kept", assertGreatJudge);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scenario:
|
||||||
|
/// - Press a key on the slider head
|
||||||
|
/// - While holding the key, move cursor just outside the tracking area
|
||||||
|
/// - Keep the cursor just outside the tracking area until the slider ends
|
||||||
|
/// Expected Result:
|
||||||
|
/// A passing test case will have the slider drop the tracking on frame 2.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestTrackingAreaOutsideEdge()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start },
|
||||||
|
new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 },
|
||||||
|
new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.201f), Actions = { OsuAction.LeftButton }, Time = time_slider_end },
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("Tracking dropped", assertMidSliderJudgementFail);
|
||||||
|
}
|
||||||
|
|
||||||
private bool assertGreatJudge() => judgementResults.Last().Type == HitResult.Great;
|
private bool assertGreatJudge() => judgementResults.Last().Type == HitResult.Great;
|
||||||
|
|
||||||
private bool assertHeadMissTailTracked() => judgementResults[^2].Type == HitResult.Great && judgementResults.First().Type == HitResult.Miss;
|
private bool assertHeadMissTailTracked() => judgementResults[^2].Type == HitResult.Great && judgementResults.First().Type == HitResult.Miss;
|
||||||
@ -294,6 +337,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
private ScoreAccessibleReplayPlayer currentPlayer;
|
private ScoreAccessibleReplayPlayer currentPlayer;
|
||||||
|
|
||||||
|
private const float slider_path_length = 25;
|
||||||
|
|
||||||
private void performTest(List<ReplayFrame> frames)
|
private void performTest(List<ReplayFrame> frames)
|
||||||
{
|
{
|
||||||
AddStep("load player", () =>
|
AddStep("load player", () =>
|
||||||
@ -309,8 +354,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
Path = new SliderPath(PathType.PerfectCurve, new[]
|
Path = new SliderPath(PathType.PerfectCurve, new[]
|
||||||
{
|
{
|
||||||
Vector2.Zero,
|
Vector2.Zero,
|
||||||
new Vector2(25, 0),
|
new Vector2(slider_path_length, 0),
|
||||||
}, 25),
|
}, slider_path_length),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
BeatmapInfo =
|
BeatmapInfo =
|
||||||
|
@ -23,7 +23,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
public Func<OsuAction?> GetInitialHitAction;
|
public Func<OsuAction?> GetInitialHitAction;
|
||||||
|
|
||||||
private readonly Slider slider;
|
private readonly Slider slider;
|
||||||
public readonly Drawable FollowCircle;
|
private readonly Drawable followCircle;
|
||||||
|
private readonly Drawable trackingArea;
|
||||||
private readonly DrawableSlider drawableSlider;
|
private readonly DrawableSlider drawableSlider;
|
||||||
|
|
||||||
public SliderBall(Slider slider, DrawableSlider drawableSlider = null)
|
public SliderBall(Slider slider, DrawableSlider drawableSlider = null)
|
||||||
@ -38,7 +39,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
FollowCircle = new FollowCircleContainer
|
// This is separate from the visible followcircle to ensure consistent internal tracking area (needed to match osu-stable)
|
||||||
|
trackingArea = new CircularContainer
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both
|
||||||
|
},
|
||||||
|
followCircle = new FollowCircleContainer
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
@ -95,8 +103,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
tracking = value;
|
tracking = value;
|
||||||
|
|
||||||
FollowCircle.ScaleTo(tracking ? 2f : 1, 300, Easing.OutQuint);
|
// Tracking area is bigger than the visible followcircle and scales instantly to match osu-stable
|
||||||
FollowCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint);
|
trackingArea.ScaleTo(tracking ? 2.4f : 1f);
|
||||||
|
followCircle.ScaleTo(tracking ? 2f : 1f, 300, Easing.OutQuint);
|
||||||
|
followCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +159,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
// in valid time range
|
// in valid time range
|
||||||
Time.Current >= slider.StartTime && Time.Current < slider.EndTime &&
|
Time.Current >= slider.StartTime && Time.Current < slider.EndTime &&
|
||||||
// in valid position range
|
// in valid position range
|
||||||
lastScreenSpaceMousePosition.HasValue && FollowCircle.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) &&
|
lastScreenSpaceMousePosition.HasValue && trackingArea.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) &&
|
||||||
// valid action
|
// valid action
|
||||||
(actions?.Any(isValidTrackingAction) ?? false);
|
(actions?.Any(isValidTrackingAction) ?? false);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,8 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
typeof(SortTabControl),
|
typeof(SortTabControl),
|
||||||
typeof(ShowChildrenButton),
|
typeof(ShowChildrenButton),
|
||||||
typeof(DeletedCommentsCounter),
|
typeof(DeletedCommentsCounter),
|
||||||
typeof(VotePill)
|
typeof(VotePill),
|
||||||
|
typeof(CommentsPage),
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override bool UseOnlineAPI => true;
|
protected override bool UseOnlineAPI => true;
|
||||||
|
162
osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs
Normal file
162
osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
// 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.Game.Overlays.Comments;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Online
|
||||||
|
{
|
||||||
|
public class TestSceneCommentsPage : OsuTestScene
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(DrawableComment),
|
||||||
|
typeof(CommentsPage),
|
||||||
|
};
|
||||||
|
|
||||||
|
[Cached]
|
||||||
|
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
|
||||||
|
|
||||||
|
private readonly BindableBool showDeleted = new BindableBool();
|
||||||
|
private readonly Container content;
|
||||||
|
|
||||||
|
public TestSceneCommentsPage()
|
||||||
|
{
|
||||||
|
Add(new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(0, 10),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Width = 200,
|
||||||
|
Child = new OsuCheckbox
|
||||||
|
{
|
||||||
|
Current = showDeleted,
|
||||||
|
LabelText = @"Show Deleted"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
content = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("load comments", () => createPage(comment_bundle));
|
||||||
|
AddStep("load empty comments", () => createPage(empty_comment_bundle));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createPage(CommentBundle commentBundle)
|
||||||
|
{
|
||||||
|
content.Clear();
|
||||||
|
content.Add(new CommentsPage(commentBundle)
|
||||||
|
{
|
||||||
|
ShowDeleted = { BindTarget = showDeleted }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly CommentBundle empty_comment_bundle = new CommentBundle
|
||||||
|
{
|
||||||
|
Comments = new List<Comment>(),
|
||||||
|
Total = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly CommentBundle comment_bundle = new CommentBundle
|
||||||
|
{
|
||||||
|
Comments = new List<Comment>
|
||||||
|
{
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Message = "Simple test comment",
|
||||||
|
LegacyName = "TestUser1",
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
VotesCount = 5
|
||||||
|
},
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Message = "This comment has been deleted :( but visible for admins",
|
||||||
|
LegacyName = "TestUser2",
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
DeletedAt = DateTimeOffset.Now,
|
||||||
|
VotesCount = 5
|
||||||
|
},
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 3,
|
||||||
|
Message = "This comment is a top level",
|
||||||
|
LegacyName = "TestUser3",
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
RepliesCount = 2,
|
||||||
|
},
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 4,
|
||||||
|
ParentId = 3,
|
||||||
|
Message = "And this is a reply",
|
||||||
|
RepliesCount = 1,
|
||||||
|
LegacyName = "TestUser1",
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
},
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 15,
|
||||||
|
ParentId = 4,
|
||||||
|
Message = "Reply to reply",
|
||||||
|
LegacyName = "TestUser1",
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
},
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 6,
|
||||||
|
ParentId = 3,
|
||||||
|
LegacyName = "TestUser11515",
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
DeletedAt = DateTimeOffset.Now,
|
||||||
|
},
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 5,
|
||||||
|
Message = "This comment is voted and edited",
|
||||||
|
LegacyName = "BigBrainUser",
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
EditedAt = DateTimeOffset.Now,
|
||||||
|
VotesCount = 1000,
|
||||||
|
EditedById = 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
IncludedComments = new List<Comment>(),
|
||||||
|
UserVotes = new List<long>
|
||||||
|
{
|
||||||
|
5
|
||||||
|
},
|
||||||
|
Users = new List<User>
|
||||||
|
{
|
||||||
|
new User
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Username = "Good_Admin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TopLevelCount = 4,
|
||||||
|
Total = 7
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
175
osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs
Normal file
175
osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Screens.Select.Details;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.SongSelect
|
||||||
|
{
|
||||||
|
[System.ComponentModel.Description("Advanced beatmap statistics display")]
|
||||||
|
public class TestSceneAdvancedStats : OsuTestScene
|
||||||
|
{
|
||||||
|
private TestAdvancedStats advancedStats;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private RulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private OsuColour colours { get; set; }
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup() => Schedule(() => Child = advancedStats = new TestAdvancedStats
|
||||||
|
{
|
||||||
|
Width = 500
|
||||||
|
});
|
||||||
|
|
||||||
|
private BeatmapInfo exampleBeatmapInfo => new BeatmapInfo
|
||||||
|
{
|
||||||
|
RulesetID = 0,
|
||||||
|
Ruleset = rulesets.AvailableRulesets.First(),
|
||||||
|
BaseDifficulty = new BeatmapDifficulty
|
||||||
|
{
|
||||||
|
CircleSize = 7.2f,
|
||||||
|
DrainRate = 3,
|
||||||
|
OverallDifficulty = 5.7f,
|
||||||
|
ApproachRate = 3.5f
|
||||||
|
},
|
||||||
|
StarDifficulty = 4.5f
|
||||||
|
};
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestNoMod()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo);
|
||||||
|
|
||||||
|
AddStep("no mods selected", () => SelectedMods.Value = Array.Empty<Mod>());
|
||||||
|
|
||||||
|
AddAssert("first bar text is Circle Size", () => advancedStats.ChildrenOfType<SpriteText>().First().Text == "Circle Size");
|
||||||
|
AddAssert("circle size bar is white", () => barIsWhite(advancedStats.FirstValue));
|
||||||
|
AddAssert("HP drain bar is white", () => barIsWhite(advancedStats.HpDrain));
|
||||||
|
AddAssert("accuracy bar is white", () => barIsWhite(advancedStats.Accuracy));
|
||||||
|
AddAssert("approach rate bar is white", () => barIsWhite(advancedStats.ApproachRate));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestManiaFirstBarText()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => advancedStats.Beatmap = new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = rulesets.GetRuleset(3),
|
||||||
|
BaseDifficulty = new BeatmapDifficulty
|
||||||
|
{
|
||||||
|
CircleSize = 5,
|
||||||
|
DrainRate = 4.3f,
|
||||||
|
OverallDifficulty = 4.5f,
|
||||||
|
ApproachRate = 3.1f
|
||||||
|
},
|
||||||
|
StarDifficulty = 8
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("first bar text is Key Count", () => advancedStats.ChildrenOfType<SpriteText>().First().Text == "Key Count");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestEasyMod()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo);
|
||||||
|
|
||||||
|
AddStep("select EZ mod", () =>
|
||||||
|
{
|
||||||
|
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance();
|
||||||
|
SelectedMods.Value = new[] { ruleset.GetAllMods().OfType<ModEasy>().Single() };
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("circle size bar is blue", () => barIsBlue(advancedStats.FirstValue));
|
||||||
|
AddAssert("HP drain bar is blue", () => barIsBlue(advancedStats.HpDrain));
|
||||||
|
AddAssert("accuracy bar is blue", () => barIsBlue(advancedStats.Accuracy));
|
||||||
|
AddAssert("approach rate bar is blue", () => barIsBlue(advancedStats.ApproachRate));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestHardRockMod()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo);
|
||||||
|
|
||||||
|
AddStep("select HR mod", () =>
|
||||||
|
{
|
||||||
|
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance();
|
||||||
|
SelectedMods.Value = new[] { ruleset.GetAllMods().OfType<ModHardRock>().Single() };
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("circle size bar is red", () => barIsRed(advancedStats.FirstValue));
|
||||||
|
AddAssert("HP drain bar is red", () => barIsRed(advancedStats.HpDrain));
|
||||||
|
AddAssert("accuracy bar is red", () => barIsRed(advancedStats.Accuracy));
|
||||||
|
AddAssert("approach rate bar is red", () => barIsRed(advancedStats.ApproachRate));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestUnchangedDifficultyAdjustMod()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo);
|
||||||
|
|
||||||
|
AddStep("select unchanged Difficulty Adjust mod", () =>
|
||||||
|
{
|
||||||
|
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance();
|
||||||
|
var difficultyAdjustMod = ruleset.GetAllMods().OfType<ModDifficultyAdjust>().Single();
|
||||||
|
difficultyAdjustMod.ReadFromDifficulty(advancedStats.Beatmap.BaseDifficulty);
|
||||||
|
SelectedMods.Value = new[] { difficultyAdjustMod };
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("circle size bar is white", () => barIsWhite(advancedStats.FirstValue));
|
||||||
|
AddAssert("HP drain bar is white", () => barIsWhite(advancedStats.HpDrain));
|
||||||
|
AddAssert("accuracy bar is white", () => barIsWhite(advancedStats.Accuracy));
|
||||||
|
AddAssert("approach rate bar is white", () => barIsWhite(advancedStats.ApproachRate));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestChangedDifficultyAdjustMod()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo);
|
||||||
|
|
||||||
|
AddStep("select changed Difficulty Adjust mod", () =>
|
||||||
|
{
|
||||||
|
var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance();
|
||||||
|
var difficultyAdjustMod = ruleset.GetAllMods().OfType<ModDifficultyAdjust>().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);
|
||||||
|
SelectedMods.Value = new[] { difficultyAdjustMod };
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("circle size bar is white", () => barIsWhite(advancedStats.FirstValue));
|
||||||
|
AddAssert("drain rate bar is blue", () => barIsBlue(advancedStats.HpDrain));
|
||||||
|
AddAssert("accuracy bar is white", () => barIsWhite(advancedStats.Accuracy));
|
||||||
|
AddAssert("approach rate bar is red", () => barIsRed(advancedStats.ApproachRate));
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool barIsWhite(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == Color4.White;
|
||||||
|
private bool barIsBlue(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == colours.BlueDark;
|
||||||
|
private bool barIsRed(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == colours.Red;
|
||||||
|
|
||||||
|
private class TestAdvancedStats : AdvancedStats
|
||||||
|
{
|
||||||
|
public new StatisticRow FirstValue => base.FirstValue;
|
||||||
|
public new StatisticRow HpDrain => base.HpDrain;
|
||||||
|
public new StatisticRow Accuracy => base.Accuracy;
|
||||||
|
public new StatisticRow ApproachRate => base.ApproachRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,14 +3,8 @@
|
|||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Testing;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Graphics.UserInterface;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.SongSelect
|
namespace osu.Game.Tests.Visual.SongSelect
|
||||||
@ -180,27 +174,5 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
OnlineBeatmapID = 162,
|
OnlineBeatmapID = 162,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private RulesetStore rulesets { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private OsuColour colours { get; set; }
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestModAdjustments()
|
|
||||||
{
|
|
||||||
TestAllMetrics();
|
|
||||||
|
|
||||||
Ruleset ruleset = rulesets.AvailableRulesets.First().CreateInstance();
|
|
||||||
|
|
||||||
AddStep("with EZ mod", () => SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModEasy) });
|
|
||||||
|
|
||||||
AddAssert("first bar coloured blue", () => details.ChildrenOfType<Bar>().Skip(1).First().AccentColour == colours.BlueDark);
|
|
||||||
|
|
||||||
AddStep("with HR mod", () => SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModHardRock) });
|
|
||||||
|
|
||||||
AddAssert("first bar coloured red", () => details.ChildrenOfType<Bar>().Skip(1).First().AccentColour == colours.Red);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,13 +40,14 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
public ShowMoreButton()
|
public ShowMoreButton()
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both;
|
Height = 30;
|
||||||
|
Width = 140;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Drawable CreateContent() => new CircularContainer
|
protected override Drawable CreateContent() => new CircularContainer
|
||||||
{
|
{
|
||||||
Masking = true,
|
Masking = true,
|
||||||
Size = new Vector2(140, 30),
|
RelativeSizeAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
background = new Box
|
background = new Box
|
||||||
|
@ -6,8 +6,6 @@ using osu.Game.Users;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests.Responses
|
namespace osu.Game.Online.API.Requests.Responses
|
||||||
{
|
{
|
||||||
@ -70,12 +68,10 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
|
|
||||||
public bool IsDeleted => DeletedAt.HasValue;
|
public bool IsDeleted => DeletedAt.HasValue;
|
||||||
|
|
||||||
public bool HasMessage => !string.IsNullOrEmpty(MessageHtml);
|
public bool HasMessage => !string.IsNullOrEmpty(Message);
|
||||||
|
|
||||||
public bool IsVoted { get; set; }
|
public bool IsVoted { get; set; }
|
||||||
|
|
||||||
public string GetMessage => HasMessage ? WebUtility.HtmlDecode(Regex.Replace(MessageHtml, @"<(.|\n)*?>", string.Empty)) : string.Empty;
|
|
||||||
|
|
||||||
public int DeletedChildrenCount => ChildComments.Count(c => c.IsDeleted);
|
public int DeletedChildrenCount => ChildComments.Count(c => c.IsDeleted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,17 +47,18 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
[JsonProperty(@"included_comments")]
|
[JsonProperty(@"included_comments")]
|
||||||
public List<Comment> IncludedComments { get; set; }
|
public List<Comment> IncludedComments { get; set; }
|
||||||
|
|
||||||
|
private List<long> userVotes;
|
||||||
|
|
||||||
[JsonProperty(@"user_votes")]
|
[JsonProperty(@"user_votes")]
|
||||||
private List<long> userVotes
|
public List<long> UserVotes
|
||||||
{
|
{
|
||||||
set => value.ForEach(v =>
|
get => userVotes;
|
||||||
|
set
|
||||||
{
|
{
|
||||||
Comments.ForEach(c =>
|
userVotes = value;
|
||||||
{
|
|
||||||
if (v == c.Id)
|
Comments.ForEach(c => c.IsVoted = value.Contains(c.Id));
|
||||||
c.IsVoted = true;
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<User> users;
|
private List<User> users;
|
||||||
|
@ -68,6 +68,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
},
|
},
|
||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
|
Name = @"Footer",
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
@ -154,6 +155,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
{
|
{
|
||||||
currentPage = 1;
|
currentPage = 1;
|
||||||
deletedCommentsCounter.Count.Value = 0;
|
deletedCommentsCounter.Count.Value = 0;
|
||||||
|
moreButton.Show();
|
||||||
moreButton.IsLoading = true;
|
moreButton.IsLoading = true;
|
||||||
content.Clear();
|
content.Clear();
|
||||||
}
|
}
|
||||||
@ -162,25 +164,10 @@ namespace osu.Game.Overlays.Comments
|
|||||||
{
|
{
|
||||||
loadCancellation = new CancellationTokenSource();
|
loadCancellation = new CancellationTokenSource();
|
||||||
|
|
||||||
var page = new FillFlowContainer
|
LoadComponentAsync(new CommentsPage(response)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
ShowDeleted = { BindTarget = ShowDeleted }
|
||||||
AutoSizeAxes = Axes.Y,
|
}, loaded =>
|
||||||
Direction = FillDirection.Vertical,
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var c in response.Comments)
|
|
||||||
{
|
|
||||||
if (c.IsTopLevel)
|
|
||||||
{
|
|
||||||
page.Add(new DrawableComment(c)
|
|
||||||
{
|
|
||||||
ShowDeleted = { BindTarget = ShowDeleted }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadComponentAsync(page, loaded =>
|
|
||||||
{
|
{
|
||||||
content.Add(loaded);
|
content.Add(loaded);
|
||||||
|
|
||||||
@ -194,10 +181,12 @@ namespace osu.Game.Overlays.Comments
|
|||||||
moreButton.Current.Value = response.TopLevelCount - loadedTopLevelComments;
|
moreButton.Current.Value = response.TopLevelCount - loadedTopLevelComments;
|
||||||
moreButton.IsLoading = false;
|
moreButton.IsLoading = false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moreButton.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
commentCounter.Current.Value = response.Total;
|
commentCounter.Current.Value = response.Total;
|
||||||
|
|
||||||
moreButton.FadeTo(response.HasMore ? 1 : 0);
|
|
||||||
}, loadCancellation.Token);
|
}, loadCancellation.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
92
osu.Game/Overlays/Comments/CommentsPage.cs
Normal file
92
osu.Game/Overlays/Comments/CommentsPage.cs
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
// 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.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Comments
|
||||||
|
{
|
||||||
|
public class CommentsPage : CompositeDrawable
|
||||||
|
{
|
||||||
|
public readonly BindableBool ShowDeleted = new BindableBool();
|
||||||
|
|
||||||
|
private readonly CommentBundle commentBundle;
|
||||||
|
|
||||||
|
public CommentsPage(CommentBundle commentBundle)
|
||||||
|
{
|
||||||
|
this.commentBundle = commentBundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OverlayColourProvider colourProvider)
|
||||||
|
{
|
||||||
|
FillFlowContainer flow;
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
|
||||||
|
AddRangeInternal(new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = colourProvider.Background5
|
||||||
|
},
|
||||||
|
flow = new FillFlowContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!commentBundle.Comments.Any())
|
||||||
|
{
|
||||||
|
flow.Add(new NoCommentsPlaceholder());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var c in commentBundle.Comments)
|
||||||
|
{
|
||||||
|
if (c.IsTopLevel)
|
||||||
|
{
|
||||||
|
flow.Add(new DrawableComment(c)
|
||||||
|
{
|
||||||
|
ShowDeleted = { BindTarget = ShowDeleted }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NoCommentsPlaceholder : CompositeDrawable
|
||||||
|
{
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OverlayColourProvider colourProvider)
|
||||||
|
{
|
||||||
|
Height = 80;
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
AddRangeInternal(new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = colourProvider.Background4
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.CentreLeft,
|
||||||
|
Margin = new MarginPadding { Left = 50 },
|
||||||
|
Text = @"No comments yet."
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,8 @@ namespace osu.Game.Overlays.Comments
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OverlayColourProvider colourProvider)
|
private void load(OverlayColourProvider colourProvider)
|
||||||
{
|
{
|
||||||
|
Height = 20;
|
||||||
|
|
||||||
IdleColour = colourProvider.Background2;
|
IdleColour = colourProvider.Background2;
|
||||||
HoverColour = colourProvider.Background1;
|
HoverColour = colourProvider.Background1;
|
||||||
ChevronIconColour = colourProvider.Foreground1;
|
ChevronIconColour = colourProvider.Foreground1;
|
||||||
|
@ -213,7 +213,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
|
|
||||||
if (comment.HasMessage)
|
if (comment.HasMessage)
|
||||||
{
|
{
|
||||||
var formattedSource = MessageFormatter.FormatText(comment.GetMessage);
|
var formattedSource = MessageFormatter.FormatText(comment.Message);
|
||||||
message.AddLinks(formattedSource.Text, formattedSource.Links);
|
message.AddLinks(formattedSource.Text, formattedSource.Links);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,7 +343,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
if (parentComment == null)
|
if (parentComment == null)
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
|
|
||||||
return parentComment.HasMessage ? parentComment.GetMessage : parentComment.IsDeleted ? @"deleted" : string.Empty;
|
return parentComment.HasMessage ? parentComment.Message : parentComment.IsDeleted ? @"deleted" : string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,8 @@ namespace osu.Game.Overlays.Profile.Sections
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OverlayColourProvider colourProvider)
|
private void load(OverlayColourProvider colourProvider)
|
||||||
{
|
{
|
||||||
background.Colour = idleColour = colourProvider.Background4;
|
background.Colour = idleColour = colourProvider.Background3;
|
||||||
hoverColour = colourProvider.Background3;
|
hoverColour = colourProvider.Background2;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnHover(HoverEvent e)
|
protected override bool OnHover(HoverEvent e)
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
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;
|
||||||
@ -16,14 +16,16 @@ using osu.Game.Online.Leaderboards;
|
|||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Profile.Sections.Ranks
|
namespace osu.Game.Overlays.Profile.Sections.Ranks
|
||||||
{
|
{
|
||||||
public class DrawableProfileScore : CompositeDrawable
|
public class DrawableProfileScore : CompositeDrawable
|
||||||
{
|
{
|
||||||
|
private const int height = 40;
|
||||||
private const int performance_width = 80;
|
private const int performance_width = 80;
|
||||||
private const int content_padding = 10;
|
|
||||||
|
private const float performance_background_shear = 0.45f;
|
||||||
|
private static readonly float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear));
|
||||||
|
|
||||||
protected readonly ScoreInfo Score;
|
protected readonly ScoreInfo Score;
|
||||||
|
|
||||||
@ -38,7 +40,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
Score = score;
|
Score = score;
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
Height = 40;
|
Height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -51,7 +53,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Padding = new MarginPadding { Left = content_padding, Right = performance_width + content_padding },
|
Padding = new MarginPadding { Left = 10, Right = performance_width + 30 },
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new FillFlowContainer
|
new FillFlowContainer
|
||||||
@ -142,20 +144,26 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
{
|
{
|
||||||
new Box
|
new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
Anchor = Anchor.TopRight,
|
||||||
Size = new Vector2(1, 0.5f),
|
Origin = Anchor.TopRight,
|
||||||
Colour = Color4.Black.Opacity(0.5f),
|
RelativeSizeAxes = Axes.Y,
|
||||||
Shear = new Vector2(-0.45f, 0),
|
Width = performance_background_width,
|
||||||
|
Height = 0.5f,
|
||||||
|
Colour = colourProvider.Background4,
|
||||||
|
Shear = new Vector2(-performance_background_shear, 0),
|
||||||
EdgeSmoothness = new Vector2(2, 0),
|
EdgeSmoothness = new Vector2(2, 0),
|
||||||
},
|
},
|
||||||
new Box
|
new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
RelativePositionAxes = Axes.Y,
|
RelativePositionAxes = Axes.Y,
|
||||||
Size = new Vector2(1, -0.5f),
|
Width = performance_background_width,
|
||||||
|
Height = -0.5f,
|
||||||
Position = new Vector2(0, 1),
|
Position = new Vector2(0, 1),
|
||||||
Colour = Color4.Black.Opacity(0.5f),
|
Colour = colourProvider.Background4,
|
||||||
Shear = new Vector2(0.45f, 0),
|
Shear = new Vector2(performance_background_shear, 0),
|
||||||
EdgeSmoothness = new Vector2(2, 0),
|
EdgeSmoothness = new Vector2(2, 0),
|
||||||
},
|
},
|
||||||
createDrawablePerformance().With(d =>
|
createDrawablePerformance().With(d =>
|
||||||
|
@ -16,6 +16,7 @@ using System.Collections.Generic;
|
|||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
|
|
||||||
@ -26,7 +27,8 @@ namespace osu.Game.Screens.Select.Details
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private IBindable<IReadOnlyList<Mod>> mods { get; set; }
|
private IBindable<IReadOnlyList<Mod>> mods { get; set; }
|
||||||
|
|
||||||
private readonly StatisticRow firstValue, hpDrain, accuracy, approachRate, starDifficulty;
|
protected readonly StatisticRow FirstValue, HpDrain, Accuracy, ApproachRate;
|
||||||
|
private readonly StatisticRow starDifficulty;
|
||||||
|
|
||||||
private BeatmapInfo beatmap;
|
private BeatmapInfo beatmap;
|
||||||
|
|
||||||
@ -52,10 +54,10 @@ namespace osu.Game.Screens.Select.Details
|
|||||||
Spacing = new Vector2(4f),
|
Spacing = new Vector2(4f),
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
firstValue = new StatisticRow(), //circle size/key amount
|
FirstValue = new StatisticRow(), //circle size/key amount
|
||||||
hpDrain = new StatisticRow { Title = "HP Drain" },
|
HpDrain = new StatisticRow { Title = "HP Drain" },
|
||||||
accuracy = new StatisticRow { Title = "Accuracy" },
|
Accuracy = new StatisticRow { Title = "Accuracy" },
|
||||||
approachRate = new StatisticRow { Title = "Approach Rate" },
|
ApproachRate = new StatisticRow { Title = "Approach Rate" },
|
||||||
starDifficulty = new StatisticRow(10, true) { Title = "Star Difficulty" },
|
starDifficulty = new StatisticRow(10, true) { Title = "Star Difficulty" },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -122,24 +124,24 @@ namespace osu.Game.Screens.Select.Details
|
|||||||
case 3:
|
case 3:
|
||||||
// Account for mania differences locally for now
|
// Account for mania differences locally for now
|
||||||
// Eventually this should be handled in a more modular way, allowing rulesets to return arbitrary difficulty attributes
|
// Eventually this should be handled in a more modular way, allowing rulesets to return arbitrary difficulty attributes
|
||||||
firstValue.Title = "Key Count";
|
FirstValue.Title = "Key Count";
|
||||||
firstValue.Value = (baseDifficulty?.CircleSize ?? 0, null);
|
FirstValue.Value = (baseDifficulty?.CircleSize ?? 0, null);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
firstValue.Title = "Circle Size";
|
FirstValue.Title = "Circle Size";
|
||||||
firstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize);
|
FirstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
starDifficulty.Value = ((float)(Beatmap?.StarDifficulty ?? 0), null);
|
starDifficulty.Value = ((float)(Beatmap?.StarDifficulty ?? 0), null);
|
||||||
|
|
||||||
hpDrain.Value = (baseDifficulty?.DrainRate ?? 0, adjustedDifficulty?.DrainRate);
|
HpDrain.Value = (baseDifficulty?.DrainRate ?? 0, adjustedDifficulty?.DrainRate);
|
||||||
accuracy.Value = (baseDifficulty?.OverallDifficulty ?? 0, adjustedDifficulty?.OverallDifficulty);
|
Accuracy.Value = (baseDifficulty?.OverallDifficulty ?? 0, adjustedDifficulty?.OverallDifficulty);
|
||||||
approachRate.Value = (baseDifficulty?.ApproachRate ?? 0, adjustedDifficulty?.ApproachRate);
|
ApproachRate.Value = (baseDifficulty?.ApproachRate ?? 0, adjustedDifficulty?.ApproachRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class StatisticRow : Container, IHasAccentColour
|
public class StatisticRow : Container, IHasAccentColour
|
||||||
{
|
{
|
||||||
private const float value_width = 25;
|
private const float value_width = 25;
|
||||||
private const float name_width = 70;
|
private const float name_width = 70;
|
||||||
@ -147,7 +149,8 @@ namespace osu.Game.Screens.Select.Details
|
|||||||
private readonly float maxValue;
|
private readonly float maxValue;
|
||||||
private readonly bool forceDecimalPlaces;
|
private readonly bool forceDecimalPlaces;
|
||||||
private readonly OsuSpriteText name, valueText;
|
private readonly OsuSpriteText name, valueText;
|
||||||
private readonly Bar bar, modBar;
|
private readonly Bar bar;
|
||||||
|
public readonly Bar ModBar;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuColour colours { get; set; }
|
private OsuColour colours { get; set; }
|
||||||
@ -173,14 +176,14 @@ namespace osu.Game.Screens.Select.Details
|
|||||||
bar.Length = value.baseValue / maxValue;
|
bar.Length = value.baseValue / maxValue;
|
||||||
|
|
||||||
valueText.Text = (value.adjustedValue ?? value.baseValue).ToString(forceDecimalPlaces ? "0.00" : "0.##");
|
valueText.Text = (value.adjustedValue ?? value.baseValue).ToString(forceDecimalPlaces ? "0.00" : "0.##");
|
||||||
modBar.Length = (value.adjustedValue ?? 0) / maxValue;
|
ModBar.Length = (value.adjustedValue ?? 0) / maxValue;
|
||||||
|
|
||||||
if (value.adjustedValue > value.baseValue)
|
if (Precision.AlmostEquals(value.baseValue, value.adjustedValue ?? value.baseValue, 0.05f))
|
||||||
modBar.AccentColour = valueText.Colour = colours.Red;
|
ModBar.AccentColour = valueText.Colour = Color4.White;
|
||||||
|
else if (value.adjustedValue > value.baseValue)
|
||||||
|
ModBar.AccentColour = valueText.Colour = colours.Red;
|
||||||
else if (value.adjustedValue < value.baseValue)
|
else if (value.adjustedValue < value.baseValue)
|
||||||
modBar.AccentColour = valueText.Colour = colours.BlueDark;
|
ModBar.AccentColour = valueText.Colour = colours.BlueDark;
|
||||||
else
|
|
||||||
modBar.AccentColour = valueText.Colour = Color4.White;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +220,7 @@ namespace osu.Game.Screens.Select.Details
|
|||||||
BackgroundColour = Color4.White.Opacity(0.5f),
|
BackgroundColour = Color4.White.Opacity(0.5f),
|
||||||
Padding = new MarginPadding { Left = name_width + 10, Right = value_width + 10 },
|
Padding = new MarginPadding { Left = name_width + 10, Right = value_width + 10 },
|
||||||
},
|
},
|
||||||
modBar = new Bar
|
ModBar = new Bar
|
||||||
{
|
{
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Loading…
Reference in New Issue
Block a user