1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-28 01:37:46 +08:00

Merge pull request #7834 from smoogipoo/match-songselect-playlist-logic

Add the ability to select multiple beatmaps in multiplayer song select
This commit is contained in:
Dean Herbert 2020-02-15 15:25:56 +09:00 committed by GitHub
commit ff3801b860
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 138 additions and 28 deletions

View File

@ -3,9 +3,19 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Utils;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu;
using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Multi.Components;
using osu.Game.Screens.Select; using osu.Game.Screens.Select;
@ -22,6 +32,72 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Resolved] [Resolved]
private BeatmapManager beatmapManager { get; set; } private BeatmapManager beatmapManager { get; set; }
private BeatmapManager manager;
private RulesetStore rulesets;
private TestMatchSongSelect songSelect;
[BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio)
{
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, Beatmap.Default));
var beatmaps = new List<BeatmapInfo>();
for (int i = 0; i < 6; i++)
{
int beatmapId = 10 * 10 + i;
int length = RNG.Next(30000, 200000);
double bpm = RNG.NextSingle(80, 200);
beatmaps.Add(new BeatmapInfo
{
Ruleset = new OsuRuleset().RulesetInfo,
OnlineBeatmapID = beatmapId,
Path = "normal.osu",
Version = $"{beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss}, bpm {bpm:0.#})",
Length = length,
BPM = bpm,
BaseDifficulty = new BeatmapDifficulty
{
OverallDifficulty = 3.5f,
},
});
}
manager.Import(new BeatmapSetInfo
{
OnlineBeatmapSetID = 10,
Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(),
Metadata = new BeatmapMetadata
{
// Create random metadata, then we can check if sorting works based on these
Artist = "Some Artist " + RNG.Next(0, 9),
Title = $"Some Song (set id 10), max bpm {beatmaps.Max(b => b.BPM):0.#})",
AuthorString = "Some Guy " + RNG.Next(0, 9),
},
Beatmaps = beatmaps,
DateAdded = DateTimeOffset.UtcNow,
}).Wait();
}
public override void SetUpSteps()
{
base.SetUpSteps();
AddStep("reset", () =>
{
Ruleset.Value = new OsuRuleset().RulesetInfo;
Beatmap.SetDefault();
});
AddStep("create song select", () => LoadScreen(songSelect = new TestMatchSongSelect()));
AddUntilStep("wait for present", () => songSelect.IsCurrentScreen());
}
[SetUp] [SetUp]
public void Setup() => Schedule(() => public void Setup() => Schedule(() =>
{ {
@ -29,9 +105,38 @@ namespace osu.Game.Tests.Visual.Multiplayer
}); });
[Test] [Test]
public void TestLoadSongSelect() public void TestItemAddedIfEmptyOnStart()
{ {
AddStep("create song select", () => LoadScreen(new MatchSongSelect())); AddStep("finalise selection", () => songSelect.FinaliseSelection());
AddAssert("playlist has 1 item", () => Room.Playlist.Count == 1);
}
[Test]
public void TestItemAddedWhenCreateNewItemClicked()
{
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem());
AddAssert("playlist has 1 item", () => Room.Playlist.Count == 1);
}
[Test]
public void TestItemNotAddedIfExistingOnStart()
{
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem());
AddStep("finalise selection", () => songSelect.FinaliseSelection());
AddAssert("playlist has 1 item", () => Room.Playlist.Count == 1);
}
[Test]
public void TestAddSameItemMultipleTimes()
{
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem());
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem());
AddAssert("playlist has 2 items", () => Room.Playlist.Count == 2);
}
private class TestMatchSongSelect : MatchSongSelect
{
public new MatchBeatmapDetailArea BeatmapDetails => (MatchBeatmapDetailArea)base.BeatmapDetails;
} }
} }
} }

View File

@ -164,8 +164,8 @@ namespace osu.Game.Screens.Multi.Match
{ {
base.LoadComplete(); base.LoadComplete();
Playlist.ItemsAdded += _ => updateSelectedItem(); Playlist.ItemsAdded += _ => Scheduler.AddOnce(updateSelectedItem);
Playlist.ItemsRemoved += _ => updateSelectedItem(); Playlist.ItemsRemoved += _ => Scheduler.AddOnce(updateSelectedItem);
updateSelectedItem(); updateSelectedItem();
} }

View File

@ -10,7 +10,6 @@ using osu.Framework.Graphics;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Multi; using osu.Game.Screens.Multi;
using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Multi.Components;
@ -36,42 +35,48 @@ namespace osu.Game.Screens.Select
Padding = new MarginPadding { Horizontal = HORIZONTAL_OVERFLOW_PADDING }; Padding = new MarginPadding { Horizontal = HORIZONTAL_OVERFLOW_PADDING };
} }
protected override BeatmapDetailArea CreateBeatmapDetailArea() => new MatchBeatmapDetailArea(); protected override BeatmapDetailArea CreateBeatmapDetailArea() => new MatchBeatmapDetailArea
{
CreateNewItem = createNewItem
};
protected override bool OnStart() protected override bool OnStart()
{ {
var item = new PlaylistItem switch (Playlist.Count)
{ {
Beatmap = { Value = Beatmap.Value.BeatmapInfo }, case 0:
Ruleset = { Value = Ruleset.Value }, createNewItem();
RulesetID = Ruleset.Value.ID ?? 0 break;
};
item.RequiredMods.AddRange(Mods.Value); case 1:
populateItemFromCurrent(Playlist.Single());
break;
}
Selected?.Invoke(item); this.Exit();
if (this.IsCurrentScreen())
this.Exit();
return true; return true;
} }
public override bool OnExiting(IScreen next) private void createNewItem()
{ {
if (base.OnExiting(next)) PlaylistItem item = new PlaylistItem
return true;
var firstItem = Playlist.FirstOrDefault();
if (firstItem != null)
{ {
Ruleset.Value = firstItem.Ruleset.Value; ID = (Playlist.LastOrDefault()?.ID + 1) ?? 0,
Beatmap.Value = beatmaps.GetWorkingBeatmap(firstItem.Beatmap.Value); };
Mods.Value = firstItem.RequiredMods?.ToArray() ?? Array.Empty<Mod>();
}
return false; populateItemFromCurrent(item);
Playlist.Add(item);
}
private void populateItemFromCurrent(PlaylistItem item)
{
item.Beatmap.Value = Beatmap.Value.BeatmapInfo;
item.Ruleset.Value = Ruleset.Value;
item.RequiredMods.Clear();
item.RequiredMods.AddRange(Mods.Value);
} }
} }
} }