mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 10:33:30 +08:00
Merge pull request #25598 from rodrigopina360/tournament-ban-count
Add ban count option to round editor
This commit is contained in:
commit
2a3761fb29
@ -9,6 +9,8 @@ using osu.Framework.Testing;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osu.Game.Tournament.Screens.MapPool;
|
||||
using osuTK;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Screens
|
||||
{
|
||||
@ -19,11 +21,28 @@ namespace osu.Game.Tournament.Tests.Screens
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Add(screen = new MapPoolScreen { Width = 0.7f });
|
||||
Add(screen = new TestMapPoolScreen { Width = 0.7f });
|
||||
}
|
||||
|
||||
[SetUpSteps]
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
AddStep("reset state", resetState);
|
||||
}
|
||||
|
||||
private void resetState()
|
||||
{
|
||||
Ladder.SplitMapPoolByMods.Value = true;
|
||||
|
||||
Ladder.CurrentMatch.Value = new TournamentMatch();
|
||||
Ladder.CurrentMatch.Value = Ladder.Matches.First();
|
||||
Ladder.CurrentMatch.Value.PicksBans.Clear();
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void SetUp() => Schedule(() => Ladder.SplitMapPoolByMods.Value = true);
|
||||
public void SetUp() => Schedule(() =>
|
||||
{
|
||||
});
|
||||
|
||||
[Test]
|
||||
public void TestFewMaps()
|
||||
@ -39,7 +58,6 @@ namespace osu.Game.Tournament.Tests.Screens
|
||||
AddStep("reset match", () =>
|
||||
{
|
||||
Ladder.CurrentMatch.Value = new TournamentMatch();
|
||||
Ladder.CurrentMatch.Value = Ladder.Matches.First();
|
||||
});
|
||||
|
||||
assertTwoWide();
|
||||
@ -56,11 +74,7 @@ namespace osu.Game.Tournament.Tests.Screens
|
||||
addBeatmap();
|
||||
});
|
||||
|
||||
AddStep("reset match", () =>
|
||||
{
|
||||
Ladder.CurrentMatch.Value = new TournamentMatch();
|
||||
Ladder.CurrentMatch.Value = Ladder.Matches.First();
|
||||
});
|
||||
AddStep("reset state", resetState);
|
||||
|
||||
assertTwoWide();
|
||||
}
|
||||
@ -76,11 +90,7 @@ namespace osu.Game.Tournament.Tests.Screens
|
||||
addBeatmap();
|
||||
});
|
||||
|
||||
AddStep("reset match", () =>
|
||||
{
|
||||
Ladder.CurrentMatch.Value = new TournamentMatch();
|
||||
Ladder.CurrentMatch.Value = Ladder.Matches.First();
|
||||
});
|
||||
AddStep("reset state", resetState);
|
||||
|
||||
assertThreeWide();
|
||||
}
|
||||
@ -96,11 +106,7 @@ namespace osu.Game.Tournament.Tests.Screens
|
||||
addBeatmap(i > 4 ? Ruleset.Value.CreateInstance().AllMods.ElementAt(i).Acronym : "NM");
|
||||
});
|
||||
|
||||
AddStep("reset match", () =>
|
||||
{
|
||||
Ladder.CurrentMatch.Value = new TournamentMatch();
|
||||
Ladder.CurrentMatch.Value = Ladder.Matches.First();
|
||||
});
|
||||
AddStep("reset state", resetState);
|
||||
|
||||
assertTwoWide();
|
||||
}
|
||||
@ -122,11 +128,7 @@ namespace osu.Game.Tournament.Tests.Screens
|
||||
addBeatmap(i > 4 ? Ruleset.Value.CreateInstance().AllMods.ElementAt(i).Acronym : "NM");
|
||||
});
|
||||
|
||||
AddStep("reset match", () =>
|
||||
{
|
||||
Ladder.CurrentMatch.Value = new TournamentMatch();
|
||||
Ladder.CurrentMatch.Value = Ladder.Matches.First();
|
||||
});
|
||||
AddStep("reset state", resetState);
|
||||
|
||||
assertThreeWide();
|
||||
}
|
||||
@ -144,13 +146,190 @@ namespace osu.Game.Tournament.Tests.Screens
|
||||
|
||||
AddStep("disable splitting map pool by mods", () => Ladder.SplitMapPoolByMods.Value = false);
|
||||
|
||||
AddStep("reset state", resetState);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBanOrderMultipleBans()
|
||||
{
|
||||
AddStep("set ban count", () => Ladder.CurrentMatch.Value!.Round.Value!.BanCount.Value = 2);
|
||||
|
||||
AddStep("load some maps", () =>
|
||||
{
|
||||
Ladder.CurrentMatch.Value!.Round.Value!.Beatmaps.Clear();
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
addBeatmap();
|
||||
});
|
||||
|
||||
AddStep("update displayed maps", () => Ladder.SplitMapPoolByMods.Value = false);
|
||||
|
||||
AddStep("start bans from blue team", () => screen.ChildrenOfType<TourneyButton>().First(btn => btn.Text == "Blue Ban").TriggerClick());
|
||||
|
||||
AddStep("ban map", () => clickBeatmapPanel(0));
|
||||
checkTotalPickBans(1);
|
||||
checkLastPick(ChoiceType.Ban, TeamColour.Blue);
|
||||
|
||||
AddStep("ban map", () => clickBeatmapPanel(1));
|
||||
checkTotalPickBans(2);
|
||||
checkLastPick(ChoiceType.Ban, TeamColour.Red);
|
||||
|
||||
AddStep("ban map", () => clickBeatmapPanel(2));
|
||||
checkTotalPickBans(3);
|
||||
checkLastPick(ChoiceType.Ban, TeamColour.Red);
|
||||
|
||||
AddStep("pick map", () => clickBeatmapPanel(3));
|
||||
checkTotalPickBans(4);
|
||||
checkLastPick(ChoiceType.Ban, TeamColour.Blue);
|
||||
|
||||
AddStep("pick map", () => clickBeatmapPanel(4));
|
||||
checkTotalPickBans(5);
|
||||
checkLastPick(ChoiceType.Pick, TeamColour.Blue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestPickBanOrder()
|
||||
{
|
||||
AddStep("set ban count", () => Ladder.CurrentMatch.Value!.Round.Value!.BanCount.Value = 1);
|
||||
|
||||
AddStep("load some maps", () =>
|
||||
{
|
||||
Ladder.CurrentMatch.Value!.Round.Value!.Beatmaps.Clear();
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
addBeatmap();
|
||||
});
|
||||
|
||||
AddStep("update displayed maps", () => Ladder.SplitMapPoolByMods.Value = false);
|
||||
|
||||
AddStep("start bans from blue team", () => screen.ChildrenOfType<TourneyButton>().First(btn => btn.Text == "Blue Ban").TriggerClick());
|
||||
|
||||
AddStep("ban map", () => clickBeatmapPanel(0));
|
||||
checkTotalPickBans(1);
|
||||
checkLastPick(ChoiceType.Ban, TeamColour.Blue);
|
||||
|
||||
AddStep("ban map", () => clickBeatmapPanel(1));
|
||||
checkTotalPickBans(2);
|
||||
checkLastPick(ChoiceType.Ban, TeamColour.Red);
|
||||
|
||||
AddStep("pick map", () => clickBeatmapPanel(2));
|
||||
checkTotalPickBans(3);
|
||||
checkLastPick(ChoiceType.Pick, TeamColour.Red);
|
||||
|
||||
AddStep("pick map", () => clickBeatmapPanel(3));
|
||||
checkTotalPickBans(4);
|
||||
checkLastPick(ChoiceType.Pick, TeamColour.Blue);
|
||||
|
||||
AddStep("pick map", () => clickBeatmapPanel(4));
|
||||
checkTotalPickBans(5);
|
||||
checkLastPick(ChoiceType.Pick, TeamColour.Red);
|
||||
|
||||
AddStep("reset match", () =>
|
||||
{
|
||||
Ladder.CurrentMatch.Value = new TournamentMatch();
|
||||
Ladder.CurrentMatch.Value = Ladder.Matches.First();
|
||||
Ladder.CurrentMatch.Value.PicksBans.Clear();
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMultipleTeamBans()
|
||||
{
|
||||
AddStep("set ban count", () => Ladder.CurrentMatch.Value!.Round.Value!.BanCount.Value = 3);
|
||||
|
||||
AddStep("load some maps", () =>
|
||||
{
|
||||
Ladder.CurrentMatch.Value!.Round.Value!.Beatmaps.Clear();
|
||||
|
||||
for (int i = 0; i < 12; i++)
|
||||
addBeatmap();
|
||||
});
|
||||
|
||||
AddStep("update displayed maps", () => Ladder.SplitMapPoolByMods.Value = false);
|
||||
|
||||
AddStep("start bans with red team", () => screen.ChildrenOfType<TourneyButton>().First(btn => btn.Text == "Red Ban").TriggerClick());
|
||||
|
||||
AddStep("first ban", () => clickBeatmapPanel(0));
|
||||
AddAssert("red ban registered",
|
||||
() => Ladder.CurrentMatch.Value!.PicksBans.Count(pb => pb.Type == ChoiceType.Ban && pb.Team == TeamColour.Red),
|
||||
() => Is.EqualTo(1));
|
||||
|
||||
AddStep("ban two more maps", () =>
|
||||
{
|
||||
clickBeatmapPanel(1);
|
||||
clickBeatmapPanel(2);
|
||||
});
|
||||
|
||||
AddAssert("three bans registered",
|
||||
() => Ladder.CurrentMatch.Value!.PicksBans.Count(pb => pb.Type == ChoiceType.Ban),
|
||||
() => Is.EqualTo(3));
|
||||
AddAssert("both new bans for blue team",
|
||||
() => Ladder.CurrentMatch.Value!.PicksBans.Count(pb => pb.Type == ChoiceType.Ban && pb.Team == TeamColour.Blue),
|
||||
() => Is.EqualTo(2));
|
||||
|
||||
AddStep("ban two more maps", () =>
|
||||
{
|
||||
clickBeatmapPanel(3);
|
||||
clickBeatmapPanel(4);
|
||||
});
|
||||
|
||||
AddAssert("five bans registered",
|
||||
() => Ladder.CurrentMatch.Value!.PicksBans.Count(pb => pb.Type == ChoiceType.Ban),
|
||||
() => Is.EqualTo(5));
|
||||
AddAssert("both new bans for red team",
|
||||
() => Ladder.CurrentMatch.Value!.PicksBans.Count(pb => pb.Type == ChoiceType.Ban && pb.Team == TeamColour.Red),
|
||||
() => Is.EqualTo(3));
|
||||
|
||||
AddStep("ban last map", () => clickBeatmapPanel(5));
|
||||
AddAssert("six bans registered",
|
||||
() => Ladder.CurrentMatch.Value!.PicksBans.Count(pb => pb.Type == ChoiceType.Ban),
|
||||
() => Is.EqualTo(6));
|
||||
AddAssert("red banned three",
|
||||
() => Ladder.CurrentMatch.Value!.PicksBans.Count(pb => pb.Type == ChoiceType.Ban && pb.Team == TeamColour.Red),
|
||||
() => Is.EqualTo(3));
|
||||
AddAssert("blue banned three",
|
||||
() => Ladder.CurrentMatch.Value!.PicksBans.Count(pb => pb.Type == ChoiceType.Ban && pb.Team == TeamColour.Blue),
|
||||
() => Is.EqualTo(3));
|
||||
|
||||
AddStep("pick map", () => clickBeatmapPanel(6));
|
||||
AddAssert("one pick registered",
|
||||
() => Ladder.CurrentMatch.Value!.PicksBans.Count(pb => pb.Type == ChoiceType.Pick),
|
||||
() => Is.EqualTo(1));
|
||||
AddAssert("pick was blue's",
|
||||
() => Ladder.CurrentMatch.Value!.PicksBans.Last().Team,
|
||||
() => Is.EqualTo(TeamColour.Blue));
|
||||
|
||||
AddStep("pick map", () => clickBeatmapPanel(7));
|
||||
AddAssert("two picks registered",
|
||||
() => Ladder.CurrentMatch.Value!.PicksBans.Count(pb => pb.Type == ChoiceType.Pick),
|
||||
() => Is.EqualTo(2));
|
||||
AddAssert("pick was red's",
|
||||
() => Ladder.CurrentMatch.Value!.PicksBans.Last().Team,
|
||||
() => Is.EqualTo(TeamColour.Red));
|
||||
|
||||
AddStep("pick map", () => clickBeatmapPanel(8));
|
||||
AddAssert("three picks registered",
|
||||
() => Ladder.CurrentMatch.Value!.PicksBans.Count(pb => pb.Type == ChoiceType.Pick),
|
||||
() => Is.EqualTo(3));
|
||||
AddAssert("pick was blue's",
|
||||
() => Ladder.CurrentMatch.Value!.PicksBans.Last().Team,
|
||||
() => Is.EqualTo(TeamColour.Blue));
|
||||
|
||||
AddStep("reset match", () =>
|
||||
{
|
||||
Ladder.CurrentMatch.Value = new TournamentMatch();
|
||||
Ladder.CurrentMatch.Value = Ladder.Matches.First();
|
||||
Ladder.CurrentMatch.Value.PicksBans.Clear();
|
||||
});
|
||||
}
|
||||
|
||||
private void checkTotalPickBans(int expected) => AddAssert($"total pickbans is {expected}", () => Ladder.CurrentMatch.Value!.PicksBans, () => Has.Count.EqualTo(expected));
|
||||
|
||||
private void checkLastPick(ChoiceType expectedChoice, TeamColour expectedColour) =>
|
||||
AddAssert($"last choice was {expectedChoice} by {expectedColour}",
|
||||
() => Ladder.CurrentMatch.Value!.PicksBans.Select(pb => (pb.Type, pb.Team)).Last(),
|
||||
() => Is.EqualTo((expectedChoice, expectedColour)));
|
||||
|
||||
private void addBeatmap(string mods = "NM")
|
||||
{
|
||||
Ladder.CurrentMatch.Value!.Round.Value!.Beatmaps.Add(new RoundBeatmap
|
||||
@ -159,5 +338,22 @@ namespace osu.Game.Tournament.Tests.Screens
|
||||
Mods = mods
|
||||
});
|
||||
}
|
||||
|
||||
private void clickBeatmapPanel(int index)
|
||||
{
|
||||
InputManager.MoveMouseTo(screen.ChildrenOfType<TournamentBeatmapPanel>().ElementAt(index));
|
||||
InputManager.Click(MouseButton.Left);
|
||||
}
|
||||
|
||||
private partial class TestMapPoolScreen : MapPoolScreen
|
||||
{
|
||||
// this is a bit of a test-specific workaround.
|
||||
// the way pick/ban is implemented is a bit funky; the screen itself is what handles the mouse there,
|
||||
// rather than the beatmap panels themselves.
|
||||
// in some extreme situations headless it may turn out that the panels overflow the screen,
|
||||
// and as such picking stops working anymore outside of the bounds of the screen drawable.
|
||||
// this override makes it so the screen sees all of the input at all times, making that impossible to happen.
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ namespace osu.Game.Tournament.Models
|
||||
public readonly Bindable<string> Description = new Bindable<string>(string.Empty);
|
||||
|
||||
public readonly BindableInt BestOf = new BindableInt(9) { Default = 9, MinValue = 3, MaxValue = 23 };
|
||||
public readonly BindableInt BanCount = new BindableInt(1) { Default = 1, MinValue = 0, MaxValue = 5 };
|
||||
|
||||
[JsonProperty]
|
||||
public readonly BindableList<RoundBeatmap> Beatmaps = new BindableList<RoundBeatmap>();
|
||||
|
@ -82,6 +82,12 @@ namespace osu.Game.Tournament.Screens.Editors
|
||||
Current = Model.StartDate
|
||||
},
|
||||
new SettingsSlider<int>
|
||||
{
|
||||
LabelText = "# of Bans",
|
||||
Width = 0.33f,
|
||||
Current = Model.BanCount
|
||||
},
|
||||
new SettingsSlider<int>
|
||||
{
|
||||
LabelText = "Best of",
|
||||
Width = 0.33f,
|
||||
|
@ -136,27 +136,45 @@ namespace osu.Game.Tournament.Screens.MapPool
|
||||
pickColour = colour;
|
||||
pickType = choiceType;
|
||||
|
||||
static Color4 setColour(bool active) => active ? Color4.White : Color4.Gray;
|
||||
|
||||
buttonRedBan.Colour = setColour(pickColour == TeamColour.Red && pickType == ChoiceType.Ban);
|
||||
buttonBlueBan.Colour = setColour(pickColour == TeamColour.Blue && pickType == ChoiceType.Ban);
|
||||
buttonRedPick.Colour = setColour(pickColour == TeamColour.Red && pickType == ChoiceType.Pick);
|
||||
buttonBluePick.Colour = setColour(pickColour == TeamColour.Blue && pickType == ChoiceType.Pick);
|
||||
|
||||
static Color4 setColour(bool active) => active ? Color4.White : Color4.Gray;
|
||||
}
|
||||
|
||||
private void setNextMode()
|
||||
{
|
||||
if (CurrentMatch.Value == null)
|
||||
if (CurrentMatch.Value?.Round.Value == null)
|
||||
return;
|
||||
|
||||
const TeamColour roll_winner = TeamColour.Red; //todo: draw from match
|
||||
int totalBansRequired = CurrentMatch.Value.Round.Value.BanCount.Value * 2;
|
||||
|
||||
var nextColour = (CurrentMatch.Value.PicksBans.LastOrDefault()?.Team ?? roll_winner) == TeamColour.Red ? TeamColour.Blue : TeamColour.Red;
|
||||
TeamColour lastPickColour = CurrentMatch.Value.PicksBans.LastOrDefault()?.Team ?? TeamColour.Red;
|
||||
|
||||
if (pickType == ChoiceType.Ban && CurrentMatch.Value.PicksBans.Count(p => p.Type == ChoiceType.Ban) >= 2)
|
||||
setMode(pickColour, ChoiceType.Pick);
|
||||
TeamColour nextColour;
|
||||
|
||||
bool hasAllBans = CurrentMatch.Value.PicksBans.Count(p => p.Type == ChoiceType.Ban) >= totalBansRequired;
|
||||
|
||||
if (!hasAllBans)
|
||||
{
|
||||
// Ban phase: switch teams every second ban.
|
||||
nextColour = CurrentMatch.Value.PicksBans.Count % 2 == 1
|
||||
? getOppositeTeamColour(lastPickColour)
|
||||
: lastPickColour;
|
||||
}
|
||||
else
|
||||
setMode(nextColour, CurrentMatch.Value.PicksBans.Count(p => p.Type == ChoiceType.Ban) >= 2 ? ChoiceType.Pick : ChoiceType.Ban);
|
||||
{
|
||||
// Pick phase : switch teams every pick, except for the first pick which generally goes to the team that placed the last ban.
|
||||
nextColour = pickType == ChoiceType.Pick
|
||||
? getOppositeTeamColour(lastPickColour)
|
||||
: lastPickColour;
|
||||
}
|
||||
|
||||
setMode(nextColour, hasAllBans ? ChoiceType.Pick : ChoiceType.Ban);
|
||||
|
||||
TeamColour getOppositeTeamColour(TeamColour colour) => colour == TeamColour.Red ? TeamColour.Blue : TeamColour.Red;
|
||||
}
|
||||
|
||||
protected override bool OnMouseDown(MouseDownEvent e)
|
||||
|
Loading…
Reference in New Issue
Block a user