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

Merge branch 'master' into correct-trail-animation-frame

This commit is contained in:
Dean Herbert 2020-03-13 09:55:41 +09:00 committed by GitHub
commit c30bfa79e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
118 changed files with 1560 additions and 692 deletions

View File

@ -52,6 +52,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.304.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.310.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.312.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,54 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Game.Rulesets.Catch.Mods;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Tests.Visual;
using osuTK;
namespace osu.Game.Rulesets.Catch.Tests.Mods
{
public class TestSceneCatchModPerfect : ModPerfectTestScene
{
public TestSceneCatchModPerfect()
: base(new CatchRuleset(), new CatchModPerfect())
{
}
[TestCase(false)]
[TestCase(true)]
public void TestBananaShower(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new BananaShower { StartTime = 1000, EndTime = 3000 }, false), shouldMiss);
[TestCase(false)]
[TestCase(true)]
public void TestFruit(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new Fruit { StartTime = 1000 }), shouldMiss);
[TestCase(false)]
[TestCase(true)]
public void TestJuiceStream(bool shouldMiss)
{
var stream = new JuiceStream
{
StartTime = 1000,
Path = new SliderPath(PathType.Linear, new[]
{
Vector2.Zero,
new Vector2(100, 0),
})
};
CreateHitObjectTest(new HitObjectTestData(stream), shouldMiss);
}
// We only care about testing misses, hits are tested via JuiceStream
[TestCase(true)]
public void TestDroplet(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new Droplet { StartTime = 1000 }), shouldMiss);
// We only care about testing misses, hits are tested via JuiceStream
[TestCase(true)]
public void TestTinyDroplet(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new TinyDroplet { StartTime = 1000 }), shouldMiss);
}
}

View File

@ -18,7 +18,9 @@ namespace osu.Game.Rulesets.Catch.Tests
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(BananaShower),
typeof(Banana),
typeof(DrawableBananaShower),
typeof(DrawableBanana),
typeof(CatchRuleset),
typeof(DrawableCatchRuleset),

View File

@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
@ -28,11 +26,6 @@ namespace osu.Game.Rulesets.Catch.Tests
{
private RulesetInfo catchRuleset;
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(CatcherArea),
};
public TestSceneCatcherArea()
{
AddSliderStep<float>("CircleSize", 0, 8, 5, createCatcher);

View File

@ -4,7 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
@ -34,8 +34,8 @@ namespace osu.Game.Rulesets.Catch.Tests
private DrawableCatchRuleset drawableRuleset;
private double playfieldTime => drawableRuleset.Playfield.Time.Current;
[BackgroundDependencyLoader]
private void load()
[SetUp]
public void Setup() => Schedule(() =>
{
var controlPointInfo = new ControlPointInfo();
controlPointInfo.Add(0, new TimingControlPoint());
@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Catch.Tests
ControlPointInfo = controlPointInfo
});
Add(new Container
Child = new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@ -66,16 +66,49 @@ namespace osu.Game.Rulesets.Catch.Tests
{
drawableRuleset = new DrawableCatchRuleset(new CatchRuleset(), beatmap.GetPlayableBeatmap(new CatchRuleset().RulesetInfo))
}
});
};
});
[Test]
public void TestFruits()
{
AddStep("hit fruits", () => spawnFruits(true));
AddUntilStep("wait for completion", () => playfieldIsEmpty);
AddAssert("catcher state is idle", () => catcherState == CatcherAnimationState.Idle);
AddStep("miss fruits", () => spawnFruits());
AddStep("hit fruits", () => spawnFruits(true));
AddStep("miss juicestream", () => spawnJuiceStream());
AddStep("hit juicestream", () => spawnJuiceStream(true));
AddStep("miss bananas", () => spawnBananas());
AddStep("hit bananas", () => spawnBananas(true));
AddUntilStep("wait for completion", () => playfieldIsEmpty);
AddAssert("catcher state is failed", () => catcherState == CatcherAnimationState.Fail);
}
[Test]
public void TestJuicestream()
{
AddStep("hit juicestream", () => spawnJuiceStream(true));
AddUntilStep("wait for completion", () => playfieldIsEmpty);
AddAssert("catcher state is idle", () => catcherState == CatcherAnimationState.Idle);
AddStep("miss juicestream", () => spawnJuiceStream());
AddUntilStep("wait for completion", () => playfieldIsEmpty);
AddAssert("catcher state is failed", () => catcherState == CatcherAnimationState.Fail);
}
[Test]
public void TestBananas()
{
AddStep("hit bananas", () => spawnBananas(true));
AddUntilStep("wait for completion", () => playfieldIsEmpty);
AddAssert("catcher state is idle", () => catcherState == CatcherAnimationState.Idle);
AddStep("miss bananas", () => spawnBananas());
AddUntilStep("wait for completion", () => playfieldIsEmpty);
AddAssert("catcher state is idle", () => catcherState == CatcherAnimationState.Idle);
}
private bool playfieldIsEmpty => !((CatchPlayfield)drawableRuleset.Playfield).AllHitObjects.Any(h => h.IsAlive);
private CatcherAnimationState catcherState => ((CatchPlayfield)drawableRuleset.Playfield).CatcherArea.MovableCatcher.CurrentState;
private void spawnFruits(bool hit = false)
{
for (int i = 1; i <= 4; i++)

View File

@ -2,19 +2,27 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Objects;
using osu.Game.Tests.Visual;
using osuTK;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestSceneHyperDash : PlayerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(CatcherArea),
};
public TestSceneHyperDash()
: base(new CatchRuleset())
{
@ -26,9 +34,11 @@ namespace osu.Game.Rulesets.Catch.Tests
public void TestHyperDash()
{
AddAssert("First note is hyperdash", () => Beatmap.Value.Beatmap.HitObjects[0] is Fruit f && f.HyperDash);
AddUntilStep("wait for left hyperdash", () => getCatcher().Scale.X < 0 && getCatcher().HyperDashing);
AddUntilStep("wait for right movement", () => getCatcher().Scale.X > 0); // don't check hyperdashing as it happens too fast.
for (int i = 0; i < 2; i++)
AddUntilStep("wait for left movement", () => getCatcher().Scale.X < 0);
for (int i = 0; i < 3; i++)
{
AddUntilStep("wait for right hyperdash", () => getCatcher().Scale.X > 0 && getCatcher().HyperDashing);
AddUntilStep("wait for left hyperdash", () => getCatcher().Scale.X < 0 && getCatcher().HyperDashing);
@ -49,39 +59,51 @@ namespace osu.Game.Rulesets.Catch.Tests
};
// Should produce a hyper-dash (edge case test)
beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 308 / 512f, NewCombo = true });
beatmap.HitObjects.Add(new JuiceStream { StartTime = 2008, X = 56 / 512f, });
beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 56 / 512f, NewCombo = true });
beatmap.HitObjects.Add(new Fruit { StartTime = 2008, X = 308 / 512f, NewCombo = true });
double startTime = 3000;
const float left_x = 0.02f;
const float right_x = 0.98f;
createObjects(() => new Fruit(), left_x);
createObjects(() => new JuiceStream(), right_x);
createObjects(() => new JuiceStream(), left_x);
createObjects(() => new Fruit(), right_x);
createObjects(() => new Fruit(), left_x);
createObjects(() => new Fruit(), right_x);
createObjects(() => new JuiceStream(), left_x);
createObjects(() => new Fruit { X = left_x });
createObjects(() => new TestJuiceStream(right_x), 1);
createObjects(() => new TestJuiceStream(left_x), 1);
createObjects(() => new Fruit { X = right_x });
createObjects(() => new Fruit { X = left_x });
createObjects(() => new Fruit { X = right_x });
createObjects(() => new TestJuiceStream(left_x), 1);
return beatmap;
void createObjects(Func<CatchHitObject> createObject, float x)
void createObjects(Func<CatchHitObject> createObject, int count = 3)
{
const float spacing = 140;
for (int i = 0; i < 3; i++)
for (int i = 0; i < count; i++)
{
var hitObject = createObject();
hitObject.X = x;
hitObject.StartTime = startTime + i * spacing;
beatmap.HitObjects.Add(hitObject);
}
startTime += 700;
}
}
private class TestJuiceStream : JuiceStream
{
public TestJuiceStream(float x)
{
X = x;
Path = new SliderPath(new[]
{
new PathControlPoint(Vector2.Zero),
new PathControlPoint(new Vector2(30, 0)),
});
}
}
}
}

View File

@ -28,8 +28,6 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
ApplyPositionOffsets(Beatmap);
initialiseHyperDash((List<CatchHitObject>)Beatmap.HitObjects);
int index = 0;
foreach (var obj in Beatmap.HitObjects.OfType<CatchHitObject>())
@ -76,6 +74,12 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
break;
case JuiceStream juiceStream:
// Todo: BUG!! Stable used the last control point as the final position of the path, but it should use the computed path instead.
lastPosition = juiceStream.X + juiceStream.Path.ControlPoints[^1].Position.Value.X / CatchPlayfield.BASE_WIDTH;
// Todo: BUG!! Stable attempted to use the end time of the stream, but referenced it too early in execution and used the start time instead.
lastStartTime = juiceStream.StartTime;
foreach (var nested in juiceStream.NestedHitObjects)
{
var catchObject = (CatchHitObject)nested;
@ -90,20 +94,12 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
break;
}
}
initialiseHyperDash(beatmap);
}
private static void applyHardRockOffset(CatchHitObject hitObject, ref float? lastPosition, ref double lastStartTime, FastRandom rng)
{
if (hitObject is JuiceStream stream)
{
lastPosition = stream.EndX;
lastStartTime = stream.EndTime;
return;
}
if (!(hitObject is Fruit))
return;
float offsetPosition = hitObject.X;
double startTime = hitObject.StartTime;
@ -116,7 +112,9 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
}
float positionDiff = offsetPosition - lastPosition.Value;
double timeDiff = startTime - lastStartTime;
// Todo: BUG!! Stable calculated time deltas as ints, which affects randomisation. This should be changed to a double.
int timeDiff = (int)(startTime - lastStartTime);
if (timeDiff > 1000)
{
@ -132,7 +130,8 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
return;
}
if (Math.Abs(positionDiff * CatchPlayfield.BASE_WIDTH) < timeDiff / 3d)
// ReSharper disable once PossibleLossOfFraction
if (Math.Abs(positionDiff * CatchPlayfield.BASE_WIDTH) < timeDiff / 3)
applyOffset(ref offsetPosition, positionDiff);
hitObject.XOffset = offsetPosition - hitObject.X;
@ -191,14 +190,14 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
}
}
private void initialiseHyperDash(List<CatchHitObject> objects)
private static void initialiseHyperDash(IBeatmap beatmap)
{
List<CatchHitObject> objectWithDroplets = new List<CatchHitObject>();
foreach (var currentObject in objects)
foreach (var currentObject in beatmap.HitObjects)
{
if (currentObject is Fruit)
objectWithDroplets.Add(currentObject);
if (currentObject is Fruit fruitObject)
objectWithDroplets.Add(fruitObject);
if (currentObject is JuiceStream)
{
@ -212,7 +211,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
objectWithDroplets.Sort((h1, h2) => h1.StartTime.CompareTo(h2.StartTime));
double halfCatcherWidth = CatcherArea.GetCatcherSize(Beatmap.BeatmapInfo.BaseDifficulty) / 2;
double halfCatcherWidth = CatcherArea.GetCatcherSize(beatmap.BeatmapInfo.BaseDifficulty) / 2;
int lastDirection = 0;
double lastExcess = halfCatcherWidth;
@ -221,6 +220,10 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
CatchHitObject currentObject = objectWithDroplets[i];
CatchHitObject nextObject = objectWithDroplets[i + 1];
// Reset variables in-case values have changed (e.g. after applying HR)
currentObject.HyperDashTarget = null;
currentObject.DistanceToHyperDash = 0;
int thisDirection = nextObject.X > currentObject.X ? 1 : -1;
double timeToNext = nextObject.StartTime - currentObject.StartTime - 1000f / 60f / 4; // 1/4th of a frame of grace time, taken from osu-stable
double distanceToNext = Math.Abs(nextObject.X - currentObject.X) - (lastDirection == thisDirection ? lastExcess : halfCatcherWidth);

View File

@ -1,11 +1,17 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Catch.Mods
{
public class CatchModPerfect : ModPerfect
{
protected override bool FailCondition(HealthProcessor healthProcessor, JudgementResult result)
=> !(result.Judgement is CatchBananaJudgement)
&& base.FailCondition(healthProcessor, result);
}
}

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Utils;
using osuTK.Graphics;
@ -22,6 +23,23 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
return colour ??= getBananaColour();
}
protected override void UpdateInitialTransforms()
{
base.UpdateInitialTransforms();
const float end_scale = 0.6f;
const float random_scale_range = 1.6f;
ScaleContainer.ScaleTo(HitObject.Scale * (end_scale + random_scale_range * RNG.NextSingle()))
.Then().ScaleTo(HitObject.Scale * end_scale, HitObject.TimePreempt);
ScaleContainer.RotateTo(getRandomAngle())
.Then()
.RotateTo(getRandomAngle(), HitObject.TimePreempt);
float getRandomAngle() => 180 * (RNG.NextSingle() * 2 - 1);
}
private Color4 getBananaColour()
{
switch (RNG.Next(0, 3))

View File

@ -91,10 +91,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
ApplyResult(r => r.Type = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss);
}
protected sealed override double InitialLifetimeOffset => HitObject.TimePreempt;
protected override void UpdateInitialTransforms() => this.FadeInFromZero(200);
protected override void UpdateStateTransforms(ArmedState state)
{
var endTime = HitObject.GetEndTime();

View File

@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
float startRotation = RNG.NextSingle() * 20;
double duration = HitObject.TimePreempt + 2000;
this.RotateTo(startRotation).RotateTo(startRotation + 720, duration);
ScaleContainer.RotateTo(startRotation).RotateTo(startRotation + 720, duration);
}
}
}

View File

@ -13,7 +13,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
public DrawableFruit(Fruit h)
: base(h)
{
Rotation = (float)(RNG.NextDouble() - 0.5f) * 40;
}
[BackgroundDependencyLoader]
@ -21,6 +20,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
{
ScaleContainer.Child = new SkinnableDrawable(
new CatchSkinComponent(getComponent(HitObject.VisualRepresentation)), _ => new FruitPiece());
ScaleContainer.Rotation = (float)(RNG.NextDouble() - 0.5f) * 40;
}
private CatchSkinComponents getComponent(FruitVisualRepresentation hitObjectVisualRepresentation)

View File

@ -6,6 +6,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osuTK;
namespace osu.Game.Rulesets.Catch.Objects.Drawables
{
@ -14,11 +15,13 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
private readonly Func<CatchHitObject, DrawableHitObject<CatchHitObject>> createDrawableRepresentation;
private readonly Container dropletContainer;
public override Vector2 OriginPosition => base.OriginPosition - new Vector2(0, CatchHitObject.OBJECT_RADIUS);
public DrawableJuiceStream(JuiceStream s, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> createDrawableRepresentation = null)
: base(s)
{
this.createDrawableRepresentation = createDrawableRepresentation;
RelativeSizeAxes = Axes.Both;
RelativeSizeAxes = Axes.X;
Origin = Anchor.BottomLeft;
X = 0;
@ -27,6 +30,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
protected override void AddNestedHitObject(DrawableHitObject hitObject)
{
hitObject.Origin = Anchor.BottomCentre;
base.AddNestedHitObject(hitObject);
dropletContainer.Add(hitObject);
}

View File

@ -24,8 +24,8 @@ namespace osu.Game.Rulesets.Catch.Objects
public int RepeatCount { get; set; }
public double Velocity;
public double TickDistance;
public double Velocity { get; private set; }
public double TickDistance { get; private set; }
/// <summary>
/// The length of one span of this <see cref="JuiceStream"/>.
@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Catch.Objects
{
base.CreateNestedHitObjects();
var tickSamples = Samples.Select(s => new HitSampleInfo
var dropletSamples = Samples.Select(s => new HitSampleInfo
{
Bank = s.Bank,
Name = @"slidertick",
@ -75,7 +75,6 @@ namespace osu.Game.Rulesets.Catch.Objects
{
AddNested(new TinyDroplet
{
Samples = tickSamples,
StartTime = t + lastEvent.Value.Time,
X = X + Path.PositionAt(
lastEvent.Value.PathProgress + (t / sinceLastTick) * (e.PathProgress - lastEvent.Value.PathProgress)).X / CatchPlayfield.BASE_WIDTH,
@ -93,7 +92,7 @@ namespace osu.Game.Rulesets.Catch.Objects
case SliderEventType.Tick:
AddNested(new Droplet
{
Samples = tickSamples,
Samples = dropletSamples,
StartTime = e.Time,
X = X + Path.PositionAt(e.PathProgress).X / CatchPlayfield.BASE_WIDTH,
});

View File

@ -188,7 +188,7 @@ namespace osu.Game.Rulesets.Catch.UI
{
currentCatcher?.Hide();
switch (currentState)
switch (CurrentState)
{
default:
currentCatcher = catcherIdle;
@ -263,16 +263,14 @@ namespace osu.Game.Rulesets.Catch.UI
Position = Position
};
AdditiveTarget?.Add(additive);
additive.FadeTo(0.4f).FadeOut(800, Easing.OutQuint);
additive.Expire(true);
AdditiveTarget?.Add(additive);
Scheduler.AddDelayed(beginTrail, HyperDashing ? 25 : 50);
}
private Drawable createCatcherSprite() => new CatcherSprite(currentState);
/// <summary>
/// Add a caught fruit to the catcher's stack.
/// </summary>
@ -341,7 +339,7 @@ namespace osu.Game.Rulesets.Catch.UI
if (validCatch)
updateState(fruit.Kiai ? CatcherAnimationState.Kiai : CatcherAnimationState.Idle);
else
else if (!(fruit is Banana))
updateState(CatcherAnimationState.Fail);
return validCatch;
@ -349,14 +347,14 @@ namespace osu.Game.Rulesets.Catch.UI
private void updateState(CatcherAnimationState state)
{
if (currentState == state)
if (CurrentState == state)
return;
currentState = state;
CurrentState = state;
updateCatcher();
}
private CatcherAnimationState currentState;
public CatcherAnimationState CurrentState { get; private set; }
private double hyperDashModifier = 1;
private int hyperDashDirection;
@ -376,14 +374,14 @@ namespace osu.Game.Rulesets.Catch.UI
{
const float hyper_dash_transition_length = 180;
bool previouslyHyperDashing = HyperDashing;
bool wasHyperDashing = HyperDashing;
if (modifier <= 1 || X == targetPosition)
{
hyperDashModifier = 1;
hyperDashDirection = 0;
if (previouslyHyperDashing)
if (wasHyperDashing)
{
this.FadeColour(Color4.White, hyper_dash_transition_length, Easing.OutQuint);
this.FadeTo(1, hyper_dash_transition_length, Easing.OutQuint);
@ -396,11 +394,18 @@ namespace osu.Game.Rulesets.Catch.UI
hyperDashDirection = Math.Sign(targetPosition - X);
hyperDashTargetPosition = targetPosition;
if (!previouslyHyperDashing)
if (!wasHyperDashing)
{
this.FadeColour(Color4.OrangeRed, hyper_dash_transition_length, Easing.OutQuint);
this.FadeTo(0.2f, hyper_dash_transition_length, Easing.OutQuint);
Trail = true;
var hyperDashEndGlow = createAdditiveSprite(true);
hyperDashEndGlow.MoveToOffset(new Vector2(0, -20), 1200, Easing.In);
hyperDashEndGlow.ScaleTo(hyperDashEndGlow.Scale * 0.9f).ScaleTo(hyperDashEndGlow.Scale * 1.2f, 1200, Easing.In);
hyperDashEndGlow.FadeOut(1200);
hyperDashEndGlow.Expire(true);
}
}
}

View File

@ -0,0 +1,26 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Game.Rulesets.Mania.Mods;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Mania.Tests.Mods
{
public class TestSceneManiaModPerfect : ModPerfectTestScene
{
public TestSceneManiaModPerfect()
: base(new ManiaRuleset(), new ManiaModPerfect())
{
}
[TestCase(false)]
[TestCase(true)]
public void TestNote(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new Note { StartTime = 1000 }), shouldMiss);
[TestCase(false)]
[TestCase(true)]
public void TestHoldNote(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new HoldNote { StartTime = 1000, EndTime = 3000 }), shouldMiss);
}
}

View File

@ -0,0 +1,52 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Tests.Visual;
using osuTK;
namespace osu.Game.Rulesets.Osu.Tests.Mods
{
public class TestSceneOsuModPerfect : ModPerfectTestScene
{
public TestSceneOsuModPerfect()
: base(new OsuRuleset(), new OsuModPerfect())
{
}
[TestCase(false)]
[TestCase(true)]
public void TestHitCircle(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new HitCircle { StartTime = 1000 }), shouldMiss);
[TestCase(false)]
[TestCase(true)]
public void TestSlider(bool shouldMiss)
{
var slider = new Slider
{
StartTime = 1000,
Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(100, 0), })
};
CreateHitObjectTest(new HitObjectTestData(slider), shouldMiss);
}
[TestCase(false)]
[TestCase(true)]
public void TestSpinner(bool shouldMiss)
{
var spinner = new Spinner
{
StartTime = 1000,
EndTime = 3000,
Position = new Vector2(256, 192)
};
CreateHitObjectTest(new HitObjectTestData(spinner), shouldMiss);
}
}
}

View File

@ -0,0 +1,101 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Game.Beatmaps;
using osu.Game.Replays;
using osu.Game.Rulesets.Osu.Beatmaps;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Replays;
using osu.Game.Rulesets.Osu.Scoring;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Tests.Visual;
using osu.Game.Users;
using osuTK;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestSceneMissHitWindowJudgements : ModTestScene
{
public TestSceneMissHitWindowJudgements()
: base(new OsuRuleset())
{
}
[Test]
public void TestMissViaEarlyHit()
{
var beatmap = new Beatmap
{
HitObjects = { new HitCircle { Position = new Vector2(256, 192) } }
};
var hitWindows = new OsuHitWindows();
hitWindows.SetDifficulty(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty);
CreateModTest(new ModTestData
{
Autoplay = false,
Mod = new TestAutoMod(),
Beatmap = new Beatmap
{
HitObjects = { new HitCircle { Position = new Vector2(256, 192) } }
},
PassCondition = () => Player.Results.Count > 0 && Player.Results[0].TimeOffset < -hitWindows.WindowFor(HitResult.Meh) && Player.Results[0].Type == HitResult.Miss
});
}
[Test]
public void TestMissViaNotHitting()
{
var beatmap = new Beatmap
{
HitObjects = { new HitCircle { Position = new Vector2(256, 192) } }
};
var hitWindows = new OsuHitWindows();
hitWindows.SetDifficulty(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty);
CreateModTest(new ModTestData
{
Autoplay = false,
Beatmap = beatmap,
PassCondition = () => Player.Results.Count > 0 && Player.Results[0].TimeOffset >= hitWindows.WindowFor(HitResult.Meh) && Player.Results[0].Type == HitResult.Miss
});
}
private class TestAutoMod : OsuModAutoplay
{
public override Score CreateReplayScore(IBeatmap beatmap) => new Score
{
ScoreInfo = new ScoreInfo { User = new User { Username = "Autoplay" } },
Replay = new MissingAutoGenerator(beatmap).Generate()
};
}
private class MissingAutoGenerator : OsuAutoGeneratorBase
{
public new OsuBeatmap Beatmap => (OsuBeatmap)base.Beatmap;
public MissingAutoGenerator(IBeatmap beatmap)
: base(beatmap)
{
}
public override Replay Generate()
{
AddFrameToReplay(new OsuReplayFrame(-100000, new Vector2(256, 500)));
AddFrameToReplay(new OsuReplayFrame(Beatmap.HitObjects[0].StartTime - 1500, new Vector2(256, 500)));
AddFrameToReplay(new OsuReplayFrame(Beatmap.HitObjects[0].StartTime - 1500, new Vector2(256, 500)));
AddFrameToReplay(new OsuReplayFrame(Beatmap.HitObjects[0].StartTime - 450, Beatmap.HitObjects[0].StackedPosition));
AddFrameToReplay(new OsuReplayFrame(Beatmap.HitObjects[0].StartTime - 350, Beatmap.HitObjects[0].StackedPosition, OsuAction.LeftButton));
AddFrameToReplay(new OsuReplayFrame(Beatmap.HitObjects[0].StartTime - 325, Beatmap.HitObjects[0].StackedPosition));
return Replay;
}
}
}
}

View File

@ -36,8 +36,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
private readonly SpriteIcon symbol;
private readonly Color4 baseColour = OsuColour.FromHex(@"002c3c");
private readonly Color4 fillColour = OsuColour.FromHex(@"005b7c");
private readonly Color4 baseColour = Color4Extensions.FromHex(@"002c3c");
private readonly Color4 fillColour = Color4Extensions.FromHex(@"005b7c");
private readonly IBindable<Vector2> positionBindable = new Bindable<Vector2>();

View File

@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Scoring
new DifficultyRange(HitResult.Great, 80, 50, 20),
new DifficultyRange(HitResult.Good, 140, 100, 60),
new DifficultyRange(HitResult.Meh, 200, 150, 100),
new DifficultyRange(HitResult.Miss, 200, 200, 200),
new DifficultyRange(HitResult.Miss, 400, 400, 400),
};
public override bool IsHitResultAllowed(HitResult result)

View File

@ -0,0 +1,47 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Mods;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.Scoring;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Taiko.Tests.Mods
{
public class TestSceneTaikoModPerfect : ModPerfectTestScene
{
public TestSceneTaikoModPerfect()
: base(new TestTaikoRuleset(), new TaikoModPerfect())
{
}
[TestCase(false)]
[TestCase(true)]
public void TestHit(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new CentreHit { StartTime = 1000 }), shouldMiss);
[TestCase(false)]
[TestCase(true)]
public void TestDrumRoll(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new DrumRoll { StartTime = 1000, EndTime = 3000 }), shouldMiss);
[TestCase(false)]
[TestCase(true)]
public void TestSwell(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new Swell { StartTime = 1000, EndTime = 3000 }), shouldMiss);
private class TestTaikoRuleset : TaikoRuleset
{
public override HealthProcessor CreateHealthProcessor(double drainStartTime) => new TestTaikoHealthProcessor();
private class TestTaikoHealthProcessor : TaikoHealthProcessor
{
protected override void Reset(bool storeResults)
{
base.Reset(storeResults);
Health.Value = 1; // Don't care about the health condition (only the mod condition)
}
}
}
}
}

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Judgements;
@ -39,7 +40,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring
{
base.ApplyBeatmap(beatmap);
hpMultiplier = 1 / (object_count_factor * beatmap.HitObjects.OfType<Hit>().Count() * BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.5, 0.75, 0.98));
hpMultiplier = 1 / (object_count_factor * Math.Max(1, beatmap.HitObjects.OfType<Hit>().Count()) * BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.5, 0.75, 0.98));
hpMissMultiplier = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.0018, 0.0075, 0.0120);
}

View File

@ -99,7 +99,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
var storyboard = decoder.Decode(stream);
StoryboardLayer background = storyboard.Layers.Single(l => l.Depth == 3);
Assert.AreEqual(123456, ((StoryboardSprite)background.Elements.Single()).InitialPosition.X);
Assert.AreEqual(3456, ((StoryboardSprite)background.Elements.Single()).InitialPosition.X);
}
}
}

View File

@ -1,5 +1,5 @@
[Variables]
$var=1234
$var=34
[Events]
Sprite,Background,TopCentre,"img.jpg",$var56,240

View File

@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.Menus
API.LocalUser.Value = new User
{
Username = API.LocalUser.Value.Username,
Id = API.LocalUser.Value.Id,
Id = API.LocalUser.Value.Id + 1,
IsSupporter = !API.LocalUser.Value.IsSupporter,
};
});

View File

@ -17,8 +17,8 @@ namespace osu.Game.Tests.Visual.Online
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(UpdateStreamBadgeArea),
typeof(UpdateStreamBadge),
typeof(ChangelogUpdateStreamControl),
typeof(ChangelogUpdateStreamItem),
typeof(ChangelogHeader),
typeof(ChangelogContent),
typeof(ChangelogListing),

View File

@ -7,6 +7,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
@ -102,7 +103,7 @@ namespace osu.Game.Tests.Visual.Online
{
bool hasBackground = !string.IsNullOrEmpty(newLine.Message.Sender.Colour);
Color4 textColour = isAction && hasBackground ? OsuColour.FromHex(newLine.Message.Sender.Colour) : Color4.White;
Color4 textColour = isAction && hasBackground ? Color4Extensions.FromHex(newLine.Message.Sender.Colour) : Color4.White;
var linkCompilers = newLine.ContentFlow.Where(d => d is DrawableLinkCompiler).ToList();
var linkSprites = linkCompilers.SelectMany(comp => ((DrawableLinkCompiler)comp).Parts);

View File

@ -497,7 +497,7 @@ namespace osu.Game.Tests.Visual.SongSelect
}
bool changed = false;
AddStep($"Load {beatmapSets.Count} Beatmaps", () =>
AddStep($"Load {(beatmapSets.Count > 0 ? beatmapSets.Count.ToString() : "some")} beatmaps", () =>
{
carousel.Filter(new FilterCriteria());
carousel.BeatmapSetsChanged = () => changed = true;
@ -697,6 +697,8 @@ namespace osu.Game.Tests.Visual.SongSelect
public new List<DrawableCarouselItem> Items => base.Items;
public bool PendingFilterTask => PendingFilter != null;
protected override IEnumerable<BeatmapSetInfo> GetLoadableBeatmaps() => Enumerable.Empty<BeatmapSetInfo>();
}
}
}

View File

@ -465,6 +465,43 @@ namespace osu.Game.Tests.Visual.SongSelect
AddAssert("carousel still correct", () => songSelect.Carousel.SelectedBeatmap.OnlineBeatmapID == target.OnlineBeatmapID);
}
[Test]
public void TestExternalBeatmapChangeWhileFilteredThenRefilter()
{
createSongSelect();
addManyTestMaps();
changeRuleset(0);
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap != null);
AddStep("set filter text", () => songSelect.FilterControl.ChildrenOfType<SearchTextBox>().First().Text = "nonono");
AddUntilStep("dummy selected", () => Beatmap.Value is DummyWorkingBeatmap);
AddUntilStep("has no selection", () => songSelect.Carousel.SelectedBeatmap == null);
BeatmapInfo target = null;
AddStep("select beatmap externally", () =>
{
target = manager.GetAllUsableBeatmapSets().Where(b => b.Beatmaps.Any(bi => bi.RulesetID == 1))
.ElementAt(5).Beatmaps.First();
Beatmap.Value = manager.GetWorkingBeatmap(target);
});
AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap != null);
AddUntilStep("carousel has correct", () => songSelect.Carousel.SelectedBeatmap?.OnlineBeatmapID == target.OnlineBeatmapID);
AddUntilStep("game has correct", () => Beatmap.Value.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID);
AddStep("set filter text", () => songSelect.FilterControl.ChildrenOfType<SearchTextBox>().First().Text = "nononoo");
AddUntilStep("game lost selection", () => Beatmap.Value is DummyWorkingBeatmap);
AddAssert("carousel lost selection", () => songSelect.Carousel.SelectedBeatmap == null);
}
[Test]
public void TestAutoplayViaCtrlEnter()
{

View File

@ -0,0 +1,63 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Overlays;
using osu.Game.Overlays.Home.Friends;
using osu.Game.Users;
namespace osu.Game.Tests.Visual.UserInterface
{
public class TestSceneFriendsOnlineStatusControl : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(FriendsOnlineStatusControl),
typeof(FriendsOnlineStatusItem),
typeof(OverlayStreamControl<>),
typeof(OverlayStreamItem<>),
typeof(FriendsBundle)
};
[Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
private FriendsOnlineStatusControl control;
[SetUp]
public void SetUp() => Schedule(() => Child = control = new FriendsOnlineStatusControl
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
});
[Test]
public void Populate()
{
AddStep("Populate", () => control.Populate(new List<User>
{
new User
{
IsOnline = true
},
new User
{
IsOnline = false
},
new User
{
IsOnline = false
}
}));
AddAssert("3 users", () => control.Items.FirstOrDefault(item => item.Status == FriendsOnlineStatus.All)?.Count == 3);
AddAssert("1 online user", () => control.Items.FirstOrDefault(item => item.Status == FriendsOnlineStatus.Online)?.Count == 1);
AddAssert("2 offline users", () => control.Items.FirstOrDefault(item => item.Status == FriendsOnlineStatus.Offline)?.Count == 2);
}
}
}

View File

@ -0,0 +1,42 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Tournament.Components;
using osu.Game.Tournament.Screens.Gameplay.Components;
using osuTK;
namespace osu.Game.Tournament.Tests.Components
{
public class TestSceneMatchHeader : TournamentTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(DrawableTournamentHeaderText),
typeof(DrawableTournamentHeaderLogo),
};
public TestSceneMatchHeader()
{
Child = new FillFlowContainer
{
RelativeSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Spacing = new Vector2(50),
Children = new Drawable[]
{
new TournamentSpriteText { Text = "with logo", Font = OsuFont.Torus.With(size: 30) },
new MatchHeader(),
new TournamentSpriteText { Text = "without logo", Font = OsuFont.Torus.With(size: 30) },
new MatchHeader { ShowLogo = false },
new TournamentSpriteText { Text = "without scores", Font = OsuFont.Torus.With(size: 30) },
new MatchHeader { ShowScores = false },
}
};
}
}
}

View File

@ -0,0 +1,37 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
namespace osu.Game.Tournament.Components
{
public class DrawableTournamentHeaderLogo : CompositeDrawable
{
public DrawableTournamentHeaderLogo()
{
InternalChild = new LogoSprite();
Height = 82;
RelativeSizeAxes = Axes.X;
}
private class LogoSprite : Sprite
{
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
RelativeSizeAxes = Axes.Both;
FillMode = FillMode.Fit;
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Texture = textures.Get("header-logo");
}
}
}
}

View File

@ -0,0 +1,37 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
namespace osu.Game.Tournament.Components
{
public class DrawableTournamentHeaderText : CompositeDrawable
{
public DrawableTournamentHeaderText()
{
InternalChild = new TextSprite();
Height = 22;
RelativeSizeAxes = Axes.X;
}
private class TextSprite : Sprite
{
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
RelativeSizeAxes = Axes.Both;
FillMode = FillMode.Fit;
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Texture = textures.Get("header-text");
}
}
}
}

View File

@ -1,16 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Game.Graphics;
namespace osu.Game.Tournament.Components
{
public class DrawableTournamentTitleText : TournamentSpriteText
{
public DrawableTournamentTitleText()
{
Text = "osu!taiko world cup 2020";
Font = OsuFont.Torus.With(size: 26, weight: FontWeight.SemiBold);
}
}
}

View File

@ -22,7 +22,7 @@ namespace osu.Game.Tournament.Components
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
new DrawableTournamentTitleText(),
new DrawableTournamentHeaderText(),
new TournamentSpriteText
{
Text = match.Round.Value?.Name.Value ?? "Unknown Round",

View File

@ -84,7 +84,7 @@ namespace osu.Game.Tournament.Components
// else if (info.CurrentMatch.Value.Team2.Value.Players.Any(u => u.Id == Message.Sender.Id))
// SenderText.Colour = TournamentGame.COLOUR_BLUE;
// else if (Message.Sender.Colour != null)
// SenderText.Colour = ColourBox.Colour = OsuColour.FromHex(Message.Sender.Colour);
// SenderText.Colour = ColourBox.Colour = Color4Extensions.FromHex(Message.Sender.Colour);
}
}
}

View File

@ -7,7 +7,6 @@ using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Video;
using osu.Framework.Platform;
using osu.Framework.Timing;
using osu.Game.Graphics;
@ -28,13 +27,13 @@ namespace osu.Game.Tournament.Components
}
[BackgroundDependencyLoader]
private void load(Storage storage)
private void load(TournamentStorage storage)
{
var stream = storage.GetStream($@"videos/{filename}.m4v");
var stream = storage.GetStream($@"videos/{filename}");
if (stream != null)
{
InternalChild = video = new VideoSprite(stream)
InternalChild = video = new VideoSprite(stream, false)
{
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,

View File

@ -163,12 +163,7 @@ namespace osu.Game.Tournament.IPC
{
try
{
stableInstallPath = "G:\\My Drive\\Main\\osu!tourney";
if (checkExists(stableInstallPath))
return stableInstallPath;
stableInstallPath = "G:\\My Drive\\Main\\osu!mappool";
stableInstallPath = Environment.GetEnvironmentVariable("OSU_STABLE_PATH");
if (checkExists(stableInstallPath))
return stableInstallPath;

View File

@ -2,14 +2,11 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
using osu.Game.Tournament.Components;
using osu.Game.Tournament.Models;
using osuTK;
using osuTK.Input;
namespace osu.Game.Tournament.Screens.Gameplay.Components
{
@ -17,13 +14,39 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
{
private TeamScoreDisplay teamDisplay1;
private TeamScoreDisplay teamDisplay2;
private DrawableTournamentHeaderLogo logo;
private bool showScores = true;
public bool ShowScores
{
get => showScores;
set
{
teamDisplay1.ShowScore = value;
teamDisplay2.ShowScore = value;
if (value == showScores)
return;
showScores = value;
if (IsLoaded)
updateDisplay();
}
}
private bool showLogo = true;
public bool ShowLogo
{
get => showLogo;
set
{
if (value == showLogo)
return;
showLogo = value;
if (IsLoaded)
updateDisplay();
}
}
@ -38,19 +61,25 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
{
RelativeSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Padding = new MarginPadding(20),
Spacing = new Vector2(5),
Children = new Drawable[]
{
new DrawableTournamentTitleText
logo = new DrawableTournamentHeaderLogo
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(1.2f)
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Alpha = showLogo ? 1 : 0
},
new RoundDisplay
new DrawableTournamentHeaderText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
},
new MatchRoundDisplay
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Scale = new Vector2(0.4f)
},
}
@ -66,76 +95,16 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
Origin = Anchor.TopRight,
},
};
}
}
public class TeamScoreDisplay : CompositeDrawable
{
private readonly TeamColour teamColour;
private readonly Bindable<TournamentMatch> currentMatch = new Bindable<TournamentMatch>();
private readonly Bindable<TournamentTeam> currentTeam = new Bindable<TournamentTeam>();
private readonly Bindable<int?> currentTeamScore = new Bindable<int?>();
private TeamDisplay teamDisplay;
public bool ShowScore { set => teamDisplay.ShowScore = value; }
public TeamScoreDisplay(TeamColour teamColour)
{
this.teamColour = teamColour;
RelativeSizeAxes = Axes.Y;
AutoSizeAxes = Axes.X;
updateDisplay();
}
[BackgroundDependencyLoader]
private void load(LadderInfo ladder)
private void updateDisplay()
{
currentMatch.BindTo(ladder.CurrentMatch);
currentMatch.BindValueChanged(matchChanged, true);
}
teamDisplay1.ShowScore = showScores;
teamDisplay2.ShowScore = showScores;
private void matchChanged(ValueChangedEvent<TournamentMatch> match)
{
currentTeamScore.UnbindBindings();
currentTeam.UnbindBindings();
if (match.NewValue != null)
{
currentTeamScore.BindTo(teamColour == TeamColour.Red ? match.NewValue.Team1Score : match.NewValue.Team2Score);
currentTeam.BindTo(teamColour == TeamColour.Red ? match.NewValue.Team1 : match.NewValue.Team2);
}
// team may change to same team, which means score is not in a good state.
// thus we handle this manually.
teamChanged(currentTeam.Value);
}
protected override bool OnMouseDown(MouseDownEvent e)
{
switch (e.Button)
{
case MouseButton.Left:
if (currentTeamScore.Value < currentMatch.Value.PointsToWin)
currentTeamScore.Value++;
return true;
case MouseButton.Right:
if (currentTeamScore.Value > 0)
currentTeamScore.Value--;
return true;
}
return base.OnMouseDown(e);
}
private void teamChanged(TournamentTeam team)
{
InternalChildren = new Drawable[]
{
teamDisplay = new TeamDisplay(team, teamColour, currentTeamScore, currentMatch.Value?.PointsToWin ?? 0),
};
logo.Alpha = showLogo ? 1 : 0;
}
}
}

View File

@ -8,7 +8,7 @@ using osu.Game.Tournament.Models;
namespace osu.Game.Tournament.Screens.Gameplay.Components
{
public class RoundDisplay : TournamentSpriteTextWithBackground
public class MatchRoundDisplay : TournamentSpriteTextWithBackground
{
private readonly Bindable<TournamentMatch> currentMatch = new Bindable<TournamentMatch>();

View File

@ -11,6 +11,7 @@ using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Tournament.IPC;
using osu.Game.Tournament.Models;
using osuTK;
namespace osu.Game.Tournament.Screens.Gameplay.Components
{
@ -131,13 +132,15 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
Margin = new MarginPadding { Top = bar_height, Horizontal = 10 };
Winning = false;
DisplayedCountSpriteText.Spacing = new Vector2(-6);
}
public bool Winning
{
set => DisplayedCountSpriteText.Font = value
? OsuFont.Torus.With(weight: FontWeight.Bold, size: 50)
: OsuFont.Torus.With(weight: FontWeight.Regular, size: 40);
? OsuFont.Torus.With(weight: FontWeight.Bold, size: 50, fixedWidth: true)
: OsuFont.Torus.With(weight: FontWeight.Regular, size: 40, fixedWidth: true);
}
}
}

View File

@ -76,7 +76,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
},
box = new Box
{
Colour = OsuColour.FromHex("#FFE8AD"),
Colour = Color4Extensions.FromHex("#FFE8AD"),
RelativeSizeAxes = Axes.Both,
},
};
@ -85,7 +85,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Colour = OsuColour.FromHex("#FFE8AD").Opacity(0.1f),
Colour = Color4Extensions.FromHex("#FFE8AD").Opacity(0.1f),
Hollow = true,
Radius = 20,
Roundness = 10,

View File

@ -0,0 +1,83 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
using osu.Game.Tournament.Models;
using osuTK.Input;
namespace osu.Game.Tournament.Screens.Gameplay.Components
{
public class TeamScoreDisplay : CompositeDrawable
{
private readonly TeamColour teamColour;
private readonly Bindable<TournamentMatch> currentMatch = new Bindable<TournamentMatch>();
private readonly Bindable<TournamentTeam> currentTeam = new Bindable<TournamentTeam>();
private readonly Bindable<int?> currentTeamScore = new Bindable<int?>();
private TeamDisplay teamDisplay;
public bool ShowScore { set => teamDisplay.ShowScore = value; }
public TeamScoreDisplay(TeamColour teamColour)
{
this.teamColour = teamColour;
RelativeSizeAxes = Axes.Y;
AutoSizeAxes = Axes.X;
}
[BackgroundDependencyLoader]
private void load(LadderInfo ladder)
{
currentMatch.BindTo(ladder.CurrentMatch);
currentMatch.BindValueChanged(matchChanged, true);
}
private void matchChanged(ValueChangedEvent<TournamentMatch> match)
{
currentTeamScore.UnbindBindings();
currentTeam.UnbindBindings();
if (match.NewValue != null)
{
currentTeamScore.BindTo(teamColour == TeamColour.Red ? match.NewValue.Team1Score : match.NewValue.Team2Score);
currentTeam.BindTo(teamColour == TeamColour.Red ? match.NewValue.Team1 : match.NewValue.Team2);
}
// team may change to same team, which means score is not in a good state.
// thus we handle this manually.
teamChanged(currentTeam.Value);
}
protected override bool OnMouseDown(MouseDownEvent e)
{
switch (e.Button)
{
case MouseButton.Left:
if (currentTeamScore.Value < currentMatch.Value.PointsToWin)
currentTeamScore.Value++;
return true;
case MouseButton.Right:
if (currentTeamScore.Value > 0)
currentTeamScore.Value--;
return true;
}
return base.OnMouseDown(e);
}
private void teamChanged(TournamentTeam team)
{
InternalChildren = new Drawable[]
{
teamDisplay = new TeamDisplay(team, teamColour, currentTeamScore, currentMatch.Value?.PointsToWin ?? 0),
};
}
}
}

View File

@ -47,7 +47,10 @@ namespace osu.Game.Tournament.Screens.Gameplay
Loop = true,
RelativeSizeAxes = Axes.Both,
},
header = new MatchHeader(),
header = new MatchHeader
{
ShowLogo = false
},
new Container
{
RelativeSizeAxes = Axes.X,

View File

@ -4,6 +4,7 @@
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
@ -85,8 +86,8 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
this.ladderEditor = ladderEditor;
colourWinner = losers
? OsuColour.FromHex("#8E7F48")
: OsuColour.FromHex("#1462AA");
? Color4Extensions.FromHex("#8E7F48")
: Color4Extensions.FromHex("#1462AA");
InternalChildren = new Drawable[]
{
@ -180,8 +181,8 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
{
bool winner = completed.Value && isWinner?.Invoke() == true;
background.FadeColour(winner ? Color4.White : OsuColour.FromHex("#444"), winner ? 500 : 0, Easing.OutQuint);
backgroundRight.FadeColour(winner ? colourWinner : OsuColour.FromHex("#333"), winner ? 500 : 0, Easing.OutQuint);
background.FadeColour(winner ? Color4.White : Color4Extensions.FromHex("#444"), winner ? 500 : 0, Easing.OutQuint);
backgroundRight.FadeColour(winner ? colourWinner : Color4Extensions.FromHex("#333"), winner ? 500 : 0, Easing.OutQuint);
AcronymText.Colour = winner ? Color4.Black : Color4.White;

View File

@ -32,8 +32,8 @@ namespace osu.Game.Tournament.Screens.Ladder
[BackgroundDependencyLoader]
private void load(OsuColour colours, Storage storage)
{
normalPathColour = OsuColour.FromHex("#66D1FF");
losersPathColour = OsuColour.FromHex("#FFC700");
normalPathColour = Color4Extensions.FromHex("#66D1FF");
losersPathColour = Color4Extensions.FromHex("#FFC700");
RelativeSizeAxes = Axes.Both;
@ -47,7 +47,7 @@ namespace osu.Game.Tournament.Screens.Ladder
RelativeSizeAxes = Axes.Both,
Loop = true,
},
new DrawableTournamentTitleText
new DrawableTournamentHeaderText
{
Y = 100,
Anchor = Anchor.TopCentre,

View File

@ -50,7 +50,7 @@ namespace osu.Game.Tournament.Screens.MapPool
new MatchHeader(),
mapFlows = new FillFlowContainer<FillFlowContainer<TournamentBeatmapPanel>>
{
Y = 100,
Y = 140,
Spacing = new Vector2(10, 10),
Padding = new MarginPadding(25),
Direction = FillDirection.Vertical,
@ -235,6 +235,7 @@ namespace osu.Game.Tournament.Screens.MapPool
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Height = 42,
});
}
}

View File

@ -62,7 +62,7 @@ namespace osu.Game.Tournament.Screens.Schedule
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
new DrawableTournamentTitleText(),
new DrawableTournamentHeaderText(),
new Container
{
Margin = new MarginPadding { Top = 40 },

View File

@ -15,7 +15,6 @@ using osu.Game.Tournament.Components;
using osu.Game.Tournament.Models;
using osu.Game.Tournament.Screens.Ladder.Components;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Tournament.Screens.TeamIntro
{
@ -140,9 +139,9 @@ namespace osu.Game.Tournament.Screens.TeamIntro
Spacing = new Vector2(5),
Children = new Drawable[]
{
new TournamentSpriteText { Text = beatmap.BeatmapInfo.Metadata.Title, Colour = Color4.Black, },
new TournamentSpriteText { Text = "by", Colour = Color4.Black, Font = OsuFont.Torus.With(weight: FontWeight.Regular) },
new TournamentSpriteText { Text = beatmap.BeatmapInfo.Metadata.Artist, Colour = Color4.Black, Font = OsuFont.Torus.With(weight: FontWeight.Regular) },
new TournamentSpriteText { Text = beatmap.BeatmapInfo.Metadata.Title, Colour = TournamentGame.TEXT_COLOUR, },
new TournamentSpriteText { Text = "by", Colour = TournamentGame.TEXT_COLOUR, Font = OsuFont.Torus.With(weight: FontWeight.Regular) },
new TournamentSpriteText { Text = beatmap.BeatmapInfo.Metadata.Artist, Colour = TournamentGame.TEXT_COLOUR, Font = OsuFont.Torus.With(weight: FontWeight.Regular) },
}
},
new FillFlowContainer
@ -154,8 +153,8 @@ namespace osu.Game.Tournament.Screens.TeamIntro
Spacing = new Vector2(40),
Children = new Drawable[]
{
new TournamentSpriteText { Text = beatmap.Score.ToString("#,0"), Colour = Color4.Black, Width = 80 },
new TournamentSpriteText { Text = "#" + beatmap.Seed.Value.ToString("#,0"), Colour = Color4.Black, Font = OsuFont.Torus.With(weight: FontWeight.Regular) },
new TournamentSpriteText { Text = beatmap.Score.ToString("#,0"), Colour = TournamentGame.TEXT_COLOUR, Width = 80 },
new TournamentSpriteText { Text = "#" + beatmap.Seed.Value.ToString("#,0"), Colour = TournamentGame.TEXT_COLOUR, Font = OsuFont.Torus.With(weight: FontWeight.Regular) },
}
},
};
@ -204,7 +203,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
Colour = TournamentGame.TEXT_COLOUR,
},
new TournamentSpriteText
{
@ -260,20 +259,18 @@ namespace osu.Game.Tournament.Screens.TeamIntro
AutoSizeAxes = Axes.Y;
RelativeSizeAxes = Axes.X;
var colour = OsuColour.Gray(0.3f);
InternalChildren = new Drawable[]
{
new TournamentSpriteText
{
Text = left,
Colour = colour,
Font = OsuFont.Torus.With(size: 22),
Colour = TournamentGame.TEXT_COLOUR,
Font = OsuFont.Torus.With(size: 22, weight: FontWeight.SemiBold),
},
new TournamentSpriteText
{
Text = right,
Colour = colour,
Colour = TournamentGame.TEXT_COLOUR,
Anchor = Anchor.TopRight,
Origin = Anchor.TopLeft,
Font = OsuFont.Torus.With(size: 22, weight: FontWeight.Regular),
@ -305,7 +302,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro
{
Text = team?.FullName.Value ?? "???",
Font = OsuFont.Torus.With(size: 32, weight: FontWeight.SemiBold),
Colour = Color4.Black,
Colour = TournamentGame.TEXT_COLOUR,
},
}
};

View File

@ -1,9 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Game.Graphics;
using osu.Game.Graphics.Cursor;
using osu.Game.Tournament.Models;
using osuTK.Graphics;
@ -14,13 +14,13 @@ namespace osu.Game.Tournament
{
public static ColourInfo GetTeamColour(TeamColour teamColour) => teamColour == TeamColour.Red ? COLOUR_RED : COLOUR_BLUE;
public static readonly Color4 COLOUR_RED = OsuColour.FromHex("#AA1414");
public static readonly Color4 COLOUR_BLUE = OsuColour.FromHex("#1462AA");
public static readonly Color4 COLOUR_RED = Color4Extensions.FromHex("#AA1414");
public static readonly Color4 COLOUR_BLUE = Color4Extensions.FromHex("#1462AA");
public static readonly Color4 ELEMENT_BACKGROUND_COLOUR = OsuColour.FromHex("#fff");
public static readonly Color4 ELEMENT_FOREGROUND_COLOUR = OsuColour.FromHex("#000");
public static readonly Color4 ELEMENT_BACKGROUND_COLOUR = Color4Extensions.FromHex("#fff");
public static readonly Color4 ELEMENT_FOREGROUND_COLOUR = Color4Extensions.FromHex("#000");
public static readonly Color4 TEXT_COLOUR = OsuColour.FromHex("#fff");
public static readonly Color4 TEXT_COLOUR = Color4Extensions.FromHex("#fff");
protected override void LoadComplete()
{

View File

@ -37,6 +37,8 @@ namespace osu.Game.Tournament
private Storage storage;
private TournamentStorage tournamentStorage;
private DependencyContainer dependencies;
private Bindable<Size> windowSize;
@ -54,7 +56,9 @@ namespace osu.Game.Tournament
{
Resources.AddStore(new DllResourceStore(typeof(TournamentGameBase).Assembly));
Textures.AddStore(new TextureLoaderStore(new ResourceStore<byte[]>(new StorageBackedResourceStore(storage))));
dependencies.CacheAs(tournamentStorage = new TournamentStorage(storage));
Textures.AddStore(new TextureLoaderStore(tournamentStorage));
this.storage = storage;

View File

@ -0,0 +1,19 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.IO.Stores;
using osu.Framework.Platform;
namespace osu.Game.Tournament
{
internal class TournamentStorage : NamespacedResourceStore<byte[]>
{
public TournamentStorage(Storage storage)
: base(new StorageBackedResourceStore(storage), "tournament")
{
AddExtension("m4v");
AddExtension("avi");
AddExtension("mp4");
}
}
}

View File

@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using osuTK;
using osuTK.Graphics;
@ -93,8 +92,8 @@ namespace osu.Game.Beatmaps.Formats
var layer = parseLayer(split[1]);
var origin = parseOrigin(split[2]);
var path = CleanFilename(split[3]);
var x = float.Parse(split[4], NumberFormatInfo.InvariantInfo);
var y = float.Parse(split[5], NumberFormatInfo.InvariantInfo);
var x = Parsing.ParseFloat(split[4], Parsing.MAX_COORDINATE_VALUE);
var y = Parsing.ParseFloat(split[5], Parsing.MAX_COORDINATE_VALUE);
storyboardSprite = new StoryboardSprite(path, origin, new Vector2(x, y));
storyboard.GetLayer(layer).Add(storyboardSprite);
break;
@ -105,10 +104,10 @@ namespace osu.Game.Beatmaps.Formats
var layer = parseLayer(split[1]);
var origin = parseOrigin(split[2]);
var path = CleanFilename(split[3]);
var x = float.Parse(split[4], NumberFormatInfo.InvariantInfo);
var y = float.Parse(split[5], NumberFormatInfo.InvariantInfo);
var frameCount = int.Parse(split[6]);
var frameDelay = double.Parse(split[7], NumberFormatInfo.InvariantInfo);
var x = Parsing.ParseFloat(split[4], Parsing.MAX_COORDINATE_VALUE);
var y = Parsing.ParseFloat(split[5], Parsing.MAX_COORDINATE_VALUE);
var frameCount = Parsing.ParseInt(split[6]);
var frameDelay = Parsing.ParseDouble(split[7]);
var loopType = split.Length > 8 ? (AnimationLoopType)Enum.Parse(typeof(AnimationLoopType), split[8]) : AnimationLoopType.LoopForever;
storyboardSprite = new StoryboardAnimation(path, origin, new Vector2(x, y), frameCount, frameDelay, loopType);
storyboard.GetLayer(layer).Add(storyboardSprite);
@ -117,10 +116,10 @@ namespace osu.Game.Beatmaps.Formats
case LegacyEventType.Sample:
{
var time = double.Parse(split[1], CultureInfo.InvariantCulture);
var time = Parsing.ParseDouble(split[1]);
var layer = parseLayer(split[2]);
var path = CleanFilename(split[3]);
var volume = split.Length > 4 ? float.Parse(split[4], CultureInfo.InvariantCulture) : 100;
var volume = split.Length > 4 ? Parsing.ParseFloat(split[4]) : 100;
storyboard.GetLayer(layer).Add(new StoryboardSampleInfo(path, time, (int)volume));
break;
}
@ -138,17 +137,17 @@ namespace osu.Game.Beatmaps.Formats
case "T":
{
var triggerName = split[1];
var startTime = split.Length > 2 ? double.Parse(split[2], CultureInfo.InvariantCulture) : double.MinValue;
var endTime = split.Length > 3 ? double.Parse(split[3], CultureInfo.InvariantCulture) : double.MaxValue;
var groupNumber = split.Length > 4 ? int.Parse(split[4]) : 0;
var startTime = split.Length > 2 ? Parsing.ParseDouble(split[2]) : double.MinValue;
var endTime = split.Length > 3 ? Parsing.ParseDouble(split[3]) : double.MaxValue;
var groupNumber = split.Length > 4 ? Parsing.ParseInt(split[4]) : 0;
timelineGroup = storyboardSprite?.AddTrigger(triggerName, startTime, endTime, groupNumber);
break;
}
case "L":
{
var startTime = double.Parse(split[1], CultureInfo.InvariantCulture);
var loopCount = int.Parse(split[2]);
var startTime = Parsing.ParseDouble(split[1]);
var loopCount = Parsing.ParseInt(split[2]);
timelineGroup = storyboardSprite?.AddLoop(startTime, loopCount);
break;
}
@ -158,52 +157,52 @@ namespace osu.Game.Beatmaps.Formats
if (string.IsNullOrEmpty(split[3]))
split[3] = split[2];
var easing = (Easing)int.Parse(split[1]);
var startTime = double.Parse(split[2], CultureInfo.InvariantCulture);
var endTime = double.Parse(split[3], CultureInfo.InvariantCulture);
var easing = (Easing)Parsing.ParseInt(split[1]);
var startTime = Parsing.ParseDouble(split[2]);
var endTime = Parsing.ParseDouble(split[3]);
switch (commandType)
{
case "F":
{
var startValue = float.Parse(split[4], CultureInfo.InvariantCulture);
var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue;
var startValue = Parsing.ParseFloat(split[4]);
var endValue = split.Length > 5 ? Parsing.ParseFloat(split[5]) : startValue;
timelineGroup?.Alpha.Add(easing, startTime, endTime, startValue, endValue);
break;
}
case "S":
{
var startValue = float.Parse(split[4], CultureInfo.InvariantCulture);
var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue;
var startValue = Parsing.ParseFloat(split[4]);
var endValue = split.Length > 5 ? Parsing.ParseFloat(split[5]) : startValue;
timelineGroup?.Scale.Add(easing, startTime, endTime, startValue, endValue);
break;
}
case "V":
{
var startX = float.Parse(split[4], CultureInfo.InvariantCulture);
var startY = float.Parse(split[5], CultureInfo.InvariantCulture);
var endX = split.Length > 6 ? float.Parse(split[6], CultureInfo.InvariantCulture) : startX;
var endY = split.Length > 7 ? float.Parse(split[7], CultureInfo.InvariantCulture) : startY;
var startX = Parsing.ParseFloat(split[4]);
var startY = Parsing.ParseFloat(split[5]);
var endX = split.Length > 6 ? Parsing.ParseFloat(split[6]) : startX;
var endY = split.Length > 7 ? Parsing.ParseFloat(split[7]) : startY;
timelineGroup?.VectorScale.Add(easing, startTime, endTime, new Vector2(startX, startY), new Vector2(endX, endY));
break;
}
case "R":
{
var startValue = float.Parse(split[4], CultureInfo.InvariantCulture);
var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue;
var startValue = Parsing.ParseFloat(split[4]);
var endValue = split.Length > 5 ? Parsing.ParseFloat(split[5]) : startValue;
timelineGroup?.Rotation.Add(easing, startTime, endTime, MathUtils.RadiansToDegrees(startValue), MathUtils.RadiansToDegrees(endValue));
break;
}
case "M":
{
var startX = float.Parse(split[4], CultureInfo.InvariantCulture);
var startY = float.Parse(split[5], CultureInfo.InvariantCulture);
var endX = split.Length > 6 ? float.Parse(split[6], CultureInfo.InvariantCulture) : startX;
var endY = split.Length > 7 ? float.Parse(split[7], CultureInfo.InvariantCulture) : startY;
var startX = Parsing.ParseFloat(split[4]);
var startY = Parsing.ParseFloat(split[5]);
var endX = split.Length > 6 ? Parsing.ParseFloat(split[6]) : startX;
var endY = split.Length > 7 ? Parsing.ParseFloat(split[7]) : startY;
timelineGroup?.X.Add(easing, startTime, endTime, startX, endX);
timelineGroup?.Y.Add(easing, startTime, endTime, startY, endY);
break;
@ -211,28 +210,28 @@ namespace osu.Game.Beatmaps.Formats
case "MX":
{
var startValue = float.Parse(split[4], CultureInfo.InvariantCulture);
var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue;
var startValue = Parsing.ParseFloat(split[4]);
var endValue = split.Length > 5 ? Parsing.ParseFloat(split[5]) : startValue;
timelineGroup?.X.Add(easing, startTime, endTime, startValue, endValue);
break;
}
case "MY":
{
var startValue = float.Parse(split[4], CultureInfo.InvariantCulture);
var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue;
var startValue = Parsing.ParseFloat(split[4]);
var endValue = split.Length > 5 ? Parsing.ParseFloat(split[5]) : startValue;
timelineGroup?.Y.Add(easing, startTime, endTime, startValue, endValue);
break;
}
case "C":
{
var startRed = float.Parse(split[4], CultureInfo.InvariantCulture);
var startGreen = float.Parse(split[5], CultureInfo.InvariantCulture);
var startBlue = float.Parse(split[6], CultureInfo.InvariantCulture);
var endRed = split.Length > 7 ? float.Parse(split[7], CultureInfo.InvariantCulture) : startRed;
var endGreen = split.Length > 8 ? float.Parse(split[8], CultureInfo.InvariantCulture) : startGreen;
var endBlue = split.Length > 9 ? float.Parse(split[9], CultureInfo.InvariantCulture) : startBlue;
var startRed = Parsing.ParseFloat(split[4]);
var startGreen = Parsing.ParseFloat(split[5]);
var startBlue = Parsing.ParseFloat(split[6]);
var endRed = split.Length > 7 ? Parsing.ParseFloat(split[7]) : startRed;
var endGreen = split.Length > 8 ? Parsing.ParseFloat(split[8]) : startGreen;
var endBlue = split.Length > 9 ? Parsing.ParseFloat(split[9]) : startBlue;
timelineGroup?.Colour.Add(easing, startTime, endTime,
new Color4(startRed / 255f, startGreen / 255f, startBlue / 255f, 1),
new Color4(endRed / 255f, endGreen / 255f, endBlue / 255f, 1));

View File

@ -15,11 +15,13 @@ namespace osu.Game.Database
{
/// <summary>
/// Fired when a <typeparamref name="TModel"/> download begins.
/// This is NOT run on the update thread and should be scheduled.
/// </summary>
event Action<ArchiveDownloadRequest<TModel>> DownloadBegan;
/// <summary>
/// Fired when a <typeparamref name="TModel"/> download is interrupted, either due to user cancellation or failure.
/// This is NOT run on the update thread and should be scheduled.
/// </summary>
event Action<ArchiveDownloadRequest<TModel>> DownloadFailed;

View File

@ -1,8 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Globalization;
using osu.Framework.Extensions.Color4Extensions;
using osu.Game.Beatmaps;
using osuTK.Graphics;
@ -13,45 +12,6 @@ namespace osu.Game.Graphics
public static Color4 Gray(float amt) => new Color4(amt, amt, amt, 1f);
public static Color4 Gray(byte amt) => new Color4(amt, amt, amt, 255);
public static Color4 FromHex(string hex)
{
var hexSpan = hex[0] == '#' ? hex.AsSpan().Slice(1) : hex.AsSpan();
switch (hexSpan.Length)
{
default:
throw new ArgumentException(@"Invalid hex string length!");
case 3:
return new Color4(
(byte)(byte.Parse(hexSpan.Slice(0, 1), NumberStyles.HexNumber) * 17),
(byte)(byte.Parse(hexSpan.Slice(1, 1), NumberStyles.HexNumber) * 17),
(byte)(byte.Parse(hexSpan.Slice(2, 1), NumberStyles.HexNumber) * 17),
255);
case 6:
return new Color4(
byte.Parse(hexSpan.Slice(0, 2), NumberStyles.HexNumber),
byte.Parse(hexSpan.Slice(2, 2), NumberStyles.HexNumber),
byte.Parse(hexSpan.Slice(4, 2), NumberStyles.HexNumber),
255);
case 4:
return new Color4(
(byte)(byte.Parse(hexSpan.Slice(0, 1), NumberStyles.HexNumber) * 17),
(byte)(byte.Parse(hexSpan.Slice(1, 1), NumberStyles.HexNumber) * 17),
(byte)(byte.Parse(hexSpan.Slice(0, 1), NumberStyles.HexNumber) * 17),
(byte)(byte.Parse(hexSpan.Slice(0, 1), NumberStyles.HexNumber) * 17));
case 8:
return new Color4(
byte.Parse(hexSpan.Slice(0, 2), NumberStyles.HexNumber),
byte.Parse(hexSpan.Slice(2, 2), NumberStyles.HexNumber),
byte.Parse(hexSpan.Slice(4, 2), NumberStyles.HexNumber),
byte.Parse(hexSpan.Slice(6, 2), NumberStyles.HexNumber));
}
}
public Color4 ForDifficultyRating(DifficultyRating difficulty, bool useLighterColour = false)
{
switch (difficulty)
@ -78,105 +38,105 @@ namespace osu.Game.Graphics
}
// See https://github.com/ppy/osu-web/blob/master/resources/assets/less/colors.less
public readonly Color4 PurpleLighter = FromHex(@"eeeeff");
public readonly Color4 PurpleLight = FromHex(@"aa88ff");
public readonly Color4 PurpleLightAlternative = FromHex(@"cba4da");
public readonly Color4 Purple = FromHex(@"8866ee");
public readonly Color4 PurpleDark = FromHex(@"6644cc");
public readonly Color4 PurpleDarkAlternative = FromHex(@"312436");
public readonly Color4 PurpleDarker = FromHex(@"441188");
public readonly Color4 PurpleLighter = Color4Extensions.FromHex(@"eeeeff");
public readonly Color4 PurpleLight = Color4Extensions.FromHex(@"aa88ff");
public readonly Color4 PurpleLightAlternative = Color4Extensions.FromHex(@"cba4da");
public readonly Color4 Purple = Color4Extensions.FromHex(@"8866ee");
public readonly Color4 PurpleDark = Color4Extensions.FromHex(@"6644cc");
public readonly Color4 PurpleDarkAlternative = Color4Extensions.FromHex(@"312436");
public readonly Color4 PurpleDarker = Color4Extensions.FromHex(@"441188");
public readonly Color4 PinkLighter = FromHex(@"ffddee");
public readonly Color4 PinkLight = FromHex(@"ff99cc");
public readonly Color4 Pink = FromHex(@"ff66aa");
public readonly Color4 PinkDark = FromHex(@"cc5288");
public readonly Color4 PinkDarker = FromHex(@"bb1177");
public readonly Color4 PinkLighter = Color4Extensions.FromHex(@"ffddee");
public readonly Color4 PinkLight = Color4Extensions.FromHex(@"ff99cc");
public readonly Color4 Pink = Color4Extensions.FromHex(@"ff66aa");
public readonly Color4 PinkDark = Color4Extensions.FromHex(@"cc5288");
public readonly Color4 PinkDarker = Color4Extensions.FromHex(@"bb1177");
public readonly Color4 BlueLighter = FromHex(@"ddffff");
public readonly Color4 BlueLight = FromHex(@"99eeff");
public readonly Color4 Blue = FromHex(@"66ccff");
public readonly Color4 BlueDark = FromHex(@"44aadd");
public readonly Color4 BlueDarker = FromHex(@"2299bb");
public readonly Color4 BlueLighter = Color4Extensions.FromHex(@"ddffff");
public readonly Color4 BlueLight = Color4Extensions.FromHex(@"99eeff");
public readonly Color4 Blue = Color4Extensions.FromHex(@"66ccff");
public readonly Color4 BlueDark = Color4Extensions.FromHex(@"44aadd");
public readonly Color4 BlueDarker = Color4Extensions.FromHex(@"2299bb");
public readonly Color4 YellowLighter = FromHex(@"ffffdd");
public readonly Color4 YellowLight = FromHex(@"ffdd55");
public readonly Color4 Yellow = FromHex(@"ffcc22");
public readonly Color4 YellowDark = FromHex(@"eeaa00");
public readonly Color4 YellowDarker = FromHex(@"cc6600");
public readonly Color4 YellowLighter = Color4Extensions.FromHex(@"ffffdd");
public readonly Color4 YellowLight = Color4Extensions.FromHex(@"ffdd55");
public readonly Color4 Yellow = Color4Extensions.FromHex(@"ffcc22");
public readonly Color4 YellowDark = Color4Extensions.FromHex(@"eeaa00");
public readonly Color4 YellowDarker = Color4Extensions.FromHex(@"cc6600");
public readonly Color4 GreenLighter = FromHex(@"eeffcc");
public readonly Color4 GreenLight = FromHex(@"b3d944");
public readonly Color4 Green = FromHex(@"88b300");
public readonly Color4 GreenDark = FromHex(@"668800");
public readonly Color4 GreenDarker = FromHex(@"445500");
public readonly Color4 GreenLighter = Color4Extensions.FromHex(@"eeffcc");
public readonly Color4 GreenLight = Color4Extensions.FromHex(@"b3d944");
public readonly Color4 Green = Color4Extensions.FromHex(@"88b300");
public readonly Color4 GreenDark = Color4Extensions.FromHex(@"668800");
public readonly Color4 GreenDarker = Color4Extensions.FromHex(@"445500");
public readonly Color4 Sky = FromHex(@"6bb5ff");
public readonly Color4 GreySkyLighter = FromHex(@"c6e3f4");
public readonly Color4 GreySkyLight = FromHex(@"8ab3cc");
public readonly Color4 GreySky = FromHex(@"405461");
public readonly Color4 GreySkyDark = FromHex(@"303d47");
public readonly Color4 GreySkyDarker = FromHex(@"21272c");
public readonly Color4 Sky = Color4Extensions.FromHex(@"6bb5ff");
public readonly Color4 GreySkyLighter = Color4Extensions.FromHex(@"c6e3f4");
public readonly Color4 GreySkyLight = Color4Extensions.FromHex(@"8ab3cc");
public readonly Color4 GreySky = Color4Extensions.FromHex(@"405461");
public readonly Color4 GreySkyDark = Color4Extensions.FromHex(@"303d47");
public readonly Color4 GreySkyDarker = Color4Extensions.FromHex(@"21272c");
public readonly Color4 Seafoam = FromHex(@"05ffa2");
public readonly Color4 GreySeafoamLighter = FromHex(@"9ebab1");
public readonly Color4 GreySeafoamLight = FromHex(@"4d7365");
public readonly Color4 GreySeafoam = FromHex(@"33413c");
public readonly Color4 GreySeafoamDark = FromHex(@"2c3532");
public readonly Color4 GreySeafoamDarker = FromHex(@"1e2422");
public readonly Color4 Seafoam = Color4Extensions.FromHex(@"05ffa2");
public readonly Color4 GreySeafoamLighter = Color4Extensions.FromHex(@"9ebab1");
public readonly Color4 GreySeafoamLight = Color4Extensions.FromHex(@"4d7365");
public readonly Color4 GreySeafoam = Color4Extensions.FromHex(@"33413c");
public readonly Color4 GreySeafoamDark = Color4Extensions.FromHex(@"2c3532");
public readonly Color4 GreySeafoamDarker = Color4Extensions.FromHex(@"1e2422");
public readonly Color4 Cyan = FromHex(@"05f4fd");
public readonly Color4 GreyCyanLighter = FromHex(@"77b1b3");
public readonly Color4 GreyCyanLight = FromHex(@"436d6f");
public readonly Color4 GreyCyan = FromHex(@"293d3e");
public readonly Color4 GreyCyanDark = FromHex(@"243536");
public readonly Color4 GreyCyanDarker = FromHex(@"1e2929");
public readonly Color4 Cyan = Color4Extensions.FromHex(@"05f4fd");
public readonly Color4 GreyCyanLighter = Color4Extensions.FromHex(@"77b1b3");
public readonly Color4 GreyCyanLight = Color4Extensions.FromHex(@"436d6f");
public readonly Color4 GreyCyan = Color4Extensions.FromHex(@"293d3e");
public readonly Color4 GreyCyanDark = Color4Extensions.FromHex(@"243536");
public readonly Color4 GreyCyanDarker = Color4Extensions.FromHex(@"1e2929");
public readonly Color4 Lime = FromHex(@"82ff05");
public readonly Color4 GreyLimeLighter = FromHex(@"deff87");
public readonly Color4 GreyLimeLight = FromHex(@"657259");
public readonly Color4 GreyLime = FromHex(@"3f443a");
public readonly Color4 GreyLimeDark = FromHex(@"32352e");
public readonly Color4 GreyLimeDarker = FromHex(@"2e302b");
public readonly Color4 Lime = Color4Extensions.FromHex(@"82ff05");
public readonly Color4 GreyLimeLighter = Color4Extensions.FromHex(@"deff87");
public readonly Color4 GreyLimeLight = Color4Extensions.FromHex(@"657259");
public readonly Color4 GreyLime = Color4Extensions.FromHex(@"3f443a");
public readonly Color4 GreyLimeDark = Color4Extensions.FromHex(@"32352e");
public readonly Color4 GreyLimeDarker = Color4Extensions.FromHex(@"2e302b");
public readonly Color4 Violet = FromHex(@"bf04ff");
public readonly Color4 GreyVioletLighter = FromHex(@"ebb8fe");
public readonly Color4 GreyVioletLight = FromHex(@"685370");
public readonly Color4 GreyViolet = FromHex(@"46334d");
public readonly Color4 GreyVioletDark = FromHex(@"2c2230");
public readonly Color4 GreyVioletDarker = FromHex(@"201823");
public readonly Color4 Violet = Color4Extensions.FromHex(@"bf04ff");
public readonly Color4 GreyVioletLighter = Color4Extensions.FromHex(@"ebb8fe");
public readonly Color4 GreyVioletLight = Color4Extensions.FromHex(@"685370");
public readonly Color4 GreyViolet = Color4Extensions.FromHex(@"46334d");
public readonly Color4 GreyVioletDark = Color4Extensions.FromHex(@"2c2230");
public readonly Color4 GreyVioletDarker = Color4Extensions.FromHex(@"201823");
public readonly Color4 Carmine = FromHex(@"ff0542");
public readonly Color4 GreyCarmineLighter = FromHex(@"deaab4");
public readonly Color4 GreyCarmineLight = FromHex(@"644f53");
public readonly Color4 GreyCarmine = FromHex(@"342b2d");
public readonly Color4 GreyCarmineDark = FromHex(@"302a2b");
public readonly Color4 GreyCarmineDarker = FromHex(@"241d1e");
public readonly Color4 Carmine = Color4Extensions.FromHex(@"ff0542");
public readonly Color4 GreyCarmineLighter = Color4Extensions.FromHex(@"deaab4");
public readonly Color4 GreyCarmineLight = Color4Extensions.FromHex(@"644f53");
public readonly Color4 GreyCarmine = Color4Extensions.FromHex(@"342b2d");
public readonly Color4 GreyCarmineDark = Color4Extensions.FromHex(@"302a2b");
public readonly Color4 GreyCarmineDarker = Color4Extensions.FromHex(@"241d1e");
public readonly Color4 Gray0 = FromHex(@"000");
public readonly Color4 Gray1 = FromHex(@"111");
public readonly Color4 Gray2 = FromHex(@"222");
public readonly Color4 Gray3 = FromHex(@"333");
public readonly Color4 Gray4 = FromHex(@"444");
public readonly Color4 Gray5 = FromHex(@"555");
public readonly Color4 Gray6 = FromHex(@"666");
public readonly Color4 Gray7 = FromHex(@"777");
public readonly Color4 Gray8 = FromHex(@"888");
public readonly Color4 Gray9 = FromHex(@"999");
public readonly Color4 GrayA = FromHex(@"aaa");
public readonly Color4 GrayB = FromHex(@"bbb");
public readonly Color4 GrayC = FromHex(@"ccc");
public readonly Color4 GrayD = FromHex(@"ddd");
public readonly Color4 GrayE = FromHex(@"eee");
public readonly Color4 GrayF = FromHex(@"fff");
public readonly Color4 Gray0 = Color4Extensions.FromHex(@"000");
public readonly Color4 Gray1 = Color4Extensions.FromHex(@"111");
public readonly Color4 Gray2 = Color4Extensions.FromHex(@"222");
public readonly Color4 Gray3 = Color4Extensions.FromHex(@"333");
public readonly Color4 Gray4 = Color4Extensions.FromHex(@"444");
public readonly Color4 Gray5 = Color4Extensions.FromHex(@"555");
public readonly Color4 Gray6 = Color4Extensions.FromHex(@"666");
public readonly Color4 Gray7 = Color4Extensions.FromHex(@"777");
public readonly Color4 Gray8 = Color4Extensions.FromHex(@"888");
public readonly Color4 Gray9 = Color4Extensions.FromHex(@"999");
public readonly Color4 GrayA = Color4Extensions.FromHex(@"aaa");
public readonly Color4 GrayB = Color4Extensions.FromHex(@"bbb");
public readonly Color4 GrayC = Color4Extensions.FromHex(@"ccc");
public readonly Color4 GrayD = Color4Extensions.FromHex(@"ddd");
public readonly Color4 GrayE = Color4Extensions.FromHex(@"eee");
public readonly Color4 GrayF = Color4Extensions.FromHex(@"fff");
public readonly Color4 RedLighter = FromHex(@"ffeded");
public readonly Color4 RedLight = FromHex(@"ed7787");
public readonly Color4 Red = FromHex(@"ed1121");
public readonly Color4 RedDark = FromHex(@"ba0011");
public readonly Color4 RedDarker = FromHex(@"870000");
public readonly Color4 RedLighter = Color4Extensions.FromHex(@"ffeded");
public readonly Color4 RedLight = Color4Extensions.FromHex(@"ed7787");
public readonly Color4 Red = Color4Extensions.FromHex(@"ed1121");
public readonly Color4 RedDark = Color4Extensions.FromHex(@"ba0011");
public readonly Color4 RedDarker = Color4Extensions.FromHex(@"870000");
public readonly Color4 ChatBlue = FromHex(@"17292e");
public readonly Color4 ChatBlue = Color4Extensions.FromHex(@"17292e");
public readonly Color4 ContextMenuGray = FromHex(@"223034");
public readonly Color4 ContextMenuGray = Color4Extensions.FromHex(@"223034");
}
}

View File

@ -4,6 +4,7 @@
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@ -38,7 +39,7 @@ namespace osu.Game.Graphics.UserInterface
sampleClick = audio.Samples.Get(@"UI/generic-select");
BackgroundColour = Color4.Transparent;
BackgroundColourHover = OsuColour.FromHex(@"172023");
BackgroundColourHover = Color4Extensions.FromHex(@"172023");
updateTextColour();
}
@ -57,7 +58,7 @@ namespace osu.Game.Graphics.UserInterface
break;
case MenuItemType.Highlighted:
text.Colour = OsuColour.FromHex(@"ffcc22");
text.Colour = Color4Extensions.FromHex(@"ffcc22");
break;
}
}

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -42,7 +43,7 @@ namespace osu.Game.Graphics.UserInterfaceV2
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex("1c2125"),
Colour = Color4Extensions.FromHex("1c2125"),
},
new FillFlowContainer
{

View File

@ -53,17 +53,17 @@ namespace osu.Game.Online
manager.ItemRemoved += itemRemoved;
}
private void downloadBegan(ArchiveDownloadRequest<TModel> request)
private void downloadBegan(ArchiveDownloadRequest<TModel> request) => Schedule(() =>
{
if (request.Model.Equals(Model.Value))
attachDownload(request);
}
});
private void downloadFailed(ArchiveDownloadRequest<TModel> request)
private void downloadFailed(ArchiveDownloadRequest<TModel> request) => Schedule(() =>
{
if (request.Model.Equals(Model.Value))
attachDownload(null);
}
});
private ArchiveDownloadRequest<TModel> attachedRequest;

View File

@ -80,23 +80,23 @@ namespace osu.Game.Online.Leaderboards
{
case ScoreRank.XH:
case ScoreRank.X:
return OsuColour.FromHex(@"ce1c9d");
return Color4Extensions.FromHex(@"ce1c9d");
case ScoreRank.SH:
case ScoreRank.S:
return OsuColour.FromHex(@"00a8b5");
return Color4Extensions.FromHex(@"00a8b5");
case ScoreRank.A:
return OsuColour.FromHex(@"7cce14");
return Color4Extensions.FromHex(@"7cce14");
case ScoreRank.B:
return OsuColour.FromHex(@"e3b130");
return Color4Extensions.FromHex(@"e3b130");
case ScoreRank.C:
return OsuColour.FromHex(@"f18252");
return Color4Extensions.FromHex(@"f18252");
default:
return OsuColour.FromHex(@"e95353");
return Color4Extensions.FromHex(@"e95353");
}
}
@ -109,23 +109,23 @@ namespace osu.Game.Online.Leaderboards
{
case ScoreRank.XH:
case ScoreRank.SH:
return ColourInfo.GradientVertical(Color4.White, OsuColour.FromHex("afdff0"));
return ColourInfo.GradientVertical(Color4.White, Color4Extensions.FromHex("afdff0"));
case ScoreRank.X:
case ScoreRank.S:
return ColourInfo.GradientVertical(OsuColour.FromHex(@"ffe7a8"), OsuColour.FromHex(@"ffb800"));
return ColourInfo.GradientVertical(Color4Extensions.FromHex(@"ffe7a8"), Color4Extensions.FromHex(@"ffb800"));
case ScoreRank.A:
return OsuColour.FromHex(@"275227");
return Color4Extensions.FromHex(@"275227");
case ScoreRank.B:
return OsuColour.FromHex(@"553a2b");
return Color4Extensions.FromHex(@"553a2b");
case ScoreRank.C:
return OsuColour.FromHex(@"473625");
return Color4Extensions.FromHex(@"473625");
default:
return OsuColour.FromHex(@"512525");
return Color4Extensions.FromHex(@"512525");
}
}
}

View File

@ -200,7 +200,7 @@ namespace osu.Game.Online.Leaderboards
scoreLabel = new GlowingSpriteText
{
TextColour = Color4.White,
GlowColour = OsuColour.FromHex(@"83ccfa"),
GlowColour = Color4Extensions.FromHex(@"83ccfa"),
Text = score.TotalScore.ToString(@"N0"),
Font = OsuFont.Numeric.With(size: 23),
},
@ -325,7 +325,7 @@ namespace osu.Game.Online.Leaderboards
Origin = Anchor.Centre,
Size = new Vector2(icon_size),
Rotation = 45,
Colour = OsuColour.FromHex(@"3087ac"),
Colour = Color4Extensions.FromHex(@"3087ac"),
Icon = FontAwesome.Solid.Square,
Shadow = true,
},
@ -334,7 +334,7 @@ namespace osu.Game.Online.Leaderboards
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(icon_size - 6),
Colour = OsuColour.FromHex(@"a4edff"),
Colour = Color4Extensions.FromHex(@"a4edff"),
Icon = statistic.Icon,
},
},
@ -344,7 +344,7 @@ namespace osu.Game.Online.Leaderboards
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
TextColour = Color4.White,
GlowColour = OsuColour.FromHex(@"83ccfa"),
GlowColour = Color4Extensions.FromHex(@"83ccfa"),
Text = statistic.Value,
Font = OsuFont.GetFont(size: 17, weight: FontWeight.Bold),
},

View File

@ -3,6 +3,7 @@
using System;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
@ -124,7 +125,7 @@ namespace osu.Game.Overlays.BeatmapSet
Icon = FontAwesome.Solid.Square,
Size = new Vector2(12),
Rotation = 45,
Colour = OsuColour.FromHex(@"441288"),
Colour = Color4Extensions.FromHex(@"441288"),
},
new SpriteIcon
{
@ -132,7 +133,7 @@ namespace osu.Game.Overlays.BeatmapSet
Origin = Anchor.Centre,
Icon = icon,
Size = new Vector2(12),
Colour = OsuColour.FromHex(@"f7dd55"),
Colour = Color4Extensions.FromHex(@"f7dd55"),
Scale = new Vector2(0.8f),
},
value = new OsuSpriteText

View File

@ -2,8 +2,8 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Overlays.BeatmapSet.Buttons
@ -19,9 +19,9 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
[BackgroundDependencyLoader]
private void load()
{
BackgroundColour = OsuColour.FromHex(@"094c5f");
Triangles.ColourLight = OsuColour.FromHex(@"0f7c9b");
Triangles.ColourDark = OsuColour.FromHex(@"094c5f");
BackgroundColour = Color4Extensions.FromHex(@"094c5f");
Triangles.ColourLight = Color4Extensions.FromHex(@"0f7c9b");
Triangles.ColourDark = Color4Extensions.FromHex(@"094c5f");
Triangles.TriangleScale = 1.5f;
}
}

View File

@ -52,22 +52,28 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
highAccuracyColour = colours.GreenLight;
}
public IReadOnlyList<ScoreInfo> Scores
private bool showPerformancePoints;
public void DisplayScores(IReadOnlyList<ScoreInfo> scores, bool showPerformanceColumn)
{
set
{
Content = null;
backgroundFlow.Clear();
ClearScores();
if (value?.Any() != true)
return;
if (!scores.Any())
return;
for (int i = 0; i < value.Count; i++)
backgroundFlow.Add(new ScoreTableRowBackground(i, value[i], row_height));
showPerformancePoints = showPerformanceColumn;
Columns = createHeaders(value[0]);
Content = value.Select((s, i) => createContent(i, s)).ToArray().ToRectangular();
}
for (int i = 0; i < scores.Count; i++)
backgroundFlow.Add(new ScoreTableRowBackground(i, scores[i], row_height));
Columns = createHeaders(scores.FirstOrDefault());
Content = scores.Select((s, i) => createContent(i, s)).ToArray().ToRectangular();
}
public void ClearScores()
{
Content = null;
backgroundFlow.Clear();
}
private TableColumn[] createHeaders(ScoreInfo score)
@ -88,11 +94,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
columns.Add(new TableColumn(score.SortedStatistics.LastOrDefault().Key.GetDescription(), Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 45, maxSize: 95)));
columns.AddRange(new[]
{
new TableColumn("pp", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, 30)),
new TableColumn("mods", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)),
});
if (showPerformancePoints)
columns.Add(new TableColumn("pp", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, 30)));
columns.Add(new TableColumn("mods", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)));
return columns.ToArray();
}
@ -150,24 +155,25 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
});
}
content.AddRange(new Drawable[]
if (showPerformancePoints)
{
new OsuSpriteText
content.Add(new OsuSpriteText
{
Text = $@"{score.PP:N0}",
Font = OsuFont.GetFont(size: text_size)
},
new FillFlowContainer
});
}
content.Add(new FillFlowContainer
{
Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both,
Spacing = new Vector2(1),
ChildrenEnumerable = score.Mods.Select(m => new ModIcon(m)
{
Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both,
Spacing = new Vector2(1),
ChildrenEnumerable = score.Mods.Select(m => new ModIcon(m)
{
AutoSizeAxes = Axes.Both,
Scale = new Vector2(0.3f)
})
},
Scale = new Vector2(0.3f)
})
});
return content.ToArray();

View File

@ -52,17 +52,17 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
if (value?.Scores.Any() != true)
{
scoreTable.Scores = null;
scoreTable.ClearScores();
scoreTable.Hide();
return;
}
var scoreInfos = value.Scores.Select(s => s.CreateScoreInfo(rulesets)).ToList();
var topScore = scoreInfos.First();
scoreTable.Scores = scoreInfos;
scoreTable.DisplayScores(scoreInfos, topScore.Beatmap?.Status == BeatmapSetOnlineStatus.Ranked);
scoreTable.Show();
var topScore = scoreInfos.First();
var userScore = value.UserScore;
var userScoreInfo = userScore?.Score.CreateScoreInfo(rulesets);

View File

@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Mods;
@ -96,6 +97,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
totalScoreColumn.Text = $@"{value.TotalScore:N0}";
accuracyColumn.Text = value.DisplayAccuracy;
maxComboColumn.Text = $@"{value.MaxCombo:N0}x";
ppColumn.Alpha = value.Beatmap?.Status == BeatmapSetOnlineStatus.Ranked ? 1 : 0;
ppColumn.Text = $@"{value.PP:N0}";
statisticsColumns.ChildrenEnumerable = value.SortedStatistics.Select(kvp => createStatisticsColumn(kvp.Key, kvp.Value));

View File

@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Changelog
public Action ListingSelected;
public UpdateStreamBadgeArea Streams;
public ChangelogUpdateStreamControl Streams;
private const string listing_string = "listing";
@ -95,7 +95,7 @@ namespace osu.Game.Overlays.Changelog
Horizontal = 65,
Vertical = 20
},
Child = Streams = new UpdateStreamBadgeArea()
Child = Streams = new ChangelogUpdateStreamControl()
}
}
};

View File

@ -0,0 +1,12 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Overlays.Changelog
{
public class ChangelogUpdateStreamControl : OverlayStreamControl<APIUpdateStream>
{
protected override OverlayStreamItem<APIUpdateStream> CreateStreamItem(APIUpdateStream value) => new ChangelogUpdateStreamItem(value);
}
}

View File

@ -0,0 +1,28 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using Humanizer;
using osu.Game.Graphics;
using osu.Game.Online.API.Requests.Responses;
using osuTK.Graphics;
namespace osu.Game.Overlays.Changelog
{
public class ChangelogUpdateStreamItem : OverlayStreamItem<APIUpdateStream>
{
public ChangelogUpdateStreamItem(APIUpdateStream stream)
: base(stream)
{
if (stream.IsFeatured)
Width *= 2;
}
protected override string MainText => Value.DisplayName;
protected override string AdditionalText => Value.LatestBuild.DisplayVersion;
protected override string InfoText => Value.LatestBuild.Users > 0 ? $"{"user".ToQuantity(Value.LatestBuild.Users, "N0")} online" : null;
protected override Color4 GetBarColour(OsuColour colours) => Value.Colour;
}
}

View File

@ -123,7 +123,7 @@ namespace osu.Game.Overlays.Chat
EdgeEffect = new EdgeEffectParameters
{
Radius = 1,
Colour = OsuColour.FromHex(message.Sender.Colour),
Colour = Color4Extensions.FromHex(message.Sender.Colour),
Type = EdgeEffectType.Shadow,
},
Padding = new MarginPadding { Left = 3, Right = 3, Bottom = 1, Top = -3 },
@ -172,7 +172,7 @@ namespace osu.Game.Overlays.Chat
t.Font = OsuFont.GetFont(italics: true);
if (senderHasBackground)
t.Colour = OsuColour.FromHex(message.Sender.Colour);
t.Colour = Color4Extensions.FromHex(message.Sender.Colour);
}
t.Font = t.Font.With(size: TextSize);
@ -249,41 +249,41 @@ namespace osu.Game.Overlays.Chat
private static readonly Color4[] username_colours =
{
OsuColour.FromHex("588c7e"),
OsuColour.FromHex("b2a367"),
OsuColour.FromHex("c98f65"),
OsuColour.FromHex("bc5151"),
OsuColour.FromHex("5c8bd6"),
OsuColour.FromHex("7f6ab7"),
OsuColour.FromHex("a368ad"),
OsuColour.FromHex("aa6880"),
Color4Extensions.FromHex("588c7e"),
Color4Extensions.FromHex("b2a367"),
Color4Extensions.FromHex("c98f65"),
Color4Extensions.FromHex("bc5151"),
Color4Extensions.FromHex("5c8bd6"),
Color4Extensions.FromHex("7f6ab7"),
Color4Extensions.FromHex("a368ad"),
Color4Extensions.FromHex("aa6880"),
OsuColour.FromHex("6fad9b"),
OsuColour.FromHex("f2e394"),
OsuColour.FromHex("f2ae72"),
OsuColour.FromHex("f98f8a"),
OsuColour.FromHex("7daef4"),
OsuColour.FromHex("a691f2"),
OsuColour.FromHex("c894d3"),
OsuColour.FromHex("d895b0"),
Color4Extensions.FromHex("6fad9b"),
Color4Extensions.FromHex("f2e394"),
Color4Extensions.FromHex("f2ae72"),
Color4Extensions.FromHex("f98f8a"),
Color4Extensions.FromHex("7daef4"),
Color4Extensions.FromHex("a691f2"),
Color4Extensions.FromHex("c894d3"),
Color4Extensions.FromHex("d895b0"),
OsuColour.FromHex("53c4a1"),
OsuColour.FromHex("eace5c"),
OsuColour.FromHex("ea8c47"),
OsuColour.FromHex("fc4f4f"),
OsuColour.FromHex("3d94ea"),
OsuColour.FromHex("7760ea"),
OsuColour.FromHex("af52c6"),
OsuColour.FromHex("e25696"),
Color4Extensions.FromHex("53c4a1"),
Color4Extensions.FromHex("eace5c"),
Color4Extensions.FromHex("ea8c47"),
Color4Extensions.FromHex("fc4f4f"),
Color4Extensions.FromHex("3d94ea"),
Color4Extensions.FromHex("7760ea"),
Color4Extensions.FromHex("af52c6"),
Color4Extensions.FromHex("e25696"),
OsuColour.FromHex("677c66"),
OsuColour.FromHex("9b8732"),
OsuColour.FromHex("8c5129"),
OsuColour.FromHex("8c3030"),
OsuColour.FromHex("1f5d91"),
OsuColour.FromHex("4335a5"),
OsuColour.FromHex("812a96"),
OsuColour.FromHex("992861"),
Color4Extensions.FromHex("677c66"),
Color4Extensions.FromHex("9b8732"),
Color4Extensions.FromHex("8c5129"),
Color4Extensions.FromHex("8c3030"),
Color4Extensions.FromHex("1f5d91"),
Color4Extensions.FromHex("4335a5"),
Color4Extensions.FromHex("812a96"),
Color4Extensions.FromHex("992861"),
};
}
}

View File

@ -41,10 +41,10 @@ namespace osu.Game.Overlays.Chat.Selection
{
RelativeSizeAxes = Axes.X;
Waves.FirstWaveColour = OsuColour.FromHex("353535");
Waves.SecondWaveColour = OsuColour.FromHex("434343");
Waves.ThirdWaveColour = OsuColour.FromHex("515151");
Waves.FourthWaveColour = OsuColour.FromHex("595959");
Waves.FirstWaveColour = Color4Extensions.FromHex("353535");
Waves.SecondWaveColour = Color4Extensions.FromHex("434343");
Waves.ThirdWaveColour = Color4Extensions.FromHex("515151");
Waves.FourthWaveColour = Color4Extensions.FromHex("595959");
Children = new Drawable[]
{
@ -154,7 +154,7 @@ namespace osu.Game.Overlays.Chat.Selection
{
bg.Colour = colours.Gray3;
triangles.ColourDark = colours.Gray3;
triangles.ColourLight = OsuColour.FromHex(@"353535");
triangles.ColourLight = Color4Extensions.FromHex(@"353535");
headerBg.Colour = colours.Gray2.Opacity(0.75f);
}

View File

@ -89,7 +89,7 @@ namespace osu.Game.Overlays.Chat.Tabs
{
var user = Value.Users.First();
BackgroundActive = user.Colour != null ? OsuColour.FromHex(user.Colour) : colours.BlueDark;
BackgroundActive = user.Colour != null ? Color4Extensions.FromHex(user.Colour) : colours.BlueDark;
BackgroundInactive = BackgroundActive.Darken(0.5f);
}
}

View File

@ -10,7 +10,6 @@ using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Containers;
using osuTK;
@ -114,13 +113,13 @@ namespace osu.Game.Overlays.Dialog
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex(@"221a21"),
Colour = Color4Extensions.FromHex(@"221a21"),
},
new Triangles
{
RelativeSizeAxes = Axes.Both,
ColourLight = OsuColour.FromHex(@"271e26"),
ColourDark = OsuColour.FromHex(@"1e171e"),
ColourLight = Color4Extensions.FromHex(@"271e26"),
ColourDark = Color4Extensions.FromHex(@"1e171e"),
TriangleScale = 4,
},
},

View File

@ -1,7 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Game.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Overlays.Dialog
@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Dialog
public PopupDialogButton()
{
Height = 50;
BackgroundColour = OsuColour.FromHex(@"150e14");
BackgroundColour = Color4Extensions.FromHex(@"150e14");
TextSize = 18;
}
}

View File

@ -3,6 +3,7 @@
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Game.Graphics;
using osu.Game.Online.API.Requests;
@ -16,7 +17,7 @@ namespace osu.Game.Overlays.Direct
{
private DirectRulesetSelector rulesetSelector;
protected override Color4 BackgroundColour => OsuColour.FromHex(@"384552");
protected override Color4 BackgroundColour => Color4Extensions.FromHex(@"384552");
protected override DirectSortCriteria DefaultTab => DirectSortCriteria.Ranked;
protected override BeatmapSearchCategory DefaultCategory => BeatmapSearchCategory.Leaderboard;

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.ComponentModel;
using osu.Framework.Extensions.Color4Extensions;
using osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
@ -13,7 +14,7 @@ namespace osu.Game.Overlays.Direct
{
public class Header : SearchableListHeader<DirectTab>
{
protected override Color4 BackgroundColour => OsuColour.FromHex(@"252f3a");
protected override Color4 BackgroundColour => Color4Extensions.FromHex(@"252f3a");
protected override DirectTab DefaultTab => DirectTab.Search;
protected override Drawable CreateHeaderText() => new OsuSpriteText { Text = @"osu!direct", Font = OsuFont.GetFont(size: 25) };

View File

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Humanizer;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Threading;
@ -34,9 +35,9 @@ namespace osu.Game.Overlays
private readonly OsuSpriteText resultCountsText;
private FillFlowContainer<DirectPanel> panels;
protected override Color4 BackgroundColour => OsuColour.FromHex(@"485e74");
protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"465b71");
protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"3f5265");
protected override Color4 BackgroundColour => Color4Extensions.FromHex(@"485e74");
protected override Color4 TrianglesColourLight => Color4Extensions.FromHex(@"465b71");
protected override Color4 TrianglesColourDark => Color4Extensions.FromHex(@"3f5265");
protected override SearchableListHeader<DirectTab> CreateHeader() => new Header();
protected override SearchableListFilterControl<DirectSortCriteria, BeatmapSearchCategory> CreateFilterControl() => new FilterControl();

View File

@ -0,0 +1,25 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
namespace osu.Game.Overlays.Home.Friends
{
public class FriendsBundle
{
public FriendsOnlineStatus Status { get; }
public int Count { get; }
public FriendsBundle(FriendsOnlineStatus status, int count)
{
Status = status;
Count = count;
}
}
public enum FriendsOnlineStatus
{
All,
Online,
Offline
}
}

View File

@ -0,0 +1,26 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq;
using osu.Game.Users;
namespace osu.Game.Overlays.Home.Friends
{
public class FriendsOnlineStatusControl : OverlayStreamControl<FriendsBundle>
{
protected override OverlayStreamItem<FriendsBundle> CreateStreamItem(FriendsBundle value) => new FriendsOnlineStatusItem(value);
public void Populate(List<User> users)
{
var userCount = users.Count;
var onlineUsersCount = users.Count(user => user.IsOnline);
AddItem(new FriendsBundle(FriendsOnlineStatus.All, userCount));
AddItem(new FriendsBundle(FriendsOnlineStatus.Online, onlineUsersCount));
AddItem(new FriendsBundle(FriendsOnlineStatus.Offline, userCount - onlineUsersCount));
Current.Value = Items.FirstOrDefault();
}
}
}

View File

@ -0,0 +1,39 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Game.Graphics;
using osuTK.Graphics;
namespace osu.Game.Overlays.Home.Friends
{
public class FriendsOnlineStatusItem : OverlayStreamItem<FriendsBundle>
{
public FriendsOnlineStatusItem(FriendsBundle value)
: base(value)
{
}
protected override string MainText => Value.Status.ToString();
protected override string AdditionalText => Value.Count.ToString();
protected override Color4 GetBarColour(OsuColour colours)
{
switch (Value.Status)
{
case FriendsOnlineStatus.All:
return Color4.White;
case FriendsOnlineStatus.Online:
return colours.GreenLight;
case FriendsOnlineStatus.Offline:
return Color4.Black;
default:
throw new ArgumentException($@"{Value.Status} status does not provide a colour in {nameof(GetBarColour)}.");
}
}
}
}

View File

@ -126,14 +126,14 @@ namespace osu.Game.Overlays
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex(@"05262f"),
Colour = Color4Extensions.FromHex(@"05262f"),
},
new Triangles
{
RelativeSizeAxes = Axes.Both,
TriangleScale = 2,
ColourDark = OsuColour.FromHex(@"04222b"),
ColourLight = OsuColour.FromHex(@"052933"),
ColourDark = Color4Extensions.FromHex(@"04222b"),
ColourLight = Color4Extensions.FromHex(@"052933"),
},
innerSpin = new Sprite
{

View File

@ -63,10 +63,10 @@ namespace osu.Game.Overlays.Mods
public ModSelectOverlay()
{
Waves.FirstWaveColour = OsuColour.FromHex(@"19b0e2");
Waves.SecondWaveColour = OsuColour.FromHex(@"2280a2");
Waves.ThirdWaveColour = OsuColour.FromHex(@"005774");
Waves.FourthWaveColour = OsuColour.FromHex(@"003a4e");
Waves.FirstWaveColour = Color4Extensions.FromHex(@"19b0e2");
Waves.SecondWaveColour = Color4Extensions.FromHex(@"2280a2");
Waves.ThirdWaveColour = Color4Extensions.FromHex(@"005774");
Waves.FourthWaveColour = Color4Extensions.FromHex(@"003a4e");
RelativeSizeAxes = Axes.Both;

View File

@ -3,42 +3,32 @@
using osu.Framework.Graphics;
using osu.Framework.Input.Events;
using osu.Game.Online.API.Requests.Responses;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics.UserInterface;
using JetBrains.Annotations;
namespace osu.Game.Overlays.Changelog
namespace osu.Game.Overlays
{
public class UpdateStreamBadgeArea : TabControl<APIUpdateStream>
public abstract class OverlayStreamControl<T> : TabControl<T>
{
public UpdateStreamBadgeArea()
protected OverlayStreamControl()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
}
public void Populate(List<APIUpdateStream> streams)
public void Populate(List<T> streams) => streams.ForEach(AddItem);
protected override Dropdown<T> CreateDropdown() => null;
protected override TabItem<T> CreateTabItem(T value) => CreateStreamItem(value).With(item =>
{
foreach (var updateStream in streams)
AddItem(updateStream);
}
item.SelectedItem.BindTo(Current);
});
protected override bool OnHover(HoverEvent e)
{
foreach (var streamBadge in TabContainer.Children.OfType<UpdateStreamBadge>())
streamBadge.UserHoveringArea = true;
return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
{
foreach (var streamBadge in TabContainer.Children.OfType<UpdateStreamBadge>())
streamBadge.UserHoveringArea = false;
base.OnHoverLost(e);
}
[NotNull]
protected abstract OverlayStreamItem<T> CreateStreamItem(T value);
protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer
{
@ -47,9 +37,20 @@ namespace osu.Game.Overlays.Changelog
AllowMultiline = true,
};
protected override Dropdown<APIUpdateStream> CreateDropdown() => null;
protected override bool OnHover(HoverEvent e)
{
foreach (var streamBadge in TabContainer.Children.OfType<OverlayStreamItem<T>>())
streamBadge.UserHoveringArea = true;
protected override TabItem<APIUpdateStream> CreateTabItem(APIUpdateStream value) =>
new UpdateStreamBadge(value) { SelectedTab = { BindTarget = Current } };
return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
{
foreach (var streamBadge in TabContainer.Children.OfType<OverlayStreamItem<T>>())
streamBadge.UserHoveringArea = false;
base.OnHoverLost(e);
}
}
}

View File

@ -1,46 +1,52 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using Humanizer;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Game.Graphics;
using osu.Game.Online.API.Requests.Responses;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.Sprites;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osuTK;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Allocation;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics;
using osuTK.Graphics;
namespace osu.Game.Overlays.Changelog
namespace osu.Game.Overlays
{
public class UpdateStreamBadge : TabItem<APIUpdateStream>
public abstract class OverlayStreamItem<T> : TabItem<T>
{
private const float badge_width = 100;
private const float transition_duration = 100;
public readonly Bindable<T> SelectedItem = new Bindable<T>();
public readonly Bindable<APIUpdateStream> SelectedTab = new Bindable<APIUpdateStream>();
private bool userHoveringArea;
private readonly APIUpdateStream stream;
public bool UserHoveringArea
{
set
{
if (value == userHoveringArea)
return;
userHoveringArea = value;
updateState();
}
}
private FillFlowContainer<SpriteText> text;
private ExpandingBar expandingBar;
public UpdateStreamBadge(APIUpdateStream stream)
: base(stream)
protected OverlayStreamItem(T value)
: base(value)
{
this.stream = stream;
Height = 60;
Width = 100;
Padding = new MarginPadding(5);
}
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
private void load(OverlayColourProvider colourProvider, OsuColour colours)
{
Size = new Vector2(stream.IsFeatured ? badge_width * 2 : badge_width, 60);
Padding = new MarginPadding(5);
AddRange(new Drawable[]
{
text = new FillFlowContainer<SpriteText>
@ -52,17 +58,17 @@ namespace osu.Game.Overlays.Changelog
{
new OsuSpriteText
{
Text = stream.DisplayName,
Text = MainText,
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black),
},
new OsuSpriteText
{
Text = stream.LatestBuild.DisplayVersion,
Text = AdditionalText,
Font = OsuFont.GetFont(size: 16, weight: FontWeight.Regular),
},
new OsuSpriteText
{
Text = stream.LatestBuild.Users > 0 ? $"{"user".ToQuantity(stream.LatestBuild.Users, "N0")} online" : null,
Text = InfoText,
Font = OsuFont.GetFont(size: 10),
Colour = colourProvider.Foreground1
},
@ -71,7 +77,7 @@ namespace osu.Game.Overlays.Changelog
expandingBar = new ExpandingBar
{
Anchor = Anchor.TopCentre,
Colour = stream.Colour,
Colour = GetBarColour(colours),
ExpandedSize = 4,
CollapsedSize = 2,
Expanded = true
@ -79,9 +85,17 @@ namespace osu.Game.Overlays.Changelog
new HoverClickSounds()
});
SelectedTab.BindValueChanged(_ => updateState(), true);
SelectedItem.BindValueChanged(_ => updateState(), true);
}
protected abstract string MainText { get; }
protected abstract string AdditionalText { get; }
protected virtual string InfoText => string.Empty;
protected abstract Color4 GetBarColour(OsuColour colours);
protected override void OnActivated() => updateState();
protected override void OnDeactivated() => updateState();
@ -104,7 +118,7 @@ namespace osu.Game.Overlays.Changelog
bool textHighlighted = IsHovered;
bool barExpanded = IsHovered;
if (SelectedTab.Value == null)
if (SelectedItem.Value == null)
{
// at listing, all badges are highlighted when user is not hovering any badge.
textHighlighted |= !userHoveringArea;
@ -120,21 +134,7 @@ namespace osu.Game.Overlays.Changelog
}
expandingBar.Expanded = barExpanded;
text.FadeTo(textHighlighted ? 1 : 0.5f, transition_duration, Easing.OutQuint);
}
private bool userHoveringArea;
public bool UserHoveringArea
{
set
{
if (value == userHoveringArea)
return;
userHoveringArea = value;
updateState();
}
text.FadeTo(textHighlighted ? 1 : 0.5f, 100, Easing.OutQuint);
}
}
}

View File

@ -3,6 +3,7 @@
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -170,7 +171,7 @@ namespace osu.Game.Overlays.Profile.Header
userCountryText.Text = user?.Country?.FullName ?? "Alien";
supporterTag.SupportLevel = user?.SupportLevel ?? 0;
titleText.Text = user?.Title ?? string.Empty;
titleText.Colour = OsuColour.FromHex(user?.Colour ?? "fff");
titleText.Colour = Color4Extensions.FromHex(user?.Colour ?? "fff");
userStats.Clear();

View File

@ -7,7 +7,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Profile.Header;
using osu.Game.Users;
@ -48,7 +47,7 @@ namespace osu.Game.Overlays.Profile
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientVertical(OsuColour.FromHex("222").Opacity(0.8f), OsuColour.FromHex("222").Opacity(0.2f))
Colour = ColourInfo.GradientVertical(Color4Extensions.FromHex("222").Opacity(0.8f), Color4Extensions.FromHex("222").Opacity(0.2f))
},
}
};

View File

@ -1,16 +1,16 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Extensions.Color4Extensions;
using osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Game.Graphics;
using osu.Game.Overlays.SearchableList;
namespace osu.Game.Overlays.Social
{
public class FilterControl : SearchableListFilterControl<SocialSortCriteria, SortDirection>
{
protected override Color4 BackgroundColour => OsuColour.FromHex(@"47253a");
protected override Color4 BackgroundColour => Color4Extensions.FromHex(@"47253a");
protected override SocialSortCriteria DefaultTab => SocialSortCriteria.Rank;
protected override SortDirection DefaultCategory => SortDirection.Ascending;

View File

@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Framework.Allocation;
using System.ComponentModel;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics.Sprites;
namespace osu.Game.Overlays.Social
@ -17,7 +18,7 @@ namespace osu.Game.Overlays.Social
{
private OsuSpriteText browser;
protected override Color4 BackgroundColour => OsuColour.FromHex(@"38202e");
protected override Color4 BackgroundColour => Color4Extensions.FromHex(@"38202e");
protected override SocialTab DefaultTab => SocialTab.AllPlayers;
protected override IconUsage Icon => FontAwesome.Solid.Users;

View File

@ -9,7 +9,6 @@ using osuTK;
using osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
@ -18,6 +17,7 @@ using osu.Game.Overlays.Social;
using osu.Game.Users;
using System.Threading;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Threading;
namespace osu.Game.Overlays
@ -27,9 +27,9 @@ namespace osu.Game.Overlays
private readonly LoadingSpinner loading;
private FillFlowContainer<SocialPanel> panels;
protected override Color4 BackgroundColour => OsuColour.FromHex(@"60284b");
protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"672b51");
protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"5c2648");
protected override Color4 BackgroundColour => Color4Extensions.FromHex(@"60284b");
protected override Color4 TrianglesColourLight => Color4Extensions.FromHex(@"672b51");
protected override Color4 TrianglesColourDark => Color4Extensions.FromHex(@"5c2648");
protected override SearchableListHeader<SocialTab> CreateHeader() => new Header();
protected override SearchableListFilterControl<SocialSortCriteria, SortDirection> CreateFilterControl() => new FilterControl();

View File

@ -14,22 +14,8 @@ namespace osu.Game.Overlays.Volume
public Func<GlobalAction, bool> ActionRequested;
public Func<GlobalAction, float, bool, bool> ScrollActionRequested;
public bool OnPressed(GlobalAction action)
{
// if nothing else handles selection actions in the game, it's safe to let volume be adjusted.
switch (action)
{
case GlobalAction.SelectPrevious:
action = GlobalAction.IncreaseVolume;
break;
case GlobalAction.SelectNext:
action = GlobalAction.DecreaseVolume;
break;
}
return ActionRequested?.Invoke(action) ?? false;
}
public bool OnPressed(GlobalAction action) =>
ActionRequested?.Invoke(action) ?? false;
public bool OnScroll(GlobalAction action, float amount, bool isPrecise) =>
ScrollActionRequested?.Invoke(action, amount, isPrecise) ?? false;

View File

@ -15,6 +15,8 @@ namespace osu.Game.Rulesets.Mods
public override IconUsage? Icon => OsuIcon.ModPerfect;
public override string Description => "SS or quit.";
protected override bool FailCondition(HealthProcessor healthProcessor, JudgementResult result) => result.Type != result.Judgement.MaxResult;
protected override bool FailCondition(HealthProcessor healthProcessor, JudgementResult result)
=> !(result.Judgement is IgnoreJudgement)
&& result.Type != result.Judgement.MaxResult;
}
}

View File

@ -3,6 +3,7 @@
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -26,7 +27,7 @@ namespace osu.Game.Screens.Edit.Components.Menus
MaskingContainer.CornerRadius = 0;
ItemsContainer.Padding = new MarginPadding { Left = 100 };
BackgroundColour = OsuColour.FromHex("111");
BackgroundColour = Color4Extensions.FromHex("111");
ScreenSelectionTabControl tabControl;
AddRangeInternal(new Drawable[]

View File

@ -2,11 +2,11 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
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.UserInterface;
using osuTK;
@ -31,7 +31,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex("111")
Colour = Color4Extensions.FromHex("111")
},
new GridContainer
{
@ -49,7 +49,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex("222")
Colour = Color4Extensions.FromHex("222")
},
new FillFlowContainer
{
@ -76,7 +76,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex("333")
Colour = Color4Extensions.FromHex("333")
},
new Container<TimelineButton>
{

View File

@ -9,6 +9,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Screens;
using osu.Framework.Utils;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Online.API;
@ -33,6 +34,7 @@ namespace osu.Game.Screens.Menu
private readonly OsuScreen nextScreen;
private readonly Bindable<User> currentUser = new Bindable<User>();
private FillFlowContainer fill;
public Disclaimer(OsuScreen nextScreen = null)
{
@ -49,16 +51,16 @@ namespace osu.Game.Screens.Menu
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.Solid.ExclamationTriangle,
Icon = FontAwesome.Solid.Poo,
Size = new Vector2(icon_size),
Y = icon_y,
},
new FillFlowContainer
fill = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Y = icon_y + icon_size,
Y = icon_y,
Anchor = Anchor.Centre,
Origin = Anchor.TopCentre,
Children = new Drawable[]
@ -71,6 +73,8 @@ namespace osu.Game.Screens.Menu
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Spacing = new Vector2(0, 2),
LayoutDuration = 2000,
LayoutEasing = Easing.OutQuint
},
supportFlow = new LinkFlowContainer
{
@ -86,23 +90,16 @@ namespace osu.Game.Screens.Menu
}
};
textFlow.AddText("This is an ", t => t.Font = t.Font.With(Typeface.Exo, 30, FontWeight.Light));
textFlow.AddText("early development build", t => t.Font = t.Font.With(Typeface.Exo, 30, FontWeight.SemiBold));
textFlow.AddText("This project is an ongoing ", t => t.Font = t.Font.With(Typeface.Exo, 30, FontWeight.Light));
textFlow.AddText("work in progress", t => t.Font = t.Font.With(Typeface.Exo, 30, FontWeight.SemiBold));
textFlow.AddParagraph("Things may not work as expected", t => t.Font = t.Font.With(size: 20));
textFlow.NewParagraph();
static void format(SpriteText t) => t.Font = OsuFont.GetFont(size: 15, weight: FontWeight.SemiBold);
textFlow.AddParagraph("Detailed bug reports are welcomed via github issues.", format);
textFlow.AddParagraph(getRandomTip(), t => t.Font = t.Font.With(Typeface.Exo, 20, FontWeight.SemiBold));
textFlow.NewParagraph();
textFlow.AddText("Visit ", format);
textFlow.AddLink("discord.gg/ppy", "https://discord.gg/ppy", creationParameters: format);
textFlow.AddText(" to help out or follow progress!", format);
textFlow.NewParagraph();
textFlow.NewParagraph();
textFlow.NewParagraph();
iconColour = colours.Yellow;
@ -114,7 +111,7 @@ namespace osu.Game.Screens.Menu
if (e.NewValue.IsSupporter)
{
supportFlow.AddText("Thank you for supporting osu!", format);
supportFlow.AddText("Eternal thanks to you for supporting osu!", format);
}
else
{
@ -125,7 +122,7 @@ namespace osu.Game.Screens.Menu
heart = supportFlow.AddIcon(FontAwesome.Solid.Heart, t =>
{
t.Padding = new MarginPadding { Left = 5 };
t.Padding = new MarginPadding { Left = 5, Top = 3 };
t.Font = t.Font.With(size: 12);
t.Origin = Anchor.Centre;
t.Colour = colours.Pink;
@ -139,11 +136,6 @@ namespace osu.Game.Screens.Menu
}, true);
}
private void animateHeart()
{
heart.FlashColour(Color4.White, 750, Easing.OutQuint).Loop();
}
protected override void LoadComplete()
{
base.LoadComplete();
@ -155,15 +147,28 @@ namespace osu.Game.Screens.Menu
{
base.OnEntering(last);
icon.Delay(1000).FadeColour(iconColour, 200, Easing.OutQuint);
icon.Delay(1000)
.MoveToY(icon_y * 1.1f, 160, Easing.OutCirc)
.RotateTo(-10, 160, Easing.OutCirc)
.Then()
.MoveToY(icon_y, 160, Easing.InCirc)
.RotateTo(0, 160, Easing.InCirc);
icon.RotateTo(10);
icon.FadeOut();
icon.ScaleTo(0.5f);
icon.Delay(500).FadeIn(500).ScaleTo(1, 500, Easing.OutQuint);
using (BeginDelayedSequence(3000, true))
{
icon.FadeColour(iconColour, 200, Easing.OutQuint);
icon.MoveToY(icon_y * 1.3f, 500, Easing.OutCirc)
.RotateTo(-360, 520, Easing.OutQuint)
.Then()
.MoveToY(icon_y, 160, Easing.InQuart)
.FadeColour(Color4.White, 160);
fill.Delay(520 + 160).MoveToOffset(new Vector2(0, 15), 160, Easing.OutQuart);
}
supportFlow.FadeOut().Delay(2000).FadeIn(500);
double delay = 500;
foreach (var c in textFlow.Children)
c.FadeTo(0.001f).Delay(delay += 20).FadeIn(500);
animateHeart();
@ -178,5 +183,35 @@ namespace osu.Game.Screens.Menu
this.Push(nextScreen);
});
}
private string getRandomTip()
{
string[] tips =
{
"You can press Ctrl-T anywhere in the game to toggle the toolbar!",
"You can press Ctrl-O anywhere in the game to access options!",
"All settings are dynamic and take effect in real-time. Try changing the skin while playing!",
"New features are coming online every update. Make sure to stay up-to-date!",
"If you find the UI too large or small, try adjusting UI scale in settings!",
"Try adjusting the \"Screen Scaling\" mode to change your gameplay or UI area, even in fullscreen!",
"For now, osu!direct is available to all users on lazer. You can access it anywhere using Ctrl-D!",
"Seeking in replays is available by dragging on the difficulty bar at the bottom of the screen!",
"Multithreading support means that even with low \"FPS\" your input and judgements will be accurate!",
"Try scrolling down in the mod select panel to find a bunch of new fun mods!",
"Most of the web content (profiles, rankings, etc.) are available natively in-game from the icons on the toolbar!",
"Get more details, hide or delete a beatmap by right-clicking on its panel at song select!",
"All delete operations are temporary until exiting. Restore accidentally deleted content from the maintenance settings!",
"Check out the \"timeshift\" multiplayer system, which has local permanent leaderboards and playlist support!",
"Toggle advanced frame / thread statistics with Ctrl-F11!",
"Take a look under the hood at performance counters and enable verbose performance logging with Ctrl-F2!",
};
return tips[RNG.Next(0, tips.Length)];
}
private void animateHeart()
{
heart.FlashColour(Color4.White, 750, Easing.OutQuint).Loop();
}
}
}

View File

@ -94,7 +94,7 @@ namespace osu.Game.Screens.Menu
},
}
},
bigRing = new Ring(OsuColour.FromHex(@"B6C5E9"), 0.85f),
bigRing = new Ring(Color4Extensions.FromHex(@"B6C5E9"), 0.85f),
mediumRing = new Ring(Color4.White.Opacity(130), 0.7f),
smallRing = new Ring(Color4.White, 0.6f),
welcomeText = new OsuSpriteText
@ -121,7 +121,7 @@ namespace osu.Game.Screens.Menu
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Height = 0,
Colour = OsuColour.FromHex(@"C6D8FF").Opacity(160),
Colour = Color4Extensions.FromHex(@"C6D8FF").Opacity(160),
},
foregroundFill = new Box
{
@ -139,28 +139,28 @@ namespace osu.Game.Screens.Menu
Anchor = Anchor.Centre,
Origin = Anchor.TopCentre,
Position = new Vector2(0, circle_offset),
Colour = OsuColour.FromHex(@"AA92FF"),
Colour = Color4Extensions.FromHex(@"AA92FF"),
},
blueCircle = new Circle
{
Anchor = Anchor.Centre,
Origin = Anchor.CentreRight,
Position = new Vector2(-circle_offset, 0),
Colour = OsuColour.FromHex(@"8FE5FE"),
Colour = Color4Extensions.FromHex(@"8FE5FE"),
},
yellowCircle = new Circle
{
Anchor = Anchor.Centre,
Origin = Anchor.BottomCentre,
Position = new Vector2(0, -circle_offset),
Colour = OsuColour.FromHex(@"FFD64C"),
Colour = Color4Extensions.FromHex(@"FFD64C"),
},
pinkCircle = new Circle
{
Anchor = Anchor.Centre,
Origin = Anchor.CentreLeft,
Position = new Vector2(circle_offset, 0),
Colour = OsuColour.FromHex(@"e967a1"),
Colour = Color4Extensions.FromHex(@"e967a1"),
},
};

View File

@ -259,11 +259,18 @@ namespace osu.Game.Screens.Menu
private class LazerLogo : CompositeDrawable
{
private readonly Stream videoStream;
public LazerLogo(Stream videoStream)
{
this.videoStream = videoStream;
Size = new Vector2(960);
}
InternalChild = new VideoSprite(videoStream)
[BackgroundDependencyLoader]
private void load()
{
InternalChild = new VideoSprite(videoStream, false)
{
RelativeSizeAxes = Axes.Both,
Clock = new FramedOffsetClock(Clock) { Offset = -logo_1 }

View File

@ -6,6 +6,7 @@ using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -14,7 +15,6 @@ using osu.Framework.Graphics.Textures;
using osu.Framework.Input.Events;
using osu.Framework.Utils;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Containers;
using osuTK;
@ -28,7 +28,7 @@ namespace osu.Game.Screens.Menu
/// </summary>
public class OsuLogo : BeatSyncedContainer
{
public readonly Color4 OsuPink = OsuColour.FromHex(@"e967a1");
public readonly Color4 OsuPink = Color4Extensions.FromHex(@"e967a1");
private const double transition_length = 300;
@ -176,8 +176,8 @@ namespace osu.Game.Screens.Menu
triangles = new Triangles
{
TriangleScale = 4,
ColourLight = OsuColour.FromHex(@"ff7db7"),
ColourDark = OsuColour.FromHex(@"de5b95"),
ColourLight = Color4Extensions.FromHex(@"ff7db7"),
ColourDark = Color4Extensions.FromHex(@"de5b95"),
RelativeSizeAxes = Axes.Both,
},
}

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
@ -27,7 +28,7 @@ namespace osu.Game.Screens.Multi.Components
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex(@"545454"),
Colour = Color4Extensions.FromHex(@"545454"),
},
};
}

View File

@ -2,12 +2,12 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Threading;
using osu.Game.Graphics;
using osu.Game.Users;
using osu.Game.Users.Drawables;
using osuTK;
@ -114,7 +114,7 @@ namespace osu.Game.Screens.Multi.Components
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex(@"27252d"),
Colour = Color4Extensions.FromHex(@"27252d"),
},
avatar = new UpdateableAvatar { RelativeSizeAxes = Axes.Both },
};

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -30,7 +31,7 @@ namespace osu.Game.Screens.Multi
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex(@"2f2043"),
Colour = Color4Extensions.FromHex(@"2f2043"),
},
new Container
{

View File

@ -134,7 +134,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex(@"212121"),
Colour = Color4Extensions.FromHex(@"212121"),
},
new StatusColouredContainer(transition_duration)
{

Some files were not shown because too many files have changed in this diff Show More