Compare commits
247 Commits
2020.306.0
...
2020.312.0
@@ -52,6 +52,6 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.304.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.305.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.312.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 130 KiB |
@@ -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),
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(CatcherArea),
|
||||
typeof(CatcherSprite)
|
||||
};
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
|
||||
@@ -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;
|
||||
@@ -10,9 +8,15 @@ using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Catch.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Judgements;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Catch.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Catch.UI;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Tests.Visual;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Tests
|
||||
@@ -22,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);
|
||||
@@ -34,9 +33,41 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
CreatedDrawables.OfType<CatchInputManager>().Select(i => i.Child)
|
||||
.OfType<TestCatcherArea>().ForEach(c => c.ToggleHyperDash(t)));
|
||||
|
||||
AddRepeatStep("catch fruit", () =>
|
||||
this.ChildrenOfType<CatcherArea>().ForEach(area =>
|
||||
area.MovableCatcher.PlaceOnPlate(new DrawableFruit(new TestSceneFruitObjects.TestCatchFruit(FruitVisualRepresentation.Grape)))), 20);
|
||||
AddRepeatStep("catch fruit", () => catchFruit(new TestFruit(false)
|
||||
{
|
||||
X = this.ChildrenOfType<CatcherArea>().First().MovableCatcher.X
|
||||
}), 20);
|
||||
AddRepeatStep("catch fruit last in combo", () => catchFruit(new TestFruit(false)
|
||||
{
|
||||
X = this.ChildrenOfType<CatcherArea>().First().MovableCatcher.X,
|
||||
LastInCombo = true,
|
||||
}), 20);
|
||||
AddRepeatStep("catch kiai fruit", () => catchFruit(new TestFruit(true)
|
||||
{
|
||||
X = this.ChildrenOfType<CatcherArea>().First().MovableCatcher.X,
|
||||
}), 20);
|
||||
AddRepeatStep("miss fruit", () => catchFruit(new Fruit
|
||||
{
|
||||
X = this.ChildrenOfType<CatcherArea>().First().MovableCatcher.X + 100,
|
||||
LastInCombo = true,
|
||||
}, true), 20);
|
||||
}
|
||||
|
||||
private void catchFruit(Fruit fruit, bool miss = false)
|
||||
{
|
||||
this.ChildrenOfType<CatcherArea>().ForEach(area =>
|
||||
{
|
||||
DrawableFruit drawable = new DrawableFruit(fruit);
|
||||
area.Add(drawable);
|
||||
|
||||
Schedule(() =>
|
||||
{
|
||||
area.AttemptCatch(fruit);
|
||||
area.OnResult(drawable, new JudgementResult(fruit, new CatchJudgement()) { Type = miss ? HitResult.Miss : HitResult.Great });
|
||||
|
||||
drawable.Expire();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void createCatcher(float size)
|
||||
@@ -47,7 +78,8 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
Child = new TestCatcherArea(new BeatmapDifficulty { CircleSize = size })
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.TopLeft
|
||||
Origin = Anchor.TopLeft,
|
||||
CreateDrawableRepresentation = ((DrawableRuleset<CatchHitObject>)catchRuleset.CreateInstance().CreateDrawableRulesetWith(new CatchBeatmap())).CreateDrawableRepresentation
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -58,6 +90,17 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
catchRuleset = rulesets.GetRuleset(2);
|
||||
}
|
||||
|
||||
public class TestFruit : Fruit
|
||||
{
|
||||
public TestFruit(bool kiai)
|
||||
{
|
||||
var kiaiCpi = new ControlPointInfo();
|
||||
kiaiCpi.Add(0, new EffectControlPoint { KiaiMode = kiai });
|
||||
|
||||
ApplyDefaultsToSelf(kiaiCpi, new BeatmapDifficulty());
|
||||
}
|
||||
}
|
||||
|
||||
private class TestCatcherArea : CatcherArea
|
||||
{
|
||||
public TestCatcherArea(BeatmapDifficulty beatmapDifficulty)
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -1,16 +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 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())
|
||||
{
|
||||
@@ -22,8 +34,19 @@ 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 right movement", () => getCatcher().Scale.X > 0); // don't check hyperdashing as it happens too fast.
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private CatcherArea.Catcher getCatcher() => Player.ChildrenOfType<CatcherArea>().First().MovableCatcher;
|
||||
|
||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||
{
|
||||
var beatmap = new Beatmap
|
||||
@@ -35,17 +58,52 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
}
|
||||
};
|
||||
|
||||
// Should produce a hyper-dash
|
||||
beatmap.HitObjects.Add(new Fruit { StartTime = 816, X = 308 / 512f, NewCombo = true });
|
||||
beatmap.HitObjects.Add(new Fruit { StartTime = 1008, X = 56 / 512f, });
|
||||
// Should produce a hyper-dash (edge case test)
|
||||
beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 56 / 512f, NewCombo = true });
|
||||
beatmap.HitObjects.Add(new Fruit { StartTime = 2008, X = 308 / 512f, NewCombo = true });
|
||||
|
||||
for (int i = 0; i < 512; i++)
|
||||
{
|
||||
if (i % 5 < 3)
|
||||
beatmap.HitObjects.Add(new Fruit { X = i % 10 < 5 ? 0.02f : 0.98f, StartTime = 2000 + i * 100, NewCombo = i % 8 == 0 });
|
||||
}
|
||||
double startTime = 3000;
|
||||
|
||||
const float left_x = 0.02f;
|
||||
const float right_x = 0.98f;
|
||||
|
||||
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, int count = 3)
|
||||
{
|
||||
const float spacing = 140;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var hitObject = createObject();
|
||||
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)),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -10,6 +10,9 @@ namespace osu.Game.Rulesets.Catch
|
||||
FruitGrapes,
|
||||
FruitOrange,
|
||||
FruitPear,
|
||||
Droplet
|
||||
Droplet,
|
||||
CatcherIdle,
|
||||
CatcherFail,
|
||||
CatcherKiai
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -44,6 +44,18 @@ namespace osu.Game.Rulesets.Catch.Skinning
|
||||
return new LegacyFruitPiece("fruit-drop") { Scale = new Vector2(0.8f) };
|
||||
|
||||
break;
|
||||
|
||||
case CatchSkinComponents.CatcherIdle:
|
||||
return this.GetAnimation("fruit-catcher-idle", true, true, true) ??
|
||||
this.GetAnimation("fruit-ryuuta", true, true, true);
|
||||
|
||||
case CatchSkinComponents.CatcherFail:
|
||||
return this.GetAnimation("fruit-catcher-fail", true, true, true) ??
|
||||
this.GetAnimation("fruit-ryuuta", true, true, true);
|
||||
|
||||
case CatchSkinComponents.CatcherKiai:
|
||||
return this.GetAnimation("fruit-catcher-kiai", true, true, true) ??
|
||||
this.GetAnimation("fruit-ryuuta", true, true, true);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -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.
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.UI
|
||||
{
|
||||
public enum CatcherAnimationState
|
||||
{
|
||||
Idle,
|
||||
Fail,
|
||||
Kiai
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Animations;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Input.Bindings;
|
||||
@@ -148,15 +149,62 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Children = new[]
|
||||
Children = new Drawable[]
|
||||
{
|
||||
caughtFruit = new Container<DrawableHitObject>
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
},
|
||||
createCatcherSprite(),
|
||||
catcherIdle = new CatcherSprite(CatcherAnimationState.Idle)
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Alpha = 0,
|
||||
},
|
||||
catcherKiai = new CatcherSprite(CatcherAnimationState.Kiai)
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Alpha = 0,
|
||||
},
|
||||
catcherFail = new CatcherSprite(CatcherAnimationState.Fail)
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Alpha = 0,
|
||||
}
|
||||
};
|
||||
|
||||
updateCatcher();
|
||||
}
|
||||
|
||||
private CatcherSprite catcherIdle;
|
||||
private CatcherSprite catcherKiai;
|
||||
private CatcherSprite catcherFail;
|
||||
|
||||
private void updateCatcher()
|
||||
{
|
||||
catcherIdle.Hide();
|
||||
catcherKiai.Hide();
|
||||
catcherFail.Hide();
|
||||
|
||||
CatcherSprite current;
|
||||
|
||||
switch (CurrentState)
|
||||
{
|
||||
default:
|
||||
current = catcherIdle;
|
||||
break;
|
||||
|
||||
case CatcherAnimationState.Fail:
|
||||
current = catcherFail;
|
||||
break;
|
||||
|
||||
case CatcherAnimationState.Kiai:
|
||||
current = catcherKiai;
|
||||
break;
|
||||
}
|
||||
|
||||
current.Show();
|
||||
(current.Drawable as IAnimation)?.GotoFrame(0);
|
||||
}
|
||||
|
||||
private int currentDirection;
|
||||
@@ -202,17 +250,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
if (!Trail) return;
|
||||
|
||||
var additive = createCatcherSprite();
|
||||
|
||||
additive.Anchor = Anchor;
|
||||
additive.OriginPosition += new Vector2(DrawWidth / 2, 0); // also temporary to align sprite correctly.
|
||||
additive.Position = Position;
|
||||
additive.Scale = Scale;
|
||||
additive.Colour = HyperDashing ? Color4.Red : Color4.White;
|
||||
additive.RelativePositionAxes = RelativePositionAxes;
|
||||
additive.Blending = BlendingParameters.Additive;
|
||||
|
||||
AdditiveTarget.Add(additive);
|
||||
var additive = createAdditiveSprite(HyperDashing);
|
||||
|
||||
additive.FadeTo(0.4f).FadeOut(800, Easing.OutQuint);
|
||||
additive.Expire(true);
|
||||
@@ -220,7 +258,23 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
Scheduler.AddDelayed(beginTrail, HyperDashing ? 25 : 50);
|
||||
}
|
||||
|
||||
private Drawable createCatcherSprite() => new CatcherSprite();
|
||||
private Drawable createAdditiveSprite(bool hyperDash)
|
||||
{
|
||||
var additive = createCatcherSprite();
|
||||
|
||||
additive.Anchor = Anchor;
|
||||
additive.Scale = Scale;
|
||||
additive.Colour = hyperDash ? Color4.Red : Color4.White;
|
||||
additive.Blending = BlendingParameters.Additive;
|
||||
additive.RelativePositionAxes = RelativePositionAxes;
|
||||
additive.Position = Position;
|
||||
|
||||
AdditiveTarget.Add(additive);
|
||||
|
||||
return additive;
|
||||
}
|
||||
|
||||
private Drawable createCatcherSprite() => new CatcherSprite(CurrentState);
|
||||
|
||||
/// <summary>
|
||||
/// Add a caught fruit to the catcher's stack.
|
||||
@@ -270,6 +324,10 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
catchObjectPosition >= catcherPosition - halfCatchWidth &&
|
||||
catchObjectPosition <= catcherPosition + halfCatchWidth;
|
||||
|
||||
// only update hyperdash state if we are catching a fruit.
|
||||
// exceptions are Droplets and JuiceStreams.
|
||||
if (!(fruit is Fruit)) return validCatch;
|
||||
|
||||
if (validCatch && fruit.HyperDash)
|
||||
{
|
||||
var target = fruit.HyperDashTarget;
|
||||
@@ -284,9 +342,25 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
SetHyperDashState();
|
||||
}
|
||||
|
||||
if (validCatch)
|
||||
updateState(fruit.Kiai ? CatcherAnimationState.Kiai : CatcherAnimationState.Idle);
|
||||
else if (!(fruit is Banana))
|
||||
updateState(CatcherAnimationState.Fail);
|
||||
|
||||
return validCatch;
|
||||
}
|
||||
|
||||
private void updateState(CatcherAnimationState state)
|
||||
{
|
||||
if (CurrentState == state)
|
||||
return;
|
||||
|
||||
CurrentState = state;
|
||||
updateCatcher();
|
||||
}
|
||||
|
||||
public CatcherAnimationState CurrentState { get; private set; }
|
||||
|
||||
private double hyperDashModifier = 1;
|
||||
private int hyperDashDirection;
|
||||
private float hyperDashTargetPosition;
|
||||
@@ -305,14 +379,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);
|
||||
@@ -325,11 +399,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,31 +3,57 @@
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.UI
|
||||
{
|
||||
public class CatcherSprite : CompositeDrawable
|
||||
public class CatcherSprite : SkinnableDrawable
|
||||
{
|
||||
public CatcherSprite()
|
||||
protected override bool ApplySizeRestrictionsToDefault => true;
|
||||
|
||||
public CatcherSprite(CatcherAnimationState state)
|
||||
: base(new CatchSkinComponent(componentFromState(state)), _ =>
|
||||
new DefaultCatcherSprite(state), confineMode: ConfineMode.ScaleDownToFit)
|
||||
{
|
||||
RelativeSizeAxes = Axes.None;
|
||||
Size = new Vector2(CatcherArea.CATCHER_SIZE);
|
||||
|
||||
// Sets the origin roughly to the centre of the catcher's plate to allow for correct scaling.
|
||||
OriginPosition = new Vector2(-0.02f, 0.06f) * CatcherArea.CATCHER_SIZE;
|
||||
OriginPosition = new Vector2(0.5f, 0.06f) * CatcherArea.CATCHER_SIZE;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
private static CatchSkinComponents componentFromState(CatcherAnimationState state)
|
||||
{
|
||||
InternalChild = new SkinnableSprite("Gameplay/catch/fruit-catcher-idle", confineMode: ConfineMode.ScaleDownToFit)
|
||||
switch (state)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
};
|
||||
case CatcherAnimationState.Fail:
|
||||
return CatchSkinComponents.CatcherFail;
|
||||
|
||||
case CatcherAnimationState.Kiai:
|
||||
return CatchSkinComponents.CatcherKiai;
|
||||
|
||||
default:
|
||||
return CatchSkinComponents.CatcherIdle;
|
||||
}
|
||||
}
|
||||
|
||||
private class DefaultCatcherSprite : Sprite
|
||||
{
|
||||
private readonly CatcherAnimationState state;
|
||||
|
||||
public DefaultCatcherSprite(CatcherAnimationState state)
|
||||
{
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
Texture = textures.Get($"Gameplay/catch/fruit-catcher-{state.ToString().ToLower()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// 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.Framework.Utils;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Tests.Visual;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests.Mods
|
||||
{
|
||||
public class TestSceneOsuModDoubleTime : ModTestScene
|
||||
{
|
||||
public TestSceneOsuModDoubleTime()
|
||||
: base(new OsuRuleset())
|
||||
{
|
||||
}
|
||||
|
||||
[TestCase(0.5)]
|
||||
[TestCase(1.01)]
|
||||
[TestCase(1.5)]
|
||||
[TestCase(2)]
|
||||
[TestCase(5)]
|
||||
public void TestSpeedChangeCustomisation(double rate)
|
||||
{
|
||||
var mod = new OsuModDoubleTime { SpeedChange = { Value = rate } };
|
||||
|
||||
CreateModTest(new ModTestData
|
||||
{
|
||||
Mod = mod,
|
||||
PassCondition = () => Player.ScoreProcessor.JudgedHits >= 2 &&
|
||||
Precision.AlmostEquals(Player.GameplayClockContainer.GameplayClock.Rate, mod.SpeedChange.Value)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests
|
||||
{
|
||||
public class TestSceneHitCircleArea : ManualInputManagerTestScene
|
||||
{
|
||||
private HitCircle hitCircle;
|
||||
private DrawableHitCircle drawableHitCircle;
|
||||
private DrawableHitCircle.HitReceptor hitAreaReceptor => drawableHitCircle.HitArea;
|
||||
|
||||
[SetUp]
|
||||
public new void SetUp()
|
||||
{
|
||||
base.SetUp();
|
||||
|
||||
Schedule(() =>
|
||||
{
|
||||
hitCircle = new HitCircle
|
||||
{
|
||||
Position = new Vector2(100, 100),
|
||||
StartTime = Time.Current + 500
|
||||
};
|
||||
|
||||
hitCircle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||
|
||||
Child = new SkinProvidingContainer(new DefaultSkin())
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = drawableHitCircle = new DrawableHitCircle(hitCircle)
|
||||
{
|
||||
Size = new Vector2(100)
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCircleHitCentre()
|
||||
{
|
||||
AddStep("move mouse to centre", () => InputManager.MoveMouseTo(hitAreaReceptor.ScreenSpaceDrawQuad.Centre));
|
||||
scheduleHit();
|
||||
|
||||
AddAssert("hit registered", () => hitAreaReceptor.HitAction == OsuAction.LeftButton);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCircleHitLeftEdge()
|
||||
{
|
||||
AddStep("move mouse to left edge", () =>
|
||||
{
|
||||
var drawQuad = hitAreaReceptor.ScreenSpaceDrawQuad;
|
||||
var mousePosition = new Vector2(drawQuad.TopLeft.X, drawQuad.Centre.Y);
|
||||
|
||||
InputManager.MoveMouseTo(mousePosition);
|
||||
});
|
||||
scheduleHit();
|
||||
|
||||
AddAssert("hit registered", () => hitAreaReceptor.HitAction == OsuAction.LeftButton);
|
||||
}
|
||||
|
||||
[TestCase(0.95f, OsuAction.LeftButton)]
|
||||
[TestCase(1.05f, null)]
|
||||
public void TestHitsCloseToEdge(float relativeDistanceFromCentre, OsuAction? expectedAction)
|
||||
{
|
||||
AddStep("move mouse to top left circle edge", () =>
|
||||
{
|
||||
var drawQuad = hitAreaReceptor.ScreenSpaceDrawQuad;
|
||||
// sqrt(2) / 2 = sin(45deg) = cos(45deg)
|
||||
// draw width halved to get radius
|
||||
float correction = relativeDistanceFromCentre * (float)Math.Sqrt(2) / 2 * (drawQuad.Width / 2);
|
||||
var mousePosition = new Vector2(drawQuad.Centre.X - correction, drawQuad.Centre.Y - correction);
|
||||
|
||||
InputManager.MoveMouseTo(mousePosition);
|
||||
});
|
||||
scheduleHit();
|
||||
|
||||
AddAssert($"hit {(expectedAction == null ? "not " : string.Empty)}registered", () => hitAreaReceptor.HitAction == expectedAction);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCircleMissBoundingBoxCorner()
|
||||
{
|
||||
AddStep("move mouse to top left corner of bounding box", () => InputManager.MoveMouseTo(hitAreaReceptor.ScreenSpaceDrawQuad.TopLeft));
|
||||
scheduleHit();
|
||||
|
||||
AddAssert("hit not registered", () => hitAreaReceptor.HitAction == null);
|
||||
}
|
||||
|
||||
private void scheduleHit() => AddStep("schedule action", () =>
|
||||
{
|
||||
var delay = hitCircle.StartTime - hitCircle.HitWindows.WindowFor(HitResult.Great) - Time.Current;
|
||||
Scheduler.AddDelayed(() => hitAreaReceptor.OnPressed(OsuAction.LeftButton), delay);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,7 +170,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
||||
public Drawable ProxiedLayer => ApproachCircle;
|
||||
|
||||
public class HitReceptor : Drawable, IKeyBindingHandler<OsuAction>
|
||||
public class HitReceptor : CompositeDrawable, IKeyBindingHandler<OsuAction>
|
||||
{
|
||||
// IsHovered is used
|
||||
public override bool HandlePositionalInput => true;
|
||||
@@ -185,6 +185,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
CornerRadius = OsuHitObject.OBJECT_RADIUS;
|
||||
CornerExponent = 2;
|
||||
}
|
||||
|
||||
public bool OnPressed(OsuAction action)
|
||||
|
||||
@@ -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>();
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[Variables]
|
||||
$var=1234
|
||||
$var=34
|
||||
|
||||
[Events]
|
||||
Sprite,Background,TopCentre,"img.jpg",$var56,240
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
using osuTK;
|
||||
@@ -45,32 +42,12 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
};
|
||||
Add(accuracyCounter);
|
||||
|
||||
StarCounter stars = new StarCounter
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Position = new Vector2(20, -160),
|
||||
CountStars = 5,
|
||||
};
|
||||
Add(stars);
|
||||
|
||||
SpriteText starsLabel = new OsuSpriteText
|
||||
{
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Position = new Vector2(20, -190),
|
||||
Text = stars.CountStars.ToString("0.00"),
|
||||
};
|
||||
Add(starsLabel);
|
||||
|
||||
AddStep(@"Reset all", delegate
|
||||
{
|
||||
score.Current.Value = 0;
|
||||
comboCounter.Current.Value = 0;
|
||||
numerator = denominator = 0;
|
||||
accuracyCounter.SetFraction(0, 0);
|
||||
stars.CountStars = 0;
|
||||
starsLabel.Text = stars.CountStars.ToString("0.00");
|
||||
});
|
||||
|
||||
AddStep(@"Hit! :D", delegate
|
||||
@@ -88,20 +65,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
denominator++;
|
||||
accuracyCounter.SetFraction(numerator, denominator);
|
||||
});
|
||||
|
||||
AddStep(@"Alter stars", delegate
|
||||
{
|
||||
stars.CountStars = RNG.NextSingle() * (stars.StarCount + 1);
|
||||
starsLabel.Text = stars.CountStars.ToString("0.00");
|
||||
});
|
||||
|
||||
AddStep(@"Stop counters", delegate
|
||||
{
|
||||
score.StopRolling();
|
||||
comboCounter.StopRolling();
|
||||
accuracyCounter.StopRolling();
|
||||
stars.StopAnimation();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// 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.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneStarCounter : OsuTestScene
|
||||
{
|
||||
public TestSceneStarCounter()
|
||||
{
|
||||
StarCounter stars = new StarCounter
|
||||
{
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
||||
Current = 5,
|
||||
};
|
||||
|
||||
Add(stars);
|
||||
|
||||
SpriteText starsLabel = new OsuSpriteText
|
||||
{
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
||||
Scale = new Vector2(2),
|
||||
Y = 50,
|
||||
Text = stars.Current.ToString("0.00"),
|
||||
};
|
||||
|
||||
Add(starsLabel);
|
||||
|
||||
AddRepeatStep(@"random value", delegate
|
||||
{
|
||||
stars.Current = RNG.NextSingle() * (stars.StarCount + 1);
|
||||
starsLabel.Text = stars.Current.ToString("0.00");
|
||||
}, 10);
|
||||
|
||||
AddStep(@"Stop animation", delegate
|
||||
{
|
||||
stars.StopAnimation();
|
||||
});
|
||||
|
||||
AddStep(@"Reset", delegate
|
||||
{
|
||||
stars.Current = 0;
|
||||
starsLabel.Text = stars.Current.ToString("0.00");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
// 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.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Tests.Visual;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osu.Game.Tournament.Screens.Drawings.Components;
|
||||
using osu.Game.Tournament.Screens.Gameplay.Components;
|
||||
using osu.Game.Tournament.Screens.Ladder.Components;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Components
|
||||
{
|
||||
public class TestSceneDrawableTournamentTeam : OsuGridTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(DrawableTeamFlag),
|
||||
typeof(DrawableTeamTitle),
|
||||
typeof(DrawableTeamTitleWithHeader),
|
||||
typeof(DrawableMatchTeam),
|
||||
typeof(DrawableTeamWithPlayers),
|
||||
typeof(GroupTeam),
|
||||
typeof(TeamDisplay),
|
||||
};
|
||||
|
||||
public TestSceneDrawableTournamentTeam()
|
||||
: base(4, 3)
|
||||
{
|
||||
var team = new TournamentTeam
|
||||
{
|
||||
FlagName = { Value = "AU" },
|
||||
FullName = { Value = "Australia" },
|
||||
Players =
|
||||
{
|
||||
new User { Username = "ASecretBox" },
|
||||
new User { Username = "Dereban" },
|
||||
new User { Username = "mReKk" },
|
||||
new User { Username = "uyghti" },
|
||||
new User { Username = "Parkes" },
|
||||
new User { Username = "Shiroha" },
|
||||
new User { Username = "Jordan The Bear" },
|
||||
}
|
||||
};
|
||||
|
||||
var match = new TournamentMatch { Team1 = { Value = team } };
|
||||
|
||||
int i = 0;
|
||||
|
||||
Cell(i++).AddRange(new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText { Text = "DrawableTeamFlag" },
|
||||
new DrawableTeamFlag(team)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
}
|
||||
});
|
||||
|
||||
Cell(i++).AddRange(new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText { Text = "DrawableTeamTitle" },
|
||||
new DrawableTeamTitle(team)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
}
|
||||
});
|
||||
|
||||
Cell(i++).AddRange(new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText { Text = "DrawableTeamTitleWithHeader" },
|
||||
new DrawableTeamTitleWithHeader(team, TeamColour.Red)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
}
|
||||
});
|
||||
|
||||
Cell(i++).AddRange(new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText { Text = "DrawableMatchTeam" },
|
||||
new DrawableMatchTeam(team, match, false)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
}
|
||||
});
|
||||
|
||||
Cell(i++).AddRange(new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText { Text = "TeamWithPlayers" },
|
||||
new DrawableTeamWithPlayers(team, TeamColour.Blue)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
}
|
||||
});
|
||||
|
||||
Cell(i++).AddRange(new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText { Text = "GroupTeam" },
|
||||
new GroupTeam(team)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
}
|
||||
});
|
||||
|
||||
Cell(i).AddRange(new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText { Text = "TeamDisplay" },
|
||||
new TeamDisplay(team, TeamColour.Red, new Bindable<int?>(2), 6)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 },
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,31 @@
|
||||
// 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.Allocation;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Screens;
|
||||
using osu.Game.Tournament.Screens.Gameplay;
|
||||
using osu.Game.Tournament.Screens.Gameplay.Components;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Screens
|
||||
{
|
||||
public class TestSceneGameplayScreen : TournamentTestScene
|
||||
{
|
||||
[Cached]
|
||||
private TournamentMatchChatDisplay chat = new TournamentMatchChatDisplay();
|
||||
private TournamentMatchChatDisplay chat = new TournamentMatchChatDisplay { Width = 0.5f };
|
||||
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(TeamScore),
|
||||
typeof(TeamScoreDisplay),
|
||||
typeof(TeamDisplay),
|
||||
typeof(MatchHeader),
|
||||
typeof(MatchScoreDisplay),
|
||||
typeof(BeatmapInfoScreen),
|
||||
typeof(SongBar),
|
||||
};
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Screens.Schedule;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Screens
|
||||
@@ -11,6 +13,7 @@ namespace osu.Game.Tournament.Tests.Screens
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Add(new TourneyVideo("main") { RelativeSizeAxes = Axes.Both });
|
||||
Add(new ScheduleScreen());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// 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 JetBrains.Annotations;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Tournament.Models;
|
||||
|
||||
namespace osu.Game.Tournament.Components
|
||||
{
|
||||
public class DrawableTeamFlag : Sprite
|
||||
{
|
||||
private readonly TournamentTeam team;
|
||||
|
||||
[UsedImplicitly]
|
||||
private Bindable<string> flag;
|
||||
|
||||
public DrawableTeamFlag(TournamentTeam team)
|
||||
{
|
||||
this.team = team;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
if (team == null) return;
|
||||
|
||||
(flag = team.FlagName.GetBoundCopy()).BindValueChanged(acronym => Texture = textures.Get($@"Flags/{team.FlagName}"), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// 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.Tournament.Models;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tournament.Components
|
||||
{
|
||||
public class DrawableTeamHeader : TournamentSpriteTextWithBackground
|
||||
{
|
||||
public DrawableTeamHeader(TeamColour colour)
|
||||
{
|
||||
Background.Colour = TournamentGame.GetTeamColour(colour);
|
||||
|
||||
Text.Colour = TournamentGame.TEXT_COLOUR;
|
||||
Text.Text = $"Team {colour}".ToUpperInvariant();
|
||||
Text.Scale = new Vector2(0.6f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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 JetBrains.Annotations;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Tournament.Models;
|
||||
|
||||
namespace osu.Game.Tournament.Components
|
||||
{
|
||||
public class DrawableTeamTitle : TournamentSpriteTextWithBackground
|
||||
{
|
||||
private readonly TournamentTeam team;
|
||||
|
||||
[UsedImplicitly]
|
||||
private Bindable<string> acronym;
|
||||
|
||||
public DrawableTeamTitle(TournamentTeam team)
|
||||
{
|
||||
this.team = team;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
if (team == null) return;
|
||||
|
||||
(acronym = team.Acronym.GetBoundCopy()).BindValueChanged(acronym => Text.Text = team?.FullName.Value ?? string.Empty, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// 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.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tournament.Components
|
||||
{
|
||||
public class DrawableTeamTitleWithHeader : CompositeDrawable
|
||||
{
|
||||
public DrawableTeamTitleWithHeader(TournamentTeam team, TeamColour colour)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 10),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new DrawableTeamHeader(colour),
|
||||
new DrawableTeamTitle(team),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// 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.Linq;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tournament.Components
|
||||
{
|
||||
public class DrawableTeamWithPlayers : CompositeDrawable
|
||||
{
|
||||
public DrawableTeamWithPlayers(TournamentTeam team, TeamColour colour)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(30),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new DrawableTeamTitleWithHeader(team, colour),
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Padding = new MarginPadding { Left = 10 },
|
||||
Spacing = new Vector2(30),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
Direction = FillDirection.Vertical,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
ChildrenEnumerable = team?.Players.Select(createPlayerText).Take(5) ?? Enumerable.Empty<Drawable>()
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Direction = FillDirection.Vertical,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
ChildrenEnumerable = team?.Players.Select(createPlayerText).Skip(5) ?? Enumerable.Empty<Drawable>()
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
TournamentSpriteText createPlayerText(User p) =>
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = p.Username,
|
||||
Font = OsuFont.Torus.With(size: 24, weight: FontWeight.SemiBold),
|
||||
Colour = Color4.White,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,14 +23,11 @@ namespace osu.Game.Tournament.Components
|
||||
[UsedImplicitly]
|
||||
private Bindable<string> acronym;
|
||||
|
||||
[UsedImplicitly]
|
||||
private Bindable<string> flag;
|
||||
|
||||
protected DrawableTournamentTeam(TournamentTeam team)
|
||||
{
|
||||
Team = team;
|
||||
|
||||
Flag = new Sprite
|
||||
Flag = new DrawableTeamFlag(team)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
FillMode = FillMode.Fit
|
||||
@@ -48,7 +45,6 @@ namespace osu.Game.Tournament.Components
|
||||
if (Team == null) return;
|
||||
|
||||
(acronym = Team.Acronym.GetBoundCopy()).BindValueChanged(acronym => AcronymText.Text = Team?.Acronym.Value?.ToUpperInvariant() ?? string.Empty, true);
|
||||
(flag = Team.FlagName.GetBoundCopy()).BindValueChanged(acronym => Flag.Texture = textures.Get($@"Flags/{Team.FlagName}"), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// 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.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Tournament.Models;
|
||||
|
||||
namespace osu.Game.Tournament.Components
|
||||
{
|
||||
public class RoundDisplay : CompositeDrawable
|
||||
{
|
||||
public RoundDisplay(TournamentMatch match)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new DrawableTournamentHeaderText(),
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = match.Round.Value?.Name.Value ?? "Unknown Round",
|
||||
Font = OsuFont.Torus.With(size: 26, weight: FontWeight.SemiBold)
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,8 @@
|
||||
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.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Beatmaps;
|
||||
@@ -24,6 +22,8 @@ namespace osu.Game.Tournament.Components
|
||||
{
|
||||
private BeatmapInfo beatmap;
|
||||
|
||||
private const float height = 145;
|
||||
|
||||
[Resolved]
|
||||
private IBindable<RulesetInfo> ruleset { get; set; }
|
||||
|
||||
@@ -52,15 +52,7 @@ namespace osu.Game.Tournament.Components
|
||||
}
|
||||
}
|
||||
|
||||
private Container panelContents;
|
||||
private Container innerPanel;
|
||||
private Container outerPanel;
|
||||
private TournamentBeatmapPanel panel;
|
||||
|
||||
private float panelWidth => expanded ? 0.6f : 1;
|
||||
|
||||
private const float main_width = 0.97f;
|
||||
private const float inner_panel_width = 0.7f;
|
||||
private FillFlowContainer flow;
|
||||
|
||||
private bool expanded;
|
||||
|
||||
@@ -70,86 +62,27 @@ namespace osu.Game.Tournament.Components
|
||||
set
|
||||
{
|
||||
expanded = value;
|
||||
panel?.ResizeWidthTo(panelWidth, 800, Easing.OutQuint);
|
||||
|
||||
if (expanded)
|
||||
{
|
||||
innerPanel.ResizeWidthTo(inner_panel_width, 800, Easing.OutQuint);
|
||||
outerPanel.ResizeWidthTo(main_width, 800, Easing.OutQuint);
|
||||
}
|
||||
else
|
||||
{
|
||||
innerPanel.ResizeWidthTo(1, 800, Easing.OutQuint);
|
||||
outerPanel.ResizeWidthTo(0.25f, 800, Easing.OutQuint);
|
||||
}
|
||||
flow.Direction = expanded ? FillDirection.Full : FillDirection.Vertical;
|
||||
}
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
outerPanel = new Container
|
||||
flow = new FillFlowContainer
|
||||
{
|
||||
Masking = true,
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Colour = Color4.Black.Opacity(0.2f),
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Radius = 5,
|
||||
},
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
LayoutDuration = 500,
|
||||
LayoutEasing = Easing.OutQuint,
|
||||
Direction = FillDirection.Full,
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
RelativePositionAxes = Axes.X,
|
||||
X = -(1 - main_width) / 2,
|
||||
Y = -10,
|
||||
Width = main_width,
|
||||
Height = TournamentBeatmapPanel.HEIGHT,
|
||||
CornerRadius = TournamentBeatmapPanel.HEIGHT / 2,
|
||||
CornerExponent = 2,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = OsuColour.Gray(0.93f),
|
||||
},
|
||||
new OsuLogo
|
||||
{
|
||||
Triangles = false,
|
||||
Colour = OsuColour.Gray(0.33f),
|
||||
Scale = new Vector2(0.08f),
|
||||
Margin = new MarginPadding(50),
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
},
|
||||
innerPanel = new Container
|
||||
{
|
||||
Masking = true,
|
||||
CornerRadius = TournamentBeatmapPanel.HEIGHT / 2,
|
||||
CornerExponent = 2,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = inner_panel_width,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = OsuColour.Gray(0.86f),
|
||||
},
|
||||
panelContents = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -160,7 +93,7 @@ namespace osu.Game.Tournament.Components
|
||||
{
|
||||
if (beatmap == null)
|
||||
{
|
||||
panelContents.Clear();
|
||||
flow.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -219,34 +152,86 @@ namespace osu.Game.Tournament.Components
|
||||
break;
|
||||
}
|
||||
|
||||
panelContents.Children = new Drawable[]
|
||||
flow.Children = new Drawable[]
|
||||
{
|
||||
new DiffPiece(("Length", TimeSpan.FromMilliseconds(length).ToString(@"mm\:ss")))
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = height / 2,
|
||||
Width = 0.5f,
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new GridContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
|
||||
Content = new[]
|
||||
{
|
||||
new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new DiffPiece(stats),
|
||||
new DiffPiece(("Star Rating", $"{beatmap.StarDifficulty:0.#}{srExtra}"))
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new DiffPiece(("Length", TimeSpan.FromMilliseconds(length).ToString(@"mm\:ss"))),
|
||||
new DiffPiece(("BPM", $"{bpm:0.#}"))
|
||||
}
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = Color4.Black,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0.1f,
|
||||
},
|
||||
new OsuLogo
|
||||
{
|
||||
Triangles = false,
|
||||
Scale = new Vector2(0.08f),
|
||||
Margin = new MarginPadding(50),
|
||||
X = -10,
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new DiffPiece(("BPM", $"{bpm:0.#}"))
|
||||
new TournamentBeatmapPanel(beatmap)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.TopLeft
|
||||
},
|
||||
new DiffPiece(stats)
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.BottomRight
|
||||
},
|
||||
new DiffPiece(("Star Rating", $"{beatmap.StarDifficulty:0.#}{srExtra}"))
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.TopRight
|
||||
},
|
||||
panel = new TournamentBeatmapPanel(beatmap)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Size = new Vector2(panelWidth, 1)
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Width = 0.5f,
|
||||
Height = height / 2,
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -258,10 +243,9 @@ namespace osu.Game.Tournament.Components
|
||||
Margin = new MarginPadding { Horizontal = 15, Vertical = 1 };
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
static void cp(SpriteText s, Color4 colour)
|
||||
static void cp(SpriteText s, bool bold)
|
||||
{
|
||||
s.Colour = colour;
|
||||
s.Font = OsuFont.Torus.With(weight: FontWeight.Bold, size: 15);
|
||||
s.Font = OsuFont.Torus.With(weight: bold ? FontWeight.Bold : FontWeight.Regular, size: 15);
|
||||
}
|
||||
|
||||
for (var i = 0; i < tuples.Length; i++)
|
||||
@@ -272,14 +256,14 @@ namespace osu.Game.Tournament.Components
|
||||
{
|
||||
AddText(" / ", s =>
|
||||
{
|
||||
cp(s, OsuColour.Gray(0.33f));
|
||||
cp(s, false);
|
||||
s.Spacing = new Vector2(-2, 0);
|
||||
});
|
||||
}
|
||||
|
||||
AddText(new TournamentSpriteText { Text = heading }, s => cp(s, OsuColour.Gray(0.33f)));
|
||||
AddText(" ", s => cp(s, OsuColour.Gray(0.33f)));
|
||||
AddText(new TournamentSpriteText { Text = content }, s => cp(s, OsuColour.Gray(0.5f)));
|
||||
AddText(new TournamentSpriteText { Text = heading }, s => cp(s, false));
|
||||
AddText(" ", s => cp(s, false));
|
||||
AddText(new TournamentSpriteText { Text = content }, s => cp(s, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace osu.Game.Tournament.Components
|
||||
private readonly string mods;
|
||||
|
||||
private const float horizontal_padding = 10;
|
||||
private const float vertical_padding = 5;
|
||||
private const float vertical_padding = 10;
|
||||
|
||||
public const float HEIGHT = 50;
|
||||
|
||||
@@ -50,8 +50,6 @@ namespace osu.Game.Tournament.Components
|
||||
currentMatch.BindValueChanged(matchChanged);
|
||||
currentMatch.BindTo(ladder.CurrentMatch);
|
||||
|
||||
CornerRadius = HEIGHT / 2;
|
||||
CornerExponent = 2;
|
||||
Masking = true;
|
||||
|
||||
AddRangeInternal(new Drawable[]
|
||||
@@ -70,16 +68,14 @@ namespace osu.Game.Tournament.Components
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Padding = new MarginPadding(vertical_padding),
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Padding = new MarginPadding(15),
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = new LocalisedString((
|
||||
$"{Beatmap.Metadata.ArtistUnicode ?? Beatmap.Metadata.Artist} - {Beatmap.Metadata.TitleUnicode ?? Beatmap.Metadata.Title}",
|
||||
$"{Beatmap.Metadata.Artist} - {Beatmap.Metadata.Title}")),
|
||||
@@ -88,9 +84,6 @@ namespace osu.Game.Tournament.Components
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Padding = new MarginPadding(vertical_padding),
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
@@ -137,8 +130,8 @@ namespace osu.Game.Tournament.Components
|
||||
Texture = textures.Get($"mods/{mods}"),
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
Margin = new MarginPadding(20),
|
||||
Scale = new Vector2(0.5f)
|
||||
Margin = new MarginPadding(10),
|
||||
Scale = new Vector2(0.8f)
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -170,16 +163,7 @@ namespace osu.Game.Tournament.Components
|
||||
|
||||
BorderThickness = 6;
|
||||
|
||||
switch (found.Team)
|
||||
{
|
||||
case TeamColour.Red:
|
||||
BorderColour = Color4.Red;
|
||||
break;
|
||||
|
||||
case TeamColour.Blue:
|
||||
BorderColour = Color4.Blue;
|
||||
break;
|
||||
}
|
||||
BorderColour = TournamentGame.GetTeamColour(found.Team);
|
||||
|
||||
switch (found.Type)
|
||||
{
|
||||
|
||||
@@ -9,8 +9,6 @@ using osu.Game.Online.Chat;
|
||||
using osu.Game.Overlays.Chat;
|
||||
using osu.Game.Tournament.IPC;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tournament.Components
|
||||
{
|
||||
@@ -23,11 +21,11 @@ namespace osu.Game.Tournament.Components
|
||||
public TournamentMatchChatDisplay()
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Y = 100;
|
||||
Size = new Vector2(0.45f, 112);
|
||||
Margin = new MarginPadding(10);
|
||||
Anchor = Anchor.BottomCentre;
|
||||
Origin = Anchor.BottomCentre;
|
||||
Height = 144;
|
||||
Anchor = Anchor.BottomLeft;
|
||||
Origin = Anchor.BottomLeft;
|
||||
|
||||
CornerRadius = 0;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
@@ -66,6 +64,10 @@ namespace osu.Game.Tournament.Components
|
||||
}
|
||||
}
|
||||
|
||||
public void Expand() => this.FadeIn(300);
|
||||
|
||||
public void Contract() => this.FadeOut(200);
|
||||
|
||||
protected override ChatLine CreateMessage(Message message) => new MatchMessage(message);
|
||||
|
||||
protected class MatchMessage : StandAloneMessage
|
||||
@@ -75,19 +77,15 @@ namespace osu.Game.Tournament.Components
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LadderInfo info)
|
||||
{
|
||||
//if (info.CurrentMatch.Value.Team1.Value.Players.Any(u => u.Id == Message.Sender.Id))
|
||||
// ColourBox.Colour = red;
|
||||
//else if (info.CurrentMatch.Value.Team2.Value.Players.Any(u => u.Id == Message.Sender.Id))
|
||||
// ColourBox.Colour = blue;
|
||||
//else if (Message.Sender.Colour != null)
|
||||
// SenderText.Colour = ColourBox.Colour = OsuColour.FromHex(Message.Sender.Colour);
|
||||
// if (info.CurrentMatch.Value.Team1.Value.Players.Any(u => u.Id == Message.Sender.Id))
|
||||
// SenderText.Colour = TournamentGame.COLOUR_RED;
|
||||
// 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 = Color4Extensions.FromHex(Message.Sender.Colour);
|
||||
}
|
||||
|
||||
private readonly Color4 red = new Color4(186, 0, 18, 255);
|
||||
private readonly Color4 blue = new Color4(17, 136, 170, 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
|
||||
namespace osu.Game.Tournament.Components
|
||||
{
|
||||
public class TournamentSpriteTextWithBackground : CompositeDrawable
|
||||
{
|
||||
protected readonly TournamentSpriteText Text;
|
||||
protected readonly Box Background;
|
||||
|
||||
public TournamentSpriteTextWithBackground(string text = "")
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
Background = new Box
|
||||
{
|
||||
Colour = TournamentGame.ELEMENT_BACKGROUND_COLOUR,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
Text = new TournamentSpriteText
|
||||
{
|
||||
Colour = TournamentGame.ELEMENT_FOREGROUND_COLOUR,
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.SemiBold, size: 50),
|
||||
Padding = new MarginPadding { Left = 10, Right = 20 },
|
||||
Text = text
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 System.IO;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
@@ -14,13 +14,34 @@ namespace osu.Game.Tournament.Components
|
||||
{
|
||||
public class TourneyVideo : CompositeDrawable
|
||||
{
|
||||
private readonly VideoSprite video;
|
||||
private readonly string filename;
|
||||
private readonly bool drawFallbackGradient;
|
||||
private VideoSprite video;
|
||||
|
||||
private readonly ManualClock manualClock;
|
||||
private ManualClock manualClock;
|
||||
|
||||
public TourneyVideo(Stream stream)
|
||||
public TourneyVideo(string filename, bool drawFallbackGradient = false)
|
||||
{
|
||||
if (stream == null)
|
||||
this.filename = filename;
|
||||
this.drawFallbackGradient = drawFallbackGradient;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TournamentStorage storage)
|
||||
{
|
||||
var stream = storage.GetStream($@"videos/{filename}");
|
||||
|
||||
if (stream != null)
|
||||
{
|
||||
InternalChild = video = new VideoSprite(stream, false)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
FillMode = FillMode.Fit,
|
||||
Clock = new FramedClock(manualClock = new ManualClock()),
|
||||
Loop = loop,
|
||||
};
|
||||
}
|
||||
else if (drawFallbackGradient)
|
||||
{
|
||||
InternalChild = new Box
|
||||
{
|
||||
@@ -28,26 +49,26 @@ namespace osu.Game.Tournament.Components
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
InternalChild = video = new VideoSprite(stream)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
FillMode = FillMode.Fit,
|
||||
Clock = new FramedClock(manualClock = new ManualClock())
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private bool loop;
|
||||
|
||||
public bool Loop
|
||||
{
|
||||
set
|
||||
{
|
||||
loop = value;
|
||||
if (video != null)
|
||||
video.Loop = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
if (manualClock != null)
|
||||
manualClock.CurrentTime = 0;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -90,6 +90,8 @@ namespace osu.Game.Tournament.Models
|
||||
[JsonIgnore]
|
||||
public TournamentTeam Loser => !Completed.Value ? null : Team1Score.Value > Team2Score.Value ? Team2.Value : Team1.Value;
|
||||
|
||||
public TeamColour WinnerColour => Winner == Team1.Value ? TeamColour.Red : TeamColour.Blue;
|
||||
|
||||
public int PointsToWin => Round.Value?.BestOf.Value / 2 + 1 ?? 0;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace osu.Game.Tournament.Screens
|
||||
{
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
Depth = float.MinValue,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
@@ -116,53 +115,5 @@ namespace osu.Game.Tournament.Screens.Drawings.Components
|
||||
sb.AppendLine(gt.Team.FullName.Value);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private class GroupTeam : DrawableTournamentTeam
|
||||
{
|
||||
private readonly FillFlowContainer innerContainer;
|
||||
|
||||
public GroupTeam(TournamentTeam team)
|
||||
: base(team)
|
||||
{
|
||||
Width = 36;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
Flag.Anchor = Anchor.TopCentre;
|
||||
Flag.Origin = Anchor.TopCentre;
|
||||
|
||||
AcronymText.Anchor = Anchor.TopCentre;
|
||||
AcronymText.Origin = Anchor.TopCentre;
|
||||
AcronymText.Text = team.Acronym.Value.ToUpperInvariant();
|
||||
AcronymText.Font = OsuFont.Torus.With(weight: FontWeight.Bold, size: 10);
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
innerContainer = new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 5f),
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Flag,
|
||||
AcronymText
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
innerContainer.ScaleTo(1.5f);
|
||||
innerContainer.ScaleTo(1f, 200);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// 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.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tournament.Screens.Drawings.Components
|
||||
{
|
||||
public class GroupTeam : DrawableTournamentTeam
|
||||
{
|
||||
private readonly FillFlowContainer innerContainer;
|
||||
|
||||
public GroupTeam(TournamentTeam team)
|
||||
: base(team)
|
||||
{
|
||||
Width = 36;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
Flag.Anchor = Anchor.TopCentre;
|
||||
Flag.Origin = Anchor.TopCentre;
|
||||
|
||||
AcronymText.Anchor = Anchor.TopCentre;
|
||||
AcronymText.Origin = Anchor.TopCentre;
|
||||
AcronymText.Text = team.Acronym.Value.ToUpperInvariant();
|
||||
AcronymText.Font = OsuFont.Torus.With(weight: FontWeight.Bold, size: 10);
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
innerContainer = new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 5f),
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Flag,
|
||||
AcronymText
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
innerContainer.ScaleTo(1.5f);
|
||||
innerContainer.ScaleTo(1f, 200);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,8 +129,6 @@ namespace osu.Game.Tournament.Screens.Editors
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
LayoutDuration = 200,
|
||||
LayoutEasing = Easing.OutQuint,
|
||||
ChildrenEnumerable = round.Beatmaps.Select(p => new RoundBeatmapRow(round, p))
|
||||
};
|
||||
}
|
||||
|
||||
@@ -124,8 +124,6 @@ namespace osu.Game.Tournament.Screens.Editors
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
LayoutDuration = 200,
|
||||
LayoutEasing = Easing.OutQuint,
|
||||
ChildrenEnumerable = round.Beatmaps.Select(p => new SeedingBeatmapRow(round, p))
|
||||
};
|
||||
}
|
||||
|
||||
@@ -172,19 +172,6 @@ namespace osu.Game.Tournament.Screens.Editors
|
||||
drawableContainer.Child = new DrawableTeamFlag(Model);
|
||||
}
|
||||
|
||||
private class DrawableTeamFlag : DrawableTournamentTeam
|
||||
{
|
||||
public DrawableTeamFlag(TournamentTeam team)
|
||||
: base(team)
|
||||
{
|
||||
InternalChild = Flag;
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
Flag.Anchor = Anchor.Centre;
|
||||
Flag.Origin = Anchor.Centre;
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerEditor : CompositeDrawable
|
||||
{
|
||||
private readonly TournamentTeam team;
|
||||
@@ -202,8 +189,6 @@ namespace osu.Game.Tournament.Screens.Editors
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
LayoutDuration = 200,
|
||||
LayoutEasing = Easing.OutQuint,
|
||||
ChildrenEnumerable = team.Players.Select(p => new PlayerRow(team, p))
|
||||
};
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ namespace osu.Game.Tournament.Screens.Editors
|
||||
new OsuScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0.9f,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Child = flow = new FillFlowContainer<TDrawable>
|
||||
@@ -48,8 +47,6 @@ namespace osu.Game.Tournament.Screens.Editors
|
||||
Direction = FillDirection.Vertical,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
LayoutDuration = 200,
|
||||
LayoutEasing = Easing.OutQuint,
|
||||
Spacing = new Vector2(20)
|
||||
},
|
||||
},
|
||||
|
||||
@@ -2,24 +2,54 @@
|
||||
// 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.Graphics.Shapes;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osu.Game.Tournament.Screens.Showcase;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
{
|
||||
public class MatchHeader : Container
|
||||
{
|
||||
private TeamScoreDisplay teamDisplay1;
|
||||
private TeamScoreDisplay teamDisplay2;
|
||||
private DrawableTournamentHeaderLogo logo;
|
||||
|
||||
private bool showScores = true;
|
||||
|
||||
public bool ShowScores
|
||||
{
|
||||
get => showScores;
|
||||
set
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
@@ -27,200 +57,54 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
Height = 95;
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TournamentLogo(),
|
||||
new RoundDisplay
|
||||
new FillFlowContainer
|
||||
{
|
||||
Y = 5,
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Padding = new MarginPadding(20),
|
||||
Spacing = new Vector2(5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
logo = new DrawableTournamentHeaderLogo
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Alpha = showLogo ? 1 : 0
|
||||
},
|
||||
new DrawableTournamentHeaderText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
},
|
||||
new MatchRoundDisplay
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Scale = new Vector2(0.4f)
|
||||
},
|
||||
}
|
||||
},
|
||||
new TeamScoreDisplay(TeamColour.Red)
|
||||
teamDisplay1 = new TeamScoreDisplay(TeamColour.Red)
|
||||
{
|
||||
Anchor = Anchor.TopLeft,
|
||||
Origin = Anchor.TopLeft,
|
||||
},
|
||||
new TeamScoreDisplay(TeamColour.Blue)
|
||||
teamDisplay2 = new TeamScoreDisplay(TeamColour.Blue)
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
},
|
||||
};
|
||||
|
||||
updateDisplay();
|
||||
}
|
||||
|
||||
private class TeamScoreDisplay : CompositeDrawable
|
||||
private void updateDisplay()
|
||||
{
|
||||
private readonly TeamColour teamColour;
|
||||
teamDisplay1.ShowScore = showScores;
|
||||
teamDisplay2.ShowScore = showScores;
|
||||
|
||||
private readonly Bindable<TournamentMatch> currentMatch = new Bindable<TournamentMatch>();
|
||||
private readonly Bindable<TournamentTeam> currentTeam = new Bindable<TournamentTeam>();
|
||||
private readonly Bindable<int?> currentTeamScore = new Bindable<int?>();
|
||||
|
||||
public TeamScoreDisplay(TeamColour teamColour)
|
||||
{
|
||||
this.teamColour = teamColour;
|
||||
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
Width = 300;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LadderInfo ladder)
|
||||
{
|
||||
currentMatch.BindValueChanged(matchChanged);
|
||||
currentMatch.BindTo(ladder.CurrentMatch);
|
||||
}
|
||||
|
||||
private void matchChanged(ValueChangedEvent<TournamentMatch> match)
|
||||
{
|
||||
currentTeamScore.UnbindBindings();
|
||||
currentTeamScore.BindTo(teamColour == TeamColour.Red ? match.NewValue.Team1Score : match.NewValue.Team2Score);
|
||||
|
||||
currentTeam.UnbindBindings();
|
||||
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)
|
||||
{
|
||||
var colour = teamColour == TeamColour.Red ? TournamentGame.COLOUR_RED : TournamentGame.COLOUR_BLUE;
|
||||
var flip = teamColour != TeamColour.Red;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new TeamDisplay(team, colour, flip),
|
||||
new TeamScore(currentTeamScore, flip, currentMatch.Value.PointsToWin)
|
||||
{
|
||||
Colour = colour
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class TeamScore : CompositeDrawable
|
||||
{
|
||||
private readonly Bindable<int?> currentTeamScore = new Bindable<int?>();
|
||||
private readonly StarCounter counter;
|
||||
|
||||
public TeamScore(Bindable<int?> score, bool flip, int count)
|
||||
{
|
||||
var anchor = flip ? Anchor.CentreRight : Anchor.CentreLeft;
|
||||
|
||||
Anchor = anchor;
|
||||
Origin = anchor;
|
||||
|
||||
InternalChild = counter = new StarCounter(count)
|
||||
{
|
||||
Anchor = anchor,
|
||||
X = (flip ? -1 : 1) * 90,
|
||||
Y = 5,
|
||||
Scale = flip ? new Vector2(-1, 1) : Vector2.One,
|
||||
};
|
||||
|
||||
currentTeamScore.BindValueChanged(scoreChanged);
|
||||
currentTeamScore.BindTo(score);
|
||||
}
|
||||
|
||||
private void scoreChanged(ValueChangedEvent<int?> score) => counter.CountStars = score.NewValue ?? 0;
|
||||
}
|
||||
|
||||
private class TeamDisplay : DrawableTournamentTeam
|
||||
{
|
||||
public TeamDisplay(TournamentTeam team, Color4 colour, bool flip)
|
||||
: base(team)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
var anchor = flip ? Anchor.CentreRight : Anchor.CentreLeft;
|
||||
|
||||
Anchor = Origin = anchor;
|
||||
|
||||
Flag.Anchor = Flag.Origin = anchor;
|
||||
Flag.RelativeSizeAxes = Axes.None;
|
||||
Flag.Size = new Vector2(60, 40);
|
||||
Flag.Margin = new MarginPadding(20);
|
||||
|
||||
InternalChild = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Flag,
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = team?.FullName.Value.ToUpper() ?? "???",
|
||||
X = (flip ? -1 : 1) * 90,
|
||||
Y = -10,
|
||||
Colour = colour,
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.Regular, size: 20),
|
||||
Origin = anchor,
|
||||
Anchor = anchor,
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class RoundDisplay : CompositeDrawable
|
||||
{
|
||||
private readonly Bindable<TournamentMatch> currentMatch = new Bindable<TournamentMatch>();
|
||||
|
||||
private readonly TournamentSpriteText text;
|
||||
|
||||
public RoundDisplay()
|
||||
{
|
||||
Width = 200;
|
||||
Height = 20;
|
||||
|
||||
Masking = true;
|
||||
CornerRadius = 10;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = OsuColour.Gray(0.18f),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
text = new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Colour = Color4.White,
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.Regular, size: 16),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LadderInfo ladder)
|
||||
{
|
||||
currentMatch.BindValueChanged(matchChanged);
|
||||
currentMatch.BindTo(ladder.CurrentMatch);
|
||||
}
|
||||
|
||||
private void matchChanged(ValueChangedEvent<TournamentMatch> match) =>
|
||||
text.Text = match.NewValue.Round.Value?.Name.Value ?? "Unknown Round";
|
||||
logo.Alpha = showLogo ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
|
||||
namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
{
|
||||
public class MatchRoundDisplay : TournamentSpriteTextWithBackground
|
||||
{
|
||||
private readonly Bindable<TournamentMatch> currentMatch = new Bindable<TournamentMatch>();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LadderInfo ladder)
|
||||
{
|
||||
currentMatch.BindValueChanged(matchChanged);
|
||||
currentMatch.BindTo(ladder.CurrentMatch);
|
||||
}
|
||||
|
||||
private void matchChanged(ValueChangedEvent<TournamentMatch> match) =>
|
||||
Text.Text = match.NewValue.Round.Value?.Name.Value ?? "Unknown Round";
|
||||
}
|
||||
}
|
||||
@@ -11,16 +11,13 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Tournament.IPC;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osuTK.Graphics;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
{
|
||||
public class MatchScoreDisplay : CompositeDrawable
|
||||
{
|
||||
private readonly Color4 red = new Color4(186, 0, 18, 255);
|
||||
private readonly Color4 blue = new Color4(17, 136, 170, 255);
|
||||
|
||||
private const float bar_height = 20;
|
||||
private const float bar_height = 18;
|
||||
|
||||
private readonly BindableInt score1 = new BindableInt();
|
||||
private readonly BindableInt score2 = new BindableInt();
|
||||
@@ -28,45 +25,63 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
private readonly MatchScoreCounter score1Text;
|
||||
private readonly MatchScoreCounter score2Text;
|
||||
|
||||
private readonly Circle score1Bar;
|
||||
private readonly Circle score2Bar;
|
||||
private readonly Drawable score1Bar;
|
||||
private readonly Drawable score2Bar;
|
||||
|
||||
public MatchScoreDisplay()
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
InternalChildren = new[]
|
||||
{
|
||||
score1Bar = new Circle
|
||||
new Box
|
||||
{
|
||||
Name = "top bar red (static)",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = bar_height / 4,
|
||||
Width = 0.5f,
|
||||
Colour = TournamentGame.COLOUR_RED,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopRight
|
||||
},
|
||||
new Box
|
||||
{
|
||||
Name = "top bar blue (static)",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = bar_height / 4,
|
||||
Width = 0.5f,
|
||||
Colour = TournamentGame.COLOUR_BLUE,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopLeft
|
||||
},
|
||||
score1Bar = new Box
|
||||
{
|
||||
Name = "top bar red",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = bar_height,
|
||||
Width = 0,
|
||||
Colour = red,
|
||||
Colour = TournamentGame.COLOUR_RED,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopRight
|
||||
},
|
||||
score1Text = new MatchScoreCounter
|
||||
{
|
||||
Colour = red,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre
|
||||
},
|
||||
score2Bar = new Circle
|
||||
score2Bar = new Box
|
||||
{
|
||||
Name = "top bar blue",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = bar_height,
|
||||
Width = 0,
|
||||
Colour = blue,
|
||||
Colour = TournamentGame.COLOUR_BLUE,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopLeft
|
||||
},
|
||||
score2Text = new MatchScoreCounter
|
||||
{
|
||||
Colour = blue,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre
|
||||
},
|
||||
@@ -103,10 +118,9 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
winningBar.ResizeWidthTo(Math.Min(0.4f, MathF.Pow(diff / 1500000f, 0.5f) / 2), 400, Easing.OutQuint);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
protected override void UpdateAfterChildren()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
base.UpdateAfterChildren();
|
||||
score1Text.X = -Math.Max(5 + score1Text.DrawWidth / 2, score1Bar.DrawWidth);
|
||||
score2Text.X = Math.Max(5 + score2Text.DrawWidth / 2, score2Bar.DrawWidth);
|
||||
}
|
||||
@@ -115,16 +129,18 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
{
|
||||
public MatchScoreCounter()
|
||||
{
|
||||
Margin = new MarginPadding { Top = bar_height + 5, Horizontal = 10 };
|
||||
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.Regular, size: 60)
|
||||
: OsuFont.Torus.With(weight: FontWeight.Light, size: 40);
|
||||
? OsuFont.Torus.With(weight: FontWeight.Bold, size: 50, fixedWidth: true)
|
||||
: OsuFont.Torus.With(weight: FontWeight.Regular, size: 40, fixedWidth: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
// 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.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
{
|
||||
public class TeamDisplay : DrawableTournamentTeam
|
||||
{
|
||||
private readonly TeamScore score;
|
||||
|
||||
public bool ShowScore { set => score.FadeTo(value ? 1 : 0, 200); }
|
||||
|
||||
public TeamDisplay(TournamentTeam team, TeamColour colour, Bindable<int?> currentTeamScore, int pointsToWin)
|
||||
: base(team)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
bool flip = colour == TeamColour.Red;
|
||||
|
||||
var anchor = flip ? Anchor.TopLeft : Anchor.TopRight;
|
||||
|
||||
Flag.RelativeSizeAxes = Axes.None;
|
||||
Flag.Size = new Vector2(60, 40);
|
||||
Flag.Origin = anchor;
|
||||
Flag.Anchor = anchor;
|
||||
|
||||
Margin = new MarginPadding(20);
|
||||
|
||||
InternalChild = new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Flag,
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Origin = anchor,
|
||||
Anchor = anchor,
|
||||
Spacing = new Vector2(5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new DrawableTeamHeader(colour)
|
||||
{
|
||||
Scale = new Vector2(0.75f),
|
||||
Origin = anchor,
|
||||
Anchor = anchor,
|
||||
},
|
||||
score = new TeamScore(currentTeamScore, colour, pointsToWin)
|
||||
{
|
||||
Origin = anchor,
|
||||
Anchor = anchor,
|
||||
}
|
||||
}
|
||||
},
|
||||
new TournamentSpriteTextWithBackground(team?.FullName.Value ?? "???")
|
||||
{
|
||||
Scale = new Vector2(0.5f),
|
||||
Origin = anchor,
|
||||
Anchor = anchor,
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
// 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.Bindables;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
{
|
||||
public class TeamScore : CompositeDrawable
|
||||
{
|
||||
private readonly Bindable<int?> currentTeamScore = new Bindable<int?>();
|
||||
private readonly StarCounter counter;
|
||||
|
||||
public TeamScore(Bindable<int?> score, TeamColour colour, int count)
|
||||
{
|
||||
bool flip = colour == TeamColour.Blue;
|
||||
var anchor = flip ? Anchor.TopRight : Anchor.TopLeft;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
InternalChild = counter = new TeamScoreStarCounter(count)
|
||||
{
|
||||
Anchor = anchor,
|
||||
Scale = flip ? new Vector2(-1, 1) : Vector2.One,
|
||||
};
|
||||
|
||||
currentTeamScore.BindValueChanged(scoreChanged);
|
||||
currentTeamScore.BindTo(score);
|
||||
}
|
||||
|
||||
private void scoreChanged(ValueChangedEvent<int?> score) => counter.Current = score.NewValue ?? 0;
|
||||
|
||||
public class TeamScoreStarCounter : StarCounter
|
||||
{
|
||||
public TeamScoreStarCounter(int count)
|
||||
: base(count)
|
||||
{
|
||||
}
|
||||
|
||||
public override Star CreateStar() => new LightSquare();
|
||||
|
||||
public class LightSquare : Star
|
||||
{
|
||||
private readonly Box box;
|
||||
|
||||
public LightSquare()
|
||||
{
|
||||
Size = new Vector2(22.5f);
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
BorderColour = OsuColour.Gray(0.5f),
|
||||
BorderThickness = 3,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = Color4.Transparent,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
AlwaysPresent = true,
|
||||
},
|
||||
}
|
||||
},
|
||||
box = new Box
|
||||
{
|
||||
Colour = Color4Extensions.FromHex("#FFE8AD"),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
};
|
||||
|
||||
Masking = true;
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Glow,
|
||||
Colour = Color4Extensions.FromHex("#FFE8AD").Opacity(0.1f),
|
||||
Hollow = true,
|
||||
Radius = 20,
|
||||
Roundness = 10,
|
||||
};
|
||||
}
|
||||
|
||||
public override void DisplayAt(float scale)
|
||||
{
|
||||
box.FadeTo(scale, 500, Easing.OutQuint);
|
||||
FadeEdgeEffectTo(0.2f * scale, 500, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Tournament.Components;
|
||||
@@ -14,12 +15,11 @@ using osu.Game.Tournament.Models;
|
||||
using osu.Game.Tournament.Screens.Gameplay.Components;
|
||||
using osu.Game.Tournament.Screens.MapPool;
|
||||
using osu.Game.Tournament.Screens.TeamWin;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tournament.Screens.Gameplay
|
||||
{
|
||||
public class GameplayScreen : BeatmapInfoScreen
|
||||
public class GameplayScreen : BeatmapInfoScreen, IProvideVideo
|
||||
{
|
||||
private readonly BindableBool warmup = new BindableBool();
|
||||
|
||||
@@ -29,9 +29,6 @@ namespace osu.Game.Tournament.Screens.Gameplay
|
||||
private OsuButton warmupButton;
|
||||
private MatchIPCInfo ipc;
|
||||
|
||||
private readonly Color4 red = new Color4(186, 0, 18, 255);
|
||||
private readonly Color4 blue = new Color4(17, 136, 170, 255);
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private TournamentSceneManager sceneManager { get; set; }
|
||||
|
||||
@@ -39,20 +36,28 @@ namespace osu.Game.Tournament.Screens.Gameplay
|
||||
private TournamentMatchChatDisplay chat { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LadderInfo ladder, MatchIPCInfo ipc)
|
||||
private void load(LadderInfo ladder, MatchIPCInfo ipc, Storage storage)
|
||||
{
|
||||
this.ipc = ipc;
|
||||
|
||||
AddRangeInternal(new Drawable[]
|
||||
{
|
||||
new MatchHeader(),
|
||||
new TourneyVideo("gameplay")
|
||||
{
|
||||
Loop = true,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
header = new MatchHeader
|
||||
{
|
||||
ShowLogo = false
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Y = 5,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Y = 110,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
@@ -60,44 +65,18 @@ namespace osu.Game.Tournament.Screens.Gameplay
|
||||
// chroma key area for stable gameplay
|
||||
Name = "chroma",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Height = 512,
|
||||
Colour = new Color4(0, 255, 0, 255),
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Y = -4,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Circle
|
||||
{
|
||||
Name = "top bar red",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 8,
|
||||
Width = 0.5f,
|
||||
Colour = red,
|
||||
},
|
||||
new Circle
|
||||
{
|
||||
Name = "top bar blue",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 8,
|
||||
Width = 0.5f,
|
||||
Colour = blue,
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
scoreDisplay = new MatchScoreDisplay
|
||||
{
|
||||
Y = -60,
|
||||
Scale = new Vector2(0.8f),
|
||||
Y = -147,
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
},
|
||||
new ControlPanel
|
||||
{
|
||||
@@ -130,13 +109,18 @@ namespace osu.Game.Tournament.Screens.Gameplay
|
||||
|
||||
currentMatch.BindTo(ladder.CurrentMatch);
|
||||
|
||||
warmup.BindValueChanged(w => warmupButton.Alpha = !w.NewValue ? 0.5f : 1, true);
|
||||
warmup.BindValueChanged(w =>
|
||||
{
|
||||
warmupButton.Alpha = !w.NewValue ? 0.5f : 1;
|
||||
header.ShowScores = !w.NewValue;
|
||||
}, true);
|
||||
}
|
||||
|
||||
private ScheduledDelegate scheduledOperation;
|
||||
private MatchScoreDisplay scoreDisplay;
|
||||
|
||||
private TourneyState lastState;
|
||||
private MatchHeader header;
|
||||
|
||||
private void stateChanged(ValueChangedEvent<TourneyState> state)
|
||||
{
|
||||
@@ -156,7 +140,7 @@ namespace osu.Game.Tournament.Screens.Gameplay
|
||||
|
||||
void expand()
|
||||
{
|
||||
chat?.Expand();
|
||||
chat?.Contract();
|
||||
|
||||
using (BeginDelayedSequence(300, true))
|
||||
{
|
||||
@@ -170,7 +154,7 @@ namespace osu.Game.Tournament.Screens.Gameplay
|
||||
SongBar.Expanded = false;
|
||||
scoreDisplay.FadeOut(100);
|
||||
using (chat?.BeginDelayedSequence(500))
|
||||
chat?.Contract();
|
||||
chat?.Expand();
|
||||
}
|
||||
|
||||
switch (state.NewValue)
|
||||
@@ -197,7 +181,7 @@ namespace osu.Game.Tournament.Screens.Gameplay
|
||||
break;
|
||||
|
||||
default:
|
||||
chat.Expand();
|
||||
chat.Contract();
|
||||
expand();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -27,21 +28,23 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
private readonly bool losers;
|
||||
private TournamentSpriteText scoreText;
|
||||
private Box background;
|
||||
private Box backgroundRight;
|
||||
|
||||
private readonly Bindable<int?> score = new Bindable<int?>();
|
||||
private readonly BindableBool completed = new BindableBool();
|
||||
|
||||
private Color4 colourWinner;
|
||||
private Color4 colourNormal;
|
||||
|
||||
private readonly Func<bool> isWinner;
|
||||
private LadderEditorScreen ladderEditor;
|
||||
|
||||
[Resolved]
|
||||
[Resolved(canBeNull: true)]
|
||||
private LadderInfo ladderInfo { get; set; }
|
||||
|
||||
private void setCurrent()
|
||||
{
|
||||
if (ladderInfo == null) return;
|
||||
|
||||
//todo: tournamentgamebase?
|
||||
if (ladderInfo.CurrentMatch.Value != null)
|
||||
ladderInfo.CurrentMatch.Value.Current.Value = false;
|
||||
@@ -60,15 +63,12 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
this.losers = losers;
|
||||
Size = new Vector2(150, 40);
|
||||
|
||||
Masking = true;
|
||||
CornerRadius = 5;
|
||||
|
||||
Flag.Scale = new Vector2(0.9f);
|
||||
Flag.Anchor = Flag.Origin = Anchor.CentreLeft;
|
||||
|
||||
AcronymText.Anchor = AcronymText.Origin = Anchor.CentreLeft;
|
||||
AcronymText.Padding = new MarginPadding { Left = 50 };
|
||||
AcronymText.Font = OsuFont.Torus.With(size: 24);
|
||||
AcronymText.Font = OsuFont.Torus.With(size: 22, weight: FontWeight.Bold);
|
||||
|
||||
if (match != null)
|
||||
{
|
||||
@@ -85,8 +85,9 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
{
|
||||
this.ladderEditor = ladderEditor;
|
||||
|
||||
colourWinner = losers ? colours.YellowDarker : colours.BlueDarker;
|
||||
colourNormal = OsuColour.Gray(0.2f);
|
||||
colourWinner = losers
|
||||
? Color4Extensions.FromHex("#8E7F48")
|
||||
: Color4Extensions.FromHex("#1462AA");
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
@@ -102,29 +103,28 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
{
|
||||
AcronymText,
|
||||
Flag,
|
||||
new Container
|
||||
}
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Masking = true,
|
||||
Width = 0.3f,
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
backgroundRight = new Box
|
||||
{
|
||||
Masking = true,
|
||||
CornerRadius = 5,
|
||||
Width = 0.3f,
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
Colour = OsuColour.Gray(0.1f),
|
||||
Alpha = 0.8f,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = OsuColour.Gray(0.1f),
|
||||
Alpha = 0.8f,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
scoreText = new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Font = OsuFont.Torus.With(size: 20),
|
||||
}
|
||||
}
|
||||
},
|
||||
scoreText = new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Font = OsuFont.Torus.With(size: 22),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,9 +181,12 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
{
|
||||
bool winner = completed.Value && isWinner?.Invoke() == true;
|
||||
|
||||
background.FadeColour(winner ? colourWinner : colourNormal, 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);
|
||||
|
||||
scoreText.Font = AcronymText.Font = OsuFont.Torus.With(weight: winner ? FontWeight.Bold : FontWeight.Regular);
|
||||
AcronymText.Colour = winner ? Color4.Black : Color4.White;
|
||||
|
||||
scoreText.Font = scoreText.Font.With(weight: winner ? FontWeight.Bold : FontWeight.Regular);
|
||||
}
|
||||
|
||||
public MenuItem[] ContextMenuItems
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
private readonly bool editor;
|
||||
protected readonly FillFlowContainer<DrawableMatchTeam> Flow;
|
||||
private readonly Drawable selectionBox;
|
||||
private readonly Drawable currentMatchSelectionBox;
|
||||
protected readonly Drawable CurrentMatchSelectionBox;
|
||||
private Bindable<TournamentMatch> globalSelection;
|
||||
|
||||
[Resolved(CanBeNull = true)]
|
||||
@@ -45,9 +45,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
{
|
||||
selectionBox = new Container
|
||||
{
|
||||
CornerRadius = 5,
|
||||
Masking = true,
|
||||
Scale = new Vector2(1.05f),
|
||||
Scale = new Vector2(1.1f),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
@@ -55,16 +53,14 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
Colour = Color4.YellowGreen,
|
||||
Child = new Box { RelativeSizeAxes = Axes.Both }
|
||||
},
|
||||
currentMatchSelectionBox = new Container
|
||||
CurrentMatchSelectionBox = new Container
|
||||
{
|
||||
CornerRadius = 5,
|
||||
Masking = true,
|
||||
Scale = new Vector2(1.05f),
|
||||
Scale = new Vector2(1.05f, 1.1f),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Alpha = 0,
|
||||
Colour = Color4.OrangeRed,
|
||||
Colour = Color4.White,
|
||||
Child = new Box { RelativeSizeAxes = Axes.Both }
|
||||
},
|
||||
Flow = new FillFlowContainer<DrawableMatchTeam>
|
||||
@@ -128,9 +124,9 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
private void updateCurrentMatch()
|
||||
{
|
||||
if (Match.Current.Value)
|
||||
currentMatchSelectionBox.Show();
|
||||
CurrentMatchSelectionBox.Show();
|
||||
else
|
||||
currentMatchSelectionBox.Hide();
|
||||
CurrentMatchSelectionBox.Hide();
|
||||
}
|
||||
|
||||
private bool selected;
|
||||
|
||||
@@ -7,7 +7,6 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
{
|
||||
@@ -33,14 +32,14 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
{
|
||||
textDescription = new TournamentSpriteText
|
||||
{
|
||||
Colour = Color4.Black,
|
||||
Colour = TournamentGame.TEXT_COLOUR,
|
||||
Origin = Anchor.TopCentre,
|
||||
Anchor = Anchor.TopCentre
|
||||
},
|
||||
textName = new TournamentSpriteText
|
||||
{
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.Bold),
|
||||
Colour = Color4.Black,
|
||||
Colour = TournamentGame.TEXT_COLOUR,
|
||||
Origin = Anchor.TopCentre,
|
||||
Anchor = Anchor.TopCentre
|
||||
},
|
||||
|
||||
@@ -32,8 +32,8 @@ namespace osu.Game.Tournament.Screens.Ladder
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, Storage storage)
|
||||
{
|
||||
normalPathColour = colours.BlueDarker.Darken(2);
|
||||
losersPathColour = colours.YellowDarker.Darken(2);
|
||||
normalPathColour = Color4Extensions.FromHex("#66D1FF");
|
||||
losersPathColour = Color4Extensions.FromHex("#FFC700");
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
@@ -42,11 +42,17 @@ namespace osu.Game.Tournament.Screens.Ladder
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TourneyVideo(storage.GetStream(@"videos/ladder.m4v"))
|
||||
new TourneyVideo("ladder")
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Loop = true,
|
||||
},
|
||||
new DrawableTournamentHeaderText
|
||||
{
|
||||
Y = 100,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
},
|
||||
ScrollContent = new LadderDragContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
|
||||
@@ -42,10 +42,15 @@ namespace osu.Game.Tournament.Screens.MapPool
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new TourneyVideo("gameplay")
|
||||
{
|
||||
Loop = true,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new MatchHeader(),
|
||||
mapFlows = new FillFlowContainer<FillFlowContainer<TournamentBeatmapPanel>>
|
||||
{
|
||||
Y = 100,
|
||||
Y = 140,
|
||||
Spacing = new Vector2(10, 10),
|
||||
Padding = new MarginPadding(25),
|
||||
Direction = FillDirection.Vertical,
|
||||
@@ -230,6 +235,7 @@ namespace osu.Game.Tournament.Screens.MapPool
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Height = 42,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tournament.Screens.Schedule
|
||||
{
|
||||
public class ScheduleScreen : TournamentScreen, IProvideVideo
|
||||
public class ScheduleScreen : TournamentScreen // IProvidesVideo
|
||||
{
|
||||
private readonly Bindable<TournamentMatch> currentMatch = new Bindable<TournamentMatch>();
|
||||
private Container mainContainer;
|
||||
@@ -33,15 +33,68 @@ namespace osu.Game.Tournament.Screens.Schedule
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new TourneyVideo(storage.GetStream(@"videos/schedule.m4v"))
|
||||
new TourneyVideo("schedule")
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Loop = true,
|
||||
},
|
||||
mainContainer = new Container
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
}
|
||||
Padding = new MarginPadding(100) { Bottom = 50 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new GridContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RowDimensions = new[]
|
||||
{
|
||||
new Dimension(GridSizeMode.AutoSize),
|
||||
new Dimension(),
|
||||
},
|
||||
Content = new[]
|
||||
{
|
||||
new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new DrawableTournamentHeaderText(),
|
||||
new Container
|
||||
{
|
||||
Margin = new MarginPadding { Top = 40 },
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = Color4.White,
|
||||
Size = new Vector2(50, 10),
|
||||
},
|
||||
new TournamentSpriteTextWithBackground("Schedule")
|
||||
{
|
||||
X = 60,
|
||||
Scale = new Vector2(0.8f)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
new Drawable[]
|
||||
{
|
||||
mainContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
currentMatch.BindValueChanged(matchChanged);
|
||||
@@ -62,7 +115,7 @@ namespace osu.Game.Tournament.Screens.Schedule
|
||||
.SelectMany(m => m.ConditionalMatches.Where(cp => m.Acronyms.TrueForAll(a => cp.Acronyms.Contains(a))));
|
||||
|
||||
upcoming = upcoming.Concat(conditionals);
|
||||
upcoming = upcoming.OrderBy(p => p.Date.Value).Take(12);
|
||||
upcoming = upcoming.OrderBy(p => p.Date.Value).Take(8);
|
||||
|
||||
mainContainer.Child = new FillFlowContainer
|
||||
{
|
||||
@@ -73,7 +126,7 @@ namespace osu.Game.Tournament.Screens.Schedule
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Height = 0.65f,
|
||||
Height = 0.74f,
|
||||
Child = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@@ -91,7 +144,7 @@ namespace osu.Game.Tournament.Screens.Schedule
|
||||
.Take(8)
|
||||
.Select(p => new ScheduleMatch(p))
|
||||
},
|
||||
new ScheduleContainer("match overview")
|
||||
new ScheduleContainer("upcoming matches")
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0.6f,
|
||||
@@ -100,26 +153,57 @@ namespace osu.Game.Tournament.Screens.Schedule
|
||||
}
|
||||
}
|
||||
},
|
||||
new ScheduleContainer("current match")
|
||||
new ScheduleContainer("coming up next")
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Height = 0.25f,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText
|
||||
new FillFlowContainer
|
||||
{
|
||||
Margin = new MarginPadding { Left = -10, Bottom = 10, Top = -5 },
|
||||
Spacing = new Vector2(10, 0),
|
||||
Text = match.NewValue.Round.Value?.Name.Value,
|
||||
Colour = Color4.Black,
|
||||
Font = OsuFont.Torus.With(size: 20)
|
||||
},
|
||||
new ScheduleMatch(match.NewValue, false),
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = "Start Time " + match.NewValue.Date.Value.ToUniversalTime().ToString("HH:mm UTC"),
|
||||
Colour = Color4.Black,
|
||||
Font = OsuFont.Torus.With(size: 20)
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(30),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new ScheduleMatch(match.NewValue, false)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
},
|
||||
new TournamentSpriteTextWithBackground(match.NewValue.Round.Value?.Name.Value)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Scale = new Vector2(0.5f)
|
||||
},
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Text = match.NewValue.Team1.Value?.FullName + " vs " + match.NewValue.Team2.Value?.FullName,
|
||||
Font = OsuFont.Torus.With(size: 24, weight: FontWeight.SemiBold)
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = "Starting ",
|
||||
Font = OsuFont.Torus.With(size: 24, weight: FontWeight.Regular)
|
||||
},
|
||||
new DrawableDate(match.NewValue.Date.Value)
|
||||
{
|
||||
Font = OsuFont.Torus.With(size: 24, weight: FontWeight.Regular)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -134,6 +218,10 @@ namespace osu.Game.Tournament.Screens.Schedule
|
||||
{
|
||||
Flow.Direction = FillDirection.Horizontal;
|
||||
|
||||
Scale = new Vector2(0.8f);
|
||||
|
||||
CurrentMatchSelectionBox.Scale = new Vector2(1.02f, 1.15f);
|
||||
|
||||
bool conditional = match is ConditionalTournamentMatch;
|
||||
|
||||
if (conditional)
|
||||
@@ -145,15 +233,16 @@ namespace osu.Game.Tournament.Screens.Schedule
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopLeft,
|
||||
Colour = Color4.Black,
|
||||
Colour = OsuColour.Gray(0.7f),
|
||||
Alpha = conditional ? 0.6f : 1,
|
||||
Font = OsuFont.Torus,
|
||||
Margin = new MarginPadding { Horizontal = 10, Vertical = 5 },
|
||||
});
|
||||
AddInternal(new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Colour = Color4.Black,
|
||||
Colour = OsuColour.Gray(0.7f),
|
||||
Alpha = conditional ? 0.6f : 1,
|
||||
Margin = new MarginPadding { Horizontal = 10, Vertical = 5 },
|
||||
Text = match.Date.Value.ToUniversalTime().ToString("HH:mm UTC") + (conditional ? " (conditional)" : "")
|
||||
@@ -170,29 +259,27 @@ namespace osu.Game.Tournament.Screens.Schedule
|
||||
|
||||
public ScheduleContainer(string title)
|
||||
{
|
||||
Padding = new MarginPadding { Left = 30, Top = 30 };
|
||||
Padding = new MarginPadding { Left = 60, Top = 10 };
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText
|
||||
new FillFlowContainer
|
||||
{
|
||||
X = 30,
|
||||
Text = title,
|
||||
Colour = Color4.Black,
|
||||
Spacing = new Vector2(10, 0),
|
||||
Font = OsuFont.Torus.With(size: 30)
|
||||
},
|
||||
content = new FillFlowContainer
|
||||
{
|
||||
Direction = FillDirection.Vertical,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Margin = new MarginPadding(40)
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TournamentSpriteTextWithBackground(title.ToUpperInvariant())
|
||||
{
|
||||
Scale = new Vector2(0.5f)
|
||||
},
|
||||
content = new FillFlowContainer
|
||||
{
|
||||
Direction = FillDirection.Vertical,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Margin = new MarginPadding(10)
|
||||
},
|
||||
}
|
||||
},
|
||||
new Circle
|
||||
{
|
||||
Colour = new Color4(233, 187, 79, 255),
|
||||
Width = 5,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -34,7 +33,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new TourneyVideo(storage.GetStream(@"videos/seeding.m4v"))
|
||||
new TourneyVideo("seeding")
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Loop = true,
|
||||
@@ -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,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6,7 +6,6 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osuTK;
|
||||
@@ -26,7 +25,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new TourneyVideo(storage.GetStream(@"videos/teamintro.m4v"))
|
||||
new TourneyVideo("teamintro")
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Loop = true,
|
||||
@@ -49,141 +48,33 @@ namespace osu.Game.Tournament.Screens.TeamIntro
|
||||
return;
|
||||
}
|
||||
|
||||
const float y_flag_offset = 292;
|
||||
|
||||
const float y_offset = 460;
|
||||
|
||||
mainContainer.Children = new Drawable[]
|
||||
{
|
||||
new TeamWithPlayers(match.NewValue.Team1.Value, true)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0.5f,
|
||||
Height = 0.6f,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.CentreRight
|
||||
},
|
||||
new TeamWithPlayers(match.NewValue.Team2.Value)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0.5f,
|
||||
Height = 0.6f,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.CentreLeft
|
||||
},
|
||||
new RoundDisplay(match.NewValue)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Height = 0.25f,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Y = 180,
|
||||
}
|
||||
Position = new Vector2(100, 100)
|
||||
},
|
||||
new DrawableTeamFlag(match.NewValue.Team1.Value)
|
||||
{
|
||||
Position = new Vector2(165, y_flag_offset),
|
||||
},
|
||||
new DrawableTeamWithPlayers(match.NewValue.Team1.Value, TeamColour.Red)
|
||||
{
|
||||
Position = new Vector2(165, y_offset),
|
||||
},
|
||||
new DrawableTeamFlag(match.NewValue.Team2.Value)
|
||||
{
|
||||
Position = new Vector2(740, y_flag_offset),
|
||||
},
|
||||
new DrawableTeamWithPlayers(match.NewValue.Team2.Value, TeamColour.Blue)
|
||||
{
|
||||
Position = new Vector2(740, y_offset),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private class RoundDisplay : CompositeDrawable
|
||||
{
|
||||
public RoundDisplay(TournamentMatch match)
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 10),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Colour = OsuColour.Gray(0.33f),
|
||||
Text = match.Round.Value?.Name.Value ?? "Unknown Round",
|
||||
Font = OsuFont.Torus.With(size: 26, weight: FontWeight.Light)
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class TeamWithPlayers : CompositeDrawable
|
||||
{
|
||||
public TeamWithPlayers(TournamentTeam team, bool left = false)
|
||||
{
|
||||
FillFlowContainer players;
|
||||
var colour = left ? TournamentGame.COLOUR_RED : TournamentGame.COLOUR_BLUE;
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new TeamDisplay(team)
|
||||
{
|
||||
Anchor = left ? Anchor.CentreRight : Anchor.CentreLeft,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
X = (left ? -1 : 1) * 0.3145f,
|
||||
Y = -0.077f,
|
||||
},
|
||||
players = new FillFlowContainer
|
||||
{
|
||||
Direction = FillDirection.Vertical,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Spacing = new Vector2(0, 5),
|
||||
Padding = new MarginPadding(20),
|
||||
Anchor = left ? Anchor.CentreRight : Anchor.CentreLeft,
|
||||
Origin = left ? Anchor.CentreRight : Anchor.CentreLeft,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
X = (left ? -1 : 1) * 0.58f,
|
||||
},
|
||||
};
|
||||
|
||||
if (team != null)
|
||||
{
|
||||
foreach (var p in team.Players)
|
||||
{
|
||||
players.Add(new TournamentSpriteText
|
||||
{
|
||||
Text = p.Username,
|
||||
Font = OsuFont.Torus.With(size: 24),
|
||||
Colour = colour,
|
||||
Anchor = left ? Anchor.CentreRight : Anchor.CentreLeft,
|
||||
Origin = left ? Anchor.CentreRight : Anchor.CentreLeft,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TeamDisplay : DrawableTournamentTeam
|
||||
{
|
||||
public TeamDisplay(TournamentTeam team)
|
||||
: base(team)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
Flag.Anchor = Flag.Origin = Anchor.TopCentre;
|
||||
Flag.RelativeSizeAxes = Axes.None;
|
||||
Flag.Size = new Vector2(300, 200);
|
||||
Flag.Scale = new Vector2(0.32f);
|
||||
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(160),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Flag,
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = team?.FullName.Value ?? "???",
|
||||
Font = OsuFont.Torus.With(size: 20, weight: FontWeight.Regular),
|
||||
Colour = OsuColour.Gray(0.2f),
|
||||
Origin = Anchor.TopCentre,
|
||||
Anchor = Anchor.TopCentre,
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tournament.Screens.TeamWin
|
||||
{
|
||||
@@ -31,13 +30,13 @@ namespace osu.Game.Tournament.Screens.TeamWin
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
blueWinVideo = new TourneyVideo(storage.GetStream(@"videos/teamwin-blue.m4v"))
|
||||
blueWinVideo = new TourneyVideo("teamwin-blue")
|
||||
{
|
||||
Alpha = 1,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Loop = true,
|
||||
},
|
||||
redWinVideo = new TourneyVideo(storage.GetStream(@"videos/teamwin-red.m4v"))
|
||||
redWinVideo = new TourneyVideo("teamwin-red")
|
||||
{
|
||||
Alpha = 0,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@@ -63,7 +62,9 @@ namespace osu.Game.Tournament.Screens.TeamWin
|
||||
update();
|
||||
}
|
||||
|
||||
private void update()
|
||||
private bool firstDisplay = true;
|
||||
|
||||
private void update() => Schedule(() =>
|
||||
{
|
||||
var match = currentMatch.Value;
|
||||
|
||||
@@ -73,105 +74,53 @@ namespace osu.Game.Tournament.Screens.TeamWin
|
||||
return;
|
||||
}
|
||||
|
||||
bool redWin = match.Winner == match.Team1.Value;
|
||||
redWinVideo.Alpha = redWin ? 1 : 0;
|
||||
blueWinVideo.Alpha = redWin ? 0 : 1;
|
||||
redWinVideo.Alpha = match.WinnerColour == TeamColour.Red ? 1 : 0;
|
||||
blueWinVideo.Alpha = match.WinnerColour == TeamColour.Blue ? 1 : 0;
|
||||
|
||||
if (firstDisplay)
|
||||
{
|
||||
if (match.WinnerColour == TeamColour.Red)
|
||||
redWinVideo.Reset();
|
||||
else
|
||||
blueWinVideo.Reset();
|
||||
firstDisplay = false;
|
||||
}
|
||||
|
||||
mainContainer.Children = new Drawable[]
|
||||
{
|
||||
new TeamFlagDisplay(match.Winner)
|
||||
new DrawableTeamFlag(match.Winner)
|
||||
{
|
||||
Size = new Vector2(300, 200),
|
||||
Scale = new Vector2(0.5f),
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
X = -387,
|
||||
Position = new Vector2(-300, 10),
|
||||
},
|
||||
new TournamentSpriteText
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.TopLeft,
|
||||
Position = new Vector2(78, -70),
|
||||
Colour = OsuColour.Gray(0.33f),
|
||||
Text = match.Round.Value?.Name.Value ?? "Unknown Round",
|
||||
Font = OsuFont.Torus.With(size: 30, weight: FontWeight.Regular)
|
||||
},
|
||||
new TeamWithPlayers(match.Winner, redWin)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0.5f,
|
||||
Height = 0.6f,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.TopLeft,
|
||||
Position = new Vector2(78, 0),
|
||||
Origin = Anchor.Centre,
|
||||
X = 260,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new RoundDisplay(match)
|
||||
{
|
||||
Margin = new MarginPadding { Bottom = 30 },
|
||||
},
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = "WINNER",
|
||||
Font = OsuFont.Torus.With(size: 100, weight: FontWeight.Bold),
|
||||
Margin = new MarginPadding { Bottom = 50 },
|
||||
},
|
||||
new DrawableTeamWithPlayers(match.Winner, match.WinnerColour)
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private class TeamWithPlayers : CompositeDrawable
|
||||
{
|
||||
public TeamWithPlayers(TournamentTeam team, bool left = false)
|
||||
{
|
||||
FillFlowContainer players;
|
||||
|
||||
var colour = left ? TournamentGame.COLOUR_RED : TournamentGame.COLOUR_BLUE;
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
Direction = FillDirection.Vertical,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = "WINNER",
|
||||
Font = OsuFont.Torus.With(size: 24, weight: FontWeight.SemiBold),
|
||||
Colour = Color4.Black,
|
||||
},
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = team?.FullName.Value ?? "???",
|
||||
Font = OsuFont.Torus.With(size: 30, weight: FontWeight.SemiBold),
|
||||
Colour = Color4.Black,
|
||||
},
|
||||
players = new FillFlowContainer
|
||||
{
|
||||
Direction = FillDirection.Vertical,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Top = 10 },
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if (team != null)
|
||||
{
|
||||
foreach (var p in team.Players)
|
||||
{
|
||||
players.Add(new TournamentSpriteText
|
||||
{
|
||||
Text = p.Username,
|
||||
Font = OsuFont.Torus.With(size: 24),
|
||||
Colour = colour,
|
||||
Anchor = left ? Anchor.CentreRight : Anchor.CentreLeft,
|
||||
Origin = left ? Anchor.CentreRight : Anchor.CentreLeft,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TeamFlagDisplay : DrawableTournamentTeam
|
||||
{
|
||||
public TeamFlagDisplay(TournamentTeam team)
|
||||
: base(team)
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
Flag
|
||||
};
|
||||
}
|
||||
}
|
||||
mainContainer.FadeOut();
|
||||
mainContainer.Delay(2000).FadeIn(1600, Easing.OutQuint);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,9 @@ namespace osu.Game.Tournament.Screens
|
||||
protected TournamentScreen()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
FillMode = FillMode.Fit;
|
||||
FillAspectRatio = 16 / 9f;
|
||||
}
|
||||
|
||||
public override void Hide() => this.FadeOut(FADE_DELAY);
|
||||
|
||||
@@ -1,16 +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 osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tournament
|
||||
{
|
||||
public class TournamentGame : TournamentGameBase
|
||||
{
|
||||
public static readonly Color4 COLOUR_RED = new Color4(144, 0, 0, 255);
|
||||
public static readonly Color4 COLOUR_BLUE = new Color4(0, 84, 144, 255);
|
||||
public static ColourInfo GetTeamColour(TeamColour teamColour) => teamColour == TeamColour.Red ? COLOUR_RED : COLOUR_BLUE;
|
||||
|
||||
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 = Color4Extensions.FromHex("#fff");
|
||||
public static readonly Color4 ELEMENT_FOREGROUND_COLOUR = Color4Extensions.FromHex("#000");
|
||||
|
||||
public static readonly Color4 TEXT_COLOUR = Color4Extensions.FromHex("#fff");
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@ using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Tournament.IPC;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osuTK.Input;
|
||||
|
||||
@@ -36,6 +37,8 @@ namespace osu.Game.Tournament
|
||||
|
||||
private Storage storage;
|
||||
|
||||
private TournamentStorage tournamentStorage;
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
|
||||
private Bindable<Size> windowSize;
|
||||
@@ -53,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;
|
||||
|
||||
@@ -74,16 +79,40 @@ namespace osu.Game.Tournament
|
||||
|
||||
AddRange(new[]
|
||||
{
|
||||
new TourneyButton
|
||||
new Container
|
||||
{
|
||||
Text = "Save Changes",
|
||||
Width = 140,
|
||||
Height = 50,
|
||||
CornerRadius = 10,
|
||||
Depth = float.MinValue,
|
||||
Position = new Vector2(5),
|
||||
Masking = true,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
Padding = new MarginPadding(10),
|
||||
Action = SaveChanges,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = OsuColour.Gray(0.2f),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new TourneyButton
|
||||
{
|
||||
Text = "Save Changes",
|
||||
Width = 140,
|
||||
Height = 50,
|
||||
Padding = new MarginPadding
|
||||
{
|
||||
Top = 10,
|
||||
Left = 10,
|
||||
},
|
||||
Margin = new MarginPadding
|
||||
{
|
||||
Right = 10,
|
||||
Bottom = 10,
|
||||
},
|
||||
Action = SaveChanges,
|
||||
},
|
||||
}
|
||||
},
|
||||
heightWarning = new Container
|
||||
{
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace osu.Game.Tournament
|
||||
//Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
video = new TourneyVideo(storage.GetStream("videos/main.m4v"))
|
||||
video = new TourneyVideo("main", true)
|
||||
{
|
||||
Loop = true,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@@ -194,9 +194,14 @@ namespace osu.Game.Tournament
|
||||
|
||||
switch (currentScreen)
|
||||
{
|
||||
case GameplayScreen _:
|
||||
case MapPoolScreen _:
|
||||
chatContainer.FadeIn(TournamentScreen.FADE_DELAY);
|
||||
chatContainer.ResizeWidthTo(1, 500, Easing.OutQuint);
|
||||
break;
|
||||
|
||||
case GameplayScreen _:
|
||||
chatContainer.FadeIn(TournamentScreen.FADE_DELAY);
|
||||
chatContainer.ResizeWidthTo(0.5f, 500, Easing.OutQuint);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,11 @@ namespace osu.Game.Graphics.UserInterface
|
||||
{
|
||||
public class OsuPasswordTextBox : OsuTextBox, ISuppressKeyEventLogging
|
||||
{
|
||||
protected override Drawable GetDrawableCharacter(char c) => new PasswordMaskChar(CalculatedTextSize);
|
||||
protected override Drawable GetDrawableCharacter(char c) => new FallingDownContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Child = new PasswordMaskChar(CalculatedTextSize),
|
||||
};
|
||||
|
||||
protected override bool AllowClipboardExport => false;
|
||||
|
||||
|
||||