1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-08 05:52:54 +08:00

Merge remote-tracking branch 'origin/master' into fix-beatmap-import-conflicts

# Conflicts:
#	osu.Game/Database/ArchiveModelManager.cs
This commit is contained in:
smoogipoo 2018-05-31 14:02:52 +09:00
commit 9da7bfd615
21 changed files with 154 additions and 105 deletions

2
.vscode/launch.json vendored
View File

@ -22,7 +22,7 @@
}, },
"type": "mono", "type": "mono",
"request": "launch", "request": "launch",
"program": "${workspaceRoot}/osu.Game.Tests/bin/Debug/net471/osu.Game.Tests.exe", "program": "${workspaceRoot}/osu.Game.Tests/bin/Release/net471/osu.Game.Tests.exe",
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release, msbuild)", "preLaunchTask": "Build (Release, msbuild)",
"runtimeExecutable": null, "runtimeExecutable": null,

@ -1 +1 @@
Subproject commit 84fdfc77a86d581638e69f5e8061c118de4b30f9 Subproject commit aebfa5bc5c634c1fd0c103e0c17518e5111a67c7

View File

@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Catch.Tests
Child = catcherArea = new TestCatcherArea(new BeatmapDifficulty { CircleSize = size }) Child = catcherArea = new TestCatcherArea(new BeatmapDifficulty { CircleSize = size })
{ {
Anchor = Anchor.CentreLeft, Anchor = Anchor.CentreLeft,
Origin = Anchor.BottomLeft Origin = Anchor.TopLeft
}, },
}; };
} }

View File

@ -25,6 +25,7 @@ namespace osu.Game.Rulesets.Catch.Tests
typeof(DrawableCatchHitObject), typeof(DrawableCatchHitObject),
typeof(DrawableFruit), typeof(DrawableFruit),
typeof(DrawableDroplet), typeof(DrawableDroplet),
typeof(BananaShower),
typeof(Pulp), typeof(Pulp),
}; };
@ -53,7 +54,14 @@ namespace osu.Game.Rulesets.Catch.Tests
private DrawableFruit createDrawable(int index) private DrawableFruit createDrawable(int index)
{ {
var fruit = new Fruit Fruit fruit = index == 5
? new BananaShower.Banana
{
StartTime = 1000000000000,
IndexInBeatmap = index,
Scale = 1.5f,
}
: new Fruit
{ {
StartTime = 1000000000000, StartTime = 1000000000000,
IndexInBeatmap = index, IndexInBeatmap = index,

View File

@ -18,12 +18,19 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{ {
private Circle border; private Circle border;
private const float drawable_radius = (float)CatchHitObject.OBJECT_RADIUS * radius_adjust;
/// <summary>
/// Because we're adding a border around the fruit, we need to scale down some.
/// </summary>
private const float radius_adjust = 1.1f;
public DrawableFruit(Fruit h) public DrawableFruit(Fruit h)
: base(h) : base(h)
{ {
Origin = Anchor.Centre; Origin = Anchor.Centre;
Size = new Vector2((float)CatchHitObject.OBJECT_RADIUS); Size = new Vector2(drawable_radius);
Masking = false; Masking = false;
Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; Rotation = (float)(RNG.NextDouble() - 0.5f) * 40;
@ -44,14 +51,14 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{ {
Hollow = !HitObject.HyperDash, Hollow = !HitObject.HyperDash,
Type = EdgeEffectType.Glow, Type = EdgeEffectType.Glow,
Radius = 4, Radius = 4 * radius_adjust,
Colour = HitObject.HyperDash ? Color4.Red : AccentColour.Darken(1).Opacity(0.6f) Colour = HitObject.HyperDash ? Color4.Red : AccentColour.Darken(1).Opacity(0.6f)
}, },
Size = new Vector2(Height * 1.5f), Size = new Vector2(Height),
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
BorderColour = Color4.White, BorderColour = Color4.White,
BorderThickness = 4f, BorderThickness = 3f * radius_adjust,
Children = new Framework.Graphics.Drawable[] Children = new Framework.Graphics.Drawable[]
{ {
new Box new Box
@ -82,8 +89,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
private Framework.Graphics.Drawable createPulp(FruitVisualRepresentation representation) private Framework.Graphics.Drawable createPulp(FruitVisualRepresentation representation)
{ {
const float large_pulp_3 = 13f; const float large_pulp_3 = 8f * radius_adjust;
const float distance_from_centre_3 = 0.23f; const float distance_from_centre_3 = 0.15f;
const float large_pulp_4 = large_pulp_3 * 0.925f; const float large_pulp_4 = large_pulp_3 * 0.925f;
const float distance_from_centre_4 = distance_from_centre_3 / 0.925f; const float distance_from_centre_4 = distance_from_centre_3 / 0.925f;
@ -106,11 +113,9 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{ {
new Pulp new Pulp
{ {
Anchor = Anchor.TopCentre,
Origin = Anchor.BottomCentre,
AccentColour = AccentColour, AccentColour = AccentColour,
Size = new Vector2(small_pulp), Size = new Vector2(small_pulp),
Y = 0.05f, Y = -0.34f,
}, },
new Pulp new Pulp
{ {
@ -146,11 +151,9 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{ {
new Pulp new Pulp
{ {
Anchor = Anchor.TopCentre,
Origin = Anchor.BottomCentre,
AccentColour = AccentColour, AccentColour = AccentColour,
Size = new Vector2(small_pulp), Size = new Vector2(small_pulp),
Y = 0.1f, Y = -0.3f,
}, },
new Pulp new Pulp
{ {
@ -186,11 +189,9 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{ {
new Pulp new Pulp
{ {
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
AccentColour = AccentColour, AccentColour = AccentColour,
Size = new Vector2(small_pulp), Size = new Vector2(small_pulp),
Y = -0.1f, Y = -0.33f,
}, },
new Pulp new Pulp
{ {
@ -220,10 +221,9 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{ {
new Pulp new Pulp
{ {
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
AccentColour = AccentColour, AccentColour = AccentColour,
Size = new Vector2(small_pulp), Size = new Vector2(small_pulp),
Y = -0.25f,
}, },
new Pulp new Pulp
{ {
@ -253,16 +253,15 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{ {
new Pulp new Pulp
{ {
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
AccentColour = AccentColour, AccentColour = AccentColour,
Size = new Vector2(small_pulp), Size = new Vector2(small_pulp),
Y = -0.15f Y = -0.3f
}, },
new Pulp new Pulp
{ {
AccentColour = AccentColour, AccentColour = AccentColour,
Size = new Vector2(large_pulp_4 * 1.2f, large_pulp_4 * 3), Size = new Vector2(large_pulp_4 * 0.8f, large_pulp_4 * 2.5f),
Y = 0.05f,
}, },
} }
}; };

View File

@ -29,14 +29,24 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces
set set
{ {
accentColour = value; accentColour = value;
if (IsLoaded) updateAccentColour();
}
}
private void updateAccentColour()
{
EdgeEffect = new EdgeEffectParameters EdgeEffect = new EdgeEffectParameters
{ {
Type = EdgeEffectType.Glow, Type = EdgeEffectType.Glow,
Radius = 8, Radius = Size.X / 2,
Colour = accentColour.Darken(0.2f).Opacity(0.75f) Colour = accentColour.Darken(0.2f).Opacity(0.75f)
}; };
} }
protected override void LoadComplete()
{
base.LoadComplete();
updateAccentColour();
} }
} }
} }

View File

@ -32,6 +32,8 @@ namespace osu.Game.Rulesets.Catch.UI
public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo); public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo);
protected override Vector2 PlayfieldArea => new Vector2(0.86f); // matches stable's vertical offset for catcher plate
protected override DrawableHitObject<CatchHitObject> GetVisualRepresentation(CatchHitObject h) protected override DrawableHitObject<CatchHitObject> GetVisualRepresentation(CatchHitObject h)
{ {
switch (h) switch (h)

View File

@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.UI
{ {
public class CatcherArea : Container public class CatcherArea : Container
{ {
public const float CATCHER_SIZE = 172; public const float CATCHER_SIZE = 84;
protected readonly Catcher MovableCatcher; protected readonly Catcher MovableCatcher;
@ -99,8 +99,6 @@ namespace osu.Game.Rulesets.Catch.UI
public class Catcher : Container, IKeyBindingHandler<CatchAction> public class Catcher : Container, IKeyBindingHandler<CatchAction>
{ {
private Texture texture;
private Container<DrawableHitObject> caughtFruit; private Container<DrawableHitObject> caughtFruit;
public Container ExplodingFruitTarget; public Container ExplodingFruitTarget;
@ -121,10 +119,8 @@ namespace osu.Game.Rulesets.Catch.UI
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(TextureStore textures) private void load()
{ {
texture = textures.Get(@"Play/Catch/fruit-catcher-idle");
Children = new Drawable[] Children = new Drawable[]
{ {
caughtFruit = new Container<DrawableHitObject> caughtFruit = new Container<DrawableHitObject>
@ -196,13 +192,7 @@ namespace osu.Game.Rulesets.Catch.UI
Scheduler.AddDelayed(beginTrail, HyperDashing ? 25 : 50); Scheduler.AddDelayed(beginTrail, HyperDashing ? 25 : 50);
} }
private Sprite createCatcherSprite() => new Sprite private Sprite createCatcherSprite() => new CatcherSprite();
{
Size = new Vector2(CATCHER_SIZE),
FillMode = FillMode.Fill,
Texture = texture,
OriginPosition = new Vector2(-3, 10) // temporary until the sprite is aligned correctly.
};
/// <summary> /// <summary>
/// Add a caught fruit to the catcher's stack. /// Add a caught fruit to the catcher's stack.
@ -411,6 +401,23 @@ namespace osu.Game.Rulesets.Catch.UI
f.Expire(); f.Expire();
} }
} }
private class CatcherSprite : Sprite
{
public CatcherSprite()
{
Size = new Vector2(CATCHER_SIZE);
// Sets the origin roughly to the centre of the catcher's plate to allow for correct scaling.
OriginPosition = new Vector2(-0.02f, 0.06f) * CATCHER_SIZE;
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
Texture = textures.Get(@"Play/Catch/fruit-catcher-idle");
}
}
} }
} }
} }

View File

@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public override string Name => "Dual Stages"; public override string Name => "Dual Stages";
public override string ShortenedName => "DS"; public override string ShortenedName => "DS";
public override string Description => @"Double the stages, double the fun!"; public override string Description => @"Double the stages, double the fun!";
public override double ScoreMultiplier => 0; public override double ScoreMultiplier => 1;
private bool isForCurrentRuleset; private bool isForCurrentRuleset;

View File

@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public override string ShortenedName => "RD"; public override string ShortenedName => "RD";
public override FontAwesome Icon => FontAwesome.fa_osu_dice; public override FontAwesome Icon => FontAwesome.fa_osu_dice;
public override string Description => @"Shuffle around the keys!"; public override string Description => @"Shuffle around the keys!";
public override double ScoreMultiplier => 0; public override double ScoreMultiplier => 1;
public void ApplyToRulesetContainer(RulesetContainer<ManiaHitObject> rulesetContainer) public void ApplyToRulesetContainer(RulesetContainer<ManiaHitObject> rulesetContainer)
{ {

View File

@ -13,8 +13,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public override string ShortenedName => "AP"; public override string ShortenedName => "AP";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_autopilot; public override FontAwesome Icon => FontAwesome.fa_osu_mod_autopilot;
public override string Description => @"Automatic cursor movement - just follow the rhythm."; public override string Description => @"Automatic cursor movement - just follow the rhythm.";
public override double ScoreMultiplier => 0; public override double ScoreMultiplier => 1;
public override bool Ranked => false;
public override Type[] IncompatibleMods => new[] { typeof(OsuModSpunOut), typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail), typeof(ModAutoplay) }; public override Type[] IncompatibleMods => new[] { typeof(OsuModSpunOut), typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail), typeof(ModAutoplay) };
} }
} }

View File

@ -39,8 +39,6 @@ namespace osu.Game.Tests.Visual
typeof(SpecialSection), typeof(SpecialSection),
}; };
private const string unranked_suffix = " (Unranked)";
private RulesetStore rulesets; private RulesetStore rulesets;
private ModDisplay modDisplay; private ModDisplay modDisplay;
private TestModSelectOverlay modSelect; private TestModSelectOverlay modSelect;
@ -121,7 +119,7 @@ namespace osu.Game.Tests.Visual
private void testManiaMods(ManiaRuleset ruleset) private void testManiaMods(ManiaRuleset ruleset)
{ {
testMultiplierTextUnranked(ruleset.GetModsFor(ModType.Special).First(m => m is ManiaModRandom)); testRankedText(ruleset.GetModsFor(ModType.Special).First(m => m is ManiaModRandom));
} }
private void testSingleMod(Mod mod) private void testSingleMod(Mod mod)
@ -198,13 +196,16 @@ namespace osu.Game.Tests.Visual
checkLabelColor(Color4.White); checkLabelColor(Color4.White);
} }
private void testMultiplierTextUnranked(Mod mod) private void testRankedText(Mod mod)
{ {
AddAssert("check for ranked", () => !modSelect.MultiplierLabel.Text.EndsWith(unranked_suffix)); AddWaitStep(1, "wait for fade");
AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0);
selectNext(mod); selectNext(mod);
AddAssert("check for unranked", () => modSelect.MultiplierLabel.Text.EndsWith(unranked_suffix)); AddWaitStep(1, "wait for fade");
AddAssert("check for unranked", () => modSelect.UnrankedLabel.Alpha != 0);
selectPrevious(mod); selectPrevious(mod);
AddAssert("check for ranked", () => !modSelect.MultiplierLabel.Text.EndsWith(unranked_suffix)); AddWaitStep(1, "wait for fade");
AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0);
} }
private void selectNext(Mod mod) => AddStep($"left click {mod.Name}", () => modSelect.GetModButton(mod)?.SelectNext(1)); private void selectNext(Mod mod) => AddStep($"left click {mod.Name}", () => modSelect.GetModButton(mod)?.SelectNext(1));
@ -240,6 +241,7 @@ namespace osu.Game.Tests.Visual
} }
public new OsuSpriteText MultiplierLabel => base.MultiplierLabel; public new OsuSpriteText MultiplierLabel => base.MultiplierLabel;
public new OsuSpriteText UnrankedLabel => base.UnrankedLabel;
public new TriangleButton DeselectAllButton => base.DeselectAllButton; public new TriangleButton DeselectAllButton => base.DeselectAllButton;
public new Color4 LowMultiplierColour => base.LowMultiplierColour; public new Color4 LowMultiplierColour => base.LowMultiplierColour;

View File

@ -174,7 +174,7 @@ namespace osu.Game.Database
/// <param name="archive">The archive to be imported.</param> /// <param name="archive">The archive to be imported.</param>
public TModel Import(ArchiveReader archive) public TModel Import(ArchiveReader archive)
{ {
TModel item; TModel item = null;
delayEvents(); delayEvents();
try try
@ -212,14 +212,17 @@ namespace osu.Game.Database
Logger.Log($"Import of {archive.Name} successfully completed!", LoggingTarget.Database); Logger.Log($"Import of {archive.Name} successfully completed!", LoggingTarget.Database);
} }
catch catch (Exception e)
{ {
Logger.Log($"Import of {archive.Name} failed and has been rolled back.", LoggingTarget.Database); Logger.Error(e, $"Import of {archive.Name} failed and has been rolled back.", LoggingTarget.Database);
item = null; item = null;
} }
finally
{
// we only want to flush events after we've confirmed the write context didn't have any errors. // we only want to flush events after we've confirmed the write context didn't have any errors.
flushEvents(item != null); flushEvents(item != null);
}
return item; return item;
} }
@ -243,12 +246,8 @@ namespace osu.Game.Database
/// <param name="item">The item to delete.</param> /// <param name="item">The item to delete.</param>
public void Delete(TModel item) public void Delete(TModel item)
{ {
using (var usage = ContextFactory.GetForWrite()) using (ContextFactory.GetForWrite())
{ {
var context = usage.Context;
context.ChangeTracker.AutoDetectChangesEnabled = false;
// re-fetch the model on the import context. // re-fetch the model on the import context.
var foundModel = queryModel().Include(s => s.Files).ThenInclude(f => f.FileInfo).First(s => s.ID == item.ID); var foundModel = queryModel().Include(s => s.Files).ThenInclude(f => f.FileInfo).First(s => s.ID == item.ID);
@ -256,8 +255,6 @@ namespace osu.Game.Database
if (ModelStore.Delete(foundModel)) if (ModelStore.Delete(foundModel))
Files.Dereference(foundModel.Files.Select(f => f.FileInfo).ToArray()); Files.Dereference(foundModel.Files.Select(f => f.FileInfo).ToArray());
context.ChangeTracker.AutoDetectChangesEnabled = true;
} }
} }

View File

@ -48,7 +48,14 @@ namespace osu.Game.Database
Monitor.Enter(writeLock); Monitor.Enter(writeLock);
if (currentWriteTransaction == null && withTransaction) if (currentWriteTransaction == null && withTransaction)
{
// this mitigates the fact that changes on tracked entities will not be rolled back with the transaction by ensuring write operations are always executed in isolated contexts.
// if this results in sub-optimal efficiency, we may need to look into removing Database-level transactions in favour of running SaveChanges where we currently commit the transaction.
if (threadContexts.IsValueCreated)
recycleThreadContexts();
currentWriteTransaction = threadContexts.Value.Database.BeginTransaction(); currentWriteTransaction = threadContexts.Value.Database.BeginTransaction();
}
Interlocked.Increment(ref currentWriteUsages); Interlocked.Increment(ref currentWriteUsages);
@ -64,18 +71,14 @@ namespace osu.Game.Database
currentWriteDidWrite |= usage.PerformedWrite; currentWriteDidWrite |= usage.PerformedWrite;
currentWriteDidError |= usage.Errors.Any(); currentWriteDidError |= usage.Errors.Any();
if (usages > 0) return; if (usages == 0)
{
if (currentWriteDidError) if (currentWriteDidError)
currentWriteTransaction?.Rollback(); currentWriteTransaction?.Rollback();
else else
currentWriteTransaction?.Commit(); currentWriteTransaction?.Commit();
currentWriteTransaction = null; if (currentWriteDidWrite || currentWriteDidError)
currentWriteDidWrite = false;
currentWriteDidError = false;
if (currentWriteDidWrite)
{ {
// explicitly dispose to ensure any outstanding flushes happen as soon as possible (and underlying resources are purged). // explicitly dispose to ensure any outstanding flushes happen as soon as possible (and underlying resources are purged).
usage.Context.Dispose(); usage.Context.Dispose();
@ -83,6 +86,11 @@ namespace osu.Game.Database
// once all writes are complete, we want to refresh thread-specific contexts to make sure they don't have stale local caches. // once all writes are complete, we want to refresh thread-specific contexts to make sure they don't have stale local caches.
recycleThreadContexts(); recycleThreadContexts();
} }
currentWriteTransaction = null;
currentWriteDidWrite = false;
currentWriteDidError = false;
}
} }
finally finally
{ {

View File

@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Mods
protected Color4 LowMultiplierColour, HighMultiplierColour; protected Color4 LowMultiplierColour, HighMultiplierColour;
protected readonly TriangleButton DeselectAllButton; protected readonly TriangleButton DeselectAllButton;
protected readonly OsuSpriteText MultiplierLabel; protected readonly OsuSpriteText MultiplierLabel, UnrankedLabel;
private readonly FillFlowContainer footerContainer; private readonly FillFlowContainer footerContainer;
protected override bool BlockPassThroughKeyboard => false; protected override bool BlockPassThroughKeyboard => false;
@ -58,6 +58,7 @@ namespace osu.Game.Overlays.Mods
LowMultiplierColour = colours.Red; LowMultiplierColour = colours.Red;
HighMultiplierColour = colours.Green; HighMultiplierColour = colours.Green;
UnrankedLabel.Colour = colours.Blue;
if (osu != null) if (osu != null)
Ruleset.BindTo(osu.Ruleset); Ruleset.BindTo(osu.Ruleset);
@ -99,15 +100,14 @@ namespace osu.Game.Overlays.Mods
} }
MultiplierLabel.Text = $"{multiplier:N2}x"; MultiplierLabel.Text = $"{multiplier:N2}x";
if (!ranked)
MultiplierLabel.Text += " (Unranked)";
if (multiplier > 1.0) if (multiplier > 1.0)
MultiplierLabel.FadeColour(HighMultiplierColour, 200); MultiplierLabel.FadeColour(HighMultiplierColour, 200);
else if (multiplier < 1.0) else if (multiplier < 1.0)
MultiplierLabel.FadeColour(LowMultiplierColour, 200); MultiplierLabel.FadeColour(LowMultiplierColour, 200);
else else
MultiplierLabel.FadeColour(Color4.White, 200); MultiplierLabel.FadeColour(Color4.White, 200);
UnrankedLabel.FadeTo(ranked ? 0 : 1, 200);
} }
protected override void PopOut() protected override void PopOut()
@ -352,23 +352,33 @@ namespace osu.Game.Overlays.Mods
}, },
new OsuSpriteText new OsuSpriteText
{ {
Text = @"Score Multiplier: ", Text = @"Score Multiplier:",
TextSize = 30, TextSize = 30,
Shadow = true,
Margin = new MarginPadding Margin = new MarginPadding
{ {
Top = 5 Top = 5,
Right = 10
} }
}, },
MultiplierLabel = new OsuSpriteText MultiplierLabel = new OsuSpriteText
{ {
Font = @"Exo2.0-Bold", Font = @"Exo2.0-Bold",
TextSize = 30, TextSize = 30,
Shadow = true,
Margin = new MarginPadding Margin = new MarginPadding
{ {
Top = 5 Top = 5
} }
},
UnrankedLabel = new OsuSpriteText
{
Font = @"Exo2.0-Bold",
Text = @"(Unranked)",
TextSize = 30,
Margin = new MarginPadding
{
Top = 5,
Left = 10
}
} }
} }
} }

View File

@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mods
public override string ShortenedName => "AT"; public override string ShortenedName => "AT";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_auto; public override FontAwesome Icon => FontAwesome.fa_osu_mod_auto;
public override string Description => "Watch a perfect automated play through the song."; public override string Description => "Watch a perfect automated play through the song.";
public override double ScoreMultiplier => 0; public override double ScoreMultiplier => 1;
public bool AllowFail => false; public bool AllowFail => false;
public override Type[] IncompatibleMods => new[] { typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail) }; public override Type[] IncompatibleMods => new[] { typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail) };
} }

View File

@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Mods
public override string Name => "Relax"; public override string Name => "Relax";
public override string ShortenedName => "RX"; public override string ShortenedName => "RX";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_relax; public override FontAwesome Icon => FontAwesome.fa_osu_mod_relax;
public override double ScoreMultiplier => 0; public override double ScoreMultiplier => 1;
public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModNoFail), typeof(ModSuddenDeath) }; public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModNoFail), typeof(ModSuddenDeath) };
} }
} }

View File

@ -20,7 +20,7 @@ namespace osu.Game.Screens.Multi
{ {
public const float HEIGHT = 121; public const float HEIGHT = 121;
private readonly OsuSpriteText screenTitle; private readonly OsuSpriteText screenType;
private readonly HeaderBreadcrumbControl breadcrumbs; private readonly HeaderBreadcrumbControl breadcrumbs;
public Header(Screen initialScreen) public Header(Screen initialScreen)
@ -67,7 +67,7 @@ namespace osu.Game.Screens.Multi
Text = "multiplayer ", Text = "multiplayer ",
TextSize = 25, TextSize = 25,
}, },
screenTitle = new OsuSpriteText screenType = new OsuSpriteText
{ {
TextSize = 25, TextSize = 25,
Font = @"Exo2.0-Light", Font = @"Exo2.0-Light",
@ -86,14 +86,14 @@ namespace osu.Game.Screens.Multi
}, },
}; };
breadcrumbs.Current.ValueChanged += s => screenTitle.Text = ((MultiplayerScreen)s).Title; breadcrumbs.Current.ValueChanged += s => screenType.Text = ((MultiplayerScreen)s).Type.ToLower();
breadcrumbs.Current.TriggerChange(); breadcrumbs.Current.TriggerChange();
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
screenTitle.Colour = colours.Yellow; screenType.Colour = colours.Yellow;
breadcrumbs.StripColour = colours.Green; breadcrumbs.StripColour = colours.Green;
} }

View File

@ -25,7 +25,7 @@ namespace osu.Game.Screens.Multi.Screens.Lounge
protected readonly FillFlowContainer<DrawableRoom> RoomsContainer; protected readonly FillFlowContainer<DrawableRoom> RoomsContainer;
protected readonly RoomInspector Inspector; protected readonly RoomInspector Inspector;
public override string Title => "lounge"; public override string Title => "Lounge";
protected override Container<Drawable> TransitionContent => content; protected override Container<Drawable> TransitionContent => content;

View File

@ -15,6 +15,11 @@ namespace osu.Game.Screens.Multi.Screens
protected virtual Container<Drawable> TransitionContent => Content; protected virtual Container<Drawable> TransitionContent => Content;
/// <summary>
/// The type to display in the title of the <see cref="Header"/>.
/// </summary>
public virtual string Type => Title;
protected override void OnEntering(Screen last) protected override void OnEntering(Screen last)
{ {
base.OnEntering(last); base.OnEntering(last);

View File

@ -57,6 +57,7 @@ namespace osu.Game.Screens.Ranking
{ {
base.OnEntering(last); base.OnEntering(last);
(Background as BackgroundScreenBeatmap)?.BlurTo(background_blur, 2500, Easing.OutQuint); (Background as BackgroundScreenBeatmap)?.BlurTo(background_blur, 2500, Easing.OutQuint);
Background.ScaleTo(1.1f, transition_time, Easing.OutQuint);
allCircles.ForEach(c => allCircles.ForEach(c =>
{ {
@ -102,6 +103,8 @@ namespace osu.Game.Screens.Ranking
c.ScaleTo(0, transition_time, Easing.OutSine); c.ScaleTo(0, transition_time, Easing.OutSine);
}); });
Background.ScaleTo(1f, transition_time / 4, Easing.OutQuint);
Content.FadeOut(transition_time / 4); Content.FadeOut(transition_time / 4);
return base.OnExiting(next); return base.OnExiting(next);
@ -160,7 +163,6 @@ namespace osu.Game.Screens.Ranking
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
ParallaxAmount = 0.01f, ParallaxAmount = 0.01f,
Scale = new Vector2(1 / circle_outer_scale / overscan),
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
Children = new Drawable[] Children = new Drawable[]