1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-25 05:11:19 +08:00
Files
osu-lazer/osu.Game.Tests/Visual/RankedPlay/TestSceneRankedPlayCard.cs
T
Dan Balasescu 0988552567 Implement ranked play (#36819)
I don't really have much to say here. Instead, I'll give a brief history
rundown that lists many pages of documentation you can read, if
interested.

- Started off as BTMC + Happy24 (Vivi)'s ["The
Vision"](https://docs.google.com/document/d/1p1IpPmd2RICp8G4OqkCSs7u8Ug8FbFv8qqP0mfSrHf0/edit?tab=t.0#heading=h.fol093d9f9xi)
- Initial
[designs](https://www.figma.com/design/f5qqC57t9jFlgpzhRqUNVX/The-Vision?node-id=0-1&p=f)
were led by Vivi.
- Designs
[morphed](https://www.figma.com/design/vtFmLrXKvWNyYiRjTezFTM/Untitled--Copy-?node-id=0-1&p=f)
during development into what's currently present, led by @minetoblend.
- There is some more ongoing work creating a [game design
document](https://docs.google.com/document/d/1iffJFCsIBfYF0D4ogItSBEj6YBmbp-rdCpItAeaJiTA/edit?tab=t.0).

**tl;dr:** Create something with the mechanics of a trading card game
within osu!. The name of this is "ranked play".

---

To be frank, a lot of stuff is missing here. Some of it I don't want to
mention, because the point of this exercise is to get the system into
the hands of players, gather feedback especially around mechanics, and
discuss any further direction with the team.

I am expecting a blanket approval on all of the new code, with
particular attention to changes in existing components that I'll point
out in a self review.

There is also some [ongoing
work](https://github.com/smoogipoo/osu/pulls) that may arrive in this
branch prior to being merged.

---------

Co-authored-by: maarvin <minetoblend@gmail.com>
Co-authored-by: Marvin <m.schuerz@hautzy.com>
Co-authored-by: Jamie Taylor <me@nekodex.net>
Co-authored-by: ArijanJ <arijanj@proton.me>
Co-authored-by: Dean Herbert <pe@ppy.sh>
Co-authored-by: Tim Oliver <git@tim.dev>
Co-authored-by: Joseph Madamba <madamba.joehu@outlook.com>
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
Co-authored-by: nil <25884226+voidstar0@users.noreply.github.com>
Co-authored-by: Ботников Максим <mr.botnikoff@ya.ru>
Co-authored-by: Denis Titovets <den232titovets@yandex.ru>
Co-authored-by: Michael Middlezong <119022671+mmiddlezong@users.noreply.github.com>
Co-authored-by: SupDos <6813986+SupDos@users.noreply.github.com>
Co-authored-by: failaip12 <86018517+failaip12@users.noreply.github.com>
2026-03-07 02:30:50 +09:00

223 lines
8.2 KiB
C#

// 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.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Cursor;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Rulesets;
using osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay.Card;
using osu.Game.Screens.OnlinePlay.Matchmaking.RankedPlay.Hand;
using osuTK;
namespace osu.Game.Tests.Visual.RankedPlay
{
public partial class TestSceneRankedPlayCard : RankedPlayTestScene
{
protected override Container<Drawable> Content { get; }
[Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
[Cached]
private readonly CardDetailsOverlayContainer overlayContainer;
[Cached]
private readonly SongPreviewParticleContainer particleContainer;
private readonly BeatmapRequestHandler requestHandler = new BeatmapRequestHandler();
public TestSceneRankedPlayCard()
{
base.Content.AddRange(new Drawable[]
{
new OsuContextMenuContainer
{
RelativeSizeAxes = Axes.Both,
Child = Content = new Container
{
RelativeSizeAxes = Axes.Both,
}
},
overlayContainer = new CardDetailsOverlayContainer(),
particleContainer = new SongPreviewParticleContainer(),
});
}
[Test]
public void TestCards()
{
AddStep("add cards", () =>
{
FillFlowContainer flow;
Child = flow = new FillFlowContainer
{
RelativeSizeAxes = Axes.Y,
Width = 800f,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Spacing = new Vector2(10),
};
for (int i = 0; i < 10; i++)
{
var beatmap = CreateAPIBeatmap();
beatmap.BeatmapSet!.Ratings = Enumerable.Range(0, 11).ToArray();
beatmap.BeatmapSet!.RelatedTags =
[
new APITag
{
Id = 2,
Name = "song representation/simple",
Description = "Accessible and straightforward map design."
},
new APITag
{
Id = 4,
Name = "style/clean",
Description = "Visually uncluttered and organised patterns, often involving few overlaps and equal visual spacing between objects."
},
new APITag
{
Id = 23,
Name = "aim/aim control",
Description = "Patterns with velocity or direction changes which strongly go against a player's natural movement pattern."
}
];
beatmap.TopTags =
[
new APIBeatmapTag { TagId = 4, VoteCount = 1 },
new APIBeatmapTag { TagId = 2, VoteCount = 1 },
new APIBeatmapTag { TagId = 23, VoteCount = 5 },
];
beatmap.FailTimes = new APIFailTimes
{
Fails = Enumerable.Range(1, 100).Select(x => x % 12 - 6).ToArray(),
Retries = Enumerable.Range(-2, 100).Select(x => x % 12 - 6).ToArray(),
};
beatmap.StarRating = i + 1;
flow.Add(new RankedPlayCardContent(beatmap)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(1.2f),
});
}
});
}
[Test]
public void TestCardHand()
{
AddStep("setup request handler", () => ((DummyAPIAccess)API).HandleRequest = requestHandler.HandleRequest);
AddStep("add cards", () =>
{
PlayerHandOfCards handOfCards;
Child = handOfCards = new PlayerHandOfCards
{
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.5f),
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
SelectionMode = HandSelectionMode.Single
};
foreach (var beatmap in requestHandler.Beatmaps)
{
handOfCards.AddCard(new RevealedRankedPlayCardWithPlaylistItem(beatmap));
}
});
}
[Resolved]
private RulesetStore rulesetStore { get; set; } = null!;
[Test]
public void TestRulesets()
{
var rulesets = rulesetStore.AvailableRulesets.Where(it => it.OnlineID >= 0);
foreach (var ruleset in rulesets)
{
AddStep(ruleset.ShortName, () =>
{
FillFlowContainer flow;
Child = flow = new FillFlowContainer
{
RelativeSizeAxes = Axes.Y,
Width = 800f,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Spacing = new Vector2(10),
};
for (int i = 0; i < 10; i++)
{
var beatmap = CreateAPIBeatmap(ruleset);
beatmap.BeatmapSet!.Ratings = Enumerable.Range(0, 11).ToArray();
beatmap.BeatmapSet!.RelatedTags =
[
new APITag
{
Id = 2,
Name = "song representation/simple",
Description = "Accessible and straightforward map design."
},
new APITag
{
Id = 4,
Name = "style/clean",
Description = "Visually uncluttered and organised patterns, often involving few overlaps and equal visual spacing between objects."
},
new APITag
{
Id = 23,
Name = "aim/aim control",
Description = "Patterns with velocity or direction changes which strongly go against a player's natural movement pattern."
}
];
beatmap.TopTags =
[
new APIBeatmapTag { TagId = 4, VoteCount = 1 },
new APIBeatmapTag { TagId = 2, VoteCount = 1 },
new APIBeatmapTag { TagId = 23, VoteCount = 5 },
];
beatmap.FailTimes = new APIFailTimes
{
Fails = Enumerable.Range(1, 100).Select(x => x % 12 - 6).ToArray(),
Retries = Enumerable.Range(-2, 100).Select(x => x % 12 - 6).ToArray(),
};
beatmap.StarRating = i + 1;
flow.Add(new RankedPlayCardContent(beatmap)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(1.2f),
});
}
});
}
}
}
}