mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 04:43:22 +08:00
Merge branch 'master' into profile-header-update
This commit is contained in:
commit
01f6199c49
@ -15,12 +15,16 @@ using Microsoft.Win32;
|
||||
using osu.Desktop.Updater;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Platform.Windows;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Screens;
|
||||
using osu.Game.Screens.Menu;
|
||||
|
||||
namespace osu.Desktop
|
||||
{
|
||||
internal class OsuGameDesktop : OsuGame
|
||||
{
|
||||
private readonly bool noVersionOverlay;
|
||||
private VersionManager versionManager;
|
||||
|
||||
public OsuGameDesktop(string[] args = null)
|
||||
: base(args)
|
||||
@ -46,7 +50,7 @@ namespace osu.Desktop
|
||||
|
||||
if (!noVersionOverlay)
|
||||
{
|
||||
LoadComponentAsync(new VersionManager { Depth = int.MinValue }, v =>
|
||||
LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, v =>
|
||||
{
|
||||
Add(v);
|
||||
v.State = Visibility.Visible;
|
||||
@ -59,6 +63,23 @@ namespace osu.Desktop
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ScreenChanged(OsuScreen current, Screen newScreen)
|
||||
{
|
||||
base.ScreenChanged(current, newScreen);
|
||||
switch (newScreen)
|
||||
{
|
||||
case Intro _:
|
||||
case MainMenu _:
|
||||
if (versionManager != null)
|
||||
versionManager.State = Visibility.Visible;
|
||||
break;
|
||||
default:
|
||||
if (versionManager != null)
|
||||
versionManager.State = Visibility.Hidden;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetHost(GameHost host)
|
||||
{
|
||||
base.SetHost(host);
|
||||
|
@ -128,11 +128,12 @@ namespace osu.Desktop.Overlays
|
||||
|
||||
protected override void PopIn()
|
||||
{
|
||||
this.FadeIn(1000);
|
||||
this.FadeIn(1400, Easing.OutQuint);
|
||||
}
|
||||
|
||||
protected override void PopOut()
|
||||
{
|
||||
this.FadeOut(500, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
23
osu.Game.Rulesets.Catch/Objects/CatchHitWindows.cs
Normal file
23
osu.Game.Rulesets.Catch/Objects/CatchHitWindows.cs
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Objects
|
||||
{
|
||||
public class CatchHitWindows : HitWindows
|
||||
{
|
||||
public override bool IsHitResultAllowed(HitResult result)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case HitResult.Perfect:
|
||||
case HitResult.Miss:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ using System;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
@ -41,5 +42,7 @@ namespace osu.Game.Rulesets.Catch.Scoring
|
||||
|
||||
Health.Value += Math.Max(result.Judgement.HealthIncreaseFor(result) - hpDrainRate, 0) * harshness;
|
||||
}
|
||||
|
||||
protected override HitWindows CreateHitWindows() => new CatchHitWindows();
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mania.Judgements;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
@ -157,5 +158,7 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override HitWindows CreateHitWindows() => new ManiaHitWindows();
|
||||
}
|
||||
}
|
||||
|
@ -123,8 +123,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
||||
|
||||
if (mods.Any(h => h is OsuModFlashlight))
|
||||
{
|
||||
// Apply length bonus again if flashlight is on simply because it becomes a lot harder on longer maps.
|
||||
aimValue *= 1.45f * lengthBonus;
|
||||
// Apply object-based bonus for flashlight.
|
||||
aimValue *= 1.0f + 0.35f * Math.Min(1.0f, totalHits / 200.0f) +
|
||||
(totalHits > 200 ? 0.3f * Math.Min(1.0f, (totalHits - 200) / 300.0f) +
|
||||
(totalHits > 500 ? (totalHits - 500) / 1200.0f : 0.0f) : 0.0f);
|
||||
}
|
||||
|
||||
// Scale the aim value with accuracy _slightly_
|
||||
|
@ -7,6 +7,7 @@ using osu.Game.Rulesets.Objects.Types;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using System.Linq;
|
||||
using osu.Framework.Caching;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Beatmaps;
|
||||
@ -26,8 +27,11 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity;
|
||||
public double Duration => EndTime - StartTime;
|
||||
|
||||
private Cached<Vector2> endPositionCache;
|
||||
|
||||
public override Vector2 EndPosition => endPositionCache.IsValid ? endPositionCache.Value : endPositionCache.Value = Position + this.CurvePositionAt(1);
|
||||
|
||||
public Vector2 StackedPositionAt(double t) => StackedPosition + this.CurvePositionAt(t);
|
||||
public override Vector2 EndPosition => Position + this.CurvePositionAt(1);
|
||||
|
||||
public override int ComboIndex
|
||||
{
|
||||
@ -56,7 +60,11 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
public SliderPath Path
|
||||
{
|
||||
get => PathBindable.Value;
|
||||
set => PathBindable.Value = value;
|
||||
set
|
||||
{
|
||||
PathBindable.Value = value;
|
||||
endPositionCache.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public double Distance => Path.Distance;
|
||||
@ -73,6 +81,8 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
|
||||
if (TailCircle != null)
|
||||
TailCircle.Position = EndPosition;
|
||||
|
||||
endPositionCache.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,7 +102,17 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
|
||||
public List<List<SampleInfo>> NodeSamples { get; set; } = new List<List<SampleInfo>>();
|
||||
|
||||
public int RepeatCount { get; set; }
|
||||
private int repeatCount;
|
||||
|
||||
public int RepeatCount
|
||||
{
|
||||
get => repeatCount;
|
||||
set
|
||||
{
|
||||
repeatCount = value;
|
||||
endPositionCache.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The length of one span of this <see cref="Slider"/>.
|
||||
@ -169,7 +189,11 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
|
||||
private void createTicks()
|
||||
{
|
||||
var length = Path.Distance;
|
||||
// A very lenient maximum length of a slider for ticks to be generated.
|
||||
// This exists for edge cases such as /b/1573664 where the beatmap has been edited by the user, and should never be reached in normal usage.
|
||||
const double max_length = 100000;
|
||||
|
||||
var length = Math.Min(max_length, Path.Distance);
|
||||
var tickDistance = MathHelper.Clamp(TickDistance, 0, length);
|
||||
|
||||
if (tickDistance == 0) return;
|
||||
|
@ -5,11 +5,11 @@ using System.Collections.Generic;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu.Judgements;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Scoring
|
||||
{
|
||||
@ -22,7 +22,6 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
||||
|
||||
private float hpDrainRate;
|
||||
|
||||
private readonly Dictionary<HitResult, int> scoreResultCounts = new Dictionary<HitResult, int>();
|
||||
private readonly Dictionary<ComboResult, int> comboResultCounts = new Dictionary<ComboResult, int>();
|
||||
|
||||
protected override void ApplyBeatmap(Beatmap<OsuHitObject> beatmap)
|
||||
@ -35,21 +34,9 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
||||
protected override void Reset(bool storeResults)
|
||||
{
|
||||
base.Reset(storeResults);
|
||||
|
||||
scoreResultCounts.Clear();
|
||||
comboResultCounts.Clear();
|
||||
}
|
||||
|
||||
public override void PopulateScore(ScoreInfo score)
|
||||
{
|
||||
base.PopulateScore(score);
|
||||
|
||||
score.Statistics[HitResult.Great] = scoreResultCounts.GetOrDefault(HitResult.Great);
|
||||
score.Statistics[HitResult.Good] = scoreResultCounts.GetOrDefault(HitResult.Good);
|
||||
score.Statistics[HitResult.Meh] = scoreResultCounts.GetOrDefault(HitResult.Meh);
|
||||
score.Statistics[HitResult.Miss] = scoreResultCounts.GetOrDefault(HitResult.Miss);
|
||||
}
|
||||
|
||||
private const double harshness = 0.01;
|
||||
|
||||
protected override void ApplyResult(JudgementResult result)
|
||||
@ -59,10 +46,7 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
||||
var osuResult = (OsuJudgementResult)result;
|
||||
|
||||
if (result.Type != HitResult.None)
|
||||
{
|
||||
scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1;
|
||||
comboResultCounts[osuResult.ComboType] = comboResultCounts.GetOrDefault(osuResult.ComboType) + 1;
|
||||
}
|
||||
|
||||
switch (result.Type)
|
||||
{
|
||||
@ -89,5 +73,7 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
||||
}
|
||||
|
||||
protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(judgement);
|
||||
|
||||
protected override HitWindows CreateHitWindows() => new OsuHitWindows();
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.Taiko.Objects;
|
||||
using osu.Game.Rulesets.UI;
|
||||
@ -65,5 +66,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
||||
|
||||
Health.Value = 0;
|
||||
}
|
||||
|
||||
protected override HitWindows CreateHitWindows() => new TaikoHitWindows();
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
{
|
||||
try
|
||||
{
|
||||
loadOszIntoOsu(loadOsu(host));
|
||||
LoadOszIntoOsu(loadOsu(host));
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -48,7 +48,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
{
|
||||
var osu = loadOsu(host);
|
||||
|
||||
var imported = loadOszIntoOsu(osu);
|
||||
var imported = LoadOszIntoOsu(osu);
|
||||
|
||||
deleteBeatmapSet(imported, osu);
|
||||
}
|
||||
@ -69,8 +69,8 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
{
|
||||
var osu = loadOsu(host);
|
||||
|
||||
var imported = loadOszIntoOsu(osu);
|
||||
var importedSecondTime = loadOszIntoOsu(osu);
|
||||
var imported = LoadOszIntoOsu(osu);
|
||||
var importedSecondTime = LoadOszIntoOsu(osu);
|
||||
|
||||
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
||||
Assert.IsTrue(imported.ID == importedSecondTime.ID);
|
||||
@ -105,7 +105,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
manager.ItemAdded += (_, __, ___) => fireCount++;
|
||||
manager.ItemRemoved += _ => fireCount++;
|
||||
|
||||
var imported = loadOszIntoOsu(osu);
|
||||
var imported = LoadOszIntoOsu(osu);
|
||||
|
||||
Assert.AreEqual(0, fireCount -= 1);
|
||||
|
||||
@ -160,12 +160,12 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
var osu = loadOsu(host);
|
||||
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||
|
||||
var imported = loadOszIntoOsu(osu);
|
||||
var imported = LoadOszIntoOsu(osu);
|
||||
|
||||
imported.Hash += "-changed";
|
||||
manager.Update(imported);
|
||||
|
||||
var importedSecondTime = loadOszIntoOsu(osu);
|
||||
var importedSecondTime = LoadOszIntoOsu(osu);
|
||||
|
||||
Assert.IsTrue(imported.ID != importedSecondTime.ID);
|
||||
Assert.IsTrue(imported.Beatmaps.First().ID < importedSecondTime.Beatmaps.First().ID);
|
||||
@ -191,11 +191,11 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
{
|
||||
var osu = loadOsu(host);
|
||||
|
||||
var imported = loadOszIntoOsu(osu);
|
||||
var imported = LoadOszIntoOsu(osu);
|
||||
|
||||
deleteBeatmapSet(imported, osu);
|
||||
|
||||
var importedSecondTime = loadOszIntoOsu(osu);
|
||||
var importedSecondTime = LoadOszIntoOsu(osu);
|
||||
|
||||
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
||||
Assert.IsTrue(imported.ID == importedSecondTime.ID);
|
||||
@ -262,7 +262,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
}
|
||||
}
|
||||
|
||||
private string createTemporaryBeatmap()
|
||||
private static string createTemporaryBeatmap()
|
||||
{
|
||||
var temp = Path.GetTempFileName() + ".osz";
|
||||
File.Copy(TEST_OSZ_PATH, temp, true);
|
||||
@ -270,7 +270,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
return temp;
|
||||
}
|
||||
|
||||
private BeatmapSetInfo loadOszIntoOsu(OsuGameBase osu, string path = null)
|
||||
public static BeatmapSetInfo LoadOszIntoOsu(OsuGameBase osu, string path = null)
|
||||
{
|
||||
var temp = path ?? createTemporaryBeatmap();
|
||||
|
||||
@ -305,7 +305,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
return osu;
|
||||
}
|
||||
|
||||
private void ensureLoaded(OsuGameBase osu, int timeout = 60000)
|
||||
private static void ensureLoaded(OsuGameBase osu, int timeout = 60000)
|
||||
{
|
||||
IEnumerable<BeatmapSetInfo> resultSets = null;
|
||||
var store = osu.Dependencies.Get<BeatmapManager>();
|
||||
@ -343,7 +343,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
Assert.IsTrue(beatmap?.HitObjects.Any() == true);
|
||||
}
|
||||
|
||||
private void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
|
||||
private static void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
|
||||
{
|
||||
Task task = Task.Run(() =>
|
||||
{
|
||||
|
@ -1,135 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Multi.Components;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseDrawableRoom : OsuTestCase
|
||||
{
|
||||
private RulesetStore rulesets;
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
DrawableRoom first;
|
||||
Add(new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Width = 580f,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
first = new DrawableRoom(new Room
|
||||
{
|
||||
Name = { Value = @"Great Room Right Here" },
|
||||
Host = { Value = new User { Username = @"Naeferith", Id = 9492835, Country = new Country { FlagName = @"FR" } } },
|
||||
Status = { Value = new RoomStatusOpen() },
|
||||
Type = { Value = new GameTypeTeamVersus() },
|
||||
Beatmap =
|
||||
{
|
||||
Value = new BeatmapInfo
|
||||
{
|
||||
StarDifficulty = 4.65,
|
||||
Ruleset = rulesets.GetRuleset(3),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Title = @"Critical Crystal",
|
||||
Artist = @"Seiryu",
|
||||
},
|
||||
BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
OnlineInfo = new BeatmapSetOnlineInfo
|
||||
{
|
||||
Covers = new BeatmapSetOnlineCovers
|
||||
{
|
||||
Cover = @"https://assets.ppy.sh//beatmaps/376340/covers/cover.jpg?1456478455",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Participants =
|
||||
{
|
||||
Value = new[]
|
||||
{
|
||||
new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 1355 } } },
|
||||
new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 8756 } } },
|
||||
},
|
||||
},
|
||||
}),
|
||||
new DrawableRoom(new Room
|
||||
{
|
||||
Name = { Value = @"Relax It's The Weekend" },
|
||||
Host = { Value = new User { Username = @"peppy", Id = 2, Country = new Country { FlagName = @"AU" } } },
|
||||
Status = { Value = new RoomStatusPlaying() },
|
||||
Type = { Value = new GameTypeTagTeam() },
|
||||
Beatmap =
|
||||
{
|
||||
Value = new BeatmapInfo
|
||||
{
|
||||
StarDifficulty = 1.96,
|
||||
Ruleset = rulesets.GetRuleset(0),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Title = @"Serendipity",
|
||||
Artist = @"ZAQ",
|
||||
},
|
||||
BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
OnlineInfo = new BeatmapSetOnlineInfo
|
||||
{
|
||||
Covers = new BeatmapSetOnlineCovers
|
||||
{
|
||||
Cover = @"https://assets.ppy.sh//beatmaps/526839/covers/cover.jpg?1493815706",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Participants =
|
||||
{
|
||||
Value = new[]
|
||||
{
|
||||
new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 578975 } } },
|
||||
new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 24554 } } },
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
});
|
||||
|
||||
AddStep(@"select", () => first.State = SelectionState.Selected);
|
||||
AddStep(@"change title", () => first.Room.Name.Value = @"I Changed Name");
|
||||
AddStep(@"change host", () => first.Room.Host.Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } });
|
||||
AddStep(@"change status", () => first.Room.Status.Value = new RoomStatusPlaying());
|
||||
AddStep(@"change type", () => first.Room.Type.Value = new GameTypeVersus());
|
||||
AddStep(@"change beatmap", () => first.Room.Beatmap.Value = null);
|
||||
AddStep(@"change participants", () => first.Room.Participants.Value = new[]
|
||||
{
|
||||
new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 1254 } } },
|
||||
new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 123189 } } },
|
||||
});
|
||||
AddStep(@"deselect", () => first.State = SelectionState.NotSelected);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(RulesetStore rulesets)
|
||||
{
|
||||
this.rulesets = rulesets;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,216 +0,0 @@
|
||||
// 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.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
using osu.Game.Screens.Multi.Components;
|
||||
using osu.Game.Screens.Multi.Screens.Lounge;
|
||||
using osu.Game.Users;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseLounge : ManualInputManagerTestCase
|
||||
{
|
||||
private TestLounge lounge;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(RulesetStore rulesets)
|
||||
{
|
||||
lounge = new TestLounge();
|
||||
|
||||
Room[] rooms =
|
||||
{
|
||||
new Room
|
||||
{
|
||||
Name = { Value = @"Just Another Room" },
|
||||
Host = { Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } } },
|
||||
Status = { Value = new RoomStatusPlaying() },
|
||||
Availability = { Value = RoomAvailability.Public },
|
||||
Type = { Value = new GameTypeTagTeam() },
|
||||
Beatmap =
|
||||
{
|
||||
Value = new BeatmapInfo
|
||||
{
|
||||
StarDifficulty = 5.65,
|
||||
Ruleset = rulesets.GetRuleset(0),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Title = @"Sidetracked Day (Short Ver.)",
|
||||
Artist = @"VINXIS",
|
||||
AuthorString = @"Hobbes2",
|
||||
},
|
||||
BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
OnlineInfo = new BeatmapSetOnlineInfo
|
||||
{
|
||||
Covers = new BeatmapSetOnlineCovers
|
||||
{
|
||||
Cover = @"https://assets.ppy.sh/beatmaps/767600/covers/cover.jpg?1526243446",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
MaxParticipants = { Value = 10 },
|
||||
Participants =
|
||||
{
|
||||
Value = new[]
|
||||
{
|
||||
new User { Username = @"flyte", Id = 3103765, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 142 } } },
|
||||
new User { Username = @"Cookiezi", Id = 124493, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 546 } } },
|
||||
new User { Username = @"Angelsim", Id = 1777162, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 287 } } },
|
||||
new User { Username = @"Rafis", Id = 2558286, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 468 } } },
|
||||
new User { Username = @"hvick225", Id = 50265, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 325 } } },
|
||||
new User { Username = @"peppy", Id = 2, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 625 } } },
|
||||
}
|
||||
}
|
||||
},
|
||||
new Room
|
||||
{
|
||||
Name = { Value = @"Not Just Any Room" },
|
||||
Host = { Value = new User { Username = @"Monstrata", Id = 2706438, Country = new Country { FlagName = @"CA" } } },
|
||||
Status = { Value = new RoomStatusOpen() },
|
||||
Availability = { Value = RoomAvailability.FriendsOnly },
|
||||
Type = { Value = new GameTypeTeamVersus() },
|
||||
Beatmap =
|
||||
{
|
||||
Value = new BeatmapInfo
|
||||
{
|
||||
StarDifficulty = 2.73,
|
||||
Ruleset = rulesets.GetRuleset(0),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Title = @"lit(var)",
|
||||
Artist = @"kensuke ushio",
|
||||
AuthorString = @"Monstrata",
|
||||
},
|
||||
BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
OnlineInfo = new BeatmapSetOnlineInfo
|
||||
{
|
||||
Covers = new BeatmapSetOnlineCovers
|
||||
{
|
||||
Cover = @"https://assets.ppy.sh/beatmaps/623972/covers/cover.jpg?1521167183",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
Participants =
|
||||
{
|
||||
Value = new[]
|
||||
{
|
||||
new User { Username = @"Jeby", Id = 3136279, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 3497 } } },
|
||||
new User { Username = @"DualAkira", Id = 5220933, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 643 } } },
|
||||
new User { Username = @"Datenshi Yohane", Id = 7171857, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 10555 } } },
|
||||
}
|
||||
}
|
||||
},
|
||||
new Room
|
||||
{
|
||||
Name = { Value = @"room THE FINAL" },
|
||||
Host = { Value = new User { Username = @"Delis", Id = 1603923, Country = new Country { FlagName = @"JP" } } },
|
||||
Status = { Value = new RoomStatusPlaying() },
|
||||
Availability = { Value = RoomAvailability.Public },
|
||||
Type = { Value = new GameTypeTagTeam() },
|
||||
Beatmap =
|
||||
{
|
||||
Value = new BeatmapInfo
|
||||
{
|
||||
StarDifficulty = 4.48,
|
||||
Ruleset = rulesets.GetRuleset(3),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Title = @"ONIGIRI FREEWAY",
|
||||
Artist = @"OISHII",
|
||||
AuthorString = @"Mentholzzz",
|
||||
},
|
||||
BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
OnlineInfo = new BeatmapSetOnlineInfo
|
||||
{
|
||||
Covers = new BeatmapSetOnlineCovers
|
||||
{
|
||||
Cover = @"https://assets.ppy.sh/beatmaps/663098/covers/cover.jpg?1521898837",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
MaxParticipants = { Value = 30 },
|
||||
Participants =
|
||||
{
|
||||
Value = new[]
|
||||
{
|
||||
new User { Username = @"KizuA", Id = 6510442, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 5372 } } },
|
||||
new User { Username = @"Colored", Id = 827563, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 810 } } },
|
||||
new User { Username = @"Beryl", Id = 3817591, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 10096 } } },
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
AddStep(@"show", () => Add(lounge));
|
||||
AddStep(@"set rooms", () => lounge.Rooms = rooms);
|
||||
selectAssert(0);
|
||||
AddStep(@"clear rooms", () => lounge.Rooms = new Room[] {});
|
||||
AddAssert(@"no room selected", () => lounge.SelectedRoom == null);
|
||||
AddStep(@"set rooms", () => lounge.Rooms = rooms);
|
||||
selectAssert(1);
|
||||
AddStep(@"open room 1", () => clickRoom(1));
|
||||
AddUntilStep(() => lounge.ChildScreen?.IsCurrentScreen == true, "wait until room current");
|
||||
AddStep(@"make lounge current", lounge.MakeCurrent);
|
||||
filterAssert(@"THE FINAL", LoungeTab.Public, 1);
|
||||
filterAssert(string.Empty, LoungeTab.Public, 2);
|
||||
filterAssert(string.Empty, LoungeTab.Private, 1);
|
||||
filterAssert(string.Empty, LoungeTab.Public, 2);
|
||||
filterAssert(@"no matches", LoungeTab.Public, 0);
|
||||
AddStep(@"clear rooms", () => lounge.Rooms = new Room[] {});
|
||||
AddStep(@"set rooms", () => lounge.Rooms = rooms);
|
||||
AddAssert(@"no matches after clear", () => !lounge.ChildRooms.Any());
|
||||
filterAssert(string.Empty, LoungeTab.Public, 2);
|
||||
AddStep(@"exit", lounge.Exit);
|
||||
}
|
||||
|
||||
private void clickRoom(int n)
|
||||
{
|
||||
InputManager.MoveMouseTo(lounge.ChildRooms.ElementAt(n));
|
||||
InputManager.Click(MouseButton.Left);
|
||||
}
|
||||
|
||||
private void selectAssert(int n)
|
||||
{
|
||||
AddStep($@"select room {n}", () => clickRoom(n));
|
||||
AddAssert($@"room {n} selected", () => lounge.SelectedRoom == lounge.ChildRooms.ElementAt(n).Room);
|
||||
}
|
||||
|
||||
private void filterAssert(string filter, LoungeTab tab, int endCount)
|
||||
{
|
||||
AddStep($@"filter '{filter}', {tab}", () => lounge.SetFilter(filter, tab));
|
||||
AddAssert(@"filtered correctly", () => lounge.ChildRooms.Count() == endCount);
|
||||
}
|
||||
|
||||
private class TestLounge : Lounge
|
||||
{
|
||||
protected override BackgroundScreen CreateBackground() => new BackgroundScreenDefault();
|
||||
|
||||
public IEnumerable<DrawableRoom> ChildRooms => RoomsContainer.Children.Where(r => r.MatchingFilter);
|
||||
public Room SelectedRoom => Inspector.Room;
|
||||
|
||||
public void SetFilter(string filter, LoungeTab tab)
|
||||
{
|
||||
Filter.Search.Current.Value = filter;
|
||||
Filter.Tabs.Current.Value = tab;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
101
osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs
Normal file
101
osu.Game.Tests/Visual/TestCaseLoungeRoomsContainer.cs
Normal file
@ -0,0 +1,101 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Screens.Multi;
|
||||
using osu.Game.Screens.Multi.Lounge.Components;
|
||||
using osu.Game.Users;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseLoungeRoomsContainer : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(RoomsContainer),
|
||||
typeof(DrawableRoom)
|
||||
};
|
||||
|
||||
[Cached(Type = typeof(IRoomManager))]
|
||||
private TestRoomManager roomManager = new TestRoomManager();
|
||||
|
||||
public TestCaseLoungeRoomsContainer()
|
||||
{
|
||||
RoomsContainer container;
|
||||
|
||||
Child = container = new RoomsContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Width = 0.5f,
|
||||
JoinRequested = joinRequested
|
||||
};
|
||||
|
||||
AddStep("clear rooms", () => roomManager.Rooms.Clear());
|
||||
|
||||
AddStep("add rooms", () =>
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
roomManager.Rooms.Add(new Room
|
||||
{
|
||||
RoomID = { Value = i },
|
||||
Name = { Value = $"Room {i}" },
|
||||
Host = { Value = new User { Username = "Host" } },
|
||||
EndDate = { Value = DateTimeOffset.Now + TimeSpan.FromSeconds(10) }
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
AddAssert("has 2 rooms", () => container.Rooms.Count == 3);
|
||||
AddStep("remove first room", () => roomManager.Rooms.Remove(roomManager.Rooms.FirstOrDefault()));
|
||||
AddAssert("has 2 rooms", () => container.Rooms.Count == 2);
|
||||
AddAssert("first room removed", () => container.Rooms.All(r => r.Room.RoomID.Value != 0));
|
||||
|
||||
AddStep("select first room", () => container.Rooms.First().Action?.Invoke());
|
||||
AddAssert("first room selected", () => container.SelectedRoom.Value == roomManager.Rooms.First());
|
||||
|
||||
AddStep("join first room", () => container.Rooms.First().Action?.Invoke());
|
||||
AddAssert("first room joined", () => roomManager.Rooms.First().Status.Value is JoinedRoomStatus);
|
||||
}
|
||||
|
||||
private void joinRequested(Room room) => room.Status.Value = new JoinedRoomStatus();
|
||||
|
||||
private class TestRoomManager : IRoomManager
|
||||
{
|
||||
public event Action RoomsUpdated;
|
||||
|
||||
public readonly BindableCollection<Room> Rooms = new BindableCollection<Room>();
|
||||
IBindableCollection<Room> IRoomManager.Rooms => Rooms;
|
||||
|
||||
public void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null) => Rooms.Add(room);
|
||||
|
||||
public void JoinRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null)
|
||||
{
|
||||
}
|
||||
|
||||
public void PartRoom()
|
||||
{
|
||||
}
|
||||
|
||||
public void Filter(FilterCriteria criteria)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private class JoinedRoomStatus : RoomStatus
|
||||
{
|
||||
public override string Message => "Joined";
|
||||
|
||||
public override Color4 GetAppropriateColour(OsuColour colours) => colours.Yellow;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,142 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Multi.Screens.Match;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseMatch : OsuTestCase
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(RulesetStore rulesets)
|
||||
{
|
||||
Room room = new Room
|
||||
{
|
||||
Name = { Value = @"One Awesome Room" },
|
||||
Status = { Value = new RoomStatusOpen() },
|
||||
Availability = { Value = RoomAvailability.Public },
|
||||
Type = { Value = new GameTypeTeamVersus() },
|
||||
Beatmap =
|
||||
{
|
||||
Value = new BeatmapInfo
|
||||
{
|
||||
StarDifficulty = 5.02,
|
||||
Ruleset = rulesets.GetRuleset(1),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Title = @"Paradigm Shift",
|
||||
Artist = @"Morimori Atsushi",
|
||||
AuthorString = @"eiri-",
|
||||
},
|
||||
BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
OnlineInfo = new BeatmapSetOnlineInfo
|
||||
{
|
||||
Covers = new BeatmapSetOnlineCovers
|
||||
{
|
||||
Cover = @"https://assets.ppy.sh/beatmaps/765055/covers/cover.jpg?1526955337",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MaxParticipants = { Value = 5 },
|
||||
Participants =
|
||||
{
|
||||
Value = new[]
|
||||
{
|
||||
new User
|
||||
{
|
||||
Username = @"eiri-",
|
||||
Id = 3388410,
|
||||
Country = new Country { FlagName = @"US" },
|
||||
CoverUrl = @"https://assets.ppy.sh/user-profile-covers/3388410/00a8486a247831e1cc4375db519f611ac970bda8bc0057d78b0f540ea38c3e58.jpeg",
|
||||
IsSupporter = true,
|
||||
},
|
||||
new User
|
||||
{
|
||||
Username = @"Nepuri",
|
||||
Id = 6637817,
|
||||
Country = new Country { FlagName = @"DE" },
|
||||
CoverUrl = @"https://assets.ppy.sh/user-profile-covers/6637817/9085fc60248b6b5327a72c1dcdecf2dbedba810ae0ab6bcf7224e46b1339632a.jpeg",
|
||||
IsSupporter = true,
|
||||
},
|
||||
new User
|
||||
{
|
||||
Username = @"goheegy",
|
||||
Id = 8057655,
|
||||
Country = new Country { FlagName = @"GB" },
|
||||
CoverUrl = @"https://assets.ppy.sh/user-profile-covers/8057655/21cec27c25a11dc197a4ec6a74253dbabb495949b0e0697113352f12007018c5.jpeg",
|
||||
},
|
||||
new User
|
||||
{
|
||||
Username = @"Alumetri",
|
||||
Id = 5371497,
|
||||
Country = new Country { FlagName = @"RU" },
|
||||
CoverUrl = @"https://assets.ppy.sh/user-profile-covers/5371497/e023b8c7fbe3613e64bd4856703517ea50fbed8a5805dc9acda9efe9897c67e2.jpeg",
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
Match match = new Match(room);
|
||||
|
||||
AddStep(@"show", () => Add(match));
|
||||
AddStep(@"null beatmap", () => room.Beatmap.Value = null);
|
||||
AddStep(@"change name", () => room.Name.Value = @"Two Awesome Rooms");
|
||||
AddStep(@"change status", () => room.Status.Value = new RoomStatusPlaying());
|
||||
AddStep(@"change availability", () => room.Availability.Value = RoomAvailability.FriendsOnly);
|
||||
AddStep(@"change type", () => room.Type.Value = new GameTypeTag());
|
||||
AddStep(@"change beatmap", () => room.Beatmap.Value = new BeatmapInfo
|
||||
{
|
||||
StarDifficulty = 4.33,
|
||||
Ruleset = rulesets.GetRuleset(2),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Title = @"Yasashisa no Riyuu",
|
||||
Artist = @"ChouCho",
|
||||
AuthorString = @"celerih",
|
||||
},
|
||||
BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
OnlineInfo = new BeatmapSetOnlineInfo
|
||||
{
|
||||
Covers = new BeatmapSetOnlineCovers
|
||||
{
|
||||
Cover = @"https://assets.ppy.sh/beatmaps/685391/covers/cover.jpg?1524597970",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
AddStep(@"null max participants", () => room.MaxParticipants.Value = null);
|
||||
AddStep(@"change participants", () => room.Participants.Value = new[]
|
||||
{
|
||||
new User
|
||||
{
|
||||
Username = @"Spectator",
|
||||
Id = 702598,
|
||||
Country = new Country { FlagName = @"KR" },
|
||||
CoverUrl = @"https://assets.ppy.sh/user-profile-covers/702598/3bbf4cb8b8d2cf8b03145000a975ff27e191ab99b0920832e7dd67386280e288.jpeg",
|
||||
IsSupporter = true,
|
||||
},
|
||||
new User
|
||||
{
|
||||
Username = @"celerih",
|
||||
Id = 4696296,
|
||||
Country = new Country { FlagName = @"CA" },
|
||||
CoverUrl = @"https://assets.ppy.sh/user-profile-covers/4696296/7f8500731d0ac66d5472569d146a7be07d9460273361913f22c038867baddaef.jpeg",
|
||||
},
|
||||
});
|
||||
|
||||
AddStep(@"exit", match.Exit);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,43 +1,54 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Screens.Multi.Screens.Match;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.GameTypes;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Screens.Multi.Match.Components;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseMatchHeader : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(Header)
|
||||
};
|
||||
|
||||
public TestCaseMatchHeader()
|
||||
{
|
||||
Header header = new Header();
|
||||
Add(header);
|
||||
var room = new Room();
|
||||
|
||||
AddStep(@"set beatmap set", () => header.BeatmapSet = new BeatmapSetInfo
|
||||
var header = new Header(room);
|
||||
|
||||
room.Playlist.Add(new PlaylistItem
|
||||
{
|
||||
OnlineInfo = new BeatmapSetOnlineInfo
|
||||
Beatmap = new BeatmapInfo
|
||||
{
|
||||
Covers = new BeatmapSetOnlineCovers
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Cover = @"https://assets.ppy.sh/beatmaps/760757/covers/cover.jpg?1526944540",
|
||||
Title = "Title",
|
||||
Artist = "Artist",
|
||||
AuthorString = "Author",
|
||||
},
|
||||
Version = "Version",
|
||||
Ruleset = new OsuRuleset().RulesetInfo
|
||||
},
|
||||
RequiredMods =
|
||||
{
|
||||
new OsuModDoubleTime(),
|
||||
new OsuModNoFail(),
|
||||
new OsuModRelax(),
|
||||
}
|
||||
});
|
||||
|
||||
AddStep(@"change beatmap set", () => header.BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
OnlineInfo = new BeatmapSetOnlineInfo
|
||||
{
|
||||
Covers = new BeatmapSetOnlineCovers
|
||||
{
|
||||
Cover = @"https://assets.ppy.sh/beatmaps/761883/covers/cover.jpg?1525557400",
|
||||
},
|
||||
},
|
||||
});
|
||||
room.Type.Value = new GameTypeTimeshift();
|
||||
|
||||
AddStep(@"null beatmap set", () => header.BeatmapSet = null);
|
||||
Child = header;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
35
osu.Game.Tests/Visual/TestCaseMatchHostInfo.cs
Normal file
35
osu.Game.Tests/Visual/TestCaseMatchHostInfo.cs
Normal file
@ -0,0 +1,35 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Screens.Multi.Match.Components;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseMatchHostInfo : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(HostInfo)
|
||||
};
|
||||
|
||||
private readonly Bindable<User> host = new Bindable<User>(new User { Username = "SomeHost" });
|
||||
|
||||
public TestCaseMatchHostInfo()
|
||||
{
|
||||
HostInfo hostInfo;
|
||||
|
||||
Child = hostInfo = new HostInfo
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
};
|
||||
|
||||
hostInfo.Host.BindTo(host);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,56 +1,80 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.RoomStatuses;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Multi.Screens.Match;
|
||||
using osu.Game.Screens.Multi.Match.Components;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseMatchInfo : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(Info),
|
||||
typeof(HeaderButton),
|
||||
typeof(ReadyButton),
|
||||
typeof(ViewBeatmapButton)
|
||||
};
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(RulesetStore rulesets)
|
||||
{
|
||||
Info info = new Info();
|
||||
var room = new Room();
|
||||
|
||||
Info info = new Info(room);
|
||||
Add(info);
|
||||
|
||||
AddStep(@"set name", () => info.Name = @"Room Name?");
|
||||
AddStep(@"set availability", () => info.Availability = RoomAvailability.FriendsOnly);
|
||||
AddStep(@"set status", () => info.Status = new RoomStatusPlaying());
|
||||
AddStep(@"set beatmap", () => info.Beatmap = new BeatmapInfo
|
||||
AddStep(@"set name", () => room.Name.Value = @"Room Name?");
|
||||
AddStep(@"set availability", () => room.Availability.Value = RoomAvailability.FriendsOnly);
|
||||
AddStep(@"set status", () => room.Status.Value = new RoomStatusPlaying());
|
||||
AddStep(@"set beatmap", () =>
|
||||
{
|
||||
StarDifficulty = 2.4,
|
||||
Ruleset = rulesets.GetRuleset(0),
|
||||
Metadata = new BeatmapMetadata
|
||||
room.Playlist.Clear();
|
||||
room.Playlist.Add(new PlaylistItem
|
||||
{
|
||||
Title = @"My Song",
|
||||
Artist = @"VisualTests",
|
||||
AuthorString = @"osu!lazer",
|
||||
},
|
||||
Beatmap = new BeatmapInfo
|
||||
{
|
||||
StarDifficulty = 2.4,
|
||||
Ruleset = rulesets.GetRuleset(0),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Title = @"My Song",
|
||||
Artist = @"VisualTests",
|
||||
AuthorString = @"osu!lazer",
|
||||
},
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
AddStep(@"set type", () => info.Type = new GameTypeTagTeam());
|
||||
|
||||
AddStep(@"change name", () => info.Name = @"Room Name!");
|
||||
AddStep(@"change availability", () => info.Availability = RoomAvailability.InviteOnly);
|
||||
AddStep(@"change status", () => info.Status = new RoomStatusOpen());
|
||||
AddStep(@"null beatmap", () => info.Beatmap = null);
|
||||
AddStep(@"change type", () => info.Type = new GameTypeTeamVersus());
|
||||
AddStep(@"change beatmap", () => info.Beatmap = new BeatmapInfo
|
||||
AddStep(@"change name", () => room.Name.Value = @"Room Name!");
|
||||
AddStep(@"change availability", () => room.Availability.Value = RoomAvailability.InviteOnly);
|
||||
AddStep(@"change status", () => room.Status.Value = new RoomStatusOpen());
|
||||
AddStep(@"null beatmap", () => room.Playlist.Clear());
|
||||
AddStep(@"change beatmap", () =>
|
||||
{
|
||||
StarDifficulty = 4.2,
|
||||
Ruleset = rulesets.GetRuleset(3),
|
||||
Metadata = new BeatmapMetadata
|
||||
room.Playlist.Clear();
|
||||
room.Playlist.Add(new PlaylistItem
|
||||
{
|
||||
Title = @"Your Song",
|
||||
Artist = @"Tester",
|
||||
AuthorString = @"Someone",
|
||||
},
|
||||
Beatmap = new BeatmapInfo
|
||||
{
|
||||
StarDifficulty = 4.2,
|
||||
Ruleset = rulesets.GetRuleset(3),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Title = @"Your Song",
|
||||
Artist = @"Tester",
|
||||
AuthorString = @"Someone",
|
||||
},
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
68
osu.Game.Tests/Visual/TestCaseMatchLeaderboard.cs
Normal file
68
osu.Game.Tests/Visual/TestCaseMatchLeaderboard.cs
Normal file
@ -0,0 +1,68 @@
|
||||
// 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.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Screens.Multi.Match.Components;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseMatchLeaderboard : OsuTestCase
|
||||
{
|
||||
public TestCaseMatchLeaderboard()
|
||||
{
|
||||
Add(new MatchLeaderboard(new Room { RoomID = { Value = 3 } })
|
||||
{
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
||||
Size = new Vector2(550f, 450f),
|
||||
Scope = MatchLeaderboardScope.Overall,
|
||||
});
|
||||
}
|
||||
|
||||
[Resolved]
|
||||
private APIAccess api { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
var req = new GetRoomScoresRequest();
|
||||
req.Success += v => { };
|
||||
req.Failure += _ => { };
|
||||
|
||||
api.Queue(req);
|
||||
}
|
||||
|
||||
private class GetRoomScoresRequest : APIRequest<List<RoomScore>>
|
||||
{
|
||||
protected override string Target => "rooms/3/leaderboard";
|
||||
}
|
||||
|
||||
private class RoomScore
|
||||
{
|
||||
[JsonProperty("user")]
|
||||
public User User { get; set; }
|
||||
|
||||
[JsonProperty("accuracy")]
|
||||
public double Accuracy { get; set; }
|
||||
|
||||
[JsonProperty("total_score")]
|
||||
public int TotalScore { get; set; }
|
||||
|
||||
[JsonProperty("pp")]
|
||||
public double PP { get; set; }
|
||||
|
||||
[JsonProperty("attempts")]
|
||||
public int TotalAttempts { get; set; }
|
||||
|
||||
[JsonProperty("completed")]
|
||||
public int CompletedAttempts { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +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.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Screens.Multi.Screens.Match;
|
||||
using osu.Game.Screens.Multi.Match.Components;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
@ -11,16 +13,20 @@ namespace osu.Game.Tests.Visual
|
||||
[TestFixture]
|
||||
public class TestCaseMatchParticipants : OsuTestCase
|
||||
{
|
||||
private readonly Bindable<int?> maxParticipants = new Bindable<int?>();
|
||||
private readonly Bindable<IEnumerable<User>> users = new Bindable<IEnumerable<User>>();
|
||||
|
||||
public TestCaseMatchParticipants()
|
||||
{
|
||||
Participants participants;
|
||||
Add(participants = new Participants
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
});
|
||||
|
||||
AddStep(@"set max to null", () => participants.Max = null);
|
||||
AddStep(@"set users", () => participants.Users = new[]
|
||||
Add(participants = new Participants { RelativeSizeAxes = Axes.Both });
|
||||
|
||||
participants.MaxParticipants.BindTo(maxParticipants);
|
||||
participants.Users.BindTo(users);
|
||||
|
||||
AddStep(@"set max to null", () => maxParticipants.Value = null);
|
||||
AddStep(@"set users", () => users.Value = new[]
|
||||
{
|
||||
new User
|
||||
{
|
||||
@ -48,9 +54,9 @@ namespace osu.Game.Tests.Visual
|
||||
},
|
||||
});
|
||||
|
||||
AddStep(@"set max", () => participants.Max = 10);
|
||||
AddStep(@"clear users", () => participants.Users = new User[] { });
|
||||
AddStep(@"set max to null", () => participants.Max = null);
|
||||
AddStep(@"set max", () => maxParticipants.Value = 10);
|
||||
AddStep(@"clear users", () => users.Value = new User[] { });
|
||||
AddStep(@"set max to null", () => maxParticipants.Value = null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
123
osu.Game.Tests/Visual/TestCaseMatchResults.cs
Normal file
123
osu.Game.Tests/Visual/TestCaseMatchResults.cs
Normal file
@ -0,0 +1,123 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Multi.Match.Components;
|
||||
using osu.Game.Screens.Multi.Ranking;
|
||||
using osu.Game.Screens.Multi.Ranking.Pages;
|
||||
using osu.Game.Screens.Multi.Ranking.Types;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseMatchResults : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(MatchResults),
|
||||
typeof(RoomLeaderboardPageInfo),
|
||||
typeof(RoomLeaderboardPage)
|
||||
};
|
||||
|
||||
[Resolved]
|
||||
private BeatmapManager beatmaps { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetID == 0);
|
||||
if (beatmapInfo != null)
|
||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo);
|
||||
|
||||
Child = new TestMatchResults(new ScoreInfo
|
||||
{
|
||||
User = new User { Id = 10 },
|
||||
});
|
||||
}
|
||||
|
||||
private class TestMatchResults : MatchResults
|
||||
{
|
||||
private readonly Room room;
|
||||
|
||||
public TestMatchResults(ScoreInfo score)
|
||||
: this(score, new Room
|
||||
{
|
||||
RoomID = { Value = 1 },
|
||||
Name = { Value = "an awesome room" }
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public TestMatchResults(ScoreInfo score, Room room)
|
||||
: base(score, room)
|
||||
{
|
||||
this.room = room;
|
||||
}
|
||||
|
||||
protected override IEnumerable<IResultPageInfo> CreateResultPages() => new[] { new TestRoomLeaderboardPageInfo(Score, Beatmap, room) };
|
||||
}
|
||||
|
||||
private class TestRoomLeaderboardPageInfo : RoomLeaderboardPageInfo
|
||||
{
|
||||
private readonly ScoreInfo score;
|
||||
private readonly WorkingBeatmap beatmap;
|
||||
private readonly Room room;
|
||||
|
||||
public TestRoomLeaderboardPageInfo(ScoreInfo score, WorkingBeatmap beatmap, Room room)
|
||||
: base(score, beatmap, room)
|
||||
{
|
||||
this.score = score;
|
||||
this.beatmap = beatmap;
|
||||
this.room = room;
|
||||
}
|
||||
|
||||
public override ResultsPage CreatePage() => new TestRoomLeaderboardPage(score, beatmap, room);
|
||||
}
|
||||
|
||||
private class TestRoomLeaderboardPage : RoomLeaderboardPage
|
||||
{
|
||||
public TestRoomLeaderboardPage(ScoreInfo score, WorkingBeatmap beatmap, Room room)
|
||||
: base(score, beatmap, room)
|
||||
{
|
||||
}
|
||||
|
||||
protected override MatchLeaderboard CreateLeaderboard(Room room) => new TestMatchLeaderboard(room);
|
||||
}
|
||||
|
||||
private class TestMatchLeaderboard : RoomLeaderboardPage.ResultsMatchLeaderboard
|
||||
{
|
||||
public TestMatchLeaderboard(Room room)
|
||||
: base(room)
|
||||
{
|
||||
}
|
||||
|
||||
protected override APIRequest FetchScores(Action<IEnumerable<APIRoomScoreInfo>> scoresCallback)
|
||||
{
|
||||
var scores = Enumerable.Range(0, 50).Select(createRoomScore).ToArray();
|
||||
|
||||
scoresCallback?.Invoke(scores);
|
||||
ScoresLoaded?.Invoke(scores);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private APIRoomScoreInfo createRoomScore(int id) => new APIRoomScoreInfo
|
||||
{
|
||||
User = new User { Id = id, Username = $"User {id}" },
|
||||
Accuracy = 0.98,
|
||||
TotalScore = 987654,
|
||||
TotalAttempts = 13,
|
||||
CompletedBeatmaps = 5
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
161
osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs
Normal file
161
osu.Game.Tests/Visual/TestCaseMatchSettingsOverlay.cs
Normal file
@ -0,0 +1,161 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Screens.Multi;
|
||||
using osu.Game.Screens.Multi.Lounge.Components;
|
||||
using osu.Game.Screens.Multi.Match.Components;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseMatchSettingsOverlay : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(MatchSettingsOverlay)
|
||||
};
|
||||
|
||||
[Cached(Type = typeof(IRoomManager))]
|
||||
private TestRoomManager roomManager = new TestRoomManager();
|
||||
|
||||
private Room room;
|
||||
private TestRoomSettings settings;
|
||||
|
||||
[SetUp]
|
||||
public void Setup() => Schedule(() =>
|
||||
{
|
||||
room = new Room();
|
||||
settings = new TestRoomSettings(room)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
State = Visibility.Visible
|
||||
};
|
||||
|
||||
Child = settings;
|
||||
});
|
||||
|
||||
[Test]
|
||||
public void TestButtonEnabledOnlyWithNameAndBeatmap()
|
||||
{
|
||||
AddStep("clear name and beatmap", () =>
|
||||
{
|
||||
room.Name.Value = "";
|
||||
room.Playlist.Clear();
|
||||
});
|
||||
|
||||
AddAssert("button disabled", () => !settings.ApplyButton.Enabled);
|
||||
|
||||
AddStep("set name", () => room.Name.Value = "Room name");
|
||||
AddAssert("button disabled", () => !settings.ApplyButton.Enabled);
|
||||
|
||||
AddStep("set beatmap", () => room.Playlist.Add(new PlaylistItem { Beatmap = new DummyWorkingBeatmap().BeatmapInfo }));
|
||||
AddAssert("button enabled", () => settings.ApplyButton.Enabled);
|
||||
|
||||
AddStep("clear name", () => room.Name.Value = "");
|
||||
AddAssert("button disabled", () => !settings.ApplyButton.Enabled);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCorrectSettingsApplied()
|
||||
{
|
||||
const string expected_name = "expected name";
|
||||
TimeSpan expectedDuration = TimeSpan.FromMinutes(15);
|
||||
|
||||
Room createdRoom = null;
|
||||
|
||||
AddStep("setup", () =>
|
||||
{
|
||||
settings.NameField.Current.Value = expected_name;
|
||||
settings.DurationField.Current.Value = expectedDuration;
|
||||
|
||||
roomManager.CreateRequested = r =>
|
||||
{
|
||||
createdRoom = r;
|
||||
return true;
|
||||
};
|
||||
});
|
||||
|
||||
AddStep("create room", () => settings.ApplyButton.Action.Invoke());
|
||||
AddAssert("has correct name", () => createdRoom.Name.Value == expected_name);
|
||||
AddAssert("has correct duration", () => createdRoom.Duration.Value == expectedDuration);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCreationFailureDisplaysError()
|
||||
{
|
||||
bool fail;
|
||||
|
||||
AddStep("setup", () =>
|
||||
{
|
||||
fail = true;
|
||||
roomManager.CreateRequested = _ => !fail;
|
||||
});
|
||||
AddAssert("error not displayed", () => !settings.ErrorText.IsPresent);
|
||||
|
||||
AddStep("create room", () => settings.ApplyButton.Action.Invoke());
|
||||
AddAssert("error displayed", () => settings.ErrorText.IsPresent);
|
||||
AddAssert("error has correct text", () => settings.ErrorText.Text == TestRoomManager.FAILED_TEXT);
|
||||
|
||||
AddStep("create room no fail", () =>
|
||||
{
|
||||
fail = false;
|
||||
settings.ApplyButton.Action.Invoke();
|
||||
});
|
||||
|
||||
AddUntilStep(() => !settings.ErrorText.IsPresent, "error not displayed");
|
||||
}
|
||||
|
||||
private class TestRoomSettings : MatchSettingsOverlay
|
||||
{
|
||||
public new TriangleButton ApplyButton => base.ApplyButton;
|
||||
|
||||
public new OsuTextBox NameField => base.NameField;
|
||||
public new OsuDropdown<TimeSpan> DurationField => base.DurationField;
|
||||
|
||||
public new OsuSpriteText ErrorText => base.ErrorText;
|
||||
|
||||
public TestRoomSettings(Room room)
|
||||
: base(room)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private class TestRoomManager : IRoomManager
|
||||
{
|
||||
public const string FAILED_TEXT = "failed";
|
||||
|
||||
public Func<Room, bool> CreateRequested;
|
||||
|
||||
public event Action RoomsUpdated;
|
||||
|
||||
public IBindableCollection<Room> Rooms { get; } = null;
|
||||
|
||||
public void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null)
|
||||
{
|
||||
if (CreateRequested == null)
|
||||
return;
|
||||
|
||||
if (!CreateRequested.Invoke(room))
|
||||
onError?.Invoke(FAILED_TEXT);
|
||||
else
|
||||
onSuccess?.Invoke(room);
|
||||
}
|
||||
|
||||
public void JoinRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null) => throw new NotImplementedException();
|
||||
|
||||
public void PartRoom() => throw new NotImplementedException();
|
||||
|
||||
public void Filter(FilterCriteria criteria) => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@ -3,8 +3,8 @@
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Screens;
|
||||
using osu.Game.Screens.Multi;
|
||||
using osu.Game.Screens.Multi.Screens.Lounge;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
@ -13,15 +13,31 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public TestCaseMultiHeader()
|
||||
{
|
||||
Lounge lounge;
|
||||
int index = 0;
|
||||
|
||||
OsuScreen currentScreen = new TestMultiplayerSubScreen(index);
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
lounge = new Lounge
|
||||
{
|
||||
Padding = new MarginPadding { Top = Header.HEIGHT },
|
||||
},
|
||||
new Header(lounge),
|
||||
currentScreen,
|
||||
new Header(currentScreen)
|
||||
};
|
||||
|
||||
AddStep("push multi screen", () => currentScreen.Push(currentScreen = new TestMultiplayerSubScreen(++index)));
|
||||
}
|
||||
|
||||
private class TestMultiplayerSubScreen : OsuScreen, IMultiplayerSubScreen
|
||||
{
|
||||
private readonly int index;
|
||||
|
||||
public string ShortTitle => $"Screen {index}";
|
||||
|
||||
public TestMultiplayerSubScreen(int index)
|
||||
{
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public override string ToString() => ShortTitle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,25 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Screens.Multi;
|
||||
using osu.Game.Screens.Multi.Lounge;
|
||||
using osu.Game.Screens.Multi.Lounge.Components;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseMultiScreen : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(Multiplayer),
|
||||
typeof(LoungeSubScreen),
|
||||
typeof(FilterControl)
|
||||
};
|
||||
|
||||
public TestCaseMultiScreen()
|
||||
{
|
||||
Multiplayer multi = new Multiplayer();
|
||||
|
@ -87,10 +87,7 @@ namespace osu.Game.Tests.Visual
|
||||
usage.Migrate();
|
||||
|
||||
Dependencies.Cache(rulesets = new RulesetStore(factory));
|
||||
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, factory, rulesets, null, null)
|
||||
{
|
||||
DefaultBeatmap = defaultBeatmap = Beatmap.Default
|
||||
});
|
||||
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, factory, rulesets, null, null, null, defaultBeatmap = Beatmap.Default));
|
||||
|
||||
Beatmap.SetDefault();
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
Beatmap.Value = new DummyWorkingBeatmap(game);
|
||||
|
||||
AddStep("load dummy beatmap", () => Add(loader = new PlayerLoader(new Player
|
||||
AddStep("load dummy beatmap", () => Add(loader = new PlayerLoader(() => new Player
|
||||
{
|
||||
AllowPause = false,
|
||||
AllowLeadIn = false,
|
||||
@ -30,9 +30,9 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
AddStep("load slow dummy beatmap", () =>
|
||||
{
|
||||
SlowLoadPlayer slow;
|
||||
SlowLoadPlayer slow = null;
|
||||
|
||||
Add(loader = new PlayerLoader(slow = new SlowLoadPlayer
|
||||
Add(loader = new PlayerLoader(() => slow = new SlowLoadPlayer
|
||||
{
|
||||
AllowPause = false,
|
||||
AllowLeadIn = false,
|
||||
|
@ -5,7 +5,6 @@ using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
@ -23,7 +22,7 @@ namespace osu.Game.Tests.Visual
|
||||
// Reset the mods
|
||||
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Where(m => !(m is ModAutoplay));
|
||||
|
||||
return new ReplayPlayer(new Score { Replay = dummyRulesetContainer.Replay });
|
||||
return new ReplayPlayer(dummyRulesetContainer.ReplayScore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual
|
||||
typeof(Results),
|
||||
typeof(ResultsPage),
|
||||
typeof(ScoreResultsPage),
|
||||
typeof(RankingResultsPage)
|
||||
typeof(LocalLeaderboardPage)
|
||||
};
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
|
@ -1,147 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Multi.Components;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseRoomInspector : OsuTestCase
|
||||
{
|
||||
private RulesetStore rulesets;
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
Room room = new Room
|
||||
{
|
||||
Name = { Value = @"My Awesome Room" },
|
||||
Host = { Value = new User { Username = @"flyte", Id = 3103765, Country = new Country { FlagName = @"JP" } } },
|
||||
Status = { Value = new RoomStatusOpen() },
|
||||
Type = { Value = new GameTypeTeamVersus() },
|
||||
Beatmap =
|
||||
{
|
||||
Value = new BeatmapInfo
|
||||
{
|
||||
StarDifficulty = 3.7,
|
||||
Ruleset = rulesets.GetRuleset(3),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Title = @"Platina",
|
||||
Artist = @"Maaya Sakamoto",
|
||||
AuthorString = @"uwutm8",
|
||||
},
|
||||
BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
OnlineInfo = new BeatmapSetOnlineInfo
|
||||
{
|
||||
Covers = new BeatmapSetOnlineCovers
|
||||
{
|
||||
Cover = @"https://assets.ppy.sh/beatmaps/560573/covers/cover.jpg?1492722343",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
MaxParticipants = { Value = 200 },
|
||||
Participants =
|
||||
{
|
||||
Value = new[]
|
||||
{
|
||||
new User { Username = @"flyte", Id = 3103765, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 142 } } },
|
||||
new User { Username = @"Cookiezi", Id = 124493, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 546 } } },
|
||||
new User { Username = @"Angelsim", Id = 1777162, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 287 } } },
|
||||
new User { Username = @"Rafis", Id = 2558286, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 468 } } },
|
||||
new User { Username = @"hvick225", Id = 50265, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 325 } } },
|
||||
new User { Username = @"peppy", Id = 2, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 625 } } },
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
RoomInspector inspector;
|
||||
Add(inspector = new RoomInspector
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0.5f,
|
||||
});
|
||||
|
||||
AddStep(@"set room", () => inspector.Room = room);
|
||||
AddStep(@"null room", () => inspector.Room = null);
|
||||
AddStep(@"set room", () => inspector.Room = room);
|
||||
AddStep(@"change title", () => room.Name.Value = @"A Better Room Than The Above");
|
||||
AddStep(@"change host", () => room.Host.Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } });
|
||||
AddStep(@"change status", () => room.Status.Value = new RoomStatusPlaying());
|
||||
AddStep(@"change type", () => room.Type.Value = new GameTypeTag());
|
||||
AddStep(@"change beatmap", () => room.Beatmap.Value = null);
|
||||
AddStep(@"change max participants", () => room.MaxParticipants.Value = null);
|
||||
AddStep(@"change participants", () => room.Participants.Value = new[]
|
||||
{
|
||||
new User { Username = @"filsdelama", Id = 2831793, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 854 } } },
|
||||
new User { Username = @"_index", Id = 652457, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 150 } } }
|
||||
});
|
||||
|
||||
AddStep(@"change room", () =>
|
||||
{
|
||||
Room newRoom = new Room
|
||||
{
|
||||
Name = { Value = @"My New, Better Than Ever Room" },
|
||||
Host = { Value = new User { Username = @"Angelsim", Id = 1777162, Country = new Country { FlagName = @"KR" } } },
|
||||
Status = { Value = new RoomStatusOpen() },
|
||||
Type = { Value = new GameTypeTagTeam() },
|
||||
Beatmap =
|
||||
{
|
||||
Value = new BeatmapInfo
|
||||
{
|
||||
StarDifficulty = 7.07,
|
||||
Ruleset = rulesets.GetRuleset(0),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Title = @"FREEDOM DIVE",
|
||||
Artist = @"xi",
|
||||
AuthorString = @"Nakagawa-Kanon",
|
||||
},
|
||||
BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
OnlineInfo = new BeatmapSetOnlineInfo
|
||||
{
|
||||
Covers = new BeatmapSetOnlineCovers
|
||||
{
|
||||
Cover = @"https://assets.ppy.sh/beatmaps/39804/covers/cover.jpg?1456506845",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MaxParticipants = { Value = 10 },
|
||||
Participants =
|
||||
{
|
||||
Value = new[]
|
||||
{
|
||||
new User { Username = @"Angelsim", Id = 1777162, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 4 } } },
|
||||
new User { Username = @"HappyStick", Id = 256802, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 752 } } },
|
||||
new User { Username = @"-Konpaku-", Id = 2258797, Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 571 } } }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inspector.Room = newRoom;
|
||||
});
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(RulesetStore rulesets)
|
||||
{
|
||||
this.rulesets = rulesets;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Testing.Input;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Screens.Multi.Screens.Match.Settings;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseRoomSettings : ManualInputManagerTestCase
|
||||
{
|
||||
private readonly Room room;
|
||||
private readonly TestRoomSettingsOverlay overlay;
|
||||
|
||||
public TestCaseRoomSettings()
|
||||
{
|
||||
room = new Room
|
||||
{
|
||||
Name = { Value = "One Testing Room" },
|
||||
Availability = { Value = RoomAvailability.Public },
|
||||
Type = { Value = new GameTypeTeamVersus() },
|
||||
MaxParticipants = { Value = 10 },
|
||||
};
|
||||
|
||||
Add(overlay = new TestRoomSettingsOverlay(room)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Height = 0.75f,
|
||||
});
|
||||
|
||||
AddStep(@"show", overlay.Show);
|
||||
assertAll();
|
||||
AddStep(@"set name", () => overlay.CurrentName = @"Two Testing Room");
|
||||
AddStep(@"set max", () => overlay.CurrentMaxParticipants = null);
|
||||
AddStep(@"set availability", () => overlay.CurrentAvailability = RoomAvailability.InviteOnly);
|
||||
AddStep(@"set type", () => overlay.CurrentType = new GameTypeTagTeam());
|
||||
apply();
|
||||
assertAll();
|
||||
AddStep(@"show", overlay.Show);
|
||||
AddStep(@"set room name", () => room.Name.Value = @"Room Changed Name!");
|
||||
AddStep(@"set room availability", () => room.Availability.Value = RoomAvailability.Public);
|
||||
AddStep(@"set room type", () => room.Type.Value = new GameTypeTag());
|
||||
AddStep(@"set room max", () => room.MaxParticipants.Value = 100);
|
||||
assertAll();
|
||||
AddStep(@"set name", () => overlay.CurrentName = @"Unsaved Testing Room");
|
||||
AddStep(@"set max", () => overlay.CurrentMaxParticipants = 20);
|
||||
AddStep(@"set availability", () => overlay.CurrentAvailability = RoomAvailability.FriendsOnly);
|
||||
AddStep(@"set type", () => overlay.CurrentType = new GameTypeVersus());
|
||||
AddStep(@"hide", overlay.Hide);
|
||||
AddWaitStep(5);
|
||||
AddStep(@"show", overlay.Show);
|
||||
assertAll();
|
||||
AddStep(@"hide", overlay.Hide);
|
||||
}
|
||||
|
||||
private void apply()
|
||||
{
|
||||
AddStep(@"apply", () =>
|
||||
{
|
||||
overlay.ClickApplyButton(InputManager);
|
||||
});
|
||||
}
|
||||
|
||||
private void assertAll()
|
||||
{
|
||||
AddAssert(@"name == room name", () => overlay.CurrentName == room.Name.Value);
|
||||
AddAssert(@"max == room max", () => overlay.CurrentMaxParticipants == room.MaxParticipants.Value);
|
||||
AddAssert(@"availability == room availability", () => overlay.CurrentAvailability == room.Availability.Value);
|
||||
AddAssert(@"type == room type", () => Equals(overlay.CurrentType, room.Type.Value));
|
||||
}
|
||||
|
||||
private class TestRoomSettingsOverlay : RoomSettingsOverlay
|
||||
{
|
||||
public string CurrentName
|
||||
{
|
||||
get => NameField.Text;
|
||||
set => NameField.Text = value;
|
||||
}
|
||||
|
||||
public int? CurrentMaxParticipants
|
||||
{
|
||||
get
|
||||
{
|
||||
if (int.TryParse(MaxParticipantsField.Text, out int max))
|
||||
return max;
|
||||
|
||||
return null;
|
||||
}
|
||||
set => MaxParticipantsField.Text = value?.ToString();
|
||||
}
|
||||
|
||||
public RoomAvailability CurrentAvailability
|
||||
{
|
||||
get => AvailabilityPicker.Current.Value;
|
||||
set => AvailabilityPicker.Current.Value = value;
|
||||
}
|
||||
|
||||
public GameType CurrentType
|
||||
{
|
||||
get => TypePicker.Current.Value;
|
||||
set => TypePicker.Current.Value = value;
|
||||
}
|
||||
|
||||
public TestRoomSettingsOverlay(Room room) : base(room)
|
||||
{
|
||||
}
|
||||
|
||||
public void ClickApplyButton(ManualInputManager inputManager)
|
||||
{
|
||||
inputManager.MoveMouseTo(ApplyButton);
|
||||
inputManager.Click(MouseButton.Left);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
50
osu.Game.Tests/Visual/TestCaseRoomStatus.cs
Normal file
50
osu.Game.Tests/Visual/TestCaseRoomStatus.cs
Normal file
@ -0,0 +1,50 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.RoomStatuses;
|
||||
using osu.Game.Screens.Multi.Lounge.Components;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseRoomStatus : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(RoomStatusEnded),
|
||||
typeof(RoomStatusOpen),
|
||||
typeof(RoomStatusPlaying)
|
||||
};
|
||||
|
||||
public TestCaseRoomStatus()
|
||||
{
|
||||
Child = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0.5f,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new DrawableRoom(new Room
|
||||
{
|
||||
Name = { Value = "Room 1" },
|
||||
Status = { Value = new RoomStatusOpen() }
|
||||
}),
|
||||
new DrawableRoom(new Room
|
||||
{
|
||||
Name = { Value = "Room 2" },
|
||||
Status = { Value = new RoomStatusPlaying() }
|
||||
}),
|
||||
new DrawableRoom(new Room
|
||||
{
|
||||
Name = { Value = "Room 3" },
|
||||
Status = { Value = new RoomStatusEnded() }
|
||||
}),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
// 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.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Tests.Beatmaps.IO;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseUpdateableBeatmapBackgroundSprite : OsuTestCase
|
||||
{
|
||||
private UpdateableBeatmapBackgroundSprite backgroundSprite;
|
||||
|
||||
[Resolved]
|
||||
private BeatmapManager beatmaps { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGameBase osu, APIAccess api, RulesetStore rulesets)
|
||||
{
|
||||
Bindable<BeatmapInfo> beatmapBindable = new Bindable<BeatmapInfo>();
|
||||
|
||||
var imported = ImportBeatmapTest.LoadOszIntoOsu(osu);
|
||||
|
||||
Child = backgroundSprite = new UpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both };
|
||||
|
||||
backgroundSprite.Beatmap.BindTo(beatmapBindable);
|
||||
|
||||
var req = new GetBeatmapSetRequest(1);
|
||||
api.Queue(req);
|
||||
|
||||
AddStep("null", () => beatmapBindable.Value = null);
|
||||
|
||||
AddStep("imported", () => beatmapBindable.Value = imported.Beatmaps.First());
|
||||
|
||||
if (api.IsLoggedIn)
|
||||
{
|
||||
AddUntilStep(() => req.Result != null, "wait for api response");
|
||||
|
||||
AddStep("online", () => beatmapBindable.Value = new BeatmapInfo
|
||||
{
|
||||
BeatmapSet = req.Result?.ToBeatmapSet(rulesets)
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
AddStep("online (login first)", () => { });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -59,7 +59,7 @@ namespace osu.Game.Beatmaps
|
||||
/// <summary>
|
||||
/// A default representation of a WorkingBeatmap to use when no beatmap is available.
|
||||
/// </summary>
|
||||
public WorkingBeatmap DefaultBeatmap { private get; set; }
|
||||
public readonly WorkingBeatmap DefaultBeatmap;
|
||||
|
||||
public override string[] HandledExtensions => new[] { ".osz" };
|
||||
|
||||
@ -77,16 +77,19 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
private readonly List<DownloadBeatmapSetRequest> currentDownloads = new List<DownloadBeatmapSetRequest>();
|
||||
|
||||
public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, APIAccess api, AudioManager audioManager, IIpcHost importHost = null)
|
||||
public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, APIAccess api, AudioManager audioManager, IIpcHost importHost = null,
|
||||
WorkingBeatmap defaultBeatmap = null)
|
||||
: base(storage, contextFactory, new BeatmapStore(contextFactory), importHost)
|
||||
{
|
||||
beatmaps = (BeatmapStore)ModelStore;
|
||||
beatmaps.BeatmapHidden += b => BeatmapHidden?.Invoke(b);
|
||||
beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b);
|
||||
|
||||
this.rulesets = rulesets;
|
||||
this.api = api;
|
||||
this.audioManager = audioManager;
|
||||
|
||||
DefaultBeatmap = defaultBeatmap;
|
||||
|
||||
beatmaps = (BeatmapStore)ModelStore;
|
||||
beatmaps.BeatmapHidden += b => BeatmapHidden?.Invoke(b);
|
||||
beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b);
|
||||
}
|
||||
|
||||
protected override void Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive)
|
||||
|
@ -23,7 +23,7 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
private void load(LargeTextureStore textures)
|
||||
{
|
||||
string resource = null;
|
||||
|
||||
|
@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Rulesets;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
@ -16,15 +17,16 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
{
|
||||
public class DifficultyIcon : DifficultyColouredContainer
|
||||
{
|
||||
private readonly BeatmapInfo beatmap;
|
||||
private readonly RulesetInfo ruleset;
|
||||
|
||||
public DifficultyIcon(BeatmapInfo beatmap)
|
||||
public DifficultyIcon(BeatmapInfo beatmap, RulesetInfo ruleset = null)
|
||||
: base(beatmap)
|
||||
{
|
||||
if (beatmap == null)
|
||||
throw new ArgumentNullException(nameof(beatmap));
|
||||
|
||||
this.beatmap = beatmap;
|
||||
this.ruleset = ruleset ?? beatmap.Ruleset;
|
||||
|
||||
Size = new Vector2(20);
|
||||
}
|
||||
|
||||
@ -58,7 +60,7 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
// the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment)
|
||||
Icon = beatmap.Ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.fa_question_circle_o }
|
||||
Icon = ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.fa_question_circle_o }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
|
||||
namespace osu.Game.Beatmaps.Drawables
|
||||
{
|
||||
/// <summary>
|
||||
/// Display a baetmap background from a local source, but fallback to online source if not available.
|
||||
/// </summary>
|
||||
public class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable<BeatmapInfo>
|
||||
{
|
||||
public readonly IBindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
|
||||
|
||||
[Resolved]
|
||||
private BeatmapManager beatmaps { get; set; }
|
||||
|
||||
public UpdateableBeatmapBackgroundSprite()
|
||||
{
|
||||
Beatmap.BindValueChanged(b => Model = b);
|
||||
}
|
||||
|
||||
protected override Drawable CreateDrawable(BeatmapInfo model)
|
||||
{
|
||||
return new DelayedLoadUnloadWrapper(() => {
|
||||
Drawable drawable;
|
||||
|
||||
var localBeatmap = beatmaps.GetWorkingBeatmap(model);
|
||||
|
||||
if (localBeatmap.BeatmapInfo.ID == 0 && model?.BeatmapSet?.OnlineInfo != null)
|
||||
drawable = new BeatmapSetCover(model.BeatmapSet);
|
||||
else
|
||||
drawable = new BeatmapBackgroundSprite(localBeatmap);
|
||||
|
||||
drawable.RelativeSizeAxes = Axes.Both;
|
||||
drawable.Anchor = Anchor.Centre;
|
||||
drawable.Origin = Anchor.Centre;
|
||||
drawable.FillMode = FillMode.Fill;
|
||||
drawable.OnLoadComplete = d => d.FadeInFromZero(400);
|
||||
|
||||
return drawable;
|
||||
}, 500, 10000);
|
||||
}
|
||||
|
||||
protected override double FadeDuration => 0;
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
@ -61,11 +62,25 @@ namespace osu.Game.Graphics.Containers
|
||||
}
|
||||
|
||||
public void AddLink(string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
||||
=> createLink(AddText(text, creationParameters), text, url, linkType, linkArgument, tooltipText);
|
||||
|
||||
public void AddLink(string text, Action action, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
||||
=> createLink(AddText(text, creationParameters), text, tooltipText: tooltipText, action: action);
|
||||
|
||||
public void AddLink(IEnumerable<SpriteText> text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null)
|
||||
{
|
||||
AddInternal(new DrawableLinkCompiler(AddText(text, creationParameters).ToList())
|
||||
foreach (var t in text)
|
||||
AddArbitraryDrawable(t);
|
||||
|
||||
createLink(text, null, url, linkType, linkArgument, tooltipText);
|
||||
}
|
||||
|
||||
private void createLink(IEnumerable<Drawable> drawables, string text, string url = null, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action action = null)
|
||||
{
|
||||
AddInternal(new DrawableLinkCompiler(drawables.OfType<SpriteText>().ToList())
|
||||
{
|
||||
TooltipText = tooltipText ?? (url != text ? url : string.Empty),
|
||||
Action = () =>
|
||||
Action = action ?? (() =>
|
||||
{
|
||||
switch (linkType)
|
||||
{
|
||||
@ -104,7 +119,7 @@ namespace osu.Game.Graphics.Containers
|
||||
default:
|
||||
throw new NotImplementedException($"This {nameof(LinkAction)} ({linkType.ToString()}) is missing an associated action.");
|
||||
}
|
||||
},
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +145,8 @@ namespace osu.Game.Online.API
|
||||
|
||||
if (!handleRequest(userReq))
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
if (State == APIState.Connecting)
|
||||
State = APIState.Failing;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ namespace osu.Game.Online.API
|
||||
/// </summary>
|
||||
public abstract class APIRequest
|
||||
{
|
||||
protected virtual string Target => string.Empty;
|
||||
protected abstract string Target { get; }
|
||||
|
||||
protected virtual WebRequest CreateWebRequest() => new WebRequest(Uri);
|
||||
|
||||
@ -92,7 +92,11 @@ namespace osu.Game.Online.API
|
||||
|
||||
public void Fail(Exception e)
|
||||
{
|
||||
if (cancelled) return;
|
||||
if (WebRequest?.Completed == true)
|
||||
return;
|
||||
|
||||
if (cancelled)
|
||||
return;
|
||||
|
||||
cancelled = true;
|
||||
WebRequest?.Abort();
|
||||
|
35
osu.Game/Online/API/Requests/CreateRoomRequest.cs
Normal file
35
osu.Game/Online/API/Requests/CreateRoomRequest.cs
Normal file
@ -0,0 +1,35 @@
|
||||
// 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.Net.Http;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Framework.IO.Network;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class CreateRoomRequest : APIRequest<APICreatedRoom>
|
||||
{
|
||||
private readonly Room room;
|
||||
|
||||
public CreateRoomRequest(Room room)
|
||||
{
|
||||
this.room = room;
|
||||
}
|
||||
|
||||
protected override WebRequest CreateWebRequest()
|
||||
{
|
||||
var req = base.CreateWebRequest();
|
||||
|
||||
req.ContentType = "application/json";
|
||||
req.Method = HttpMethod.Post;
|
||||
|
||||
req.AddRaw(JsonConvert.SerializeObject(room));
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
protected override string Target => "rooms";
|
||||
}
|
||||
}
|
30
osu.Game/Online/API/Requests/CreateRoomScoreRequest.cs
Normal file
30
osu.Game/Online/API/Requests/CreateRoomScoreRequest.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// 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.Net.Http;
|
||||
using osu.Framework.IO.Network;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class CreateRoomScoreRequest : APIRequest<APIScoreToken>
|
||||
{
|
||||
private readonly int roomId;
|
||||
private readonly int playlistItemId;
|
||||
|
||||
public CreateRoomScoreRequest(int roomId, int playlistItemId)
|
||||
{
|
||||
this.roomId = roomId;
|
||||
this.playlistItemId = playlistItemId;
|
||||
}
|
||||
|
||||
protected override WebRequest CreateWebRequest()
|
||||
{
|
||||
var req = base.CreateWebRequest();
|
||||
req.Method = HttpMethod.Post;
|
||||
return req;
|
||||
}
|
||||
|
||||
protected override string Target => $@"rooms/{roomId}/playlist/{playlistItemId}/scores";
|
||||
}
|
||||
}
|
20
osu.Game/Online/API/Requests/GetRoomScoresRequest.cs
Normal file
20
osu.Game/Online/API/Requests/GetRoomScoresRequest.cs
Normal file
@ -0,0 +1,20 @@
|
||||
// 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.Generic;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetRoomScoresRequest : APIRequest<List<APIRoomScoreInfo>>
|
||||
{
|
||||
private readonly int roomId;
|
||||
|
||||
public GetRoomScoresRequest(int roomId)
|
||||
{
|
||||
this.roomId = roomId;
|
||||
}
|
||||
|
||||
protected override string Target => $@"rooms/{roomId}/leaderboard";
|
||||
}
|
||||
}
|
44
osu.Game/Online/API/Requests/GetRoomsRequest.cs
Normal file
44
osu.Game/Online/API/Requests/GetRoomsRequest.cs
Normal file
@ -0,0 +1,44 @@
|
||||
// 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.Generic;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Screens.Multi.Lounge.Components;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetRoomsRequest : APIRequest<List<Room>>
|
||||
{
|
||||
private readonly PrimaryFilter primaryFilter;
|
||||
|
||||
public GetRoomsRequest(PrimaryFilter primaryFilter)
|
||||
{
|
||||
this.primaryFilter = primaryFilter;
|
||||
}
|
||||
|
||||
protected override string Target
|
||||
{
|
||||
get
|
||||
{
|
||||
string target = "rooms";
|
||||
|
||||
switch (primaryFilter)
|
||||
{
|
||||
case PrimaryFilter.Open:
|
||||
break;
|
||||
case PrimaryFilter.Owned:
|
||||
target += "/owned";
|
||||
break;
|
||||
case PrimaryFilter.Participated:
|
||||
target += "/participated";
|
||||
break;
|
||||
case PrimaryFilter.RecentlyEnded:
|
||||
target += "/ended";
|
||||
break;
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
31
osu.Game/Online/API/Requests/JoinRoomRequest.cs
Normal file
31
osu.Game/Online/API/Requests/JoinRoomRequest.cs
Normal file
@ -0,0 +1,31 @@
|
||||
// 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.Net.Http;
|
||||
using osu.Framework.IO.Network;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class JoinRoomRequest : APIRequest
|
||||
{
|
||||
private readonly Room room;
|
||||
private readonly User user;
|
||||
|
||||
public JoinRoomRequest(Room room, User user)
|
||||
{
|
||||
this.room = room;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
protected override WebRequest CreateWebRequest()
|
||||
{
|
||||
var req = base.CreateWebRequest();
|
||||
req.Method = HttpMethod.Put;
|
||||
return req;
|
||||
}
|
||||
|
||||
protected override string Target => $"rooms/{room.RoomID.Value}/users/{user.Id}";
|
||||
}
|
||||
}
|
31
osu.Game/Online/API/Requests/PartRoomRequest.cs
Normal file
31
osu.Game/Online/API/Requests/PartRoomRequest.cs
Normal file
@ -0,0 +1,31 @@
|
||||
// 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.Net.Http;
|
||||
using osu.Framework.IO.Network;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class PartRoomRequest : APIRequest
|
||||
{
|
||||
private readonly Room room;
|
||||
private readonly User user;
|
||||
|
||||
public PartRoomRequest(Room room, User user)
|
||||
{
|
||||
this.room = room;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
protected override WebRequest CreateWebRequest()
|
||||
{
|
||||
var req = base.CreateWebRequest();
|
||||
req.Method = HttpMethod.Delete;
|
||||
return req;
|
||||
}
|
||||
|
||||
protected override string Target => $"rooms/{room.RoomID.Value}/users/{user.Id}";
|
||||
}
|
||||
}
|
@ -59,19 +59,17 @@ namespace osu.Game.Online.API.Requests.Responses
|
||||
|
||||
public BeatmapInfo ToBeatmap(RulesetStore rulesets)
|
||||
{
|
||||
var set = BeatmapSet?.ToBeatmapSet(rulesets);
|
||||
|
||||
return new BeatmapInfo
|
||||
{
|
||||
Metadata = this,
|
||||
Metadata = set?.Metadata ?? this,
|
||||
Ruleset = rulesets.GetRuleset(ruleset),
|
||||
StarDifficulty = starDifficulty,
|
||||
OnlineBeatmapID = OnlineBeatmapID,
|
||||
Version = version,
|
||||
Status = Status,
|
||||
BeatmapSet = new BeatmapSetInfo
|
||||
{
|
||||
OnlineBeatmapSetID = OnlineBeatmapSetID,
|
||||
Status = BeatmapSet?.Status ?? BeatmapSetOnlineStatus.None
|
||||
},
|
||||
BeatmapSet = set,
|
||||
BaseDifficulty = new BeatmapDifficulty
|
||||
{
|
||||
DrainRate = drainRate,
|
||||
|
14
osu.Game/Online/API/Requests/Responses/APICreatedRoom.cs
Normal file
14
osu.Game/Online/API/Requests/Responses/APICreatedRoom.cs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
|
||||
namespace osu.Game.Online.API.Requests.Responses
|
||||
{
|
||||
public class APICreatedRoom : Room
|
||||
{
|
||||
[JsonProperty("error")]
|
||||
public string Error { get; set; }
|
||||
}
|
||||
}
|
12
osu.Game/Online/API/Requests/Responses/APIMod.cs
Normal file
12
osu.Game/Online/API/Requests/Responses/APIMod.cs
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Rulesets.Mods;
|
||||
|
||||
namespace osu.Game.Online.API.Requests.Responses
|
||||
{
|
||||
public class APIMod : IMod
|
||||
{
|
||||
public string Acronym { get; set; }
|
||||
}
|
||||
}
|
17
osu.Game/Online/API/Requests/Responses/APIRoomScoreInfo.cs
Normal file
17
osu.Game/Online/API/Requests/Responses/APIRoomScoreInfo.cs
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Online.API.Requests.Responses
|
||||
{
|
||||
public class APIRoomScoreInfo : ScoreInfo
|
||||
{
|
||||
[JsonProperty("attempts")]
|
||||
public int TotalAttempts { get; set; }
|
||||
|
||||
[JsonProperty("completed")]
|
||||
public int CompletedBeatmaps { get; set; }
|
||||
}
|
||||
}
|
13
osu.Game/Online/API/Requests/Responses/APIScoreToken.cs
Normal file
13
osu.Game/Online/API/Requests/Responses/APIScoreToken.cs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace osu.Game.Online.API.Requests.Responses
|
||||
{
|
||||
public class APIScoreToken
|
||||
{
|
||||
[JsonProperty("id")]
|
||||
public int ID { get; set; }
|
||||
}
|
||||
}
|
40
osu.Game/Online/API/Requests/SubmitRoomScoreRequest.cs
Normal file
40
osu.Game/Online/API/Requests/SubmitRoomScoreRequest.cs
Normal file
@ -0,0 +1,40 @@
|
||||
// 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.Net.Http;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Framework.IO.Network;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class SubmitRoomScoreRequest : APIRequest
|
||||
{
|
||||
private readonly int scoreId;
|
||||
private readonly int roomId;
|
||||
private readonly int playlistItemId;
|
||||
private readonly ScoreInfo scoreInfo;
|
||||
|
||||
public SubmitRoomScoreRequest(int scoreId, int roomId, int playlistItemId, ScoreInfo scoreInfo)
|
||||
{
|
||||
this.scoreId = scoreId;
|
||||
this.roomId = roomId;
|
||||
this.playlistItemId = playlistItemId;
|
||||
this.scoreInfo = scoreInfo;
|
||||
}
|
||||
|
||||
protected override WebRequest CreateWebRequest()
|
||||
{
|
||||
var req = base.CreateWebRequest();
|
||||
|
||||
req.ContentType = "application/json";
|
||||
req.Method = HttpMethod.Put;
|
||||
|
||||
req.AddRaw(JsonConvert.SerializeObject(scoreInfo));
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
protected override string Target => $@"rooms/{roomId}/playlist/{playlistItemId}/scores/{scoreId}";
|
||||
}
|
||||
}
|
@ -19,10 +19,10 @@ namespace osu.Game.Online.Chat
|
||||
/// </summary>
|
||||
public class StandAloneChatDisplay : CompositeDrawable
|
||||
{
|
||||
private readonly bool postingTextbox;
|
||||
|
||||
public readonly Bindable<Channel> Channel = new Bindable<Channel>();
|
||||
|
||||
public Action Exit;
|
||||
|
||||
private readonly FocusedTextBox textbox;
|
||||
|
||||
protected ChannelManager ChannelManager;
|
||||
@ -31,6 +31,8 @@ namespace osu.Game.Online.Chat
|
||||
|
||||
private DrawableChannel drawableChannel;
|
||||
|
||||
private readonly bool postingTextbox;
|
||||
|
||||
private const float textbox_height = 30;
|
||||
|
||||
/// <summary>
|
||||
@ -66,6 +68,8 @@ namespace osu.Game.Online.Chat
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
});
|
||||
|
||||
textbox.Exit += () => Exit?.Invoke();
|
||||
}
|
||||
|
||||
Channel.BindValueChanged(channelChanged);
|
||||
|
@ -18,7 +18,7 @@ using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Online.Leaderboards
|
||||
{
|
||||
public abstract class Leaderboard<TScope, ScoreInfo> : Container
|
||||
public abstract class Leaderboard<TScope, ScoreInfo> : Container, IOnlineComponent
|
||||
{
|
||||
private const double fade_duration = 300;
|
||||
|
||||
@ -55,14 +55,8 @@ namespace osu.Game.Online.Leaderboards
|
||||
// ensure placeholder is hidden when displaying scores
|
||||
PlaceholderState = PlaceholderState.Successful;
|
||||
|
||||
var flow = scrollFlow = new FillFlowContainer<LeaderboardScore>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Spacing = new Vector2(0f, 5f),
|
||||
Padding = new MarginPadding { Top = 10, Bottom = 5 },
|
||||
ChildrenEnumerable = scores.Select((s, index) => CreateDrawableScore(s, index + 1))
|
||||
};
|
||||
scrollFlow = CreateScoreFlow();
|
||||
scrollFlow.ChildrenEnumerable = scores.Select((s, index) => CreateDrawableScore(s, index + 1));
|
||||
|
||||
// schedule because we may not be loaded yet (LoadComponentAsync complains).
|
||||
showScoresDelegate?.Cancel();
|
||||
@ -71,12 +65,12 @@ namespace osu.Game.Online.Leaderboards
|
||||
else
|
||||
showScores();
|
||||
|
||||
void showScores() => LoadComponentAsync(flow, _ =>
|
||||
void showScores() => LoadComponentAsync(scrollFlow, _ =>
|
||||
{
|
||||
scrollContainer.Add(flow);
|
||||
scrollContainer.Add(scrollFlow);
|
||||
|
||||
int i = 0;
|
||||
foreach (var s in flow.Children)
|
||||
foreach (var s in scrollFlow.Children)
|
||||
{
|
||||
using (s.BeginDelayedSequence(i++ * 50, true))
|
||||
s.Show();
|
||||
@ -87,6 +81,15 @@ namespace osu.Game.Online.Leaderboards
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual FillFlowContainer<LeaderboardScore> CreateScoreFlow()
|
||||
=> new FillFlowContainer<LeaderboardScore>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Spacing = new Vector2(0f, 5f),
|
||||
Padding = new MarginPadding { Top = 10, Bottom = 5 },
|
||||
};
|
||||
|
||||
private TScope scope;
|
||||
|
||||
public TScope Scope
|
||||
@ -175,26 +178,22 @@ namespace osu.Game.Online.Leaderboards
|
||||
private void load(APIAccess api)
|
||||
{
|
||||
this.api = api;
|
||||
|
||||
if (api != null)
|
||||
api.OnStateChange += handleApiStateChange;
|
||||
api?.Register(this);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (api != null)
|
||||
api.OnStateChange -= handleApiStateChange;
|
||||
api?.Unregister(this);
|
||||
}
|
||||
|
||||
public void RefreshScores() => UpdateScores();
|
||||
|
||||
private APIRequest getScoresRequest;
|
||||
|
||||
private void handleApiStateChange(APIState oldState, APIState newState)
|
||||
public void APIStateChanged(APIAccess api, APIState state)
|
||||
{
|
||||
if (newState == APIState.Online)
|
||||
if (state == APIState.Online)
|
||||
UpdateScores();
|
||||
}
|
||||
|
||||
@ -265,14 +264,18 @@ namespace osu.Game.Online.Leaderboards
|
||||
currentPlaceholder = placeholder;
|
||||
}
|
||||
|
||||
protected virtual bool FadeBottom => true;
|
||||
protected virtual bool FadeTop => false;
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
{
|
||||
base.UpdateAfterChildren();
|
||||
|
||||
var fadeStart = scrollContainer.Current + scrollContainer.DrawHeight;
|
||||
var fadeBottom = scrollContainer.Current + scrollContainer.DrawHeight;
|
||||
var fadeTop = scrollContainer.Current + LeaderboardScore.HEIGHT;
|
||||
|
||||
if (!scrollContainer.IsScrolledToEnd())
|
||||
fadeStart -= LeaderboardScore.HEIGHT;
|
||||
fadeBottom -= LeaderboardScore.HEIGHT;
|
||||
|
||||
if (scrollFlow == null)
|
||||
return;
|
||||
@ -282,15 +285,23 @@ namespace osu.Game.Online.Leaderboards
|
||||
var topY = c.ToSpaceOfOtherDrawable(Vector2.Zero, scrollFlow).Y;
|
||||
var bottomY = topY + LeaderboardScore.HEIGHT;
|
||||
|
||||
if (bottomY < fadeStart)
|
||||
bool requireTopFade = FadeTop && topY <= fadeTop;
|
||||
bool requireBottomFade = FadeBottom && bottomY >= fadeBottom;
|
||||
|
||||
if (!requireTopFade && !requireBottomFade)
|
||||
c.Colour = Color4.White;
|
||||
else if (topY > fadeStart + LeaderboardScore.HEIGHT)
|
||||
else if (topY > fadeBottom + LeaderboardScore.HEIGHT || bottomY < fadeTop - LeaderboardScore.HEIGHT)
|
||||
c.Colour = Color4.Transparent;
|
||||
else
|
||||
{
|
||||
c.Colour = ColourInfo.GradientVertical(
|
||||
Color4.White.Opacity(Math.Min(1 - (topY - fadeStart) / LeaderboardScore.HEIGHT, 1)),
|
||||
Color4.White.Opacity(Math.Min(1 - (bottomY - fadeStart) / LeaderboardScore.HEIGHT, 1)));
|
||||
if (bottomY - fadeBottom > 0 && FadeBottom)
|
||||
c.Colour = ColourInfo.GradientVertical(
|
||||
Color4.White.Opacity(Math.Min(1 - (topY - fadeBottom) / LeaderboardScore.HEIGHT, 1)),
|
||||
Color4.White.Opacity(Math.Min(1 - (bottomY - fadeBottom) / LeaderboardScore.HEIGHT, 1)));
|
||||
else if (FadeTop)
|
||||
c.Colour = ColourInfo.GradientVertical(
|
||||
Color4.White.Opacity(Math.Min(1 - (fadeTop - topY) / LeaderboardScore.HEIGHT, 1)),
|
||||
Color4.White.Opacity(Math.Min(1 - (fadeTop - bottomY) / LeaderboardScore.HEIGHT, 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,8 +73,8 @@ namespace osu.Game.Online.Leaderboards
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Font = @"Exo2.0-MediumItalic",
|
||||
TextSize = 22,
|
||||
// ReSharper disable once ImpureMethodCallOnReadonlyValueField
|
||||
|
@ -1,11 +1,7 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
|
||||
namespace osu.Game.Online.Multiplayer
|
||||
@ -13,137 +9,10 @@ namespace osu.Game.Online.Multiplayer
|
||||
public abstract class GameType
|
||||
{
|
||||
public abstract string Name { get; }
|
||||
|
||||
public abstract Drawable GetIcon(OsuColour colours, float size);
|
||||
|
||||
public override int GetHashCode() => GetType().GetHashCode();
|
||||
public override bool Equals(object obj) => GetType() == obj?.GetType();
|
||||
}
|
||||
|
||||
public class GameTypeTag : GameType
|
||||
{
|
||||
public override string Name => "Tag";
|
||||
public override Drawable GetIcon(OsuColour colours, float size)
|
||||
{
|
||||
return new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Icon = FontAwesome.fa_refresh,
|
||||
Size = new Vector2(size),
|
||||
Colour = colours.Blue,
|
||||
Shadow = false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class GameTypeVersus : GameType
|
||||
{
|
||||
public override string Name => "Versus";
|
||||
public override Drawable GetIcon(OsuColour colours, float size)
|
||||
{
|
||||
return new VersusRow(colours.Blue, colours.Blue, size * 0.6f)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class GameTypeTagTeam : GameType
|
||||
{
|
||||
public override string Name => "Tag Team";
|
||||
public override Drawable GetIcon(OsuColour colours, float size)
|
||||
{
|
||||
return new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(2f),
|
||||
Children = new[]
|
||||
{
|
||||
new SpriteIcon
|
||||
{
|
||||
Icon = FontAwesome.fa_refresh,
|
||||
Size = new Vector2(size * 0.75f),
|
||||
Colour = colours.Blue,
|
||||
Shadow = false,
|
||||
},
|
||||
new SpriteIcon
|
||||
{
|
||||
Icon = FontAwesome.fa_refresh,
|
||||
Size = new Vector2(size * 0.75f),
|
||||
Colour = colours.Pink,
|
||||
Shadow = false,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class GameTypeTeamVersus : GameType
|
||||
{
|
||||
public override string Name => "Team Versus";
|
||||
public override Drawable GetIcon(OsuColour colours, float size)
|
||||
{
|
||||
return new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(2f),
|
||||
Children = new[]
|
||||
{
|
||||
new VersusRow(colours.Blue, colours.Pink, size * 0.5f),
|
||||
new VersusRow(colours.Blue, colours.Pink, size * 0.5f),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class VersusRow : FillFlowContainer
|
||||
{
|
||||
public VersusRow(Color4 first, Color4 second, float size)
|
||||
{
|
||||
var triangleSize = new Vector2(size);
|
||||
AutoSizeAxes = Axes.Both;
|
||||
Spacing = new Vector2(2f, 0f);
|
||||
|
||||
Children = new[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Size = triangleSize,
|
||||
Colour = first,
|
||||
Children = new[]
|
||||
{
|
||||
new EquilateralTriangle
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Rotation = 90,
|
||||
EdgeSmoothness = new Vector2(1f),
|
||||
},
|
||||
},
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Size = triangleSize,
|
||||
Colour = second,
|
||||
Children = new[]
|
||||
{
|
||||
new EquilateralTriangle
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Rotation = -90,
|
||||
EdgeSmoothness = new Vector2(1f),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
27
osu.Game/Online/Multiplayer/GameTypes/GameTypeTag.cs
Normal file
27
osu.Game/Online/Multiplayer/GameTypes/GameTypeTag.cs
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Online.Multiplayer.GameTypes
|
||||
{
|
||||
public class GameTypeTag : GameType
|
||||
{
|
||||
public override string Name => "Tag";
|
||||
|
||||
public override Drawable GetIcon(OsuColour colours, float size)
|
||||
{
|
||||
return new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Icon = FontAwesome.fa_refresh,
|
||||
Size = new Vector2(size),
|
||||
Colour = colours.Blue,
|
||||
Shadow = false,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
44
osu.Game/Online/Multiplayer/GameTypes/GameTypeTagTeam.cs
Normal file
44
osu.Game/Online/Multiplayer/GameTypes/GameTypeTagTeam.cs
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Online.Multiplayer.GameTypes
|
||||
{
|
||||
public class GameTypeTagTeam : GameType
|
||||
{
|
||||
public override string Name => "Tag Team";
|
||||
|
||||
public override Drawable GetIcon(OsuColour colours, float size)
|
||||
{
|
||||
return new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(2f),
|
||||
Children = new[]
|
||||
{
|
||||
new SpriteIcon
|
||||
{
|
||||
Icon = FontAwesome.fa_refresh,
|
||||
Size = new Vector2(size * 0.75f),
|
||||
Colour = colours.Blue,
|
||||
Shadow = false,
|
||||
},
|
||||
new SpriteIcon
|
||||
{
|
||||
Icon = FontAwesome.fa_refresh,
|
||||
Size = new Vector2(size * 0.75f),
|
||||
Colour = colours.Pink,
|
||||
Shadow = false,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
32
osu.Game/Online/Multiplayer/GameTypes/GameTypeTeamVersus.cs
Normal file
32
osu.Game/Online/Multiplayer/GameTypes/GameTypeTeamVersus.cs
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Online.Multiplayer.GameTypes
|
||||
{
|
||||
public class GameTypeTeamVersus : GameType
|
||||
{
|
||||
public override string Name => "Team Versus";
|
||||
|
||||
public override Drawable GetIcon(OsuColour colours, float size)
|
||||
{
|
||||
return new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(2f),
|
||||
Children = new[]
|
||||
{
|
||||
new VersusRow(colours.Blue, colours.Pink, size * 0.5f),
|
||||
new VersusRow(colours.Blue, colours.Pink, size * 0.5f),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
24
osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs
Normal file
24
osu.Game/Online/Multiplayer/GameTypes/GameTypeTimeshift.cs
Normal 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
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Online.Multiplayer.GameTypes
|
||||
{
|
||||
public class GameTypeTimeshift : GameType
|
||||
{
|
||||
public override string Name => "Timeshift";
|
||||
|
||||
public override Drawable GetIcon(OsuColour colours, float size) => new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Icon = FontAwesome.fa_clock_o,
|
||||
Size = new Vector2(size),
|
||||
Colour = colours.Blue,
|
||||
Shadow = false
|
||||
};
|
||||
}
|
||||
}
|
22
osu.Game/Online/Multiplayer/GameTypes/GameTypeVersus.cs
Normal file
22
osu.Game/Online/Multiplayer/GameTypes/GameTypeVersus.cs
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics;
|
||||
|
||||
namespace osu.Game.Online.Multiplayer.GameTypes
|
||||
{
|
||||
public class GameTypeVersus : GameType
|
||||
{
|
||||
public override string Name => "Versus";
|
||||
|
||||
public override Drawable GetIcon(OsuColour colours, float size)
|
||||
{
|
||||
return new VersusRow(colours.Blue, colours.Blue, size * 0.6f)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
55
osu.Game/Online/Multiplayer/GameTypes/VersusRow.cs
Normal file
55
osu.Game/Online/Multiplayer/GameTypes/VersusRow.cs
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Online.Multiplayer.GameTypes
|
||||
{
|
||||
public class VersusRow : FillFlowContainer
|
||||
{
|
||||
public VersusRow(Color4 first, Color4 second, float size)
|
||||
{
|
||||
var triangleSize = new Vector2(size);
|
||||
AutoSizeAxes = Axes.Both;
|
||||
Spacing = new Vector2(2f, 0f);
|
||||
|
||||
Children = new[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Size = triangleSize,
|
||||
Colour = first,
|
||||
Children = new[]
|
||||
{
|
||||
new EquilateralTriangle
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Rotation = 90,
|
||||
EdgeSmoothness = new Vector2(1f),
|
||||
},
|
||||
},
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Size = triangleSize,
|
||||
Colour = second,
|
||||
Children = new[]
|
||||
{
|
||||
new EquilateralTriangle
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Rotation = -90,
|
||||
EdgeSmoothness = new Vector2(1f),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
93
osu.Game/Online/Multiplayer/PlaylistItem.cs
Normal file
93
osu.Game/Online/Multiplayer/PlaylistItem.cs
Normal file
@ -0,0 +1,93 @@
|
||||
// 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 Newtonsoft.Json;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
|
||||
namespace osu.Game.Online.Multiplayer
|
||||
{
|
||||
public class PlaylistItem
|
||||
{
|
||||
[JsonProperty("id")]
|
||||
public int ID { get; set; }
|
||||
|
||||
[JsonProperty("beatmap_id")]
|
||||
public int BeatmapID { get; set; }
|
||||
|
||||
[JsonProperty("ruleset_id")]
|
||||
public int RulesetID { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public BeatmapInfo Beatmap
|
||||
{
|
||||
get => beatmap;
|
||||
set
|
||||
{
|
||||
beatmap = value;
|
||||
BeatmapID = value?.OnlineBeatmapID ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public RulesetInfo Ruleset { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public readonly BindableCollection<Mod> AllowedMods = new BindableCollection<Mod>();
|
||||
|
||||
[JsonIgnore]
|
||||
public readonly BindableCollection<Mod> RequiredMods = new BindableCollection<Mod>();
|
||||
|
||||
[JsonProperty("beatmap")]
|
||||
private APIBeatmap apiBeatmap { get; set; }
|
||||
|
||||
[JsonProperty("allowed_mods")]
|
||||
private APIMod[] allowedMods
|
||||
{
|
||||
get => AllowedMods.Select(m => new APIMod { Acronym = m.Acronym }).ToArray();
|
||||
set => _allowedMods = value;
|
||||
}
|
||||
|
||||
[JsonProperty("required_mods")]
|
||||
private APIMod[] requiredMods
|
||||
{
|
||||
get => RequiredMods.Select(m => new APIMod { Acronym = m.Acronym }).ToArray();
|
||||
set => _requiredMods = value;
|
||||
}
|
||||
|
||||
private BeatmapInfo beatmap;
|
||||
private APIMod[] _allowedMods;
|
||||
private APIMod[] _requiredMods;
|
||||
|
||||
public void MapObjects(BeatmapManager beatmaps, RulesetStore rulesets)
|
||||
{
|
||||
// If we don't have an api beatmap, the request occurred as a result of room creation, so we can query the local beatmap instead
|
||||
// Todo: Is this a bug? Room creation only returns the beatmap ID
|
||||
Beatmap = apiBeatmap == null ? beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == BeatmapID) : apiBeatmap.ToBeatmap(rulesets);
|
||||
Ruleset = rulesets.GetRuleset(RulesetID);
|
||||
|
||||
if (_allowedMods != null)
|
||||
{
|
||||
AllowedMods.Clear();
|
||||
AllowedMods.AddRange(Ruleset.CreateInstance().GetAllMods().Where(mod => _allowedMods.Any(m => m.Acronym == mod.Acronym)));
|
||||
|
||||
_allowedMods = null;
|
||||
}
|
||||
|
||||
if (_requiredMods != null)
|
||||
{
|
||||
RequiredMods.Clear();
|
||||
RequiredMods.AddRange(Ruleset.CreateInstance().GetAllMods().Where(mod => _requiredMods.Any(m => m.Acronym == mod.Acronym)));
|
||||
|
||||
_requiredMods = null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShouldSerializeID() => false;
|
||||
public bool ShouldSerializeapiBeatmap() => false;
|
||||
}
|
||||
}
|
@ -1,22 +1,120 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.Multiplayer.GameTypes;
|
||||
using osu.Game.Online.Multiplayer.RoomStatuses;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Online.Multiplayer
|
||||
{
|
||||
public class Room
|
||||
{
|
||||
public Bindable<string> Name = new Bindable<string>();
|
||||
public Bindable<User> Host = new Bindable<User>();
|
||||
public Bindable<RoomStatus> Status = new Bindable<RoomStatus>();
|
||||
public Bindable<RoomAvailability> Availability = new Bindable<RoomAvailability>();
|
||||
public Bindable<GameType> Type = new Bindable<GameType>();
|
||||
public Bindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
|
||||
public Bindable<int?> MaxParticipants = new Bindable<int?>();
|
||||
public Bindable<IEnumerable<User>> Participants = new Bindable<IEnumerable<User>>();
|
||||
[JsonProperty("id")]
|
||||
public Bindable<int?> RoomID { get; private set; } = new Bindable<int?>();
|
||||
|
||||
[JsonProperty("name")]
|
||||
public Bindable<string> Name { get; private set; } = new Bindable<string>();
|
||||
|
||||
[JsonProperty("host")]
|
||||
public Bindable<User> Host { get; private set; } = new Bindable<User>();
|
||||
|
||||
[JsonProperty("playlist")]
|
||||
public BindableCollection<PlaylistItem> Playlist { get; set; } = new BindableCollection<PlaylistItem>();
|
||||
|
||||
[JsonProperty("channel_id")]
|
||||
public Bindable<int> ChannelId { get; private set; } = new Bindable<int>();
|
||||
|
||||
[JsonIgnore]
|
||||
public Bindable<TimeSpan> Duration { get; private set; } = new Bindable<TimeSpan>(TimeSpan.FromMinutes(30));
|
||||
|
||||
[JsonIgnore]
|
||||
public Bindable<int?> MaxAttempts { get; private set; } = new Bindable<int?>();
|
||||
|
||||
[JsonIgnore]
|
||||
public Bindable<RoomStatus> Status { get; private set; } = new Bindable<RoomStatus>(new RoomStatusOpen());
|
||||
|
||||
[JsonIgnore]
|
||||
public Bindable<RoomAvailability> Availability { get; private set; } = new Bindable<RoomAvailability>();
|
||||
|
||||
[JsonIgnore]
|
||||
public Bindable<GameType> Type { get; private set; } = new Bindable<GameType>(new GameTypeTimeshift());
|
||||
|
||||
[JsonIgnore]
|
||||
public Bindable<int?> MaxParticipants { get; private set; } = new Bindable<int?>();
|
||||
|
||||
[JsonIgnore]
|
||||
public Bindable<IEnumerable<User>> Participants { get; private set; } = new Bindable<IEnumerable<User>>(Enumerable.Empty<User>());
|
||||
|
||||
public Bindable<int> ParticipantCount { get; private set; } = new Bindable<int>();
|
||||
|
||||
// todo: TEMPORARY
|
||||
[JsonProperty("participant_count")]
|
||||
private int? participantCount
|
||||
{
|
||||
get => ParticipantCount;
|
||||
set => ParticipantCount.Value = value ?? 0;
|
||||
}
|
||||
|
||||
[JsonProperty("duration")]
|
||||
private int duration
|
||||
{
|
||||
get => (int)Duration.Value.TotalMinutes;
|
||||
set => Duration.Value = TimeSpan.FromMinutes(value);
|
||||
}
|
||||
|
||||
// Only supports retrieval for now
|
||||
[JsonProperty("ends_at")]
|
||||
public Bindable<DateTimeOffset> EndDate { get; private set; } = new Bindable<DateTimeOffset>();
|
||||
|
||||
// Todo: Find a better way to do this (https://github.com/ppy/osu-framework/issues/1930)
|
||||
[JsonProperty("max_attempts", DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
private int? maxAttempts
|
||||
{
|
||||
get => MaxAttempts;
|
||||
set => MaxAttempts.Value = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The position of this <see cref="Room"/> in the list. This is not read from or written to the API.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public int Position = -1;
|
||||
|
||||
public void CopyFrom(Room other)
|
||||
{
|
||||
RoomID.Value = other.RoomID;
|
||||
Name.Value = other.Name;
|
||||
|
||||
if (other.Host.Value != null && Host.Value?.Id != other.Host.Value.Id)
|
||||
Host.Value = other.Host;
|
||||
|
||||
Status.Value = other.Status;
|
||||
Availability.Value = other.Availability;
|
||||
Type.Value = other.Type;
|
||||
MaxParticipants.Value = other.MaxParticipants;
|
||||
ParticipantCount.Value = other.ParticipantCount.Value;
|
||||
Participants.Value = other.Participants.Value.ToArray();
|
||||
EndDate.Value = other.EndDate;
|
||||
|
||||
if (DateTimeOffset.Now >= EndDate.Value)
|
||||
Status.Value = new RoomStatusEnded();
|
||||
|
||||
// Todo: Temporary, should only remove/add new items (requires framework changes)
|
||||
if (Playlist.Count == 0)
|
||||
Playlist.AddRange(other.Playlist);
|
||||
else if (other.Playlist.Count > 0)
|
||||
Playlist.First().ID = other.Playlist.First().ID;
|
||||
|
||||
Position = other.Position;
|
||||
}
|
||||
|
||||
public bool ShouldSerializeRoomID() => false;
|
||||
public bool ShouldSerializeHost() => false;
|
||||
public bool ShouldSerializeEndDate() => false;
|
||||
}
|
||||
}
|
||||
|
@ -10,17 +10,8 @@ namespace osu.Game.Online.Multiplayer
|
||||
{
|
||||
public abstract string Message { get; }
|
||||
public abstract Color4 GetAppropriateColour(OsuColour colours);
|
||||
}
|
||||
|
||||
public class RoomStatusOpen : RoomStatus
|
||||
{
|
||||
public override string Message => @"Welcoming Players";
|
||||
public override Color4 GetAppropriateColour(OsuColour colours) => colours.GreenLight;
|
||||
}
|
||||
|
||||
public class RoomStatusPlaying : RoomStatus
|
||||
{
|
||||
public override string Message => @"Now Playing";
|
||||
public override Color4 GetAppropriateColour(OsuColour colours) => colours.Purple;
|
||||
public override int GetHashCode() => GetType().GetHashCode();
|
||||
public override bool Equals(object obj) => GetType() == obj?.GetType();
|
||||
}
|
||||
}
|
||||
|
14
osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusEnded.cs
Normal file
14
osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusEnded.cs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Graphics;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Online.Multiplayer.RoomStatuses
|
||||
{
|
||||
public class RoomStatusEnded : RoomStatus
|
||||
{
|
||||
public override string Message => @"Ended";
|
||||
public override Color4 GetAppropriateColour(OsuColour colours) => colours.YellowDarker;
|
||||
}
|
||||
}
|
14
osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusOpen.cs
Normal file
14
osu.Game/Online/Multiplayer/RoomStatuses/RoomStatusOpen.cs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Graphics;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Online.Multiplayer.RoomStatuses
|
||||
{
|
||||
public class RoomStatusOpen : RoomStatus
|
||||
{
|
||||
public override string Message => @"Welcoming Players";
|
||||
public override Color4 GetAppropriateColour(OsuColour colours) => colours.GreenLight;
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Graphics;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Online.Multiplayer.RoomStatuses
|
||||
{
|
||||
public class RoomStatusPlaying : RoomStatus
|
||||
{
|
||||
public override string Message => @"Now Playing";
|
||||
public override Color4 GetAppropriateColour(OsuColour colours) => colours.Purple;
|
||||
}
|
||||
}
|
@ -39,7 +39,7 @@ namespace osu.Game.Online
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="timeBetweenPolls">The initial time in milliseconds to wait between polls. Setting to zero stops al polling.</param>
|
||||
/// <param name="timeBetweenPolls">The initial time in milliseconds to wait between polls. Setting to zero stops all polling.</param>
|
||||
protected PollingComponent(double timeBetweenPolls = 0)
|
||||
{
|
||||
TimeBetweenPolls = timeBetweenPolls;
|
||||
@ -87,13 +87,22 @@ namespace osu.Game.Online
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform the polling in this method. Call <see cref="pollComplete"/> when done.
|
||||
/// Performs a poll. Implement but do not call this.
|
||||
/// </summary>
|
||||
protected virtual Task Poll()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Immediately performs a <see cref="Poll"/>.
|
||||
/// </summary>
|
||||
public void PollImmediately()
|
||||
{
|
||||
lastTimePolled = Time.Current - timeBetweenPolls;
|
||||
scheduleNextPoll();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call when a poll operation has completed.
|
||||
/// </summary>
|
||||
@ -103,7 +112,7 @@ namespace osu.Game.Online
|
||||
pollingActive = false;
|
||||
|
||||
if (scheduledPoll == null)
|
||||
scheduleNextPoll();
|
||||
pollIfNecessary();
|
||||
}
|
||||
|
||||
private void scheduleNextPoll()
|
||||
|
@ -317,7 +317,7 @@ namespace osu.Game
|
||||
Beatmap.Value = BeatmapManager.GetWorkingBeatmap(databasedBeatmap);
|
||||
Beatmap.Value.Mods.Value = databasedScoreInfo.Mods;
|
||||
|
||||
currentScreen.Push(new PlayerLoader(new ReplayPlayer(databasedScore)));
|
||||
currentScreen.Push(new PlayerLoader(() => new ReplayPlayer(databasedScore)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -690,10 +690,41 @@ namespace osu.Game
|
||||
MenuCursorContainer.CanShowCursor = currentScreen?.CursorVisible ?? false;
|
||||
}
|
||||
|
||||
private void screenAdded(Screen newScreen)
|
||||
/// <summary>
|
||||
/// Sets <see cref="Beatmap"/> while ignoring any beatmap.
|
||||
/// </summary>
|
||||
/// <param name="beatmap">The beatmap to set.</param>
|
||||
public void ForcefullySetBeatmap(WorkingBeatmap beatmap)
|
||||
{
|
||||
var beatmapDisabled = Beatmap.Disabled;
|
||||
|
||||
Beatmap.Disabled = false;
|
||||
Beatmap.Value = beatmap;
|
||||
Beatmap.Disabled = beatmapDisabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets <see cref="Ruleset"/> while ignoring any ruleset restrictions.
|
||||
/// </summary>
|
||||
/// <param name="beatmap">The beatmap to set.</param>
|
||||
public void ForcefullySetRuleset(RulesetInfo ruleset)
|
||||
{
|
||||
var rulesetDisabled = this.ruleset.Disabled;
|
||||
|
||||
this.ruleset.Disabled = false;
|
||||
this.ruleset.Value = ruleset;
|
||||
this.ruleset.Disabled = rulesetDisabled;
|
||||
}
|
||||
|
||||
protected virtual void ScreenChanged(OsuScreen current, Screen newScreen)
|
||||
{
|
||||
currentScreen = (OsuScreen)newScreen;
|
||||
Logger.Log($"Screen changed → {currentScreen}");
|
||||
}
|
||||
|
||||
private void screenAdded(Screen newScreen)
|
||||
{
|
||||
ScreenChanged(currentScreen, newScreen);
|
||||
Logger.Log($"Screen changed → {newScreen}");
|
||||
|
||||
newScreen.ModePushed += screenAdded;
|
||||
newScreen.Exited += screenRemoved;
|
||||
@ -701,7 +732,7 @@ namespace osu.Game
|
||||
|
||||
private void screenRemoved(Screen newScreen)
|
||||
{
|
||||
currentScreen = (OsuScreen)newScreen;
|
||||
ScreenChanged(currentScreen, newScreen);
|
||||
Logger.Log($"Screen changed ← {currentScreen}");
|
||||
|
||||
if (newScreen == null)
|
||||
|
@ -153,9 +153,12 @@ namespace osu.Game
|
||||
dependencies.Cache(API);
|
||||
dependencies.CacheAs<IAPIProvider>(API);
|
||||
|
||||
var defaultBeatmap = new DummyWorkingBeatmap(this);
|
||||
beatmap = new OsuBindableBeatmap(defaultBeatmap, Audio);
|
||||
|
||||
dependencies.Cache(RulesetStore = new RulesetStore(contextFactory));
|
||||
dependencies.Cache(FileStore = new FileStore(contextFactory, Host.Storage));
|
||||
dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, contextFactory, RulesetStore, API, Audio, Host));
|
||||
dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, contextFactory, RulesetStore, API, Audio, Host, defaultBeatmap));
|
||||
dependencies.Cache(ScoreManager = new ScoreManager(RulesetStore, BeatmapManager, Host.Storage, contextFactory, Host));
|
||||
dependencies.Cache(KeyBindingStore = new KeyBindingStore(contextFactory, RulesetStore));
|
||||
dependencies.Cache(SettingsStore = new SettingsStore(contextFactory));
|
||||
@ -166,10 +169,6 @@ namespace osu.Game
|
||||
fileImporters.Add(ScoreManager);
|
||||
fileImporters.Add(SkinManager);
|
||||
|
||||
var defaultBeatmap = new DummyWorkingBeatmap(this);
|
||||
beatmap = new OsuBindableBeatmap(defaultBeatmap, Audio);
|
||||
BeatmapManager.DefaultBeatmap = defaultBeatmap;
|
||||
|
||||
// tracks play so loud our samples can't keep up.
|
||||
// this adds a global reduction of track volume for the time being.
|
||||
Audio.Track.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8));
|
||||
@ -261,7 +260,7 @@ namespace osu.Game
|
||||
RegisterAudioManager(audioManager);
|
||||
}
|
||||
|
||||
private OsuBindableBeatmap(WorkingBeatmap defaultValue)
|
||||
public OsuBindableBeatmap(WorkingBeatmap defaultValue)
|
||||
: base(defaultValue)
|
||||
{
|
||||
}
|
||||
|
@ -3,10 +3,12 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
@ -110,7 +112,7 @@ namespace osu.Game.Overlays.Music
|
||||
{
|
||||
sprite.TextSize = 16;
|
||||
sprite.Font = @"Exo2.0-Regular";
|
||||
});
|
||||
}).OfType<SpriteText>();
|
||||
|
||||
text.AddText(artistBind.Value, sprite =>
|
||||
{
|
||||
|
@ -17,6 +17,7 @@ using osu.Game.Graphics;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using RectangleF = osu.Framework.Graphics.Primitives.RectangleF;
|
||||
using Container = osu.Framework.Graphics.Containers.Container;
|
||||
|
||||
@ -86,25 +87,29 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
};
|
||||
break;
|
||||
case APIState.Failing:
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = "Connection failing :(",
|
||||
},
|
||||
};
|
||||
break;
|
||||
case APIState.Connecting:
|
||||
LinkFlowContainer linkFlow;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
new LoadingAnimation
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Text = "Connecting...",
|
||||
State = Visibility.Visible,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
},
|
||||
linkFlow = new LinkFlowContainer
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
TextAnchor = Anchor.TopCentre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Text = state == APIState.Failing ? "Connection is failing, will attempt to reconnect... " : "Attempting to connect... ",
|
||||
Margin = new MarginPadding { Top = 10, Bottom = 10 },
|
||||
},
|
||||
};
|
||||
|
||||
linkFlow.AddLink("cancel", api.Logout, string.Empty);
|
||||
break;
|
||||
case APIState.Online:
|
||||
Children = new Drawable[]
|
||||
|
@ -1,6 +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 Newtonsoft.Json;
|
||||
|
||||
namespace osu.Game.Rulesets.Mods
|
||||
{
|
||||
public interface IMod
|
||||
@ -8,6 +10,7 @@ namespace osu.Game.Rulesets.Mods
|
||||
/// <summary>
|
||||
/// The shortened name of this mod.
|
||||
/// </summary>
|
||||
[JsonProperty("acronym")]
|
||||
string Acronym { get; }
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Mods
|
||||
|
||||
public override bool HasImplementation => GetType().GenericTypeArguments.Length == 0;
|
||||
|
||||
public virtual void ApplyToRulesetContainer(RulesetContainer<T> rulesetContainer) => rulesetContainer.SetReplay(CreateReplayScore(rulesetContainer.Beatmap)?.Replay);
|
||||
public virtual void ApplyToRulesetContainer(RulesetContainer<T> rulesetContainer) => rulesetContainer.SetReplayScore(CreateReplayScore(rulesetContainer.Beatmap));
|
||||
}
|
||||
|
||||
public abstract class ModAutoplay : Mod, IApplicableFailOverride
|
||||
|
@ -2,8 +2,11 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Extensions.TypeExtensions;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
@ -57,6 +60,11 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// </summary>
|
||||
public readonly BindableInt Combo = new BindableInt();
|
||||
|
||||
/// <summary>
|
||||
/// Create a <see cref="HitWindows"/> for this processor.
|
||||
/// </summary>
|
||||
protected virtual HitWindows CreateHitWindows() => new HitWindows();
|
||||
|
||||
/// <summary>
|
||||
/// The current rank.
|
||||
/// </summary>
|
||||
@ -166,7 +174,16 @@ namespace osu.Game.Rulesets.Scoring
|
||||
score.Accuracy = Math.Round(Accuracy, 4);
|
||||
score.Rank = Rank;
|
||||
score.Date = DateTimeOffset.Now;
|
||||
|
||||
var hitWindows = CreateHitWindows();
|
||||
|
||||
foreach (var result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Where(r => r > HitResult.None && hitWindows.IsHitResultAllowed(r)))
|
||||
score.Statistics[result] = GetStatistic(result);
|
||||
}
|
||||
|
||||
protected abstract int GetStatistic(HitResult result);
|
||||
|
||||
public abstract double GetStandardisedScore();
|
||||
}
|
||||
|
||||
public class ScoreProcessor<TObject> : ScoreProcessor
|
||||
@ -273,6 +290,8 @@ namespace osu.Game.Rulesets.Scoring
|
||||
updateScore();
|
||||
}
|
||||
|
||||
private readonly Dictionary<HitResult, int> scoreResultCounts = new Dictionary<HitResult, int>();
|
||||
|
||||
/// <summary>
|
||||
/// Applies the score change of a <see cref="JudgementResult"/> to this <see cref="ScoreProcessor"/>.
|
||||
/// </summary>
|
||||
@ -284,6 +303,9 @@ namespace osu.Game.Rulesets.Scoring
|
||||
|
||||
JudgedHits++;
|
||||
|
||||
if (result.Type != HitResult.None)
|
||||
scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1;
|
||||
|
||||
if (result.Judgement.AffectsCombo)
|
||||
{
|
||||
switch (result.Type)
|
||||
@ -340,20 +362,30 @@ namespace osu.Game.Rulesets.Scoring
|
||||
if (rollingMaxBaseScore != 0)
|
||||
Accuracy.Value = baseScore / rollingMaxBaseScore;
|
||||
|
||||
switch (Mode.Value)
|
||||
TotalScore.Value = getScore(Mode.Value);
|
||||
}
|
||||
|
||||
private double getScore(ScoringMode mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
default:
|
||||
case ScoringMode.Standardised:
|
||||
TotalScore.Value = max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo / maxHighestCombo) + bonusScore;
|
||||
break;
|
||||
return max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo / maxHighestCombo) + bonusScore;
|
||||
case ScoringMode.Classic:
|
||||
// should emulate osu-stable's scoring as closely as we can (https://osu.ppy.sh/help/wiki/Score/ScoreV1)
|
||||
TotalScore.Value = bonusScore + baseScore * (1 + Math.Max(0, HighestCombo - 1) / 25);
|
||||
break;
|
||||
return bonusScore + baseScore * (1 + Math.Max(0, HighestCombo - 1) / 25);
|
||||
}
|
||||
}
|
||||
|
||||
protected override int GetStatistic(HitResult result) => scoreResultCounts.GetOrDefault(result);
|
||||
|
||||
public override double GetStandardisedScore() => getScore(ScoringMode.Standardised);
|
||||
|
||||
protected override void Reset(bool storeResults)
|
||||
{
|
||||
scoreResultCounts.Clear();
|
||||
|
||||
if (storeResults)
|
||||
{
|
||||
MaxHits = JudgedHits;
|
||||
|
@ -22,6 +22,7 @@ using osu.Game.Overlays;
|
||||
using osu.Game.Replays;
|
||||
using osu.Game.Rulesets.Configuration;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.UI
|
||||
{
|
||||
@ -130,7 +131,7 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
protected virtual ReplayInputHandler CreateReplayInputHandler(Replay replay) => null;
|
||||
|
||||
public Replay Replay { get; private set; }
|
||||
public Score ReplayScore { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the game is paused. Used to block user input.
|
||||
@ -140,14 +141,14 @@ namespace osu.Game.Rulesets.UI
|
||||
/// <summary>
|
||||
/// Sets a replay to be used, overriding local input.
|
||||
/// </summary>
|
||||
/// <param name="replay">The replay, null for local input.</param>
|
||||
public virtual void SetReplay(Replay replay)
|
||||
/// <param name="replayScore">The replay, null for local input.</param>
|
||||
public virtual void SetReplayScore(Score replayScore)
|
||||
{
|
||||
if (ReplayInputManager == null)
|
||||
throw new InvalidOperationException($"A {nameof(KeyBindingInputManager)} which supports replay loading is not available");
|
||||
|
||||
Replay = replay;
|
||||
ReplayInputManager.ReplayInputHandler = replay != null ? CreateReplayInputHandler(replay) : null;
|
||||
ReplayScore = replayScore;
|
||||
ReplayInputManager.ReplayInputHandler = replayScore != null ? CreateReplayInputHandler(replayScore.Replay) : null;
|
||||
|
||||
HasReplayLoaded.Value = ReplayInputManager.ReplayInputHandler != null;
|
||||
}
|
||||
@ -302,9 +303,9 @@ namespace osu.Game.Rulesets.UI
|
||||
mod.ReadFromConfig(config);
|
||||
}
|
||||
|
||||
public override void SetReplay(Replay replay)
|
||||
public override void SetReplayScore(Score replayScore)
|
||||
{
|
||||
base.SetReplay(replay);
|
||||
base.SetReplayScore(replayScore);
|
||||
|
||||
if (ReplayInputManager?.ReplayInputHandler != null)
|
||||
ReplayInputManager.ReplayInputHandler.GamefieldToScreenSpace = Playfield.GamefieldToScreenSpace;
|
||||
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Rulesets;
|
||||
@ -19,25 +20,39 @@ namespace osu.Game.Scoring
|
||||
{
|
||||
public int ID { get; set; }
|
||||
|
||||
[JsonProperty("rank")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public ScoreRank Rank { get; set; }
|
||||
|
||||
[JsonProperty("total_score")]
|
||||
public int TotalScore { get; set; }
|
||||
|
||||
[JsonProperty("accuracy")]
|
||||
[Column(TypeName="DECIMAL(1,4)")]
|
||||
public double Accuracy { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public double? PP { get; set; }
|
||||
|
||||
[JsonProperty("max_combo")]
|
||||
public int MaxCombo { get; set; }
|
||||
|
||||
public int Combo { get; set; }
|
||||
[JsonIgnore]
|
||||
public int Combo { get; set; } // Todo: Shouldn't exist in here
|
||||
|
||||
[JsonIgnore]
|
||||
public int RulesetID { get; set; }
|
||||
|
||||
[JsonProperty("passed")]
|
||||
[NotMapped]
|
||||
public bool Passed { get; set; } = true;
|
||||
|
||||
[JsonIgnore]
|
||||
public virtual RulesetInfo Ruleset { get; set; }
|
||||
|
||||
private Mod[] mods;
|
||||
|
||||
[JsonProperty("mods")]
|
||||
[NotMapped]
|
||||
public Mod[] Mods
|
||||
{
|
||||
@ -62,6 +77,7 @@ namespace osu.Game.Scoring
|
||||
|
||||
private string modsJson;
|
||||
|
||||
[JsonIgnore]
|
||||
[Column("Mods")]
|
||||
public string ModsJson
|
||||
{
|
||||
@ -84,9 +100,11 @@ namespace osu.Game.Scoring
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public User User;
|
||||
[NotMapped]
|
||||
[JsonProperty("user")]
|
||||
public User User { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[Column("User")]
|
||||
public string UserString
|
||||
{
|
||||
@ -97,15 +115,19 @@ namespace osu.Game.Scoring
|
||||
[JsonIgnore]
|
||||
public int BeatmapInfoID { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public virtual BeatmapInfo Beatmap { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public long? OnlineScoreID { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public DateTimeOffset Date { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[JsonProperty("statistics")]
|
||||
public Dictionary<HitResult, int> Statistics = new Dictionary<HitResult, int>();
|
||||
|
||||
[JsonIgnore]
|
||||
[Column("Statistics")]
|
||||
public string StatisticsJson
|
||||
{
|
||||
@ -125,8 +147,10 @@ namespace osu.Game.Scoring
|
||||
[JsonIgnore]
|
||||
public List<ScoreFileInfo> Files { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string Hash { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public bool DeletePending { get; set; }
|
||||
|
||||
[Serializable]
|
||||
|
@ -17,7 +17,9 @@ using osu.Framework.Threading;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Input;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osuTK.Input;
|
||||
@ -90,7 +92,7 @@ namespace osu.Game.Screens.Menu
|
||||
buttonArea.Flow.CentreTarget = iconFacade;
|
||||
|
||||
buttonsPlay.Add(new Button(@"solo", @"button-solo-select", FontAwesome.fa_user, new Color4(102, 68, 204, 255), () => OnSolo?.Invoke(), WEDGE_WIDTH, Key.P));
|
||||
buttonsPlay.Add(new Button(@"multi", @"button-generic-select", FontAwesome.fa_users, new Color4(94, 63, 186, 255), () => OnMulti?.Invoke(), 0, Key.M));
|
||||
buttonsPlay.Add(new Button(@"multi", @"button-generic-select", FontAwesome.fa_users, new Color4(94, 63, 186, 255), onMulti, 0, Key.M));
|
||||
buttonsPlay.Add(new Button(@"chart", @"button-generic-select", FontAwesome.fa_osu_charts, new Color4(80, 53, 160, 255), () => OnChart?.Invoke()));
|
||||
buttonsPlay.ForEach(b => b.VisibleState = ButtonSystemState.Play);
|
||||
|
||||
@ -103,19 +105,41 @@ namespace osu.Game.Screens.Menu
|
||||
buttonArea.AddRange(buttonsTopLevel);
|
||||
}
|
||||
|
||||
private OsuGame game;
|
||||
[Resolved(CanBeNull = true)]
|
||||
private OsuGame game { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private APIAccess api { get; set; }
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private NotificationOverlay notifications { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(AudioManager audio, OsuGame game, IdleTracker idleTracker)
|
||||
private void load(AudioManager audio, IdleTracker idleTracker)
|
||||
{
|
||||
this.game = game;
|
||||
|
||||
isIdle.ValueChanged += updateIdleState;
|
||||
|
||||
if (idleTracker != null) isIdle.BindTo(idleTracker.IsIdle);
|
||||
|
||||
sampleBack = audio.Sample.Get(@"Menu/button-back-select");
|
||||
}
|
||||
|
||||
private void onMulti()
|
||||
{
|
||||
if (!api.IsLoggedIn)
|
||||
{
|
||||
notifications?.Post(new SimpleNotification
|
||||
{
|
||||
Text = "You gotta be logged in to multi 'yo!",
|
||||
Icon = FontAwesome.fa_globe
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
OnMulti?.Invoke();
|
||||
}
|
||||
|
||||
private void updateIdleState(bool isIdle)
|
||||
{
|
||||
if (isIdle && State != ButtonSystemState.Exit)
|
||||
|
@ -1,68 +1,89 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Chat;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Components
|
||||
{
|
||||
public class BeatmapTitle : FillFlowContainer<OsuSpriteText>
|
||||
public class BeatmapTitle : CompositeDrawable
|
||||
{
|
||||
private readonly OsuSpriteText beatmapTitle, beatmapDash, beatmapArtist;
|
||||
public readonly IBindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
|
||||
|
||||
public float TextSize
|
||||
{
|
||||
set { beatmapTitle.TextSize = beatmapDash.TextSize = beatmapArtist.TextSize = value; }
|
||||
}
|
||||
|
||||
private BeatmapInfo beatmap;
|
||||
|
||||
public BeatmapInfo Beatmap
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value == beatmap) return;
|
||||
beatmap = value;
|
||||
|
||||
if (IsLoaded)
|
||||
updateText();
|
||||
}
|
||||
}
|
||||
private readonly LinkFlowContainer textFlow;
|
||||
|
||||
public BeatmapTitle()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
Direction = FillDirection.Horizontal;
|
||||
|
||||
Children = new[]
|
||||
{
|
||||
beatmapTitle = new OsuSpriteText { Font = @"Exo2.0-BoldItalic", },
|
||||
beatmapDash = new OsuSpriteText { Font = @"Exo2.0-BoldItalic", },
|
||||
beatmapArtist = new OsuSpriteText { Font = @"Exo2.0-RegularItalic", },
|
||||
};
|
||||
InternalChild = textFlow = new LinkFlowContainer { AutoSizeAxes = Axes.Both };
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
updateText();
|
||||
Beatmap.BindValueChanged(v => updateText(), true);
|
||||
}
|
||||
|
||||
private float textSize = OsuSpriteText.FONT_SIZE;
|
||||
|
||||
public float TextSize
|
||||
{
|
||||
get => textSize;
|
||||
set
|
||||
{
|
||||
if (textSize == value)
|
||||
return;
|
||||
textSize = value;
|
||||
|
||||
updateText();
|
||||
}
|
||||
}
|
||||
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; }
|
||||
|
||||
private void updateText()
|
||||
{
|
||||
if (beatmap == null)
|
||||
{
|
||||
beatmapTitle.Text = "Changing map";
|
||||
beatmapDash.Text = beatmapArtist.Text = string.Empty;
|
||||
}
|
||||
if (!IsLoaded)
|
||||
return;
|
||||
|
||||
textFlow.Clear();
|
||||
|
||||
if (Beatmap.Value == null)
|
||||
textFlow.AddText("No beatmap selected", s =>
|
||||
{
|
||||
s.TextSize = TextSize;
|
||||
s.Colour = colours.PinkLight;
|
||||
});
|
||||
else
|
||||
{
|
||||
beatmapTitle.Text = new LocalisedString((beatmap.Metadata.TitleUnicode, beatmap.Metadata.Title));
|
||||
beatmapDash.Text = @" - ";
|
||||
beatmapArtist.Text = new LocalisedString((beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist));
|
||||
textFlow.AddLink(new[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = new LocalisedString((Beatmap.Value.Metadata.ArtistUnicode, Beatmap.Value.Metadata.Artist)),
|
||||
TextSize = TextSize,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = " - ",
|
||||
TextSize = TextSize,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = new LocalisedString((Beatmap.Value.Metadata.TitleUnicode, Beatmap.Value.Metadata.Title)),
|
||||
TextSize = TextSize,
|
||||
}
|
||||
}, null, LinkAction.OpenBeatmap, Beatmap.Value.OnlineBeatmapID.ToString(), "Open beatmap");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,70 +1,77 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Rulesets;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Components
|
||||
{
|
||||
public class BeatmapTypeInfo : FillFlowContainer
|
||||
public class BeatmapTypeInfo : CompositeDrawable
|
||||
{
|
||||
private readonly ModeTypeInfo modeTypeInfo;
|
||||
private readonly BeatmapTitle beatmapTitle;
|
||||
private readonly OsuSpriteText beatmapAuthor;
|
||||
|
||||
public BeatmapInfo Beatmap
|
||||
{
|
||||
set
|
||||
{
|
||||
modeTypeInfo.Beatmap = beatmapTitle.Beatmap = value;
|
||||
beatmapAuthor.Text = value == null ? string.Empty : $"mapped by {value.Metadata.Author}";
|
||||
}
|
||||
}
|
||||
|
||||
public GameType Type
|
||||
{
|
||||
set { modeTypeInfo.Type = value; }
|
||||
}
|
||||
public readonly IBindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
|
||||
public readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
|
||||
public readonly IBindable<GameType> Type = new Bindable<GameType>();
|
||||
|
||||
public BeatmapTypeInfo()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
Direction = FillDirection.Horizontal;
|
||||
LayoutDuration = 100;
|
||||
Spacing = new Vector2(5f, 0f);
|
||||
|
||||
Children = new Drawable[]
|
||||
BeatmapTitle beatmapTitle;
|
||||
ModeTypeInfo modeTypeInfo;
|
||||
LinkFlowContainer beatmapAuthor;
|
||||
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
modeTypeInfo = new ModeTypeInfo(),
|
||||
new Container
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
LayoutDuration = 100,
|
||||
Spacing = new Vector2(5, 0),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
AutoSizeAxes = Axes.X,
|
||||
Height = 30,
|
||||
Margin = new MarginPadding { Left = 5 },
|
||||
Children = new Drawable[]
|
||||
modeTypeInfo = new ModeTypeInfo(),
|
||||
new Container
|
||||
{
|
||||
beatmapTitle = new BeatmapTitle(),
|
||||
beatmapAuthor = new OsuSpriteText
|
||||
AutoSizeAxes = Axes.X,
|
||||
Height = 30,
|
||||
Margin = new MarginPadding { Left = 5 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
TextSize = 14,
|
||||
beatmapTitle = new BeatmapTitle(),
|
||||
beatmapAuthor = new LinkFlowContainer(s => s.TextSize = 14)
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
AutoSizeAxes = Axes.Both
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
beatmapAuthor.Colour = colours.Gray9;
|
||||
modeTypeInfo.Beatmap.BindTo(Beatmap);
|
||||
modeTypeInfo.Ruleset.BindTo(Ruleset);
|
||||
modeTypeInfo.Type.BindTo(Type);
|
||||
|
||||
beatmapTitle.Beatmap.BindTo(Beatmap);
|
||||
|
||||
Beatmap.BindValueChanged(v =>
|
||||
{
|
||||
beatmapAuthor.Clear();
|
||||
|
||||
if (v != null)
|
||||
{
|
||||
beatmapAuthor.AddText("mapped by ", s => s.Colour = OsuColour.Gray(0.8f));
|
||||
beatmapAuthor.AddLink(v.Metadata.Author.Username, null, LinkAction.OpenUserProfile, v.Metadata.Author.Id.ToString(), "View Profile");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
38
osu.Game/Screens/Multi/Components/DisableableTabControl.cs
Normal file
38
osu.Game/Screens/Multi/Components/DisableableTabControl.cs
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Input.Events;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Components
|
||||
{
|
||||
public abstract class DisableableTabControl<T> : TabControl<T>
|
||||
{
|
||||
public readonly BindableBool Enabled = new BindableBool();
|
||||
|
||||
protected override void AddTabItem(TabItem<T> tab, bool addToDropdown = true)
|
||||
{
|
||||
if (tab is DisableableTabItem<T> disableable)
|
||||
disableable.Enabled.BindTo(Enabled);
|
||||
base.AddTabItem(tab, addToDropdown);
|
||||
}
|
||||
|
||||
protected abstract class DisableableTabItem<T> : TabItem<T>
|
||||
{
|
||||
public readonly BindableBool Enabled = new BindableBool();
|
||||
|
||||
protected DisableableTabItem(T value)
|
||||
: base(value)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool OnClick(ClickEvent e)
|
||||
{
|
||||
if (!Enabled)
|
||||
return true;
|
||||
return base.OnClick(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,83 +1,67 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Rulesets;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Components
|
||||
{
|
||||
public class ModeTypeInfo : Container
|
||||
public class ModeTypeInfo : CompositeDrawable
|
||||
{
|
||||
private const float height = 30;
|
||||
private const float transition_duration = 100;
|
||||
|
||||
private readonly Container rulesetContainer, gameTypeContainer;
|
||||
private readonly Container rulesetContainer;
|
||||
|
||||
public BeatmapInfo Beatmap
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
rulesetContainer.FadeIn(transition_duration);
|
||||
rulesetContainer.Children = new[]
|
||||
{
|
||||
new DifficultyIcon(value)
|
||||
{
|
||||
Size = new Vector2(height),
|
||||
},
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
rulesetContainer.FadeOut(transition_duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GameType Type
|
||||
{
|
||||
set
|
||||
{
|
||||
gameTypeContainer.Children = new[]
|
||||
{
|
||||
new DrawableGameType(value)
|
||||
{
|
||||
Size = new Vector2(height),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
public readonly IBindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
|
||||
public readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
|
||||
public readonly IBindable<GameType> Type = new Bindable<GameType>();
|
||||
|
||||
public ModeTypeInfo()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
Children = new[]
|
||||
Container gameTypeContainer;
|
||||
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
new FillFlowContainer
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5f, 0f),
|
||||
LayoutDuration = 100,
|
||||
Children = new[]
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5f, 0f),
|
||||
LayoutDuration = 100,
|
||||
Children = new[]
|
||||
rulesetContainer = new Container
|
||||
{
|
||||
rulesetContainer = new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
},
|
||||
gameTypeContainer = new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
},
|
||||
AutoSizeAxes = Axes.Both,
|
||||
},
|
||||
gameTypeContainer = new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Beatmap.BindValueChanged(updateBeatmap);
|
||||
Ruleset.BindValueChanged(_ => updateBeatmap(Beatmap.Value));
|
||||
Type.BindValueChanged(v => gameTypeContainer.Child = new DrawableGameType(v) { Size = new Vector2(height) });
|
||||
}
|
||||
|
||||
private void updateBeatmap(BeatmapInfo beatmap)
|
||||
{
|
||||
if (beatmap != null)
|
||||
{
|
||||
rulesetContainer.FadeIn(transition_duration);
|
||||
rulesetContainer.Child = new DifficultyIcon(beatmap, Ruleset.Value) { Size = new Vector2(height) };
|
||||
}
|
||||
else
|
||||
rulesetContainer.FadeOut(transition_duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,69 +1,67 @@
|
||||
// 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.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Components
|
||||
{
|
||||
public class ParticipantCount : FillFlowContainer
|
||||
public class ParticipantCountDisplay : CompositeDrawable
|
||||
{
|
||||
private const float text_size = 30;
|
||||
private const float transition_duration = 100;
|
||||
|
||||
private readonly OsuSpriteText count, slash, maxText;
|
||||
private readonly OsuSpriteText slash, maxText;
|
||||
|
||||
public int Count
|
||||
{
|
||||
set => count.Text = value.ToString();
|
||||
}
|
||||
public readonly IBindable<IEnumerable<User>> Participants = new Bindable<IEnumerable<User>>();
|
||||
public readonly IBindable<int> ParticipantCount = new Bindable<int>();
|
||||
public readonly IBindable<int?> MaxParticipants = new Bindable<int?>();
|
||||
|
||||
private int? max;
|
||||
public int? Max
|
||||
{
|
||||
get => max;
|
||||
set
|
||||
{
|
||||
if (value == max) return;
|
||||
max = value;
|
||||
|
||||
updateMax();
|
||||
}
|
||||
}
|
||||
|
||||
public ParticipantCount()
|
||||
public ParticipantCountDisplay()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
Direction = FillDirection.Horizontal;
|
||||
LayoutDuration = transition_duration;
|
||||
|
||||
Children = new[]
|
||||
OsuSpriteText count;
|
||||
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
count = new OsuSpriteText
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
LayoutDuration = transition_duration,
|
||||
Children = new[]
|
||||
{
|
||||
TextSize = text_size,
|
||||
Font = @"Exo2.0-Bold"
|
||||
},
|
||||
slash = new OsuSpriteText
|
||||
{
|
||||
Text = @"/",
|
||||
TextSize = text_size,
|
||||
Font = @"Exo2.0-Light"
|
||||
},
|
||||
maxText = new OsuSpriteText
|
||||
{
|
||||
TextSize = text_size,
|
||||
Font = @"Exo2.0-Light"
|
||||
},
|
||||
count = new OsuSpriteText
|
||||
{
|
||||
TextSize = text_size,
|
||||
Font = @"Exo2.0-Bold"
|
||||
},
|
||||
slash = new OsuSpriteText
|
||||
{
|
||||
Text = @"/",
|
||||
TextSize = text_size,
|
||||
Font = @"Exo2.0-Light"
|
||||
},
|
||||
maxText = new OsuSpriteText
|
||||
{
|
||||
TextSize = text_size,
|
||||
Font = @"Exo2.0-Light"
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
updateMax();
|
||||
Participants.BindValueChanged(v => count.Text = v.Count().ToString());
|
||||
MaxParticipants.BindValueChanged(_ => updateMax(), true);
|
||||
ParticipantCount.BindValueChanged(v => count.Text = v.ToString("#,0"));
|
||||
}
|
||||
|
||||
private void updateMax()
|
||||
{
|
||||
if (Max == null)
|
||||
if (MaxParticipants.Value == null)
|
||||
{
|
||||
slash.FadeOut(transition_duration);
|
||||
maxText.FadeOut(transition_duration);
|
||||
@ -71,7 +69,7 @@ namespace osu.Game.Screens.Multi.Components
|
||||
else
|
||||
{
|
||||
slash.FadeIn(transition_duration);
|
||||
maxText.Text = Max.ToString();
|
||||
maxText.Text = MaxParticipants.Value.ToString();
|
||||
maxText.FadeIn(transition_duration);
|
||||
}
|
||||
}
|
||||
|
@ -1,145 +0,0 @@
|
||||
// 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.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Components
|
||||
{
|
||||
public class ParticipantInfo : Container
|
||||
{
|
||||
private readonly Container flagContainer;
|
||||
private readonly OsuSpriteText host;
|
||||
private readonly FillFlowContainer levelRangeContainer;
|
||||
private readonly OsuSpriteText levelRangeLower;
|
||||
private readonly OsuSpriteText levelRangeHigher;
|
||||
|
||||
public User Host
|
||||
{
|
||||
set
|
||||
{
|
||||
host.Text = value.Username;
|
||||
flagContainer.Children = new[] { new DrawableFlag(value.Country) { RelativeSizeAxes = Axes.Both } };
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<User> Participants
|
||||
{
|
||||
set
|
||||
{
|
||||
var ranks = value.Select(u => u.Statistics.Ranks.Global);
|
||||
levelRangeLower.Text = ranks.Min().ToString();
|
||||
levelRangeHigher.Text = ranks.Max().ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public ParticipantInfo(string rankPrefix = null)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = 15f;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.X,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5f, 0f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
flagContainer = new Container
|
||||
{
|
||||
Width = 22f,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
},
|
||||
new Container //todo: team banners
|
||||
{
|
||||
Width = 38f,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
CornerRadius = 2f,
|
||||
Masking = true,
|
||||
Children = new[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = OsuColour.FromHex(@"ad387e"),
|
||||
},
|
||||
},
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = "hosted by",
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
TextSize = 14,
|
||||
},
|
||||
host = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
TextSize = 14,
|
||||
Font = @"Exo2.0-BoldItalic",
|
||||
},
|
||||
},
|
||||
},
|
||||
levelRangeContainer = new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = rankPrefix,
|
||||
TextSize = 14,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = "#",
|
||||
TextSize = 14,
|
||||
},
|
||||
levelRangeLower = new OsuSpriteText
|
||||
{
|
||||
TextSize = 14,
|
||||
Font = @"Exo2.0-Bold",
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = " - ",
|
||||
TextSize = 14,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = "#",
|
||||
TextSize = 14,
|
||||
},
|
||||
levelRangeHigher = new OsuSpriteText
|
||||
{
|
||||
TextSize = 14,
|
||||
Font = @"Exo2.0-Bold",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
levelRangeContainer.Colour = colours.Gray9;
|
||||
host.Colour = colours.Blue;
|
||||
}
|
||||
}
|
||||
}
|
111
osu.Game/Screens/Multi/Components/RoomStatusInfo.cs
Normal file
111
osu.Game/Screens/Multi/Components/RoomStatusInfo.cs
Normal file
@ -0,0 +1,111 @@
|
||||
// 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;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.RoomStatuses;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Components
|
||||
{
|
||||
public class RoomStatusInfo : CompositeDrawable
|
||||
{
|
||||
private readonly RoomBindings bindings = new RoomBindings();
|
||||
|
||||
public RoomStatusInfo(Room room)
|
||||
{
|
||||
bindings.Room = room;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
StatusPart statusPart;
|
||||
EndDatePart endDatePart;
|
||||
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
statusPart = new StatusPart
|
||||
{
|
||||
TextSize = 14,
|
||||
Font = "Exo2.0-Bold"
|
||||
},
|
||||
endDatePart = new EndDatePart { TextSize = 14 }
|
||||
}
|
||||
};
|
||||
|
||||
statusPart.EndDate.BindTo(bindings.EndDate);
|
||||
statusPart.Status.BindTo(bindings.Status);
|
||||
statusPart.Availability.BindTo(bindings.Availability);
|
||||
endDatePart.EndDate.BindTo(bindings.EndDate);
|
||||
}
|
||||
|
||||
private class EndDatePart : DrawableDate
|
||||
{
|
||||
public readonly IBindable<DateTimeOffset> EndDate = new Bindable<DateTimeOffset>();
|
||||
|
||||
public EndDatePart()
|
||||
: base(DateTimeOffset.UtcNow)
|
||||
{
|
||||
EndDate.BindValueChanged(d => Date = d);
|
||||
}
|
||||
|
||||
protected override string Format()
|
||||
{
|
||||
var diffToNow = Date.Subtract(DateTimeOffset.Now);
|
||||
|
||||
if (diffToNow.TotalSeconds < -5)
|
||||
return $"Closed {base.Format()}";
|
||||
|
||||
if (diffToNow.TotalSeconds < 0)
|
||||
return "Closed";
|
||||
|
||||
if (diffToNow.TotalSeconds < 5)
|
||||
return "Closing soon";
|
||||
|
||||
return $"Closing {base.Format()}";
|
||||
}
|
||||
}
|
||||
|
||||
private class StatusPart : EndDatePart
|
||||
{
|
||||
public readonly IBindable<RoomStatus> Status = new Bindable<RoomStatus>();
|
||||
public readonly IBindable<RoomAvailability> Availability = new Bindable<RoomAvailability>();
|
||||
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; }
|
||||
|
||||
public StatusPart()
|
||||
{
|
||||
EndDate.BindValueChanged(_ => Format());
|
||||
Status.BindValueChanged(_ => Format());
|
||||
Availability.BindValueChanged(_ => Format());
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
Text = Format();
|
||||
}
|
||||
|
||||
protected override string Format()
|
||||
{
|
||||
if (!IsLoaded)
|
||||
return string.Empty;
|
||||
|
||||
RoomStatus status = Date < DateTimeOffset.Now ? new RoomStatusEnded() : Status.Value ?? new RoomStatusOpen();
|
||||
|
||||
this.FadeColour(status.GetAppropriateColour(colours), 100);
|
||||
return $"{Availability.Value.GetDescription()}, {status.Message}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -10,7 +10,6 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Overlays.SearchableList;
|
||||
using osu.Game.Screens.Multi.Screens;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
@ -86,7 +85,12 @@ namespace osu.Game.Screens.Multi
|
||||
},
|
||||
};
|
||||
|
||||
breadcrumbs.Current.ValueChanged += s => screenType.Text = ((MultiplayerScreen)s).Type.ToLowerInvariant();
|
||||
breadcrumbs.Current.ValueChanged += s =>
|
||||
{
|
||||
if (s is IMultiplayerSubScreen mpScreen)
|
||||
screenType.Text = mpScreen.ShortTitle.ToLowerInvariant();
|
||||
};
|
||||
|
||||
breadcrumbs.Current.TriggerChange();
|
||||
}
|
||||
|
||||
@ -99,7 +103,8 @@ namespace osu.Game.Screens.Multi
|
||||
|
||||
private class HeaderBreadcrumbControl : ScreenBreadcrumbControl
|
||||
{
|
||||
public HeaderBreadcrumbControl(Screen initialScreen) : base(initialScreen)
|
||||
public HeaderBreadcrumbControl(Screen initialScreen)
|
||||
: base(initialScreen)
|
||||
{
|
||||
}
|
||||
|
||||
|
10
osu.Game/Screens/Multi/IMultiplayerSubScreen.cs
Normal file
10
osu.Game/Screens/Multi/IMultiplayerSubScreen.cs
Normal file
@ -0,0 +1,10 @@
|
||||
// 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.Screens.Multi
|
||||
{
|
||||
public interface IMultiplayerSubScreen
|
||||
{
|
||||
string ShortTitle { get; }
|
||||
}
|
||||
}
|
50
osu.Game/Screens/Multi/IRoomManager.cs
Normal file
50
osu.Game/Screens/Multi/IRoomManager.cs
Normal file
@ -0,0 +1,50 @@
|
||||
// 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;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Screens.Multi.Lounge.Components;
|
||||
|
||||
namespace osu.Game.Screens.Multi
|
||||
{
|
||||
public interface IRoomManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked when the <see cref="Room"/>s have been updated.
|
||||
/// </summary>
|
||||
event Action RoomsUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// All the active <see cref="Room"/>s.
|
||||
/// </summary>
|
||||
IBindableCollection<Room> Rooms { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Room"/>.
|
||||
/// </summary>
|
||||
/// <param name="room">The <see cref="Room"/> to create.</param>
|
||||
/// <param name="onSuccess">An action to be invoked if the creation succeeds.</param>
|
||||
/// <param name="onError">An action to be invoked if an error occurred.</param>
|
||||
void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null);
|
||||
|
||||
/// <summary>
|
||||
/// Joins a <see cref="Room"/>.
|
||||
/// </summary>
|
||||
/// <param name="room">The <see cref="Room"/> to join. <see cref="Room.RoomID"/> must be populated.</param>
|
||||
/// <param name="onSuccess"></param>
|
||||
/// <param name="onError"></param>
|
||||
void JoinRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null);
|
||||
|
||||
/// <summary>
|
||||
/// Parts the currently-joined <see cref="Room"/>.
|
||||
/// </summary>
|
||||
void PartRoom();
|
||||
|
||||
/// <summary>
|
||||
/// Queries for <see cref="Room"/>s matching a new <see cref="FilterCriteria"/>.
|
||||
/// </summary>
|
||||
/// <param name="criteria">The <see cref="FilterCriteria"/> to match.</param>
|
||||
void Filter(FilterCriteria criteria);
|
||||
}
|
||||
}
|
@ -5,12 +5,10 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Graphics;
|
||||
@ -18,11 +16,11 @@ using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Users;
|
||||
using osu.Game.Screens.Multi.Components;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Components
|
||||
namespace osu.Game.Screens.Multi.Lounge.Components
|
||||
{
|
||||
public class DrawableRoom : OsuClickableContainer, IStateful<SelectionState>, IFilterable
|
||||
{
|
||||
@ -30,18 +28,21 @@ namespace osu.Game.Screens.Multi.Components
|
||||
private const float corner_radius = 5;
|
||||
private const float transition_duration = 60;
|
||||
private const float content_padding = 10;
|
||||
private const float height = 100;
|
||||
private const float height = 110;
|
||||
private const float side_strip_width = 5;
|
||||
private const float cover_width = 145;
|
||||
|
||||
private readonly Box selectionBox;
|
||||
public event Action<SelectionState> StateChanged;
|
||||
|
||||
private readonly Bindable<string> nameBind = new Bindable<string>();
|
||||
private readonly Bindable<User> hostBind = new Bindable<User>();
|
||||
private readonly Bindable<RoomStatus> statusBind = new Bindable<RoomStatus>();
|
||||
private readonly Bindable<GameType> typeBind = new Bindable<GameType>();
|
||||
private readonly Bindable<BeatmapInfo> beatmapBind = new Bindable<BeatmapInfo>();
|
||||
private readonly Bindable<IEnumerable<User>> participantsBind = new Bindable<IEnumerable<User>>();
|
||||
private readonly RoomBindings bindings = new RoomBindings();
|
||||
|
||||
private readonly Box selectionBox;
|
||||
private UpdateableBeatmapBackgroundSprite background;
|
||||
private BeatmapTitle beatmapTitle;
|
||||
private ModeTypeInfo modeTypeInfo;
|
||||
|
||||
[Resolved]
|
||||
private BeatmapManager beatmaps { get; set; }
|
||||
|
||||
public readonly Room Room;
|
||||
|
||||
@ -76,22 +77,10 @@ namespace osu.Game.Screens.Multi.Components
|
||||
}
|
||||
}
|
||||
|
||||
private Action<DrawableRoom> action;
|
||||
public new Action<DrawableRoom> Action
|
||||
{
|
||||
get { return action; }
|
||||
set
|
||||
{
|
||||
action = value;
|
||||
Enabled.Value = action != null;
|
||||
}
|
||||
}
|
||||
|
||||
public event Action<SelectionState> StateChanged;
|
||||
|
||||
public DrawableRoom(Room room)
|
||||
{
|
||||
Room = room;
|
||||
bindings.Room = room;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = height + SELECTION_BORDER_WIDTH * 2;
|
||||
@ -110,11 +99,8 @@ namespace osu.Game.Screens.Multi.Components
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
Box sideStrip;
|
||||
UpdateableBeatmapSetCover cover;
|
||||
OsuSpriteText name, status;
|
||||
ParticipantInfo participantInfo;
|
||||
BeatmapTitle beatmapTitle;
|
||||
ModeTypeInfo modeTypeInfo;
|
||||
OsuSpriteText name;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
@ -146,12 +132,13 @@ namespace osu.Game.Screens.Multi.Components
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = side_strip_width,
|
||||
},
|
||||
cover = new UpdateableBeatmapSetCover
|
||||
new Container
|
||||
{
|
||||
Width = cover_width,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = cover_width,
|
||||
Masking = true,
|
||||
Margin = new MarginPadding { Left = side_strip_width },
|
||||
Child = background = new UpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both }
|
||||
},
|
||||
new Container
|
||||
{
|
||||
@ -172,10 +159,7 @@ namespace osu.Game.Screens.Multi.Components
|
||||
Spacing = new Vector2(5f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
name = new OsuSpriteText
|
||||
{
|
||||
TextSize = 18,
|
||||
},
|
||||
name = new OsuSpriteText { TextSize = 18 },
|
||||
participantInfo = new ParticipantInfo(),
|
||||
},
|
||||
},
|
||||
@ -186,18 +170,11 @@ namespace osu.Game.Screens.Multi.Components
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
status = new OsuSpriteText
|
||||
{
|
||||
TextSize = 14,
|
||||
Font = @"Exo2.0-Bold",
|
||||
},
|
||||
beatmapTitle = new BeatmapTitle
|
||||
{
|
||||
TextSize = 14,
|
||||
Colour = colours.Gray9
|
||||
},
|
||||
new RoomStatusInfo(Room),
|
||||
beatmapTitle = new BeatmapTitle { TextSize = 14 },
|
||||
},
|
||||
},
|
||||
modeTypeInfo = new ModeTypeInfo
|
||||
@ -212,32 +189,21 @@ namespace osu.Game.Screens.Multi.Components
|
||||
},
|
||||
};
|
||||
|
||||
nameBind.ValueChanged += n => name.Text = n;
|
||||
hostBind.ValueChanged += h => participantInfo.Host = h;
|
||||
typeBind.ValueChanged += m => modeTypeInfo.Type = m;
|
||||
participantsBind.ValueChanged += p => participantInfo.Participants = p;
|
||||
background.Beatmap.BindTo(bindings.CurrentBeatmap);
|
||||
modeTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap);
|
||||
modeTypeInfo.Ruleset.BindTo(bindings.CurrentRuleset);
|
||||
modeTypeInfo.Type.BindTo(bindings.Type);
|
||||
beatmapTitle.Beatmap.BindTo(bindings.CurrentBeatmap);
|
||||
participantInfo.Host.BindTo(bindings.Host);
|
||||
participantInfo.Participants.BindTo(bindings.Participants);
|
||||
participantInfo.ParticipantCount.BindTo(bindings.ParticipantCount);
|
||||
|
||||
statusBind.ValueChanged += s =>
|
||||
bindings.Name.BindValueChanged(n => name.Text = n, true);
|
||||
bindings.Status.BindValueChanged(s =>
|
||||
{
|
||||
status.Text = s.Message;
|
||||
|
||||
foreach (Drawable d in new Drawable[] { selectionBox, sideStrip, status })
|
||||
foreach (Drawable d in new Drawable[] { selectionBox, sideStrip })
|
||||
d.FadeColour(s.GetAppropriateColour(colours), transition_duration);
|
||||
};
|
||||
|
||||
beatmapBind.ValueChanged += b =>
|
||||
{
|
||||
cover.BeatmapSet = b?.BeatmapSet;
|
||||
beatmapTitle.Beatmap = b;
|
||||
modeTypeInfo.Beatmap = b;
|
||||
};
|
||||
|
||||
nameBind.BindTo(Room.Name);
|
||||
hostBind.BindTo(Room.Host);
|
||||
statusBind.BindTo(Room.Status);
|
||||
typeBind.BindTo(Room.Type);
|
||||
beatmapBind.BindTo(Room.Beatmap);
|
||||
participantsBind.BindTo(Room.Participants);
|
||||
}, true);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
@ -245,16 +211,5 @@ namespace osu.Game.Screens.Multi.Components
|
||||
base.LoadComplete();
|
||||
this.FadeInFromZero(transition_duration);
|
||||
}
|
||||
|
||||
protected override bool OnClick(ClickEvent e)
|
||||
{
|
||||
if (Enabled.Value)
|
||||
{
|
||||
Action?.Invoke(this);
|
||||
State = SelectionState.Selected;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
43
osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs
Normal file
43
osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs
Normal file
@ -0,0 +1,43 @@
|
||||
// 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.ComponentModel;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Overlays.SearchableList;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Lounge.Components
|
||||
{
|
||||
public class FilterControl : SearchableListFilterControl<PrimaryFilter, SecondaryFilter>
|
||||
{
|
||||
protected override Color4 BackgroundColour => OsuColour.FromHex(@"362e42");
|
||||
protected override PrimaryFilter DefaultTab => PrimaryFilter.Open;
|
||||
|
||||
public FilterControl()
|
||||
{
|
||||
DisplayStyleControl.Hide();
|
||||
}
|
||||
|
||||
public FilterCriteria CreateCriteria() => new FilterCriteria
|
||||
{
|
||||
SearchString = Search.Current.Value ?? string.Empty,
|
||||
PrimaryFilter = Tabs.Current,
|
||||
SecondaryFilter = DisplayStyleControl.Dropdown.Current
|
||||
};
|
||||
}
|
||||
|
||||
public enum PrimaryFilter
|
||||
{
|
||||
Open,
|
||||
[Description("Recently Ended")]
|
||||
RecentlyEnded,
|
||||
Participated,
|
||||
Owned,
|
||||
}
|
||||
|
||||
public enum SecondaryFilter
|
||||
{
|
||||
Public,
|
||||
//Private,
|
||||
}
|
||||
}
|
12
osu.Game/Screens/Multi/Lounge/Components/FilterCriteria.cs
Normal file
12
osu.Game/Screens/Multi/Lounge/Components/FilterCriteria.cs
Normal file
@ -0,0 +1,12 @@
|
||||
// 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.Screens.Multi.Lounge.Components
|
||||
{
|
||||
public class FilterCriteria
|
||||
{
|
||||
public string SearchString;
|
||||
public PrimaryFilter PrimaryFilter;
|
||||
public SecondaryFilter SecondaryFilter;
|
||||
}
|
||||
}
|
118
osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs
Normal file
118
osu.Game/Screens/Multi/Lounge/Components/ParticipantInfo.cs
Normal file
@ -0,0 +1,118 @@
|
||||
// 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.Generic;
|
||||
using Humanizer;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Lounge.Components
|
||||
{
|
||||
public class ParticipantInfo : Container
|
||||
{
|
||||
private readonly FillFlowContainer summaryContainer;
|
||||
|
||||
public readonly IBindable<User> Host = new Bindable<User>();
|
||||
public readonly IBindable<IEnumerable<User>> Participants = new Bindable<IEnumerable<User>>();
|
||||
public readonly IBindable<int> ParticipantCount = new Bindable<int>();
|
||||
|
||||
public ParticipantInfo()
|
||||
{
|
||||
OsuSpriteText summary;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = 15f;
|
||||
|
||||
OsuSpriteText levelRangeHigher;
|
||||
OsuSpriteText levelRangeLower;
|
||||
Container flagContainer;
|
||||
LinkFlowContainer hostText;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.X,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5f, 0f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
flagContainer = new Container
|
||||
{
|
||||
Width = 22f,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
},
|
||||
/*new Container //todo: team banners
|
||||
{
|
||||
Width = 38f,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
CornerRadius = 2f,
|
||||
Masking = true,
|
||||
Children = new[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = OsuColour.FromHex(@"ad387e"),
|
||||
},
|
||||
},
|
||||
},*/
|
||||
hostText = new LinkFlowContainer
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
AutoSizeAxes = Axes.Both
|
||||
}
|
||||
},
|
||||
},
|
||||
summaryContainer = new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new[]
|
||||
{
|
||||
summary = new OsuSpriteText
|
||||
{
|
||||
Text = "0 participants",
|
||||
TextSize = 14,
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Host.BindValueChanged(v =>
|
||||
{
|
||||
hostText.Clear();
|
||||
hostText.AddText("hosted by ");
|
||||
hostText.AddLink(v.Username, null, LinkAction.OpenUserProfile, v.Id.ToString(), "Open profile", s => s.Font = "Exo2.0-BoldItalic");
|
||||
|
||||
flagContainer.Child = new DrawableFlag(v.Country) { RelativeSizeAxes = Axes.Both };
|
||||
});
|
||||
|
||||
ParticipantCount.BindValueChanged(v => summary.Text = $"{v:#,0}{" participant".Pluralize(v == 1)}");
|
||||
|
||||
/*Participants.BindValueChanged(v =>
|
||||
{
|
||||
var ranks = v.Select(u => u.Statistics.Ranks.Global);
|
||||
levelRangeLower.Text = ranks.Min().ToString();
|
||||
levelRangeHigher.Text = ranks.Max().ToString();
|
||||
});*/
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
summaryContainer.Colour = colours.Gray9;
|
||||
}
|
||||
}
|
||||
}
|
@ -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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
@ -17,66 +16,35 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Screens.Multi.Components;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Components
|
||||
namespace osu.Game.Screens.Multi.Lounge.Components
|
||||
{
|
||||
public class RoomInspector : Container
|
||||
{
|
||||
private const float transition_duration = 100;
|
||||
|
||||
public readonly IBindable<Room> Room = new Bindable<Room>();
|
||||
|
||||
private readonly MarginPadding contentPadding = new MarginPadding { Horizontal = 20, Vertical = 10 };
|
||||
private readonly Bindable<string> nameBind = new Bindable<string>();
|
||||
private readonly Bindable<User> hostBind = new Bindable<User>();
|
||||
private readonly Bindable<RoomStatus> statusBind = new Bindable<RoomStatus>();
|
||||
private readonly Bindable<GameType> typeBind = new Bindable<GameType>();
|
||||
private readonly Bindable<BeatmapInfo> beatmapBind = new Bindable<BeatmapInfo>();
|
||||
private readonly Bindable<int?> maxParticipantsBind = new Bindable<int?>();
|
||||
private readonly Bindable<IEnumerable<User>> participantsBind = new Bindable<IEnumerable<User>>();
|
||||
|
||||
private readonly RoomBindings bindings = new RoomBindings();
|
||||
|
||||
private OsuColour colours;
|
||||
private Box statusStrip;
|
||||
private UpdateableBeatmapSetCover cover;
|
||||
private ParticipantCount participantCount;
|
||||
private UpdateableBeatmapBackgroundSprite background;
|
||||
private ParticipantCountDisplay participantCount;
|
||||
private FillFlowContainer topFlow, participantsFlow;
|
||||
private OsuSpriteText name, status;
|
||||
private BeatmapTypeInfo beatmapTypeInfo;
|
||||
private ScrollContainer participantsScroll;
|
||||
private ParticipantInfo participantInfo;
|
||||
|
||||
private Room room;
|
||||
public Room Room
|
||||
{
|
||||
get { return room; }
|
||||
set
|
||||
{
|
||||
if (value == room) return;
|
||||
room = value;
|
||||
|
||||
nameBind.UnbindBindings();
|
||||
hostBind.UnbindBindings();
|
||||
statusBind.UnbindBindings();
|
||||
typeBind.UnbindBindings();
|
||||
beatmapBind.UnbindBindings();
|
||||
maxParticipantsBind.UnbindBindings();
|
||||
participantsBind.UnbindBindings();
|
||||
|
||||
if (room != null)
|
||||
{
|
||||
nameBind.BindTo(room.Name);
|
||||
hostBind.BindTo(room.Host);
|
||||
statusBind.BindTo(room.Status);
|
||||
typeBind.BindTo(room.Type);
|
||||
beatmapBind.BindTo(room.Beatmap);
|
||||
maxParticipantsBind.BindTo(room.MaxParticipants);
|
||||
participantsBind.BindTo(room.Participants);
|
||||
}
|
||||
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
[Resolved]
|
||||
private BeatmapManager beatmaps { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
@ -104,10 +72,7 @@ namespace osu.Game.Screens.Multi.Components
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
cover = new UpdateableBeatmapSetCover
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
background = new UpdateableBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both },
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@ -119,7 +84,7 @@ namespace osu.Game.Screens.Multi.Components
|
||||
Padding = new MarginPadding(20),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
participantCount = new ParticipantCount
|
||||
participantCount = new ParticipantCountDisplay
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
@ -177,7 +142,7 @@ namespace osu.Game.Screens.Multi.Components
|
||||
Padding = contentPadding,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
participantInfo = new ParticipantInfo(@"Rank Range "),
|
||||
participantInfo = new ParticipantInfo(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -201,26 +166,48 @@ namespace osu.Game.Screens.Multi.Components
|
||||
},
|
||||
};
|
||||
|
||||
nameBind.ValueChanged += n => name.Text = n;
|
||||
hostBind.ValueChanged += h => participantInfo.Host = h;
|
||||
typeBind.ValueChanged += t => beatmapTypeInfo.Type = t;
|
||||
maxParticipantsBind.ValueChanged += m => participantCount.Max = m;
|
||||
statusBind.ValueChanged += displayStatus;
|
||||
participantInfo.Host.BindTo(bindings.Host);
|
||||
participantInfo.ParticipantCount.BindTo(bindings.ParticipantCount);
|
||||
participantInfo.Participants.BindTo(bindings.Participants);
|
||||
|
||||
beatmapBind.ValueChanged += b =>
|
||||
participantCount.Participants.BindTo(bindings.Participants);
|
||||
participantCount.ParticipantCount.BindTo(bindings.ParticipantCount);
|
||||
participantCount.MaxParticipants.BindTo(bindings.MaxParticipants);
|
||||
|
||||
beatmapTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap);
|
||||
beatmapTypeInfo.Ruleset.BindTo(bindings.CurrentRuleset);
|
||||
beatmapTypeInfo.Type.BindTo(bindings.Type);
|
||||
background.Beatmap.BindTo(bindings.CurrentBeatmap);
|
||||
|
||||
bindings.Status.BindValueChanged(displayStatus);
|
||||
bindings.Participants.BindValueChanged(p => participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u)));
|
||||
bindings.Name.BindValueChanged(n => name.Text = n);
|
||||
|
||||
Room.BindValueChanged(updateRoom, true);
|
||||
}
|
||||
|
||||
private void updateRoom(Room room)
|
||||
{
|
||||
bindings.Room = room;
|
||||
|
||||
if (room != null)
|
||||
{
|
||||
cover.BeatmapSet = b?.BeatmapSet;
|
||||
beatmapTypeInfo.Beatmap = b;
|
||||
};
|
||||
|
||||
participantsBind.ValueChanged += p =>
|
||||
participantsFlow.FadeIn(transition_duration);
|
||||
participantCount.FadeIn(transition_duration);
|
||||
beatmapTypeInfo.FadeIn(transition_duration);
|
||||
name.FadeIn(transition_duration);
|
||||
participantInfo.FadeIn(transition_duration);
|
||||
}
|
||||
else
|
||||
{
|
||||
participantCount.Count = p.Count();
|
||||
participantInfo.Participants = p;
|
||||
participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u));
|
||||
};
|
||||
participantsFlow.FadeOut(transition_duration);
|
||||
participantCount.FadeOut(transition_duration);
|
||||
beatmapTypeInfo.FadeOut(transition_duration);
|
||||
name.FadeOut(transition_duration);
|
||||
participantInfo.FadeOut(transition_duration);
|
||||
|
||||
updateState();
|
||||
displayStatus(new RoomStatusNoneSelected());
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
@ -239,32 +226,6 @@ namespace osu.Game.Screens.Multi.Components
|
||||
status.FadeColour(c, transition_duration);
|
||||
}
|
||||
|
||||
private void updateState()
|
||||
{
|
||||
if (Room == null)
|
||||
{
|
||||
cover.BeatmapSet = null;
|
||||
participantsFlow.FadeOut(transition_duration);
|
||||
participantCount.FadeOut(transition_duration);
|
||||
beatmapTypeInfo.FadeOut(transition_duration);
|
||||
name.FadeOut(transition_duration);
|
||||
participantInfo.FadeOut(transition_duration);
|
||||
|
||||
displayStatus(new RoomStatusNoneSelected());
|
||||
}
|
||||
else
|
||||
{
|
||||
participantsFlow.FadeIn(transition_duration);
|
||||
participantCount.FadeIn(transition_duration);
|
||||
beatmapTypeInfo.FadeIn(transition_duration);
|
||||
name.FadeIn(transition_duration);
|
||||
participantInfo.FadeIn(transition_duration);
|
||||
|
||||
statusBind.TriggerChange();
|
||||
beatmapBind.TriggerChange();
|
||||
}
|
||||
}
|
||||
|
||||
private class UserTile : Container, IHasTooltip
|
||||
{
|
||||
private readonly User user;
|
135
osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs
Normal file
135
osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs
Normal file
@ -0,0 +1,135 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Lounge.Components
|
||||
{
|
||||
public class RoomsContainer : CompositeDrawable
|
||||
{
|
||||
public Action<Room> JoinRequested;
|
||||
|
||||
private readonly Bindable<Room> selectedRoom = new Bindable<Room>();
|
||||
public IBindable<Room> SelectedRoom => selectedRoom;
|
||||
|
||||
private readonly IBindableCollection<Room> rooms = new BindableCollection<Room>();
|
||||
|
||||
private readonly FillFlowContainer<DrawableRoom> roomFlow;
|
||||
public IReadOnlyList<DrawableRoom> Rooms => roomFlow;
|
||||
|
||||
[Resolved]
|
||||
private IRoomManager roomManager { get; set; }
|
||||
|
||||
public RoomsContainer()
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
InternalChild = roomFlow = new FillFlowContainer<DrawableRoom>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(2),
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
rooms.BindTo(roomManager.Rooms);
|
||||
|
||||
rooms.ItemsAdded += addRooms;
|
||||
rooms.ItemsRemoved += removeRooms;
|
||||
|
||||
roomManager.RoomsUpdated += updateSorting;
|
||||
|
||||
addRooms(rooms);
|
||||
}
|
||||
|
||||
private FilterCriteria currentFilter;
|
||||
|
||||
public void Filter(FilterCriteria criteria)
|
||||
{
|
||||
roomFlow.Children.ForEach(r =>
|
||||
{
|
||||
if (criteria == null)
|
||||
r.MatchingFilter = true;
|
||||
else
|
||||
{
|
||||
bool matchingFilter = true;
|
||||
matchingFilter &= r.FilterTerms.Any(term => term.IndexOf(criteria.SearchString, StringComparison.InvariantCultureIgnoreCase) >= 0);
|
||||
|
||||
switch (criteria.SecondaryFilter)
|
||||
{
|
||||
default:
|
||||
case SecondaryFilter.Public:
|
||||
r.MatchingFilter = r.Room.Availability.Value == RoomAvailability.Public;
|
||||
break;
|
||||
}
|
||||
|
||||
r.MatchingFilter = matchingFilter;
|
||||
}
|
||||
});
|
||||
|
||||
currentFilter = criteria;
|
||||
}
|
||||
|
||||
private void addRooms(IEnumerable<Room> rooms)
|
||||
{
|
||||
foreach (var r in rooms)
|
||||
roomFlow.Add(new DrawableRoom(r) { Action = () => selectRoom(r) });
|
||||
|
||||
Filter(currentFilter);
|
||||
}
|
||||
|
||||
private void removeRooms(IEnumerable<Room> rooms)
|
||||
{
|
||||
foreach (var r in rooms)
|
||||
{
|
||||
var toRemove = roomFlow.Single(d => d.Room == r);
|
||||
toRemove.Action = null;
|
||||
|
||||
roomFlow.Remove(toRemove);
|
||||
|
||||
selectRoom(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSorting()
|
||||
{
|
||||
foreach (var room in roomFlow)
|
||||
roomFlow.SetLayoutPosition(room, room.Room.Position);
|
||||
}
|
||||
|
||||
private void selectRoom(Room room)
|
||||
{
|
||||
var drawable = roomFlow.FirstOrDefault(r => r.Room == room);
|
||||
|
||||
if (drawable != null && drawable.State == SelectionState.Selected)
|
||||
JoinRequested?.Invoke(room);
|
||||
else
|
||||
roomFlow.Children.ForEach(r => r.State = r.Room == room ? SelectionState.Selected : SelectionState.NotSelected);
|
||||
|
||||
selectedRoom.Value = room;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (roomManager != null)
|
||||
roomManager.RoomsUpdated -= updateSorting;
|
||||
}
|
||||
}
|
||||
}
|
151
osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs
Normal file
151
osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs
Normal file
@ -0,0 +1,151 @@
|
||||
// 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;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Overlays.SearchableList;
|
||||
using osu.Game.Screens.Multi.Lounge.Components;
|
||||
using osu.Game.Screens.Multi.Match;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Lounge
|
||||
{
|
||||
public class LoungeSubScreen : MultiplayerSubScreen
|
||||
{
|
||||
protected readonly FilterControl Filter;
|
||||
|
||||
private readonly Container content;
|
||||
private readonly RoomsContainer rooms;
|
||||
private readonly Action<Screen> pushGameplayScreen;
|
||||
private readonly ProcessingOverlay processingOverlay;
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private IRoomManager roomManager { get; set; }
|
||||
|
||||
public override string Title => "Lounge";
|
||||
|
||||
protected override Drawable TransitionContent => content;
|
||||
|
||||
public LoungeSubScreen(Action<Screen> pushGameplayScreen)
|
||||
{
|
||||
this.pushGameplayScreen = pushGameplayScreen;
|
||||
|
||||
RoomInspector inspector;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Filter = new FilterControl { Depth = -1 },
|
||||
content = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0.55f,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new ScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
ScrollbarOverlapsContent = false,
|
||||
Padding = new MarginPadding(10),
|
||||
Child = new SearchContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Child = rooms = new RoomsContainer { JoinRequested = joinRequested }
|
||||
},
|
||||
},
|
||||
processingOverlay = new ProcessingOverlay { Alpha = 0 }
|
||||
}
|
||||
},
|
||||
inspector = new RoomInspector
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0.45f,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
inspector.Room.BindTo(rooms.SelectedRoom);
|
||||
|
||||
Filter.Search.Current.ValueChanged += s => filterRooms();
|
||||
Filter.Tabs.Current.ValueChanged += t => filterRooms();
|
||||
Filter.Search.Exit += Exit;
|
||||
}
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
{
|
||||
base.UpdateAfterChildren();
|
||||
|
||||
content.Padding = new MarginPadding
|
||||
{
|
||||
Top = Filter.DrawHeight,
|
||||
Left = SearchableListOverlay.WIDTH_PADDING - DrawableRoom.SELECTION_BORDER_WIDTH,
|
||||
Right = SearchableListOverlay.WIDTH_PADDING,
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnFocus(FocusEvent e)
|
||||
{
|
||||
GetContainingInputManager().ChangeFocus(Filter.Search);
|
||||
}
|
||||
|
||||
protected override void OnEntering(Screen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
Filter.Search.HoldFocus = true;
|
||||
}
|
||||
|
||||
protected override bool OnExiting(Screen next)
|
||||
{
|
||||
Filter.Search.HoldFocus = false;
|
||||
// no base call; don't animate
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void OnSuspending(Screen next)
|
||||
{
|
||||
base.OnSuspending(next);
|
||||
Filter.Search.HoldFocus = false;
|
||||
}
|
||||
|
||||
private void filterRooms()
|
||||
{
|
||||
rooms.Filter(Filter.CreateCriteria());
|
||||
roomManager?.Filter(Filter.CreateCriteria());
|
||||
}
|
||||
|
||||
private void joinRequested(Room room)
|
||||
{
|
||||
processingOverlay.Show();
|
||||
roomManager?.JoinRoom(room, r =>
|
||||
{
|
||||
Push(room);
|
||||
processingOverlay.Hide();
|
||||
}, _ => processingOverlay.Hide());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Push a room as a new subscreen.
|
||||
/// </summary>
|
||||
public void Push(Room room)
|
||||
{
|
||||
// Handles the case where a room is clicked 3 times in quick succession
|
||||
if (!IsCurrentScreen)
|
||||
return;
|
||||
|
||||
Push(new MatchSubScreen(room, s => pushGameplayScreen?.Invoke(s)));
|
||||
}
|
||||
}
|
||||
}
|
@ -9,17 +9,19 @@ using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.GameTypes;
|
||||
using osu.Game.Screens.Multi.Components;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Screens.Match.Settings
|
||||
namespace osu.Game.Screens.Multi.Match.Components
|
||||
{
|
||||
public class GameTypePicker : TabControl<GameType>
|
||||
public class GameTypePicker : DisableableTabControl<GameType>
|
||||
{
|
||||
private const float height = 40;
|
||||
private const float selection_width = 3;
|
||||
|
||||
protected override TabItem<GameType> CreateTabItem(GameType value) => new GameTypePickerItem(value);
|
||||
|
||||
protected override Dropdown<GameType> CreateDropdown() => null;
|
||||
|
||||
public GameTypePicker()
|
||||
@ -31,15 +33,17 @@ namespace osu.Game.Screens.Multi.Screens.Match.Settings
|
||||
AddItem(new GameTypeVersus());
|
||||
AddItem(new GameTypeTagTeam());
|
||||
AddItem(new GameTypeTeamVersus());
|
||||
AddItem(new GameTypeTimeshift());
|
||||
}
|
||||
|
||||
private class GameTypePickerItem : TabItem<GameType>
|
||||
private class GameTypePickerItem : DisableableTabItem<GameType>
|
||||
{
|
||||
private const float transition_duration = 200;
|
||||
|
||||
private readonly CircularContainer hover, selection;
|
||||
|
||||
public GameTypePickerItem(GameType value) : base(value)
|
||||
public GameTypePickerItem(GameType value)
|
||||
: base(value)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
147
osu.Game/Screens/Multi/Match/Components/Header.cs
Normal file
147
osu.Game/Screens/Multi/Match/Components/Header.cs
Normal file
@ -0,0 +1,147 @@
|
||||
// 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;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Overlays.SearchableList;
|
||||
using osu.Game.Screens.Multi.Components;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Match.Components
|
||||
{
|
||||
public class Header : Container
|
||||
{
|
||||
public const float HEIGHT = 200;
|
||||
|
||||
private readonly RoomBindings bindings = new RoomBindings();
|
||||
|
||||
private readonly Box tabStrip;
|
||||
|
||||
public readonly MatchTabControl Tabs;
|
||||
|
||||
public Action OnRequestSelectBeatmap;
|
||||
|
||||
public Header(Room room)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = HEIGHT;
|
||||
|
||||
bindings.Room = room;
|
||||
|
||||
BeatmapTypeInfo beatmapTypeInfo;
|
||||
BeatmapSelectButton beatmapButton;
|
||||
UpdateableBeatmapBackgroundSprite background;
|
||||
ModDisplay modDisplay;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
background = new HeaderBeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both },
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.4f), Color4.Black.Opacity(0.6f)),
|
||||
},
|
||||
}
|
||||
},
|
||||
tabStrip = new Box
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 1,
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Top = 20 },
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
beatmapTypeInfo = new BeatmapTypeInfo(),
|
||||
modDisplay = new ModDisplay
|
||||
{
|
||||
Scale = new Vector2(0.75f),
|
||||
DisplayUnrankedText = false
|
||||
},
|
||||
}
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = 200,
|
||||
Padding = new MarginPadding { Vertical = 10 },
|
||||
Child = beatmapButton = new BeatmapSelectButton(room)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Height = 1,
|
||||
},
|
||||
},
|
||||
Tabs = new MatchTabControl(room)
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.X
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
beatmapTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap);
|
||||
beatmapTypeInfo.Ruleset.BindTo(bindings.CurrentRuleset);
|
||||
beatmapTypeInfo.Type.BindTo(bindings.Type);
|
||||
background.Beatmap.BindTo(bindings.CurrentBeatmap);
|
||||
bindings.CurrentMods.BindValueChanged(m => modDisplay.Current.Value = m, true);
|
||||
|
||||
beatmapButton.Action = () => OnRequestSelectBeatmap?.Invoke();
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
tabStrip.Colour = colours.Yellow;
|
||||
}
|
||||
|
||||
private class BeatmapSelectButton : HeaderButton
|
||||
{
|
||||
private readonly IBindable<int?> roomIDBind = new Bindable<int?>();
|
||||
|
||||
public BeatmapSelectButton(Room room)
|
||||
{
|
||||
Text = "Select beatmap";
|
||||
|
||||
roomIDBind.BindTo(room.RoomID);
|
||||
roomIDBind.BindValueChanged(v => this.FadeTo(v.HasValue ? 0 : 1), true);
|
||||
}
|
||||
}
|
||||
|
||||
private class HeaderBeatmapBackgroundSprite : UpdateableBeatmapBackgroundSprite
|
||||
{
|
||||
protected override double FadeDuration => 200;
|
||||
}
|
||||
}
|
||||
}
|
48
osu.Game/Screens/Multi/Match/Components/HeaderButton.cs
Normal file
48
osu.Game/Screens/Multi/Match/Components/HeaderButton.cs
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Match.Components
|
||||
{
|
||||
public class HeaderButton : TriangleButton
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
BackgroundColour = OsuColour.FromHex(@"1187aa");
|
||||
|
||||
Triangles.ColourLight = OsuColour.FromHex(@"277b9c");
|
||||
Triangles.ColourDark = OsuColour.FromHex(@"1f6682");
|
||||
Triangles.TriangleScale = 1.5f;
|
||||
|
||||
Add(new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 1f,
|
||||
Child = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0.15f,
|
||||
Blending = BlendingMode.Additive,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
protected override SpriteText CreateText() => new OsuSpriteText
|
||||
{
|
||||
Depth = -1,
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
||||
Font = @"Exo2.0-Light",
|
||||
TextSize = 30,
|
||||
};
|
||||
}
|
||||
}
|
60
osu.Game/Screens/Multi/Match/Components/HostInfo.cs
Normal file
60
osu.Game/Screens/Multi/Match/Components/HostInfo.cs
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Match.Components
|
||||
{
|
||||
public class HostInfo : CompositeDrawable
|
||||
{
|
||||
public readonly IBindable<User> Host = new Bindable<User>();
|
||||
|
||||
private readonly LinkFlowContainer linkContainer;
|
||||
private readonly UpdateableAvatar avatar;
|
||||
|
||||
public HostInfo()
|
||||
{
|
||||
AutoSizeAxes = Axes.X;
|
||||
Height = 50;
|
||||
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5, 0),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
avatar = new UpdateableAvatar { Size = new Vector2(50) },
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Child = linkContainer = new LinkFlowContainer { AutoSizeAxes = Axes.Both }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Host.BindValueChanged(updateHost);
|
||||
}
|
||||
|
||||
private void updateHost(User host)
|
||||
{
|
||||
avatar.User = host;
|
||||
|
||||
if (host != null)
|
||||
{
|
||||
linkContainer.AddText("hosted by");
|
||||
linkContainer.NewLine();
|
||||
linkContainer.AddLink(host.Username, null, LinkAction.OpenUserProfile, host.Id.ToString(), "View Profile", s => s.Font = "Exo2.0-BoldItalic");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
100
osu.Game/Screens/Multi/Match/Components/Info.cs
Normal file
100
osu.Game/Screens/Multi/Match/Components/Info.cs
Normal file
@ -0,0 +1,100 @@
|
||||
// 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;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Overlays.SearchableList;
|
||||
using osu.Game.Screens.Multi.Components;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Match.Components
|
||||
{
|
||||
public class Info : Container
|
||||
{
|
||||
public Action OnStart;
|
||||
|
||||
private readonly RoomBindings bindings = new RoomBindings();
|
||||
|
||||
public Info(Room room)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
ReadyButton readyButton;
|
||||
ViewBeatmapButton viewBeatmapButton;
|
||||
HostInfo hostInfo;
|
||||
RoomStatusInfo statusInfo;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = OsuColour.FromHex(@"28242d"),
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 10),
|
||||
Padding = new MarginPadding { Vertical = 20 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
TextSize = 30,
|
||||
Current = bindings.Name
|
||||
},
|
||||
new RoomStatusInfo(room),
|
||||
}
|
||||
},
|
||||
hostInfo = new HostInfo(),
|
||||
},
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
AutoSizeAxes = Axes.X,
|
||||
Height = 70,
|
||||
Spacing = new Vector2(10, 0),
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
viewBeatmapButton = new ViewBeatmapButton(),
|
||||
readyButton = new ReadyButton(room)
|
||||
{
|
||||
Action = () => OnStart?.Invoke()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
viewBeatmapButton.Beatmap.BindTo(bindings.CurrentBeatmap);
|
||||
readyButton.Beatmap.BindTo(bindings.CurrentBeatmap);
|
||||
hostInfo.Host.BindTo(bindings.Host);
|
||||
|
||||
bindings.Room = room;
|
||||
}
|
||||
}
|
||||
}
|
36
osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs
Normal file
36
osu.Game/Screens/Multi/Match/Components/MatchChatDisplay.cs
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
|
||||
namespace osu.Game.Screens.Multi.Match.Components
|
||||
{
|
||||
public class MatchChatDisplay : StandAloneChatDisplay
|
||||
{
|
||||
private readonly Room room;
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
private ChannelManager channelManager { get; set; }
|
||||
|
||||
public MatchChatDisplay(Room room)
|
||||
: base(true)
|
||||
{
|
||||
this.room = room;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
room.RoomID.BindValueChanged(v => updateChannel(), true);
|
||||
}
|
||||
|
||||
private void updateChannel()
|
||||
{
|
||||
if (room.RoomID.Value != null)
|
||||
Channel.Value = channelManager?.JoinChannel(new Channel { Id = room.ChannelId, Type = ChannelType.Multiplayer, Name = $"#mp_{room.RoomID}" });
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user