1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 09:27:29 +08:00

Add support for picks and bans

This commit is contained in:
Dean Herbert 2018-11-08 06:29:04 +09:00
parent e4a767d656
commit 5c84c3c0a8
8 changed files with 232 additions and 38 deletions

View File

@ -18,7 +18,7 @@ namespace osu.Game.Tournament.Tests
Add(new OsuContextMenuContainer
{
RelativeSizeAxes = Axes.Both,
Child = manager = new LadderManager(Ladder)
Child = manager = new LadderManager()
});
}

View File

@ -1,7 +1,8 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Linq;
using System;
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Game.Tournament.Screens.MapPool;
@ -9,13 +10,15 @@ namespace osu.Game.Tournament.Tests
{
public class TestCaseMapPool : LadderTestCase
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(MapPoolScreen)
};
[BackgroundDependencyLoader]
private void load()
{
var round = Ladder.Groupings.FirstOrDefault(g => g.Name == "Finals");
if (round != null)
Add(new MapPoolScreen(round));
Add(new MapPoolScreen { Width = 0.7f });
}
}
}

View File

@ -1,7 +1,11 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -10,28 +14,35 @@ using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Tournament.Screens.Ladder.Components;
using OpenTK.Graphics;
namespace osu.Game.Tournament.Components
{
public class TournamentBeatmapPanel : CompositeDrawable
{
private readonly BeatmapInfo beatmap;
public readonly BeatmapInfo Beatmap;
private const float horizontal_padding = 10;
private const float vertical_padding = 5;
public const float HEIGHT = 50;
private readonly Bindable<MatchPairing> currentMatch = new Bindable<MatchPairing>();
public TournamentBeatmapPanel(BeatmapInfo beatmap)
{
this.beatmap = beatmap;
Beatmap = beatmap;
Width = 400;
Height = HEIGHT;
}
[BackgroundDependencyLoader]
private void load()
private void load(LadderInfo ladder)
{
currentMatch.BindValueChanged(matchChanged);
currentMatch.BindTo(ladder.CurrentMatch);
CornerRadius = 25;
Masking = true;
@ -46,7 +57,7 @@ namespace osu.Game.Tournament.Components
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(0.5f),
BeatmapSet = beatmap.BeatmapSet,
BeatmapSet = Beatmap.BeatmapSet,
},
new FillFlowContainer
{
@ -62,8 +73,8 @@ namespace osu.Game.Tournament.Components
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = new LocalisedString((
$"{beatmap.Metadata.ArtistUnicode} - {beatmap.Metadata.TitleUnicode}",
$"{beatmap.Metadata.Artist} - {beatmap.Metadata.Title}")),
$"{Beatmap.Metadata.ArtistUnicode} - {Beatmap.Metadata.TitleUnicode}",
$"{Beatmap.Metadata.Artist} - {Beatmap.Metadata.Title}")),
Font = @"Exo2.0-BoldItalic",
},
new FillFlowContainer
@ -84,7 +95,7 @@ namespace osu.Game.Tournament.Components
},
new OsuSpriteText
{
Text = beatmap.Metadata.AuthorString,
Text = Beatmap.Metadata.AuthorString,
Font = @"Exo2.0-BoldItalic",
Padding = new MarginPadding { Right = 20 },
TextSize = 14
@ -98,7 +109,7 @@ namespace osu.Game.Tournament.Components
},
new OsuSpriteText
{
Text = beatmap.Version,
Text = Beatmap.Version,
Font = @"Exo2.0-BoldItalic",
TextSize = 14
},
@ -108,5 +119,46 @@ namespace osu.Game.Tournament.Components
},
});
}
private void matchChanged(MatchPairing match)
{
match.PicksBans.CollectionChanged += picksBansOnCollectionChanged;
updateState();
}
private void updateState()
{
var found = currentMatch.Value.PicksBans.FirstOrDefault(p => p.BeatmapID == Beatmap.OnlineBeatmapID);
if (found != null)
{
switch (found.Team)
{
case TeamColour.Red:
Colour = Color4.Red;
break;
case TeamColour.Blue:
Colour = Color4.Blue;
break;
}
}
else
{
Colour = Color4.White;
}
}
private void picksBansOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
var list = (ObservableCollection<BeatmapChoice>)sender;
if (sender != currentMatch.Value.PicksBans)
{
// todo: we need a last attribute in bindable valuechanged events badly.
list.CollectionChanged -= picksBansOnCollectionChanged;
return;
}
updateState();
}
}
}

View File

@ -0,0 +1,24 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Tournament.Screens.Ladder.Components
{
public class BeatmapChoice
{
public TeamColour Team;
public ChoiceType Type;
public int BeatmapID;
}
public enum TeamColour
{
Red,
Blue
}
public enum ChoiceType
{
Pick,
Ban,
}
}

View File

@ -2,6 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.ObjectModel;
using Newtonsoft.Json;
using osu.Framework.Configuration;
using osu.Game.Tournament.Components;
@ -34,6 +35,8 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
public readonly Bindable<bool> Losers = new Bindable<bool>();
public readonly ObservableCollection<BeatmapChoice> PicksBans = new ObservableCollection<BeatmapChoice>();
[JsonIgnore]
public readonly Bindable<TournamentGrouping> Grouping = new Bindable<TournamentGrouping>();
@ -58,7 +61,8 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
Team2.BindValueChanged(t => Team2Acronym = t?.Acronym, true);
}
public MatchPairing(TournamentTeam team1 = null, TournamentTeam team2 = null) : this()
public MatchPairing(TournamentTeam team1 = null, TournamentTeam team2 = null)
: this()
{
Team1.Value = team1;
Team2.Value = team2;

View File

@ -26,20 +26,24 @@ namespace osu.Game.Tournament.Screens.Ladder
[Cached]
public class LadderManager : CompositeDrawable, IHasContextMenu
{
public readonly List<TournamentTeam> Teams;
private readonly Container<DrawableMatchPairing> pairingsContainer;
private readonly Container<Path> paths;
private readonly Container headings;
public List<TournamentTeam> Teams;
private Container<DrawableMatchPairing> pairingsContainer;
private Container<Path> paths;
private Container headings;
private readonly LadderInfo info;
private LadderInfo info;
private readonly ScrollableContainer scrollContent;
private ScrollableContainer scrollContent;
[Cached]
private readonly LadderEditorInfo editorInfo = new LadderEditorInfo();
private LadderEditorInfo editorInfo = new LadderEditorInfo();
public LadderManager(LadderInfo info)
[BackgroundDependencyLoader]
private void load(LadderInfo info, OsuColour colours)
{
normalPathColour = colours.BlueDarker.Darken(2);
losersPathColour = colours.YellowDarker.Darken(2);
this.info = info;
editorInfo.Teams = Teams = info.Teams;
editorInfo.Groupings = info.Groupings;
@ -128,13 +132,6 @@ namespace osu.Game.Tournament.Screens.Ladder
private Color4 normalPathColour;
private Color4 losersPathColour;
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
normalPathColour = colours.BlueDarker.Darken(2);
losersPathColour = colours.YellowDarker.Darken(2);
}
private void updateLayout()
{
paths.Clear();

View File

@ -1,33 +1,148 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens;
using osu.Game.Tournament.Components;
using osu.Game.Tournament.Screens.Ladder.Components;
using OpenTK;
using OpenTK.Input;
namespace osu.Game.Tournament.Screens.MapPool
{
public class MapPoolScreen : OsuScreen
{
public MapPoolScreen(TournamentGrouping round)
{
FillFlowContainer maps;
private readonly FillFlowContainer<TournamentBeatmapPanel> maps;
private readonly Bindable<MatchPairing> currentMatch = new Bindable<MatchPairing>();
public MapPoolScreen()
{
InternalChildren = new Drawable[]
{
maps = new FillFlowContainer
maps = new FillFlowContainer<TournamentBeatmapPanel>
{
Spacing = new Vector2(20),
Padding = new MarginPadding(50),
Direction = FillDirection.Full,
RelativeSizeAxes = Axes.Both,
},
new ControlPanel
{
Children = new Drawable[]
{
new OsuSpriteText
{
Text = "Current Mode"
},
buttonRedBan = new TriangleButton
{
RelativeSizeAxes = Axes.X,
Text = "Red Ban",
Action = () => setMode(TeamColour.Red, ChoiceType.Ban)
},
buttonBlueBan = new TriangleButton
{
RelativeSizeAxes = Axes.X,
Text = "Blue Ban",
Action = () => setMode(TeamColour.Blue, ChoiceType.Ban)
},
buttonRedPick = new TriangleButton
{
RelativeSizeAxes = Axes.X,
Text = "Red Pick",
Action = () => setMode(TeamColour.Red, ChoiceType.Pick)
},
buttonBluePick = new TriangleButton
{
RelativeSizeAxes = Axes.X,
Text = "Blue Pick",
Action = () => setMode(TeamColour.Blue, ChoiceType.Pick)
}
}
}
};
}
foreach (var b in round.Beatmaps)
private TeamColour pickColour;
private ChoiceType pickType;
private readonly TriangleButton buttonRedBan;
private readonly TriangleButton buttonBlueBan;
private readonly TriangleButton buttonRedPick;
private readonly TriangleButton buttonBluePick;
private void setMode(TeamColour colour, ChoiceType choiceType)
{
pickColour = colour;
pickType = choiceType;
var enabled = currentMatch.Value.PicksBans.Count == 0;
buttonRedBan.Enabled.Value = enabled || pickColour == TeamColour.Red && pickType == ChoiceType.Ban;
buttonBlueBan.Enabled.Value = enabled || pickColour == TeamColour.Blue && pickType == ChoiceType.Ban;
buttonRedPick.Enabled.Value = enabled || pickColour == TeamColour.Red && pickType == ChoiceType.Pick;
buttonBluePick.Enabled.Value = enabled || pickColour == TeamColour.Blue && pickType == ChoiceType.Pick;
}
private void setNextMode()
{
const TeamColour roll_winner = TeamColour.Red; //todo: draw from match
var nextColour = (currentMatch.Value.PicksBans.LastOrDefault()?.Team ?? roll_winner) == TeamColour.Red ? TeamColour.Blue : TeamColour.Red;
setMode(nextColour, currentMatch.Value.PicksBans.Count(p => p.Type == ChoiceType.Ban) >= 2 ? ChoiceType.Pick : ChoiceType.Ban);
}
protected override bool OnMouseDown(MouseDownEvent e)
{
var map = maps.FirstOrDefault(m => m.ReceivePositionalInputAt(e.ScreenSpaceMousePosition));
if (map != null)
{
if (e.Button == MouseButton.Left)
{
currentMatch.Value.PicksBans.Add(new BeatmapChoice
{
Team = pickColour,
Type = pickType,
BeatmapID = map.Beatmap.OnlineBeatmapID ?? -1
});
setNextMode();
}
else
{
var existing = currentMatch.Value.PicksBans.FirstOrDefault(p => p.BeatmapID == map.Beatmap.OnlineBeatmapID);
if (existing != null)
{
currentMatch.Value.PicksBans.Remove(existing);
setNextMode();
}
}
return true;
}
return base.OnMouseDown(e);
}
[BackgroundDependencyLoader]
private void load(LadderInfo ladder)
{
currentMatch.BindValueChanged(matchChanged);
currentMatch.BindTo(ladder.CurrentMatch);
}
private void matchChanged(MatchPairing match)
{
foreach (var b in match.Grouping.Value.Beatmaps)
maps.Add(new TournamentBeatmapPanel(b.BeatmapInfo)
{
Anchor = Anchor.TopCentre,

View File

@ -1,7 +1,6 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -88,9 +87,9 @@ namespace osu.Game.Tournament.Screens
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
bracket = new LadderManager(ladder),
bracket = new LadderManager(),
showcase = new ShowcaseScreen(),
mapPool = new MapPoolScreen(ladder.Groupings.First(g => g.Name == "Finals")),
mapPool = new MapPoolScreen(),
teamIntro = new TeamIntroScreen(),
drawings = new DrawingsScreen(),
gameplay = new GameplayScreen()