mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 19:42:55 +08:00
Merge branch 'master' into morth-taiko-changes
This commit is contained in:
commit
d04da46522
@ -51,7 +51,7 @@
|
|||||||
<Reference Include="Java.Interop" />
|
<Reference Include="Java.Interop" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.427.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.512.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.508.1" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.518.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
36
osu.Game.Rulesets.Catch.Tests/CatchSkinColourDecodingTest.cs
Normal file
36
osu.Game.Rulesets.Catch.Tests/CatchSkinColourDecodingTest.cs
Normal file
@ -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 NUnit.Framework;
|
||||||
|
using osu.Framework.IO.Stores;
|
||||||
|
using osu.Game.Rulesets.Catch.Skinning;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Tests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class CatchSkinColourDecodingTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestCatchSkinColourDecoding()
|
||||||
|
{
|
||||||
|
var store = new NamespacedResourceStore<byte[]>(new DllResourceStore(GetType().Assembly), "Resources/special-skin");
|
||||||
|
var rawSkin = new TestLegacySkin(new SkinInfo { Name = "special-skin" }, store);
|
||||||
|
var skin = new CatchLegacySkinTransformer(rawSkin);
|
||||||
|
|
||||||
|
Assert.AreEqual(new Color4(232, 185, 35, 255), skin.GetConfig<CatchSkinColour, Color4>(CatchSkinColour.HyperDash)?.Value);
|
||||||
|
Assert.AreEqual(new Color4(232, 74, 35, 255), skin.GetConfig<CatchSkinColour, Color4>(CatchSkinColour.HyperDashAfterImage)?.Value);
|
||||||
|
Assert.AreEqual(new Color4(0, 255, 255, 255), skin.GetConfig<CatchSkinColour, Color4>(CatchSkinColour.HyperDashFruit)?.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestLegacySkin : LegacySkin
|
||||||
|
{
|
||||||
|
public TestLegacySkin(SkinInfo skin, IResourceStore<byte[]> storage)
|
||||||
|
// Bypass LegacySkinResourceStore to avoid returning null for retrieving files due to bad skin info (SkinInfo.Files = null).
|
||||||
|
: base(skin, storage, null, "skin.ini")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +1,12 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using osu.Game.Rulesets.Catch.Skinning;
|
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Tests
|
namespace osu.Game.Rulesets.Catch.Tests
|
||||||
{
|
{
|
||||||
public abstract class CatchSkinnableTestScene : SkinnableTestScene
|
public abstract class CatchSkinnableTestScene : SkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(CatchRuleset),
|
|
||||||
typeof(CatchLegacySkinTransformer),
|
|
||||||
};
|
|
||||||
|
|
||||||
protected override Ruleset CreateRulesetForSkinProvider() => new CatchRuleset();
|
protected override Ruleset CreateRulesetForSkinProvider() => new CatchRuleset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
[CatchTheBeat]
|
||||||
|
HyperDash: 232,185,35
|
||||||
|
HyperDashFruit: 0,255,255
|
||||||
|
HyperDashAfterImage: 232,74,35
|
@ -1,13 +1,9 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.Objects.Drawables;
|
|
||||||
using osu.Game.Rulesets.Catch.UI;
|
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Tests
|
namespace osu.Game.Rulesets.Catch.Tests
|
||||||
@ -15,17 +11,6 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneBananaShower : PlayerTestScene
|
public class TestSceneBananaShower : PlayerTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(BananaShower),
|
|
||||||
typeof(Banana),
|
|
||||||
typeof(DrawableBananaShower),
|
|
||||||
typeof(DrawableBanana),
|
|
||||||
|
|
||||||
typeof(CatchRuleset),
|
|
||||||
typeof(DrawableCatchRuleset),
|
|
||||||
};
|
|
||||||
|
|
||||||
public TestSceneBananaShower()
|
public TestSceneBananaShower()
|
||||||
: base(new CatchRuleset())
|
: base(new CatchRuleset())
|
||||||
{
|
{
|
||||||
|
@ -4,26 +4,18 @@
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Game.Rulesets.Catch.UI;
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Tests
|
namespace osu.Game.Rulesets.Catch.Tests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneCatcher : CatchSkinnableTestScene
|
public class TestSceneCatcher : CatchSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[]
|
|
||||||
{
|
|
||||||
typeof(CatcherArea),
|
|
||||||
typeof(CatcherSprite)
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
SetContents(() => new Catcher
|
SetContents(() => new Catcher(new Container())
|
||||||
{
|
{
|
||||||
RelativePositionAxes = Axes.None,
|
RelativePositionAxes = Axes.None,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@ -22,15 +21,6 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
{
|
{
|
||||||
public class TestSceneDrawableHitObjects : OsuTestScene
|
public class TestSceneDrawableHitObjects : OsuTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(Catcher),
|
|
||||||
typeof(DrawableCatchRuleset),
|
|
||||||
typeof(DrawableFruit),
|
|
||||||
typeof(DrawableJuiceStream),
|
|
||||||
typeof(DrawableBanana)
|
|
||||||
};
|
|
||||||
|
|
||||||
private DrawableCatchRuleset drawableRuleset;
|
private DrawableCatchRuleset drawableRuleset;
|
||||||
private double playfieldTime => drawableRuleset.Playfield.Time.Current;
|
private double playfieldTime => drawableRuleset.Playfield.Time.Current;
|
||||||
|
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// 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 NUnit.Framework;
|
||||||
using osu.Game.Rulesets.Catch.Mods;
|
using osu.Game.Rulesets.Catch.Mods;
|
||||||
|
|
||||||
@ -11,8 +8,6 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
{
|
{
|
||||||
public class TestSceneDrawableHitObjectsHidden : TestSceneDrawableHitObjects
|
public class TestSceneDrawableHitObjectsHidden : TestSceneDrawableHitObjects
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(CatchModHidden) }).ToList();
|
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
|
@ -2,13 +2,10 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.Objects.Drawables;
|
using osu.Game.Rulesets.Catch.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Catch.Objects.Drawables.Pieces;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Tests
|
namespace osu.Game.Rulesets.Catch.Tests
|
||||||
@ -16,22 +13,6 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneFruitObjects : CatchSkinnableTestScene
|
public class TestSceneFruitObjects : CatchSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[]
|
|
||||||
{
|
|
||||||
typeof(CatchHitObject),
|
|
||||||
typeof(Fruit),
|
|
||||||
typeof(FruitPiece),
|
|
||||||
typeof(Droplet),
|
|
||||||
typeof(Banana),
|
|
||||||
typeof(BananaShower),
|
|
||||||
typeof(DrawableCatchHitObject),
|
|
||||||
typeof(DrawableFruit),
|
|
||||||
typeof(DrawableDroplet),
|
|
||||||
typeof(DrawableBanana),
|
|
||||||
typeof(DrawableBananaShower),
|
|
||||||
typeof(Pulp),
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
@ -18,11 +17,6 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneHyperDash : PlayerTestScene
|
public class TestSceneHyperDash : PlayerTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(CatcherArea),
|
|
||||||
};
|
|
||||||
|
|
||||||
public TestSceneHyperDash()
|
public TestSceneHyperDash()
|
||||||
: base(new CatchRuleset())
|
: base(new CatchRuleset())
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,48 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private SkinManager skins { get; set; }
|
private SkinManager skins { get; set; }
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDefaultCatcherColour()
|
||||||
|
{
|
||||||
|
var skin = new TestSkin();
|
||||||
|
|
||||||
|
checkHyperDashCatcherColour(skin, Catcher.DEFAULT_HYPER_DASH_COLOUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCustomCatcherColour()
|
||||||
|
{
|
||||||
|
var skin = new TestSkin
|
||||||
|
{
|
||||||
|
HyperDashColour = Color4.Goldenrod
|
||||||
|
};
|
||||||
|
|
||||||
|
checkHyperDashCatcherColour(skin, skin.HyperDashColour);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCustomEndGlowColour()
|
||||||
|
{
|
||||||
|
var skin = new TestSkin
|
||||||
|
{
|
||||||
|
HyperDashAfterImageColour = Color4.Lime
|
||||||
|
};
|
||||||
|
|
||||||
|
checkHyperDashCatcherColour(skin, Catcher.DEFAULT_HYPER_DASH_COLOUR, skin.HyperDashAfterImageColour);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCustomEndGlowColourPriority()
|
||||||
|
{
|
||||||
|
var skin = new TestSkin
|
||||||
|
{
|
||||||
|
HyperDashColour = Color4.Goldenrod,
|
||||||
|
HyperDashAfterImageColour = Color4.Lime
|
||||||
|
};
|
||||||
|
|
||||||
|
checkHyperDashCatcherColour(skin, skin.HyperDashColour, skin.HyperDashAfterImageColour);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestDefaultFruitColour()
|
public void TestDefaultFruitColour()
|
||||||
{
|
{
|
||||||
@ -68,6 +110,38 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
checkHyperDashFruitColour(skin, skin.HyperDashColour);
|
checkHyperDashFruitColour(skin, skin.HyperDashColour);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkHyperDashCatcherColour(ISkin skin, Color4 expectedCatcherColour, Color4? expectedEndGlowColour = null)
|
||||||
|
{
|
||||||
|
CatcherArea catcherArea = null;
|
||||||
|
CatcherTrailDisplay trails = null;
|
||||||
|
|
||||||
|
AddStep("create hyper-dashing catcher", () =>
|
||||||
|
{
|
||||||
|
Child = setupSkinHierarchy(catcherArea = new CatcherArea
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Scale = new Vector2(4f),
|
||||||
|
}, skin);
|
||||||
|
|
||||||
|
trails = catcherArea.OfType<CatcherTrailDisplay>().Single();
|
||||||
|
catcherArea.MovableCatcher.SetHyperDashState(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("catcher colour is correct", () => catcherArea.MovableCatcher.Colour == expectedCatcherColour);
|
||||||
|
|
||||||
|
AddAssert("catcher trails colours are correct", () => trails.HyperDashTrailsColour == expectedCatcherColour);
|
||||||
|
AddAssert("catcher end-glow colours are correct", () => trails.EndGlowSpritesColour == (expectedEndGlowColour ?? expectedCatcherColour));
|
||||||
|
|
||||||
|
AddStep("finish hyper-dashing", () =>
|
||||||
|
{
|
||||||
|
catcherArea.MovableCatcher.SetHyperDashState(1);
|
||||||
|
catcherArea.MovableCatcher.FinishTransforms();
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("catcher colour returned to white", () => catcherArea.MovableCatcher.Colour == Color4.White);
|
||||||
|
}
|
||||||
|
|
||||||
private void checkHyperDashFruitColour(ISkin skin, Color4 expectedColour)
|
private void checkHyperDashFruitColour(ISkin skin, Color4 expectedColour)
|
||||||
{
|
{
|
||||||
DrawableFruit drawableFruit = null;
|
DrawableFruit drawableFruit = null;
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Difficulty;
|
using osu.Game.Rulesets.Difficulty;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Scoring.Legacy;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Difficulty
|
namespace osu.Game.Rulesets.Catch.Difficulty
|
||||||
{
|
{
|
||||||
@ -34,11 +34,11 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
{
|
{
|
||||||
mods = Score.Mods;
|
mods = Score.Mods;
|
||||||
|
|
||||||
fruitsHit = Score?.GetCount300() ?? Score.Statistics[HitResult.Perfect];
|
fruitsHit = Score.Statistics.GetOrDefault(HitResult.Perfect);
|
||||||
ticksHit = Score?.GetCount100() ?? 0;
|
ticksHit = Score.Statistics.GetOrDefault(HitResult.LargeTickHit);
|
||||||
tinyTicksHit = Score?.GetCount50() ?? 0;
|
tinyTicksHit = Score.Statistics.GetOrDefault(HitResult.SmallTickHit);
|
||||||
tinyTicksMissed = Score?.GetCountKatu() ?? 0;
|
tinyTicksMissed = Score.Statistics.GetOrDefault(HitResult.SmallTickMiss);
|
||||||
misses = Score.Statistics[HitResult.Miss];
|
misses = Score.Statistics.GetOrDefault(HitResult.Miss);
|
||||||
|
|
||||||
// Don't count scores made with supposedly unranked mods
|
// Don't count scores made with supposedly unranked mods
|
||||||
if (mods.Any(m => !m.Ranked))
|
if (mods.Any(m => !m.Ranked))
|
||||||
@ -52,8 +52,8 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
|
|
||||||
// Longer maps are worth more
|
// Longer maps are worth more
|
||||||
double lengthBonus =
|
double lengthBonus =
|
||||||
0.95f + 0.3f * Math.Min(1.0f, numTotalHits / 2500.0f) +
|
0.95 + 0.3 * Math.Min(1.0, numTotalHits / 2500.0) +
|
||||||
(numTotalHits > 2500 ? (float)Math.Log10(numTotalHits / 2500.0f) * 0.475f : 0.0f);
|
(numTotalHits > 2500 ? Math.Log10(numTotalHits / 2500.0) * 0.475 : 0.0);
|
||||||
|
|
||||||
// Longer maps are worth more
|
// Longer maps are worth more
|
||||||
value *= lengthBonus;
|
value *= lengthBonus;
|
||||||
@ -65,14 +65,14 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
if (Attributes.MaxCombo > 0)
|
if (Attributes.MaxCombo > 0)
|
||||||
value *= Math.Min(Math.Pow(Score.MaxCombo, 0.8) / Math.Pow(Attributes.MaxCombo, 0.8), 1.0);
|
value *= Math.Min(Math.Pow(Score.MaxCombo, 0.8) / Math.Pow(Attributes.MaxCombo, 0.8), 1.0);
|
||||||
|
|
||||||
float approachRate = (float)Attributes.ApproachRate;
|
double approachRate = Attributes.ApproachRate;
|
||||||
float approachRateFactor = 1.0f;
|
double approachRateFactor = 1.0;
|
||||||
if (approachRate > 9.0f)
|
if (approachRate > 9.0)
|
||||||
approachRateFactor += 0.1f * (approachRate - 9.0f); // 10% for each AR above 9
|
approachRateFactor += 0.1 * (approachRate - 9.0); // 10% for each AR above 9
|
||||||
if (approachRate > 10.0f)
|
if (approachRate > 10.0)
|
||||||
approachRateFactor += 0.1f * (approachRate - 10.0f); // Additional 10% at AR 11, 30% total
|
approachRateFactor += 0.1 * (approachRate - 10.0); // Additional 10% at AR 11, 30% total
|
||||||
else if (approachRate < 8.0f)
|
else if (approachRate < 8.0)
|
||||||
approachRateFactor += 0.025f * (8.0f - approachRate); // 2.5% for each AR below 8
|
approachRateFactor += 0.025 * (8.0 - approachRate); // 2.5% for each AR below 8
|
||||||
|
|
||||||
value *= approachRateFactor;
|
value *= approachRateFactor;
|
||||||
|
|
||||||
@ -80,10 +80,10 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
{
|
{
|
||||||
value *= 1.05 + 0.075 * (10.0 - Math.Min(10.0, Attributes.ApproachRate)); // 7.5% for each AR below 10
|
value *= 1.05 + 0.075 * (10.0 - Math.Min(10.0, Attributes.ApproachRate)); // 7.5% for each AR below 10
|
||||||
// Hiddens gives almost nothing on max approach rate, and more the lower it is
|
// Hiddens gives almost nothing on max approach rate, and more the lower it is
|
||||||
if (approachRate <= 10.0f)
|
if (approachRate <= 10.0)
|
||||||
value *= 1.05f + 0.075f * (10.0f - approachRate); // 7.5% for each AR below 10
|
value *= 1.05 + 0.075 * (10.0 - approachRate); // 7.5% for each AR below 10
|
||||||
else if (approachRate > 10.0f)
|
else if (approachRate > 10.0)
|
||||||
value *= 1.01f + 0.04f * (11.0f - Math.Min(11.0f, approachRate)); // 5% at AR 10, 1% at AR 11
|
value *= 1.01 + 0.04 * (11.0 - Math.Min(11.0, approachRate)); // 5% at AR 10, 1% at AR 11
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mods.Any(m => m is ModFlashlight))
|
if (mods.Any(m => m is ModFlashlight))
|
||||||
@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float accuracy() => totalHits() == 0 ? 0 : Math.Clamp((float)totalSuccessfulHits() / totalHits(), 0, 1);
|
private double accuracy() => totalHits() == 0 ? 0 : Math.Clamp((double)totalSuccessfulHits() / totalHits(), 0, 1);
|
||||||
private int totalHits() => tinyTicksHit + ticksHit + fruitsHit + misses + tinyTicksMissed;
|
private int totalHits() => tinyTicksHit + ticksHit + fruitsHit + misses + tinyTicksMissed;
|
||||||
private int totalSuccessfulHits() => tinyTicksHit + ticksHit + fruitsHit;
|
private int totalSuccessfulHits() => tinyTicksHit + ticksHit + fruitsHit;
|
||||||
private int totalComboHits() => misses + ticksHit + fruitsHit;
|
private int totalComboHits() => misses + ticksHit + fruitsHit;
|
||||||
|
@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Skinning
|
|||||||
{
|
{
|
||||||
private readonly ISkin source;
|
private readonly ISkin source;
|
||||||
|
|
||||||
public CatchLegacySkinTransformer(ISkinSource source)
|
public CatchLegacySkinTransformer(ISkin source)
|
||||||
{
|
{
|
||||||
this.source = source;
|
this.source = source;
|
||||||
}
|
}
|
||||||
|
@ -3,26 +3,37 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Animations;
|
using osu.Framework.Graphics.Animations;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.Objects.Drawables;
|
using osu.Game.Rulesets.Catch.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Catch.Skinning;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.UI
|
namespace osu.Game.Rulesets.Catch.UI
|
||||||
{
|
{
|
||||||
public class Catcher : Container, IKeyBindingHandler<CatchAction>
|
public class Catcher : SkinReloadableDrawable, IKeyBindingHandler<CatchAction>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The default colour used to tint hyper-dash fruit, along with the moving catcher, its trail
|
||||||
|
/// and end glow/after-image during a hyper-dash.
|
||||||
|
/// </summary>
|
||||||
public static readonly Color4 DEFAULT_HYPER_DASH_COLOUR = Color4.Red;
|
public static readonly Color4 DEFAULT_HYPER_DASH_COLOUR = Color4.Red;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The duration between transitioning to hyper-dash state.
|
||||||
|
/// </summary>
|
||||||
|
public const double HYPER_DASH_TRANSITION_DURATION = 180;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether we are hyper-dashing or not.
|
/// Whether we are hyper-dashing or not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -35,7 +46,10 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
public Container ExplodingFruitTarget;
|
public Container ExplodingFruitTarget;
|
||||||
|
|
||||||
public Container AdditiveTarget;
|
[NotNull]
|
||||||
|
private readonly Container trailsTarget;
|
||||||
|
|
||||||
|
private CatcherTrailDisplay trails;
|
||||||
|
|
||||||
public CatcherAnimationState CurrentState { get; private set; }
|
public CatcherAnimationState CurrentState { get; private set; }
|
||||||
|
|
||||||
@ -44,33 +58,23 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private const float allowed_catch_range = 0.8f;
|
private const float allowed_catch_range = 0.8f;
|
||||||
|
|
||||||
protected bool Dashing
|
/// <summary>
|
||||||
|
/// The drawable catcher for <see cref="CurrentState"/>.
|
||||||
|
/// </summary>
|
||||||
|
internal Drawable CurrentDrawableCatcher => currentCatcher.Drawable;
|
||||||
|
|
||||||
|
private bool dashing;
|
||||||
|
|
||||||
|
public bool Dashing
|
||||||
{
|
{
|
||||||
get => dashing;
|
get => dashing;
|
||||||
set
|
protected set
|
||||||
{
|
{
|
||||||
if (value == dashing) return;
|
if (value == dashing) return;
|
||||||
|
|
||||||
dashing = value;
|
dashing = value;
|
||||||
|
|
||||||
Trail |= dashing;
|
updateTrailVisibility();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Activate or deactivate the trail. Will be automatically deactivated when conditions to keep the trail displayed are no longer met.
|
|
||||||
/// </summary>
|
|
||||||
protected bool Trail
|
|
||||||
{
|
|
||||||
get => trail;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value == trail || AdditiveTarget == null) return;
|
|
||||||
|
|
||||||
trail = value;
|
|
||||||
|
|
||||||
if (Trail)
|
|
||||||
beginTrail();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,18 +91,19 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
private CatcherSprite currentCatcher;
|
private CatcherSprite currentCatcher;
|
||||||
|
|
||||||
|
private Color4 hyperDashColour = DEFAULT_HYPER_DASH_COLOUR;
|
||||||
|
private Color4 hyperDashEndGlowColour = DEFAULT_HYPER_DASH_COLOUR;
|
||||||
|
|
||||||
private int currentDirection;
|
private int currentDirection;
|
||||||
|
|
||||||
private bool dashing;
|
|
||||||
|
|
||||||
private bool trail;
|
|
||||||
|
|
||||||
private double hyperDashModifier = 1;
|
private double hyperDashModifier = 1;
|
||||||
private int hyperDashDirection;
|
private int hyperDashDirection;
|
||||||
private float hyperDashTargetPosition;
|
private float hyperDashTargetPosition;
|
||||||
|
|
||||||
public Catcher(BeatmapDifficulty difficulty = null)
|
public Catcher([NotNull] Container trailsTarget, BeatmapDifficulty difficulty = null)
|
||||||
{
|
{
|
||||||
|
this.trailsTarget = trailsTarget;
|
||||||
|
|
||||||
RelativePositionAxes = Axes.X;
|
RelativePositionAxes = Axes.X;
|
||||||
X = 0.5f;
|
X = 0.5f;
|
||||||
|
|
||||||
@ -114,7 +119,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
caughtFruit = new Container<DrawableHitObject>
|
caughtFruit = new Container<DrawableHitObject>
|
||||||
{
|
{
|
||||||
@ -138,6 +143,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
trailsTarget.Add(trails = new CatcherTrailDisplay(this));
|
||||||
|
|
||||||
updateCatcher();
|
updateCatcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +192,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
caughtFruit.Add(fruit);
|
caughtFruit.Add(fruit);
|
||||||
|
|
||||||
Add(new HitExplosion(fruit)
|
AddInternal(new HitExplosion(fruit)
|
||||||
{
|
{
|
||||||
X = fruit.X,
|
X = fruit.X,
|
||||||
Scale = new Vector2(fruit.HitObject.Scale)
|
Scale = new Vector2(fruit.HitObject.Scale)
|
||||||
@ -240,8 +247,6 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
/// <param name="targetPosition">When this catcher crosses this position, this catcher ends hyper-dashing.</param>
|
/// <param name="targetPosition">When this catcher crosses this position, this catcher ends hyper-dashing.</param>
|
||||||
public void SetHyperDashState(double modifier = 1, float targetPosition = -1)
|
public void SetHyperDashState(double modifier = 1, float targetPosition = -1)
|
||||||
{
|
{
|
||||||
const float hyper_dash_transition_length = 180;
|
|
||||||
|
|
||||||
var wasHyperDashing = HyperDashing;
|
var wasHyperDashing = HyperDashing;
|
||||||
|
|
||||||
if (modifier <= 1 || X == targetPosition)
|
if (modifier <= 1 || X == targetPosition)
|
||||||
@ -250,11 +255,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
hyperDashDirection = 0;
|
hyperDashDirection = 0;
|
||||||
|
|
||||||
if (wasHyperDashing)
|
if (wasHyperDashing)
|
||||||
{
|
runHyperDashStateTransition(false);
|
||||||
this.FadeColour(Color4.White, hyper_dash_transition_length, Easing.OutQuint);
|
|
||||||
this.FadeTo(1, hyper_dash_transition_length, Easing.OutQuint);
|
|
||||||
Trail &= Dashing;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -264,20 +265,32 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
if (!wasHyperDashing)
|
if (!wasHyperDashing)
|
||||||
{
|
{
|
||||||
this.FadeColour(Color4.OrangeRed, hyper_dash_transition_length, Easing.OutQuint);
|
trails.DisplayEndGlow();
|
||||||
this.FadeTo(0.2f, hyper_dash_transition_length, Easing.OutQuint);
|
runHyperDashStateTransition(true);
|
||||||
Trail = true;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var hyperDashEndGlow = createAdditiveSprite();
|
private void runHyperDashStateTransition(bool hyperDashing)
|
||||||
|
{
|
||||||
|
trails.HyperDashTrailsColour = hyperDashColour;
|
||||||
|
trails.EndGlowSpritesColour = hyperDashEndGlowColour;
|
||||||
|
updateTrailVisibility();
|
||||||
|
|
||||||
hyperDashEndGlow.MoveToOffset(new Vector2(0, -10), 1200, Easing.In);
|
if (hyperDashing)
|
||||||
hyperDashEndGlow.ScaleTo(hyperDashEndGlow.Scale * 0.95f).ScaleTo(hyperDashEndGlow.Scale * 1.2f, 1200, Easing.In);
|
{
|
||||||
hyperDashEndGlow.FadeOut(1200);
|
this.FadeColour(hyperDashColour, HYPER_DASH_TRANSITION_DURATION, Easing.OutQuint);
|
||||||
hyperDashEndGlow.Expire(true);
|
this.FadeTo(0.2f, HYPER_DASH_TRANSITION_DURATION, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.FadeColour(Color4.White, HYPER_DASH_TRANSITION_DURATION, Easing.OutQuint);
|
||||||
|
this.FadeTo(1f, HYPER_DASH_TRANSITION_DURATION, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateTrailVisibility() => trails.DisplayTrail = Dashing || HyperDashing;
|
||||||
|
|
||||||
public bool OnPressed(CatchAction action)
|
public bool OnPressed(CatchAction action)
|
||||||
{
|
{
|
||||||
switch (action)
|
switch (action)
|
||||||
@ -366,6 +379,21 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
|
||||||
|
{
|
||||||
|
base.SkinChanged(skin, allowFallback);
|
||||||
|
|
||||||
|
hyperDashColour =
|
||||||
|
skin.GetConfig<CatchSkinColour, Color4>(CatchSkinColour.HyperDash)?.Value ??
|
||||||
|
DEFAULT_HYPER_DASH_COLOUR;
|
||||||
|
|
||||||
|
hyperDashEndGlowColour =
|
||||||
|
skin.GetConfig<CatchSkinColour, Color4>(CatchSkinColour.HyperDashAfterImage)?.Value ??
|
||||||
|
hyperDashColour;
|
||||||
|
|
||||||
|
runHyperDashStateTransition(HyperDashing);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
@ -411,22 +439,6 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
(currentCatcher.Drawable as IFramedAnimation)?.GotoFrame(0);
|
(currentCatcher.Drawable as IFramedAnimation)?.GotoFrame(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void beginTrail()
|
|
||||||
{
|
|
||||||
if (!dashing && !HyperDashing)
|
|
||||||
{
|
|
||||||
Trail = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var additive = createAdditiveSprite();
|
|
||||||
|
|
||||||
additive.FadeTo(0.4f).FadeOut(800, Easing.OutQuint);
|
|
||||||
additive.Expire(true);
|
|
||||||
|
|
||||||
Scheduler.AddDelayed(beginTrail, HyperDashing ? 25 : 50);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateState(CatcherAnimationState state)
|
private void updateState(CatcherAnimationState state)
|
||||||
{
|
{
|
||||||
if (CurrentState == state)
|
if (CurrentState == state)
|
||||||
@ -436,25 +448,6 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
updateCatcher();
|
updateCatcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
private CatcherTrailSprite createAdditiveSprite()
|
|
||||||
{
|
|
||||||
var tex = (currentCatcher.Drawable as TextureAnimation)?.CurrentFrame ?? ((Sprite)currentCatcher.Drawable).Texture;
|
|
||||||
|
|
||||||
var sprite = new CatcherTrailSprite(tex)
|
|
||||||
{
|
|
||||||
Anchor = Anchor,
|
|
||||||
Scale = Scale,
|
|
||||||
Colour = HyperDashing ? Color4.Red : Color4.White,
|
|
||||||
Blending = BlendingParameters.Additive,
|
|
||||||
RelativePositionAxes = RelativePositionAxes,
|
|
||||||
Position = Position
|
|
||||||
};
|
|
||||||
|
|
||||||
AdditiveTarget?.Add(sprite);
|
|
||||||
|
|
||||||
return sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeFromPlateWithTransform(DrawableHitObject fruit, Action<DrawableHitObject> action)
|
private void removeFromPlateWithTransform(DrawableHitObject fruit, Action<DrawableHitObject> action)
|
||||||
{
|
{
|
||||||
if (ExplodingFruitTarget != null)
|
if (ExplodingFruitTarget != null)
|
||||||
|
@ -33,10 +33,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
Height = CATCHER_SIZE;
|
Height = CATCHER_SIZE;
|
||||||
Child = MovableCatcher = new Catcher(difficulty)
|
Child = MovableCatcher = new Catcher(this, difficulty);
|
||||||
{
|
|
||||||
AdditiveTarget = this,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float GetCatcherSize(BeatmapDifficulty difficulty)
|
public static float GetCatcherSize(BeatmapDifficulty difficulty)
|
||||||
|
135
osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs
Normal file
135
osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
// 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 JetBrains.Annotations;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Animations;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.UI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a component responsible for displaying
|
||||||
|
/// the appropriate catcher trails when requested to.
|
||||||
|
/// </summary>
|
||||||
|
public class CatcherTrailDisplay : CompositeDrawable
|
||||||
|
{
|
||||||
|
private readonly Catcher catcher;
|
||||||
|
|
||||||
|
private readonly Container<CatcherTrailSprite> dashTrails;
|
||||||
|
private readonly Container<CatcherTrailSprite> hyperDashTrails;
|
||||||
|
private readonly Container<CatcherTrailSprite> endGlowSprites;
|
||||||
|
|
||||||
|
private Color4 hyperDashTrailsColour;
|
||||||
|
|
||||||
|
public Color4 HyperDashTrailsColour
|
||||||
|
{
|
||||||
|
get => hyperDashTrailsColour;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (hyperDashTrailsColour == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hyperDashTrailsColour = value;
|
||||||
|
hyperDashTrails.FadeColour(hyperDashTrailsColour, Catcher.HYPER_DASH_TRANSITION_DURATION, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color4 endGlowSpritesColour;
|
||||||
|
|
||||||
|
public Color4 EndGlowSpritesColour
|
||||||
|
{
|
||||||
|
get => endGlowSpritesColour;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (endGlowSpritesColour == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
endGlowSpritesColour = value;
|
||||||
|
endGlowSprites.FadeColour(endGlowSpritesColour, Catcher.HYPER_DASH_TRANSITION_DURATION, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool trail;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to start displaying trails following the catcher.
|
||||||
|
/// </summary>
|
||||||
|
public bool DisplayTrail
|
||||||
|
{
|
||||||
|
get => trail;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (trail == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
trail = value;
|
||||||
|
|
||||||
|
if (trail)
|
||||||
|
displayTrail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CatcherTrailDisplay([NotNull] Catcher catcher)
|
||||||
|
{
|
||||||
|
this.catcher = catcher ?? throw new ArgumentNullException(nameof(catcher));
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
InternalChildren = new[]
|
||||||
|
{
|
||||||
|
dashTrails = new Container<CatcherTrailSprite> { RelativeSizeAxes = Axes.Both },
|
||||||
|
hyperDashTrails = new Container<CatcherTrailSprite> { RelativeSizeAxes = Axes.Both, Colour = Catcher.DEFAULT_HYPER_DASH_COLOUR },
|
||||||
|
endGlowSprites = new Container<CatcherTrailSprite> { RelativeSizeAxes = Axes.Both, Colour = Catcher.DEFAULT_HYPER_DASH_COLOUR },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Displays a single end-glow catcher sprite.
|
||||||
|
/// </summary>
|
||||||
|
public void DisplayEndGlow()
|
||||||
|
{
|
||||||
|
var endGlow = createTrailSprite(endGlowSprites);
|
||||||
|
|
||||||
|
endGlow.MoveToOffset(new Vector2(0, -10), 1200, Easing.In);
|
||||||
|
endGlow.ScaleTo(endGlow.Scale * 0.95f).ScaleTo(endGlow.Scale * 1.2f, 1200, Easing.In);
|
||||||
|
endGlow.FadeOut(1200);
|
||||||
|
endGlow.Expire(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayTrail()
|
||||||
|
{
|
||||||
|
if (!DisplayTrail)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var sprite = createTrailSprite(catcher.HyperDashing ? hyperDashTrails : dashTrails);
|
||||||
|
|
||||||
|
sprite.FadeTo(0.4f).FadeOut(800, Easing.OutQuint);
|
||||||
|
sprite.Expire(true);
|
||||||
|
|
||||||
|
Scheduler.AddDelayed(displayTrail, catcher.HyperDashing ? 25 : 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CatcherTrailSprite createTrailSprite(Container<CatcherTrailSprite> target)
|
||||||
|
{
|
||||||
|
var texture = (catcher.CurrentDrawableCatcher as TextureAnimation)?.CurrentFrame ?? ((Sprite)catcher.CurrentDrawableCatcher).Texture;
|
||||||
|
|
||||||
|
var sprite = new CatcherTrailSprite(texture)
|
||||||
|
{
|
||||||
|
Anchor = catcher.Anchor,
|
||||||
|
Scale = catcher.Scale,
|
||||||
|
Blending = BlendingParameters.Additive,
|
||||||
|
RelativePositionAxes = catcher.RelativePositionAxes,
|
||||||
|
Position = catcher.Position
|
||||||
|
};
|
||||||
|
|
||||||
|
target.Add(sprite);
|
||||||
|
|
||||||
|
return sprite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,12 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Rulesets.Mania.Skinning;
|
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using osu.Game.Rulesets.UI.Scrolling.Algorithms;
|
using osu.Game.Rulesets.UI.Scrolling.Algorithms;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
@ -27,13 +24,6 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
|||||||
[Cached(Type = typeof(IScrollingInfo))]
|
[Cached(Type = typeof(IScrollingInfo))]
|
||||||
private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo();
|
private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo();
|
||||||
|
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(ManiaRuleset),
|
|
||||||
typeof(ManiaLegacySkinTransformer),
|
|
||||||
typeof(ManiaSettingsSubsection)
|
|
||||||
};
|
|
||||||
|
|
||||||
protected override Ruleset CreateRulesetForSkinProvider() => new ManiaRuleset();
|
protected override Ruleset CreateRulesetForSkinProvider() => new ManiaRuleset();
|
||||||
|
|
||||||
protected ManiaSkinnableTestScene()
|
protected ManiaSkinnableTestScene()
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -15,12 +14,6 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
|||||||
{
|
{
|
||||||
public class TestSceneDrawableJudgement : ManiaSkinnableTestScene
|
public class TestSceneDrawableJudgement : ManiaSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(DrawableJudgement),
|
|
||||||
typeof(DrawableManiaJudgement)
|
|
||||||
};
|
|
||||||
|
|
||||||
public TestSceneDrawableJudgement()
|
public TestSceneDrawableJudgement()
|
||||||
{
|
{
|
||||||
foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Skip(1))
|
foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Skip(1))
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
@ -21,12 +18,6 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneHitExplosion : ManiaSkinnableTestScene
|
public class TestSceneHitExplosion : ManiaSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(DrawableNote),
|
|
||||||
typeof(DrawableManiaHitObject),
|
|
||||||
};
|
|
||||||
|
|
||||||
public TestSceneHitExplosion()
|
public TestSceneHitExplosion()
|
||||||
{
|
{
|
||||||
int runcount = 0;
|
int runcount = 0;
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Rulesets.Mania.Skinning;
|
|
||||||
using osu.Game.Rulesets.Mania.UI.Components;
|
using osu.Game.Rulesets.Mania.UI.Components;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -15,12 +12,6 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
|||||||
{
|
{
|
||||||
public class TestSceneKeyArea : ManiaSkinnableTestScene
|
public class TestSceneKeyArea : ManiaSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(DefaultKeyArea),
|
|
||||||
typeof(LegacyKeyArea)
|
|
||||||
};
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Mania.Skinning;
|
|
||||||
using osu.Game.Rulesets.Mania.UI.Components;
|
using osu.Game.Rulesets.Mania.UI.Components;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
@ -14,12 +10,6 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
|||||||
{
|
{
|
||||||
public class TestSceneStageBackground : ManiaSkinnableTestScene
|
public class TestSceneStageBackground : ManiaSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[]
|
|
||||||
{
|
|
||||||
typeof(DefaultStageBackground),
|
|
||||||
typeof(LegacyStageBackground),
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
@ -1,23 +1,14 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Mania.Skinning;
|
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
||||||
{
|
{
|
||||||
public class TestSceneStageForeground : ManiaSkinnableTestScene
|
public class TestSceneStageForeground : ManiaSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[]
|
|
||||||
{
|
|
||||||
typeof(LegacyStageForeground),
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,6 @@ using osu.Game.Beatmaps.ControlPoints;
|
|||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
using osu.Game.Rulesets.Mania.UI.Components;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
@ -24,15 +23,6 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneColumn : ManiaInputTestScene
|
public class TestSceneColumn : ManiaInputTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(Column),
|
|
||||||
typeof(ColumnBackground),
|
|
||||||
typeof(ColumnHitObjectArea),
|
|
||||||
typeof(DefaultKeyArea),
|
|
||||||
typeof(DefaultHitTarget)
|
|
||||||
};
|
|
||||||
|
|
||||||
[Cached(typeof(IReadOnlyList<Mod>))]
|
[Cached(typeof(IReadOnlyList<Mod>))]
|
||||||
private IReadOnlyList<Mod> mods { get; set; } = Array.Empty<Mod>();
|
private IReadOnlyList<Mod> mods { get; set; } = Array.Empty<Mod>();
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
@ -29,11 +27,6 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
{
|
{
|
||||||
public class TestSceneManiaHitObjectComposer : EditorClockTestScene
|
public class TestSceneManiaHitObjectComposer : EditorClockTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(ManiaBlueprintContainer)
|
|
||||||
};
|
|
||||||
|
|
||||||
private TestComposer composer;
|
private TestComposer composer;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
@ -30,12 +28,6 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneNotes : OsuTestScene
|
public class TestSceneNotes : OsuTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(DrawableNote),
|
|
||||||
typeof(DrawableHoldNote)
|
|
||||||
};
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Difficulty;
|
using osu.Game.Rulesets.Difficulty;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -37,12 +38,12 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
|||||||
{
|
{
|
||||||
mods = Score.Mods;
|
mods = Score.Mods;
|
||||||
scaledScore = Score.TotalScore;
|
scaledScore = Score.TotalScore;
|
||||||
countPerfect = Score.Statistics[HitResult.Perfect];
|
countPerfect = Score.Statistics.GetOrDefault(HitResult.Perfect);
|
||||||
countGreat = Score.Statistics[HitResult.Great];
|
countGreat = Score.Statistics.GetOrDefault(HitResult.Great);
|
||||||
countGood = Score.Statistics[HitResult.Good];
|
countGood = Score.Statistics.GetOrDefault(HitResult.Good);
|
||||||
countOk = Score.Statistics[HitResult.Ok];
|
countOk = Score.Statistics.GetOrDefault(HitResult.Ok);
|
||||||
countMeh = Score.Statistics[HitResult.Meh];
|
countMeh = Score.Statistics.GetOrDefault(HitResult.Meh);
|
||||||
countMiss = Score.Statistics[HitResult.Miss];
|
countMiss = Score.Statistics.GetOrDefault(HitResult.Miss);
|
||||||
|
|
||||||
if (mods.Any(m => !m.Ranked))
|
if (mods.Any(m => !m.Ranked))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -7,6 +7,7 @@ using osu.Framework.Input.Events;
|
|||||||
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
|
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||||
{
|
{
|
||||||
@ -49,6 +50,9 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
|||||||
|
|
||||||
protected override void OnMouseUp(MouseUpEvent e)
|
protected override void OnMouseUp(MouseUpEvent e)
|
||||||
{
|
{
|
||||||
|
if (e.Button != MouseButton.Left)
|
||||||
|
return;
|
||||||
|
|
||||||
base.OnMouseUp(e);
|
base.OnMouseUp(e);
|
||||||
EndPlacement(true);
|
EndPlacement(true);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
|||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||||
{
|
{
|
||||||
@ -46,6 +47,9 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
|||||||
|
|
||||||
protected override bool OnMouseDown(MouseDownEvent e)
|
protected override bool OnMouseDown(MouseDownEvent e)
|
||||||
{
|
{
|
||||||
|
if (e.Button != MouseButton.Left)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (Column == null)
|
if (Column == null)
|
||||||
return base.OnMouseDown(e);
|
return base.OnMouseDown(e);
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
|
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||||
{
|
{
|
||||||
@ -30,6 +31,9 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
|||||||
|
|
||||||
protected override bool OnMouseDown(MouseDownEvent e)
|
protected override bool OnMouseDown(MouseDownEvent e)
|
||||||
{
|
{
|
||||||
|
if (e.Button != MouseButton.Left)
|
||||||
|
return false;
|
||||||
|
|
||||||
base.OnMouseDown(e);
|
base.OnMouseDown(e);
|
||||||
|
|
||||||
// Place the note immediately.
|
// Place the note immediately.
|
||||||
|
@ -7,5 +7,20 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
|||||||
{
|
{
|
||||||
public class ManiaHitWindows : HitWindows
|
public class ManiaHitWindows : HitWindows
|
||||||
{
|
{
|
||||||
|
public override bool IsHitResultAllowed(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case HitResult.Perfect:
|
||||||
|
case HitResult.Great:
|
||||||
|
case HitResult.Good:
|
||||||
|
case HitResult.Ok:
|
||||||
|
case HitResult.Meh:
|
||||||
|
case HitResult.Miss:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,12 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using osu.Game.Rulesets.Osu.Skinning;
|
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Tests
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
{
|
{
|
||||||
public abstract class OsuSkinnableTestScene : SkinnableTestScene
|
public abstract class OsuSkinnableTestScene : SkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(OsuRuleset),
|
|
||||||
typeof(OsuLegacySkinTransformer),
|
|
||||||
};
|
|
||||||
|
|
||||||
protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset();
|
protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -15,12 +14,6 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
public class TestSceneDrawableJudgement : OsuSkinnableTestScene
|
public class TestSceneDrawableJudgement : OsuSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[]
|
|
||||||
{
|
|
||||||
typeof(DrawableJudgement),
|
|
||||||
typeof(DrawableOsuJudgement)
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
public TestSceneDrawableJudgement()
|
public TestSceneDrawableJudgement()
|
||||||
{
|
{
|
||||||
foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Skip(1))
|
foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Skip(1))
|
||||||
|
@ -2,16 +2,12 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Testing.Input;
|
using osu.Framework.Testing.Input;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Rulesets.Osu.Skinning;
|
|
||||||
using osu.Game.Rulesets.Osu.UI.Cursor;
|
using osu.Game.Rulesets.Osu.UI.Cursor;
|
||||||
using osu.Game.Rulesets.UI;
|
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -20,16 +16,6 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneGameplayCursor : OsuSkinnableTestScene
|
public class TestSceneGameplayCursor : OsuSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[]
|
|
||||||
{
|
|
||||||
typeof(GameplayCursorContainer),
|
|
||||||
typeof(OsuCursorContainer),
|
|
||||||
typeof(OsuCursor),
|
|
||||||
typeof(LegacyCursor),
|
|
||||||
typeof(LegacyCursorTrail),
|
|
||||||
typeof(CursorTrail)
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
[Cached]
|
[Cached]
|
||||||
private GameplayBeatmap gameplayBeatmap;
|
private GameplayBeatmap gameplayBeatmap;
|
||||||
|
|
||||||
|
@ -8,8 +8,6 @@ using osu.Game.Beatmaps.ControlPoints;
|
|||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@ -20,11 +18,6 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneHitCircle : OsuSkinnableTestScene
|
public class TestSceneHitCircle : OsuSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(DrawableHitCircle)
|
|
||||||
};
|
|
||||||
|
|
||||||
private int depthIndex;
|
private int depthIndex;
|
||||||
|
|
||||||
public TestSceneHitCircle()
|
public TestSceneHitCircle()
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// 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 NUnit.Framework;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
|
|
||||||
@ -12,8 +9,6 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneHitCircleHidden : TestSceneHitCircle
|
public class TestSceneHitCircleHidden : TestSceneHitCircle
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
|
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -16,7 +15,6 @@ using osu.Game.Rulesets.Osu.Beatmaps;
|
|||||||
using osu.Game.Rulesets.Osu.Edit;
|
using osu.Game.Rulesets.Osu.Edit;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
using osu.Game.Screens.Edit.Compose.Components;
|
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
@ -28,11 +26,6 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
private const double beat_length = 100;
|
private const double beat_length = 100;
|
||||||
private static readonly Vector2 grid_position = new Vector2(512, 384);
|
private static readonly Vector2 grid_position = new Vector2(512, 384);
|
||||||
|
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(CircularDistanceSnapGrid)
|
|
||||||
};
|
|
||||||
|
|
||||||
[Cached(typeof(EditorBeatmap))]
|
[Cached(typeof(EditorBeatmap))]
|
||||||
private readonly EditorBeatmap editorBeatmap;
|
private readonly EditorBeatmap editorBeatmap;
|
||||||
|
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Humanizer;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -19,13 +16,6 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
public class TestScenePathControlPointVisualiser : OsuTestScene
|
public class TestScenePathControlPointVisualiser : OsuTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(StringHumanizeExtensions),
|
|
||||||
typeof(PathControlPointPiece),
|
|
||||||
typeof(PathControlPointConnectionPiece)
|
|
||||||
};
|
|
||||||
|
|
||||||
private Slider slider;
|
private Slider slider;
|
||||||
private PathControlPointVisualiser visualiser;
|
private PathControlPointVisualiser visualiser;
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// 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;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
@ -14,11 +12,6 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
public class TestSceneResumeOverlay : OsuManualInputManagerTestScene
|
public class TestSceneResumeOverlay : OsuManualInputManagerTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(OsuResumeOverlay),
|
|
||||||
};
|
|
||||||
|
|
||||||
public TestSceneResumeOverlay()
|
public TestSceneResumeOverlay()
|
||||||
{
|
{
|
||||||
ManualOsuInputManager osuInputManager;
|
ManualOsuInputManager osuInputManager;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -21,29 +20,12 @@ using osu.Game.Rulesets.Judgements;
|
|||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Tests
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneSlider : OsuSkinnableTestScene
|
public class TestSceneSlider : OsuSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(Slider),
|
|
||||||
typeof(SliderTick),
|
|
||||||
typeof(SliderTailCircle),
|
|
||||||
typeof(SliderBall),
|
|
||||||
typeof(SliderBody),
|
|
||||||
typeof(SnakingSliderBody),
|
|
||||||
typeof(DrawableSlider),
|
|
||||||
typeof(DrawableSliderTick),
|
|
||||||
typeof(DrawableSliderTail),
|
|
||||||
typeof(DrawableSliderHead),
|
|
||||||
typeof(DrawableSliderRepeat),
|
|
||||||
typeof(DrawableOsuHitObject)
|
|
||||||
};
|
|
||||||
|
|
||||||
private Container content;
|
private Container content;
|
||||||
|
|
||||||
protected override Container<Drawable> Content
|
protected override Container<Drawable> Content
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// 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 NUnit.Framework;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
|
|
||||||
@ -12,8 +9,6 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneSliderHidden : TestSceneSlider
|
public class TestSceneSliderHidden : TestSceneSlider
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
|
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@ -13,8 +12,6 @@ using osu.Game.Rulesets.Judgements;
|
|||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
|
|
||||||
using osu.Game.Rulesets.Osu.Replays;
|
using osu.Game.Rulesets.Osu.Replays;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
@ -27,17 +24,6 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
public class TestSceneSliderInput : RateAdjustedBeatmapTestScene
|
public class TestSceneSliderInput : RateAdjustedBeatmapTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(SliderBall),
|
|
||||||
typeof(DrawableSlider),
|
|
||||||
typeof(DrawableSliderTick),
|
|
||||||
typeof(DrawableSliderRepeat),
|
|
||||||
typeof(DrawableOsuHitObject),
|
|
||||||
typeof(DrawableSliderHead),
|
|
||||||
typeof(DrawableSliderTail),
|
|
||||||
};
|
|
||||||
|
|
||||||
private const double time_before_slider = 250;
|
private const double time_before_slider = 250;
|
||||||
private const double time_slider_start = 1500;
|
private const double time_slider_start = 1500;
|
||||||
private const double time_during_slide_1 = 2500;
|
private const double time_during_slide_1 = 2500;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -22,16 +20,6 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
public class TestSceneSliderSelectionBlueprint : SelectionBlueprintTestScene
|
public class TestSceneSliderSelectionBlueprint : SelectionBlueprintTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(SliderSelectionBlueprint),
|
|
||||||
typeof(SliderCircleSelectionBlueprint),
|
|
||||||
typeof(SliderBodyPiece),
|
|
||||||
typeof(SliderCircle),
|
|
||||||
typeof(PathControlPointVisualiser),
|
|
||||||
typeof(PathControlPointPiece)
|
|
||||||
};
|
|
||||||
|
|
||||||
private Slider slider;
|
private Slider slider;
|
||||||
private DrawableSlider drawableObject;
|
private DrawableSlider drawableObject;
|
||||||
private TestSliderBlueprint blueprint;
|
private TestSliderBlueprint blueprint;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -12,7 +10,6 @@ using osu.Game.Beatmaps.ControlPoints;
|
|||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
|
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Tests
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
@ -20,13 +17,6 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneSpinner : OsuTestScene
|
public class TestSceneSpinner : OsuTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(SpinnerDisc),
|
|
||||||
typeof(DrawableSpinner),
|
|
||||||
typeof(DrawableOsuHitObject)
|
|
||||||
};
|
|
||||||
|
|
||||||
private readonly Container content;
|
private readonly Container content;
|
||||||
protected override Container<Drawable> Content => content;
|
protected override Container<Drawable> Content => content;
|
||||||
|
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// 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 NUnit.Framework;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
|
|
||||||
@ -12,8 +9,6 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneSpinnerHidden : TestSceneSpinner
|
public class TestSceneSpinnerHidden : TestSceneSpinner
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
|
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// 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;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners;
|
using osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners;
|
||||||
using osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners.Components;
|
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
@ -18,12 +15,6 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
public class TestSceneSpinnerSelectionBlueprint : SelectionBlueprintTestScene
|
public class TestSceneSpinnerSelectionBlueprint : SelectionBlueprintTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(SpinnerSelectionBlueprint),
|
|
||||||
typeof(SpinnerPiece)
|
|
||||||
};
|
|
||||||
|
|
||||||
public TestSceneSpinnerSelectionBlueprint()
|
public TestSceneSpinnerSelectionBlueprint()
|
||||||
{
|
{
|
||||||
var spinner = new Spinner
|
var spinner = new Spinner
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -12,7 +10,6 @@ using osu.Game.Rulesets.Mods;
|
|||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
|
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Tests
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
@ -20,14 +17,6 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneSpinnerSpunOut : OsuTestScene
|
public class TestSceneSpinnerSpunOut : OsuTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(SpinnerDisc),
|
|
||||||
typeof(DrawableSpinner),
|
|
||||||
typeof(DrawableOsuHitObject),
|
|
||||||
typeof(OsuModSpunOut)
|
|
||||||
};
|
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Difficulty;
|
using osu.Game.Rulesets.Difficulty;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -45,10 +46,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
mods = Score.Mods;
|
mods = Score.Mods;
|
||||||
accuracy = Score.Accuracy;
|
accuracy = Score.Accuracy;
|
||||||
scoreMaxCombo = Score.MaxCombo;
|
scoreMaxCombo = Score.MaxCombo;
|
||||||
countGreat = Score.Statistics[HitResult.Great];
|
countGreat = Score.Statistics.GetOrDefault(HitResult.Great);
|
||||||
countGood = Score.Statistics[HitResult.Good];
|
countGood = Score.Statistics.GetOrDefault(HitResult.Good);
|
||||||
countMeh = Score.Statistics[HitResult.Meh];
|
countMeh = Score.Statistics.GetOrDefault(HitResult.Meh);
|
||||||
countMiss = Score.Statistics[HitResult.Miss];
|
countMiss = Score.Statistics.GetOrDefault(HitResult.Miss);
|
||||||
|
|
||||||
// Don't count scores made with supposedly unranked mods
|
// Don't count scores made with supposedly unranked mods
|
||||||
if (mods.Any(m => !m.Ranked))
|
if (mods.Any(m => !m.Ranked))
|
||||||
@ -180,7 +181,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
int amountHitObjectsWithAccuracy = countHitCircles;
|
int amountHitObjectsWithAccuracy = countHitCircles;
|
||||||
|
|
||||||
if (amountHitObjectsWithAccuracy > 0)
|
if (amountHitObjectsWithAccuracy > 0)
|
||||||
betterAccuracyPercentage = ((countGreat - (totalHits - amountHitObjectsWithAccuracy)) * 6 + countGood * 2 + countMeh) / (amountHitObjectsWithAccuracy * 6);
|
betterAccuracyPercentage = ((countGreat - (totalHits - amountHitObjectsWithAccuracy)) * 6 + countGood * 2 + countMeh) / (double)(amountHitObjectsWithAccuracy * 6);
|
||||||
else
|
else
|
||||||
betterAccuracyPercentage = 0;
|
betterAccuracyPercentage = 0;
|
||||||
|
|
||||||
@ -203,7 +204,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
return accuracyValue;
|
return accuracyValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double totalHits => countGreat + countGood + countMeh + countMiss;
|
private int totalHits => countGreat + countGood + countMeh + countMiss;
|
||||||
private double totalSuccessfulHits => countGreat + countGood + countMeh;
|
private int totalSuccessfulHits => countGreat + countGood + countMeh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,8 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(OsuModSpunOut), typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail), typeof(ModAutoplay) };
|
public override Type[] IncompatibleMods => new[] { typeof(OsuModSpunOut), typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail), typeof(ModAutoplay) };
|
||||||
|
|
||||||
public bool AllowFail => false;
|
public bool PerformFail() => false;
|
||||||
|
|
||||||
public bool RestartOnFail => false;
|
public bool RestartOnFail => false;
|
||||||
|
|
||||||
private OsuInputManager inputManager;
|
private OsuInputManager inputManager;
|
||||||
|
@ -28,8 +28,11 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
slider.NestedHitObjects.OfType<SliderTick>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
slider.NestedHitObjects.OfType<SliderTick>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
||||||
slider.NestedHitObjects.OfType<SliderRepeat>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
slider.NestedHitObjects.OfType<SliderRepeat>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
|
||||||
|
|
||||||
foreach (var point in slider.Path.ControlPoints)
|
var controlPoints = slider.Path.ControlPoints.Select(p => new PathControlPoint(p.Position.Value, p.Type.Value)).ToArray();
|
||||||
|
foreach (var point in controlPoints)
|
||||||
point.Position.Value = new Vector2(point.Position.Value.X, -point.Position.Value.Y);
|
point.Position.Value = new Vector2(point.Position.Value.X, -point.Position.Value.Y);
|
||||||
|
|
||||||
|
slider.Path = new SliderPath(controlPoints, slider.Path.ExpectedDistance.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,12 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using osu.Game.Rulesets.Taiko.Skinning;
|
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
||||||
{
|
{
|
||||||
public abstract class TaikoSkinnableTestScene : SkinnableTestScene
|
public abstract class TaikoSkinnableTestScene : SkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(TaikoRuleset),
|
|
||||||
typeof(TaikoLegacySkinTransformer),
|
|
||||||
};
|
|
||||||
|
|
||||||
protected override Ruleset CreateRulesetForSkinProvider() => new TaikoRuleset();
|
protected override Ruleset CreateRulesetForSkinProvider() => new TaikoRuleset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// 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 NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -12,7 +9,6 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Taiko.Skinning;
|
|
||||||
using osu.Game.Rulesets.Taiko.UI;
|
using osu.Game.Rulesets.Taiko.UI;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
@ -22,13 +18,6 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneDrawableBarLine : TaikoSkinnableTestScene
|
public class TestSceneDrawableBarLine : TaikoSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[]
|
|
||||||
{
|
|
||||||
typeof(DrawableBarLine),
|
|
||||||
typeof(LegacyBarLine),
|
|
||||||
typeof(BarLine),
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
[Cached(typeof(IScrollingInfo))]
|
[Cached(typeof(IScrollingInfo))]
|
||||||
private ScrollingTestContainer.TestScrollingInfo info = new ScrollingTestContainer.TestScrollingInfo
|
private ScrollingTestContainer.TestScrollingInfo info = new ScrollingTestContainer.TestScrollingInfo
|
||||||
{
|
{
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// 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 NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -11,7 +8,6 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Taiko.Skinning;
|
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
@ -20,13 +16,6 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneDrawableDrumRoll : TaikoSkinnableTestScene
|
public class TestSceneDrawableDrumRoll : TaikoSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[]
|
|
||||||
{
|
|
||||||
typeof(DrawableDrumRoll),
|
|
||||||
typeof(DrawableDrumRollTick),
|
|
||||||
typeof(LegacyDrumRoll),
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
[Cached(typeof(IScrollingInfo))]
|
[Cached(typeof(IScrollingInfo))]
|
||||||
private ScrollingTestContainer.TestScrollingInfo info = new ScrollingTestContainer.TestScrollingInfo
|
private ScrollingTestContainer.TestScrollingInfo info = new ScrollingTestContainer.TestScrollingInfo
|
||||||
{
|
{
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// 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 NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -11,20 +8,12 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Taiko.Skinning;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneDrawableHit : TaikoSkinnableTestScene
|
public class TestSceneDrawableHit : TaikoSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[]
|
|
||||||
{
|
|
||||||
typeof(DrawableHit),
|
|
||||||
typeof(LegacyHit),
|
|
||||||
typeof(LegacyCirclePiece),
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,216 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Humanizer;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
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.Judgements;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Rulesets.Taiko.Judgements;
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
using osu.Game.Rulesets.Taiko.Scoring;
|
||||||
|
using osu.Game.Rulesets.Taiko.UI;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestSceneDrawableTaikoMascot : TaikoSkinnableTestScene
|
||||||
|
{
|
||||||
|
[Cached(typeof(IScrollingInfo))]
|
||||||
|
private ScrollingTestContainer.TestScrollingInfo info = new ScrollingTestContainer.TestScrollingInfo
|
||||||
|
{
|
||||||
|
Direction = { Value = ScrollingDirection.Left },
|
||||||
|
TimeRange = { Value = 5000 },
|
||||||
|
};
|
||||||
|
|
||||||
|
private TaikoScoreProcessor scoreProcessor;
|
||||||
|
|
||||||
|
private IEnumerable<DrawableTaikoMascot> mascots => this.ChildrenOfType<DrawableTaikoMascot>();
|
||||||
|
private IEnumerable<TaikoPlayfield> playfields => this.ChildrenOfType<TaikoPlayfield>();
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
scoreProcessor = new TaikoScoreProcessor();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestStateAnimations()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => setBeatmap());
|
||||||
|
|
||||||
|
AddStep("clear state", () => SetContents(() => new TaikoMascotAnimation(TaikoMascotAnimationState.Clear)));
|
||||||
|
AddStep("idle state", () => SetContents(() => new TaikoMascotAnimation(TaikoMascotAnimationState.Idle)));
|
||||||
|
AddStep("kiai state", () => SetContents(() => new TaikoMascotAnimation(TaikoMascotAnimationState.Kiai)));
|
||||||
|
AddStep("fail state", () => SetContents(() => new TaikoMascotAnimation(TaikoMascotAnimationState.Fail)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestInitialState()
|
||||||
|
{
|
||||||
|
AddStep("create mascot", () => SetContents(() => new DrawableTaikoMascot { RelativeSizeAxes = Axes.Both }));
|
||||||
|
|
||||||
|
AddAssert("mascot initially idle", () => allMascotsIn(TaikoMascotAnimationState.Idle));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestClearStateTransition()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => setBeatmap());
|
||||||
|
|
||||||
|
AddStep("create mascot", () => SetContents(() => new DrawableTaikoMascot { RelativeSizeAxes = Axes.Both }));
|
||||||
|
|
||||||
|
AddStep("set clear state", () => mascots.ForEach(mascot => mascot.State.Value = TaikoMascotAnimationState.Clear));
|
||||||
|
AddStep("miss", () => mascots.ForEach(mascot => mascot.LastResult.Value = new JudgementResult(new Hit(), new TaikoJudgement()) { Type = HitResult.Miss }));
|
||||||
|
AddAssert("skins with animations remain in clear state", () => someMascotsIn(TaikoMascotAnimationState.Clear));
|
||||||
|
AddUntilStep("state reverts to fail", () => allMascotsIn(TaikoMascotAnimationState.Fail));
|
||||||
|
|
||||||
|
AddStep("set clear state again", () => mascots.ForEach(mascot => mascot.State.Value = TaikoMascotAnimationState.Clear));
|
||||||
|
AddAssert("skins with animations change to clear", () => someMascotsIn(TaikoMascotAnimationState.Clear));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestIdleState()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => setBeatmap());
|
||||||
|
|
||||||
|
createDrawableRuleset();
|
||||||
|
|
||||||
|
assertStateAfterResult(new JudgementResult(new Hit(), new TaikoJudgement()) { Type = HitResult.Great }, TaikoMascotAnimationState.Idle);
|
||||||
|
assertStateAfterResult(new JudgementResult(new StrongHitObject(), new TaikoStrongJudgement()) { Type = HitResult.Miss }, TaikoMascotAnimationState.Idle);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestKiaiState()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => setBeatmap(true));
|
||||||
|
|
||||||
|
createDrawableRuleset();
|
||||||
|
|
||||||
|
assertStateAfterResult(new JudgementResult(new Hit(), new TaikoJudgement()) { Type = HitResult.Good }, TaikoMascotAnimationState.Kiai);
|
||||||
|
assertStateAfterResult(new JudgementResult(new Hit(), new TaikoStrongJudgement()) { Type = HitResult.Miss }, TaikoMascotAnimationState.Kiai);
|
||||||
|
assertStateAfterResult(new JudgementResult(new Hit(), new TaikoJudgement()) { Type = HitResult.Miss }, TaikoMascotAnimationState.Fail);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMissState()
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => setBeatmap());
|
||||||
|
|
||||||
|
createDrawableRuleset();
|
||||||
|
|
||||||
|
assertStateAfterResult(new JudgementResult(new Hit(), new TaikoJudgement()) { Type = HitResult.Great }, TaikoMascotAnimationState.Idle);
|
||||||
|
assertStateAfterResult(new JudgementResult(new Hit(), new TaikoJudgement()) { Type = HitResult.Miss }, TaikoMascotAnimationState.Fail);
|
||||||
|
assertStateAfterResult(new JudgementResult(new DrumRoll(), new TaikoDrumRollJudgement()) { Type = HitResult.Great }, TaikoMascotAnimationState.Fail);
|
||||||
|
assertStateAfterResult(new JudgementResult(new Hit(), new TaikoJudgement()) { Type = HitResult.Good }, TaikoMascotAnimationState.Idle);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(true)]
|
||||||
|
[TestCase(false)]
|
||||||
|
public void TestClearStateOnComboMilestone(bool kiai)
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => setBeatmap(kiai));
|
||||||
|
|
||||||
|
createDrawableRuleset();
|
||||||
|
|
||||||
|
AddRepeatStep("reach 49 combo", () => applyNewResult(new JudgementResult(new Hit(), new TaikoJudgement()) { Type = HitResult.Great }), 49);
|
||||||
|
|
||||||
|
assertStateAfterResult(new JudgementResult(new Hit(), new TaikoJudgement()) { Type = HitResult.Good }, TaikoMascotAnimationState.Clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(true, TaikoMascotAnimationState.Kiai)]
|
||||||
|
[TestCase(false, TaikoMascotAnimationState.Idle)]
|
||||||
|
public void TestClearStateOnClearedSwell(bool kiai, TaikoMascotAnimationState expectedStateAfterClear)
|
||||||
|
{
|
||||||
|
AddStep("set beatmap", () => setBeatmap(kiai));
|
||||||
|
|
||||||
|
createDrawableRuleset();
|
||||||
|
|
||||||
|
assertStateAfterResult(new JudgementResult(new Swell(), new TaikoSwellJudgement()) { Type = HitResult.Great }, TaikoMascotAnimationState.Clear);
|
||||||
|
AddUntilStep($"state reverts to {expectedStateAfterClear.ToString().ToLower()}", () => allMascotsIn(expectedStateAfterClear));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setBeatmap(bool kiai = false)
|
||||||
|
{
|
||||||
|
var controlPointInfo = new ControlPointInfo();
|
||||||
|
controlPointInfo.Add(0, new TimingControlPoint { BeatLength = 90 });
|
||||||
|
|
||||||
|
if (kiai)
|
||||||
|
controlPointInfo.Add(0, new EffectControlPoint { KiaiMode = true });
|
||||||
|
|
||||||
|
Beatmap.Value = CreateWorkingBeatmap(new Beatmap
|
||||||
|
{
|
||||||
|
HitObjects = new List<HitObject> { new Hit { Type = HitType.Centre } },
|
||||||
|
BeatmapInfo = new BeatmapInfo
|
||||||
|
{
|
||||||
|
BaseDifficulty = new BeatmapDifficulty(),
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Artist = "Unknown",
|
||||||
|
Title = "Sample Beatmap",
|
||||||
|
AuthorString = "Craftplacer",
|
||||||
|
},
|
||||||
|
Ruleset = new TaikoRuleset().RulesetInfo
|
||||||
|
},
|
||||||
|
ControlPointInfo = controlPointInfo
|
||||||
|
});
|
||||||
|
|
||||||
|
scoreProcessor.ApplyBeatmap(Beatmap.Value.Beatmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createDrawableRuleset()
|
||||||
|
{
|
||||||
|
AddUntilStep("wait for beatmap to be loaded", () => Beatmap.Value.Track.IsLoaded);
|
||||||
|
|
||||||
|
AddStep("create drawable ruleset", () =>
|
||||||
|
{
|
||||||
|
Beatmap.Value.Track.Start();
|
||||||
|
|
||||||
|
SetContents(() =>
|
||||||
|
{
|
||||||
|
var ruleset = new TaikoRuleset();
|
||||||
|
return new DrawableTaikoRuleset(ruleset, Beatmap.Value.GetPlayableBeatmap(ruleset.RulesetInfo));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertStateAfterResult(JudgementResult judgementResult, TaikoMascotAnimationState expectedState)
|
||||||
|
{
|
||||||
|
AddStep($"{judgementResult.Type.ToString().ToLower()} result for {judgementResult.Judgement.GetType().Name.Humanize(LetterCasing.LowerCase)}",
|
||||||
|
() => applyNewResult(judgementResult));
|
||||||
|
|
||||||
|
AddAssert($"state is {expectedState.ToString().ToLower()}", () => allMascotsIn(expectedState));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyNewResult(JudgementResult judgementResult)
|
||||||
|
{
|
||||||
|
scoreProcessor.ApplyResult(judgementResult);
|
||||||
|
|
||||||
|
foreach (var playfield in playfields)
|
||||||
|
{
|
||||||
|
var hit = new DrawableTestHit(new Hit(), judgementResult.Type);
|
||||||
|
Add(hit);
|
||||||
|
|
||||||
|
playfield.OnNewResult(hit, judgementResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var mascot in mascots)
|
||||||
|
{
|
||||||
|
mascot.LastResult.Value = judgementResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool allMascotsIn(TaikoMascotAnimationState state) => mascots.All(d => d.State.Value == state);
|
||||||
|
private bool someMascotsIn(TaikoMascotAnimationState state) => mascots.Any(d => d.State.Value == state);
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// 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 NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -11,7 +8,6 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Taiko.Skinning;
|
|
||||||
using osu.Game.Rulesets.Taiko.UI;
|
using osu.Game.Rulesets.Taiko.UI;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
||||||
@ -19,13 +15,6 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneHitExplosion : TaikoSkinnableTestScene
|
public class TestSceneHitExplosion : TaikoSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[]
|
|
||||||
{
|
|
||||||
typeof(HitExplosion),
|
|
||||||
typeof(LegacyHitExplosion),
|
|
||||||
typeof(DefaultHitExplosion),
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// 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 NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Taiko.Skinning;
|
|
||||||
using osu.Game.Rulesets.Taiko.UI;
|
using osu.Game.Rulesets.Taiko.UI;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -18,12 +14,6 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneInputDrum : TaikoSkinnableTestScene
|
public class TestSceneInputDrum : TaikoSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[]
|
|
||||||
{
|
|
||||||
typeof(InputDrum),
|
|
||||||
typeof(LegacyInputDrum),
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
@ -2,15 +2,12 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Taiko.Beatmaps;
|
using osu.Game.Rulesets.Taiko.Beatmaps;
|
||||||
using osu.Game.Rulesets.Taiko.Skinning;
|
|
||||||
using osu.Game.Rulesets.Taiko.UI;
|
using osu.Game.Rulesets.Taiko.UI;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
@ -19,14 +16,6 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
|||||||
{
|
{
|
||||||
public class TestSceneTaikoPlayfield : TaikoSkinnableTestScene
|
public class TestSceneTaikoPlayfield : TaikoSkinnableTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[]
|
|
||||||
{
|
|
||||||
typeof(TaikoHitTarget),
|
|
||||||
typeof(TaikoLegacyHitTarget),
|
|
||||||
typeof(PlayfieldBackgroundRight),
|
|
||||||
typeof(LegacyTaikoScroller),
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
[Cached(typeof(IScrollingInfo))]
|
[Cached(typeof(IScrollingInfo))]
|
||||||
private ScrollingTestContainer.TestScrollingInfo info = new ScrollingTestContainer.TestScrollingInfo
|
private ScrollingTestContainer.TestScrollingInfo info = new ScrollingTestContainer.TestScrollingInfo
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
|
using osu.Framework.Timing;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.Taiko.Skinning;
|
using osu.Game.Rulesets.Taiko.Skinning;
|
||||||
@ -12,11 +13,30 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
|||||||
{
|
{
|
||||||
public class TestSceneTaikoScroller : TaikoSkinnableTestScene
|
public class TestSceneTaikoScroller : TaikoSkinnableTestScene
|
||||||
{
|
{
|
||||||
|
private readonly ManualClock clock = new ManualClock();
|
||||||
|
|
||||||
|
private bool reversed;
|
||||||
|
|
||||||
public TestSceneTaikoScroller()
|
public TestSceneTaikoScroller()
|
||||||
{
|
{
|
||||||
AddStep("Load scroller", () => SetContents(() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.TaikoScroller), _ => Empty())));
|
AddStep("Load scroller", () => SetContents(() =>
|
||||||
|
new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Scroller), _ => Empty())
|
||||||
|
{
|
||||||
|
Clock = new FramedClock(clock),
|
||||||
|
Height = 0.4f,
|
||||||
|
}));
|
||||||
|
|
||||||
AddToggleStep("Toggle passing", passing => this.ChildrenOfType<LegacyTaikoScroller>().ForEach(s => s.LastResult.Value =
|
AddToggleStep("Toggle passing", passing => this.ChildrenOfType<LegacyTaikoScroller>().ForEach(s => s.LastResult.Value =
|
||||||
new JudgementResult(null, new Judgement()) { Type = passing ? HitResult.Perfect : HitResult.Miss }));
|
new JudgementResult(null, new Judgement()) { Type = passing ? HitResult.Perfect : HitResult.Miss }));
|
||||||
|
|
||||||
|
AddToggleStep("toggle playback direction", reversed => this.reversed = reversed);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
clock.CurrentTime += (reversed ? -1 : 1) * Clock.ElapsedFrameTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
[NonParallelizable]
|
[NonParallelizable]
|
||||||
[TestCase("basic")]
|
[TestCase("basic")]
|
||||||
[TestCase("slider-generating-drumroll")]
|
[TestCase("slider-generating-drumroll")]
|
||||||
|
[TestCase("sample-to-type-conversions")]
|
||||||
public void Test(string name) => base.Test(name);
|
public void Test(string name) => base.Test(name);
|
||||||
|
|
||||||
protected override IEnumerable<ConvertValue> CreateConvertValue(HitObject hitObject)
|
protected override IEnumerable<ConvertValue> CreateConvertValue(HitObject hitObject)
|
||||||
@ -41,7 +42,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
public struct ConvertValue : IEquatable<ConvertValue>
|
public struct ConvertValue : IEquatable<ConvertValue>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A sane value to account for osu!stable using ints everwhere.
|
/// A sane value to account for osu!stable using ints everywhere.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const float conversion_lenience = 2;
|
private const float conversion_lenience = 2;
|
||||||
|
|
||||||
|
49
osu.Game.Rulesets.Taiko.Tests/TestSceneSampleOutput.cs
Normal file
49
osu.Game.Rulesets.Taiko.Tests/TestSceneSampleOutput.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// 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.Testing;
|
||||||
|
using osu.Game.Audio;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Tests
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Taiko has some interesting rules for legacy mappings.
|
||||||
|
/// </summary>
|
||||||
|
[HeadlessTest]
|
||||||
|
public class TestSceneSampleOutput : PlayerTestScene
|
||||||
|
{
|
||||||
|
public TestSceneSampleOutput()
|
||||||
|
: base(new TaikoRuleset())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetUpSteps()
|
||||||
|
{
|
||||||
|
base.SetUpSteps();
|
||||||
|
AddAssert("has correct samples", () =>
|
||||||
|
{
|
||||||
|
var names = Player.DrawableRuleset.Playfield.AllHitObjects.OfType<DrawableHit>().Select(h => string.Join(',', h.GetSamples().Select(s => s.Name)));
|
||||||
|
|
||||||
|
var expected = new[]
|
||||||
|
{
|
||||||
|
string.Empty,
|
||||||
|
string.Empty,
|
||||||
|
string.Empty,
|
||||||
|
string.Empty,
|
||||||
|
HitSampleInfo.HIT_FINISH,
|
||||||
|
HitSampleInfo.HIT_WHISTLE,
|
||||||
|
HitSampleInfo.HIT_WHISTLE,
|
||||||
|
HitSampleInfo.HIT_WHISTLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
return names.SequenceEqual(expected);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TaikoBeatmapConversionTest().GetBeatmap("sample-to-type-conversions");
|
||||||
|
}
|
||||||
|
}
|
@ -167,13 +167,15 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
bool isRim = samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP || s.Name == HitSampleInfo.HIT_WHISTLE);
|
bool isRimDefinition(HitSampleInfo s) => s.Name == HitSampleInfo.HIT_CLAP || s.Name == HitSampleInfo.HIT_WHISTLE;
|
||||||
|
|
||||||
|
bool isRim = samples.Any(isRimDefinition);
|
||||||
|
|
||||||
yield return new Hit
|
yield return new Hit
|
||||||
{
|
{
|
||||||
StartTime = obj.StartTime,
|
StartTime = obj.StartTime,
|
||||||
Type = isRim ? HitType.Rim : HitType.Centre,
|
Type = isRim ? HitType.Rim : HitType.Centre,
|
||||||
Samples = obj.Samples,
|
Samples = samples,
|
||||||
IsStrong = strong
|
IsStrong = strong
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Difficulty;
|
using osu.Game.Rulesets.Difficulty;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -31,10 +32,10 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
|||||||
public override double Calculate(Dictionary<string, double> categoryDifficulty = null)
|
public override double Calculate(Dictionary<string, double> categoryDifficulty = null)
|
||||||
{
|
{
|
||||||
mods = Score.Mods;
|
mods = Score.Mods;
|
||||||
countGreat = Convert.ToInt32(Score.Statistics[HitResult.Great]);
|
countGreat = Score.Statistics.GetOrDefault(HitResult.Great);
|
||||||
countGood = Convert.ToInt32(Score.Statistics[HitResult.Good]);
|
countGood = Score.Statistics.GetOrDefault(HitResult.Good);
|
||||||
countMeh = Convert.ToInt32(Score.Statistics[HitResult.Meh]);
|
countMeh = Score.Statistics.GetOrDefault(HitResult.Meh);
|
||||||
countMiss = Convert.ToInt32(Score.Statistics[HitResult.Miss]);
|
countMiss = Score.Statistics.GetOrDefault(HitResult.Miss);
|
||||||
|
|
||||||
// Don't count scores made with supposedly unranked mods
|
// Don't count scores made with supposedly unranked mods
|
||||||
if (mods.Any(m => !m.Ranked))
|
if (mods.Any(m => !m.Ranked))
|
||||||
|
@ -2,9 +2,11 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Audio;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
|
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
|
||||||
@ -47,6 +49,42 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
? new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit)
|
? new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit)
|
||||||
: new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit);
|
: new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit);
|
||||||
|
|
||||||
|
public override IEnumerable<HitSampleInfo> GetSamples()
|
||||||
|
{
|
||||||
|
// normal and claps are always handled by the drum (see DrumSampleMapping).
|
||||||
|
// in addition, whistles are excluded as they are an alternative rim marker.
|
||||||
|
|
||||||
|
var samples = HitObject.Samples.Where(s =>
|
||||||
|
s.Name != HitSampleInfo.HIT_NORMAL
|
||||||
|
&& s.Name != HitSampleInfo.HIT_CLAP
|
||||||
|
&& s.Name != HitSampleInfo.HIT_WHISTLE);
|
||||||
|
|
||||||
|
if (HitObject.Type == HitType.Rim && HitObject.IsStrong)
|
||||||
|
{
|
||||||
|
// strong + rim always maps to whistle.
|
||||||
|
// TODO: this should really be in the legacy decoder, but can't be because legacy encoding parity would be broken.
|
||||||
|
// when we add a taiko editor, this is probably not going to play nice.
|
||||||
|
|
||||||
|
var corrected = samples.ToList();
|
||||||
|
|
||||||
|
for (var i = 0; i < corrected.Count; i++)
|
||||||
|
{
|
||||||
|
var s = corrected[i];
|
||||||
|
|
||||||
|
if (s.Name != HitSampleInfo.HIT_FINISH)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var sClone = s.Clone();
|
||||||
|
sClone.Name = HitSampleInfo.HIT_WHISTLE;
|
||||||
|
corrected[i] = sClone;
|
||||||
|
}
|
||||||
|
|
||||||
|
return corrected;
|
||||||
|
}
|
||||||
|
|
||||||
|
return samples;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||||
{
|
{
|
||||||
Debug.Assert(HitObject.HitWindows != null);
|
Debug.Assert(HitObject.HitWindows != null);
|
||||||
|
@ -165,8 +165,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
return base.CreateNestedHitObject(hitObject);
|
return base.CreateNestedHitObject(hitObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal and clap samples are handled by the drum
|
// Most osu!taiko hitsounds are managed by the drum (see DrumSampleMapping).
|
||||||
protected override IEnumerable<HitSampleInfo> GetSamples() => HitObject.Samples.Where(s => s.Name != HitSampleInfo.HIT_NORMAL && s.Name != HitSampleInfo.HIT_CLAP);
|
public override IEnumerable<HitSampleInfo> GetSamples() => Enumerable.Empty<HitSampleInfo>();
|
||||||
|
|
||||||
protected abstract SkinnableDrawable CreateMainPiece();
|
protected abstract SkinnableDrawable CreateMainPiece();
|
||||||
|
|
||||||
|
@ -0,0 +1,116 @@
|
|||||||
|
{
|
||||||
|
"Mappings": [
|
||||||
|
{
|
||||||
|
"StartTime": 110.0,
|
||||||
|
"Objects": [
|
||||||
|
{
|
||||||
|
"StartTime": 110.0,
|
||||||
|
"EndTime": 110.0,
|
||||||
|
"IsRim": false,
|
||||||
|
"IsCentre": true,
|
||||||
|
"IsDrumRoll": false,
|
||||||
|
"IsSwell": false,
|
||||||
|
"IsStrong": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"StartTime": 538.0,
|
||||||
|
"Objects": [
|
||||||
|
{
|
||||||
|
"StartTime": 538.0,
|
||||||
|
"EndTime": 538.0,
|
||||||
|
"IsRim": true,
|
||||||
|
"IsCentre": false,
|
||||||
|
"IsDrumRoll": false,
|
||||||
|
"IsSwell": false,
|
||||||
|
"IsStrong": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"StartTime": 967.0,
|
||||||
|
"Objects": [
|
||||||
|
{
|
||||||
|
"StartTime": 967.0,
|
||||||
|
"EndTime": 967.0,
|
||||||
|
"IsRim": true,
|
||||||
|
"IsCentre": false,
|
||||||
|
"IsDrumRoll": false,
|
||||||
|
"IsSwell": false,
|
||||||
|
"IsStrong": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"StartTime": 1395.0,
|
||||||
|
"Objects": [
|
||||||
|
{
|
||||||
|
"StartTime": 1395.0,
|
||||||
|
"EndTime": 1395.0,
|
||||||
|
"IsRim": true,
|
||||||
|
"IsCentre": false,
|
||||||
|
"IsDrumRoll": false,
|
||||||
|
"IsSwell": false,
|
||||||
|
"IsStrong": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"StartTime": 1824.0,
|
||||||
|
"Objects": [
|
||||||
|
{
|
||||||
|
"StartTime": 1824.0,
|
||||||
|
"EndTime": 1824.0,
|
||||||
|
"IsRim": false,
|
||||||
|
"IsCentre": true,
|
||||||
|
"IsDrumRoll": false,
|
||||||
|
"IsSwell": false,
|
||||||
|
"IsStrong": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"StartTime": 2252.0,
|
||||||
|
"Objects": [
|
||||||
|
{
|
||||||
|
"StartTime": 2252.0,
|
||||||
|
"EndTime": 2252.0,
|
||||||
|
"IsRim": true,
|
||||||
|
"IsCentre": false,
|
||||||
|
"IsDrumRoll": false,
|
||||||
|
"IsSwell": false,
|
||||||
|
"IsStrong": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"StartTime": 2681.0,
|
||||||
|
"Objects": [
|
||||||
|
{
|
||||||
|
"StartTime": 2681.0,
|
||||||
|
"EndTime": 2681.0,
|
||||||
|
"IsRim": true,
|
||||||
|
"IsCentre": false,
|
||||||
|
"IsDrumRoll": false,
|
||||||
|
"IsSwell": false,
|
||||||
|
"IsStrong": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"StartTime": 3110.0,
|
||||||
|
"Objects": [
|
||||||
|
{
|
||||||
|
"StartTime": 3110.0,
|
||||||
|
"EndTime": 3110.0,
|
||||||
|
"IsRim": true,
|
||||||
|
"IsCentre": false,
|
||||||
|
"IsDrumRoll": false,
|
||||||
|
"IsSwell": false,
|
||||||
|
"IsStrong": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
osu file format v14
|
||||||
|
|
||||||
|
[General]
|
||||||
|
AudioFilename: audio.mp3
|
||||||
|
AudioLeadIn: 0
|
||||||
|
PreviewTime: -1
|
||||||
|
Countdown: 0
|
||||||
|
SampleSet: Normal
|
||||||
|
StackLeniency: 0.5
|
||||||
|
Mode: 1
|
||||||
|
LetterboxInBreaks: 0
|
||||||
|
WidescreenStoryboard: 1
|
||||||
|
|
||||||
|
[Editor]
|
||||||
|
Bookmarks: 110,13824,54967,82395,109824
|
||||||
|
DistanceSpacing: 0.1
|
||||||
|
BeatDivisor: 4
|
||||||
|
GridSize: 32
|
||||||
|
TimelineZoom: 3.099999
|
||||||
|
|
||||||
|
[Metadata]
|
||||||
|
Title:test
|
||||||
|
TitleUnicode:test
|
||||||
|
Artist:sample conversion
|
||||||
|
ArtistUnicode:sample conversion
|
||||||
|
Creator:banchobot
|
||||||
|
Version:sample test
|
||||||
|
Source:
|
||||||
|
Tags:
|
||||||
|
BeatmapID:0
|
||||||
|
BeatmapSetID:-1
|
||||||
|
|
||||||
|
[Difficulty]
|
||||||
|
HPDrainRate:6
|
||||||
|
CircleSize:2
|
||||||
|
OverallDifficulty:6
|
||||||
|
ApproachRate:7
|
||||||
|
SliderMultiplier:1.4
|
||||||
|
SliderTickRate:4
|
||||||
|
|
||||||
|
[Events]
|
||||||
|
//Background and Video events
|
||||||
|
//Break Periods
|
||||||
|
//Storyboard Layer 0 (Background)
|
||||||
|
//Storyboard Layer 1 (Fail)
|
||||||
|
//Storyboard Layer 2 (Pass)
|
||||||
|
//Storyboard Layer 3 (Foreground)
|
||||||
|
//Storyboard Layer 4 (Overlay)
|
||||||
|
//Storyboard Sound Samples
|
||||||
|
|
||||||
|
[TimingPoints]
|
||||||
|
110,428.571428571429,4,1,0,100,1,0
|
||||||
|
|
||||||
|
[HitObjects]
|
||||||
|
256,192,110,5,0,0:0:0:0:
|
||||||
|
256,192,538,1,8,0:0:0:0:
|
||||||
|
256,192,967,1,2,0:0:0:0:
|
||||||
|
256,192,1395,1,10,0:0:0:0:
|
||||||
|
256,192,1824,1,4,0:0:0:0:
|
||||||
|
256,192,2252,1,12,0:0:0:0:
|
||||||
|
256,192,2681,1,6,0:0:0:0:
|
||||||
|
256,192,3110,1,14,0:0:0:0:
|
@ -17,6 +17,8 @@ namespace osu.Game.Rulesets.Taiko.Skinning
|
|||||||
{
|
{
|
||||||
public class LegacyTaikoScroller : CompositeDrawable
|
public class LegacyTaikoScroller : CompositeDrawable
|
||||||
{
|
{
|
||||||
|
public Bindable<JudgementResult> LastResult = new Bindable<JudgementResult>();
|
||||||
|
|
||||||
public LegacyTaikoScroller()
|
public LegacyTaikoScroller()
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
@ -50,37 +52,38 @@ namespace osu.Game.Rulesets.Taiko.Skinning
|
|||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bindable<JudgementResult> LastResult = new Bindable<JudgementResult>();
|
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
while (true)
|
// store X before checking wide enough so if we perform layout there is no positional discrepancy.
|
||||||
{
|
float currentX = (InternalChildren?.FirstOrDefault()?.X ?? 0) - (float)Clock.ElapsedFrameTime * 0.1f;
|
||||||
float? additiveX = null;
|
|
||||||
|
// ensure we have enough sprites
|
||||||
|
if (!InternalChildren.Any()
|
||||||
|
|| InternalChildren.First().ScreenSpaceDrawQuad.Width * InternalChildren.Count < ScreenSpaceDrawQuad.Width * 2)
|
||||||
|
AddInternal(new ScrollerSprite { Passing = passing });
|
||||||
|
|
||||||
|
var first = InternalChildren.First();
|
||||||
|
var last = InternalChildren.Last();
|
||||||
|
|
||||||
foreach (var sprite in InternalChildren)
|
foreach (var sprite in InternalChildren)
|
||||||
{
|
{
|
||||||
// add the x coordinates and perform re-layout on all sprites as spacing may change with gameplay scale.
|
// add the x coordinates and perform re-layout on all sprites as spacing may change with gameplay scale.
|
||||||
sprite.X = additiveX ??= sprite.X - (float)Time.Elapsed * 0.1f;
|
sprite.X = currentX;
|
||||||
|
currentX += sprite.DrawWidth;
|
||||||
additiveX += sprite.DrawWidth - 1;
|
|
||||||
|
|
||||||
if (sprite.X + sprite.DrawWidth < 0)
|
|
||||||
sprite.Expire();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var last = InternalChildren.LastOrDefault();
|
if (first.ScreenSpaceDrawQuad.TopLeft.X >= ScreenSpaceDrawQuad.TopLeft.X)
|
||||||
|
|
||||||
// only break from this loop once we have saturated horizontal space completely.
|
|
||||||
if (last != null && last.ScreenSpaceDrawQuad.TopRight.X >= ScreenSpaceDrawQuad.TopRight.X)
|
|
||||||
break;
|
|
||||||
|
|
||||||
AddInternal(new ScrollerSprite
|
|
||||||
{
|
{
|
||||||
Passing = passing
|
foreach (var internalChild in InternalChildren)
|
||||||
});
|
internalChild.X -= first.DrawWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last.ScreenSpaceDrawQuad.TopRight.X <= ScreenSpaceDrawQuad.TopRight.X)
|
||||||
|
{
|
||||||
|
foreach (var internalChild in InternalChildren)
|
||||||
|
internalChild.X += first.DrawWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
|
using osu.Game.Rulesets.Taiko.UI;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Skinning
|
namespace osu.Game.Rulesets.Taiko.Skinning
|
||||||
@ -86,11 +87,17 @@ namespace osu.Game.Rulesets.Taiko.Skinning
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
case TaikoSkinComponents.TaikoScroller:
|
case TaikoSkinComponents.Scroller:
|
||||||
if (GetTexture("taiko-slider") != null)
|
if (GetTexture("taiko-slider") != null)
|
||||||
return new LegacyTaikoScroller();
|
return new LegacyTaikoScroller();
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
case TaikoSkinComponents.Mascot:
|
||||||
|
if (GetTexture("pippidonclear0") != null)
|
||||||
|
return new DrawableTaikoMascot();
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return source.GetDrawableComponent(component);
|
return source.GetDrawableComponent(component);
|
||||||
|
@ -18,6 +18,7 @@ namespace osu.Game.Rulesets.Taiko
|
|||||||
TaikoExplosionMiss,
|
TaikoExplosionMiss,
|
||||||
TaikoExplosionGood,
|
TaikoExplosionGood,
|
||||||
TaikoExplosionGreat,
|
TaikoExplosionGreat,
|
||||||
TaikoScroller
|
Scroller,
|
||||||
|
Mascot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
123
osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs
Normal file
123
osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Taiko.Judgements;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.UI
|
||||||
|
{
|
||||||
|
public class DrawableTaikoMascot : BeatSyncedContainer
|
||||||
|
{
|
||||||
|
public readonly Bindable<TaikoMascotAnimationState> State;
|
||||||
|
public readonly Bindable<JudgementResult> LastResult;
|
||||||
|
|
||||||
|
private readonly Dictionary<TaikoMascotAnimationState, TaikoMascotAnimation> animations;
|
||||||
|
private TaikoMascotAnimation currentAnimation;
|
||||||
|
|
||||||
|
private bool lastObjectHit = true;
|
||||||
|
private bool kiaiMode;
|
||||||
|
|
||||||
|
public DrawableTaikoMascot(TaikoMascotAnimationState startingState = TaikoMascotAnimationState.Idle)
|
||||||
|
{
|
||||||
|
Origin = Anchor = Anchor.BottomLeft;
|
||||||
|
|
||||||
|
State = new Bindable<TaikoMascotAnimationState>(startingState);
|
||||||
|
LastResult = new Bindable<JudgementResult>();
|
||||||
|
|
||||||
|
animations = new Dictionary<TaikoMascotAnimationState, TaikoMascotAnimation>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader(true)]
|
||||||
|
private void load(TextureStore textures, GameplayBeatmap gameplayBeatmap)
|
||||||
|
{
|
||||||
|
InternalChildren = new[]
|
||||||
|
{
|
||||||
|
animations[TaikoMascotAnimationState.Idle] = new TaikoMascotAnimation(TaikoMascotAnimationState.Idle),
|
||||||
|
animations[TaikoMascotAnimationState.Clear] = new TaikoMascotAnimation(TaikoMascotAnimationState.Clear),
|
||||||
|
animations[TaikoMascotAnimationState.Kiai] = new TaikoMascotAnimation(TaikoMascotAnimationState.Kiai),
|
||||||
|
animations[TaikoMascotAnimationState.Fail] = new TaikoMascotAnimation(TaikoMascotAnimationState.Fail),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (gameplayBeatmap != null)
|
||||||
|
((IBindable<JudgementResult>)LastResult).BindTo(gameplayBeatmap.LastJudgementResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
animations.Values.ForEach(animation => animation.Hide());
|
||||||
|
|
||||||
|
State.BindValueChanged(mascotStateChanged, true);
|
||||||
|
LastResult.BindValueChanged(onNewResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onNewResult(ValueChangedEvent<JudgementResult> resultChangedEvent)
|
||||||
|
{
|
||||||
|
var result = resultChangedEvent.NewValue;
|
||||||
|
if (result == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: missing support for clear/fail state transition at end of beatmap gameplay
|
||||||
|
|
||||||
|
if (triggerComboClear(result) || triggerSwellClear(result))
|
||||||
|
{
|
||||||
|
State.Value = TaikoMascotAnimationState.Clear;
|
||||||
|
// always consider a clear equivalent to a hit to avoid clear -> miss transitions
|
||||||
|
lastObjectHit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result.Judgement.AffectsCombo)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lastObjectHit = result.IsHit;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||||
|
{
|
||||||
|
kiaiMode = effectPoint.KiaiMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
State.Value = getNextState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private TaikoMascotAnimationState getNextState()
|
||||||
|
{
|
||||||
|
// don't change state if current animation is still playing (and we haven't rewound before it).
|
||||||
|
// used for clear state - others are manually animated on new beats.
|
||||||
|
if (currentAnimation?.Completed == false && currentAnimation.DisplayTime <= Time.Current)
|
||||||
|
return State.Value;
|
||||||
|
|
||||||
|
if (!lastObjectHit)
|
||||||
|
return TaikoMascotAnimationState.Fail;
|
||||||
|
|
||||||
|
return kiaiMode ? TaikoMascotAnimationState.Kiai : TaikoMascotAnimationState.Idle;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mascotStateChanged(ValueChangedEvent<TaikoMascotAnimationState> state)
|
||||||
|
{
|
||||||
|
currentAnimation?.Hide();
|
||||||
|
currentAnimation = animations[state.NewValue];
|
||||||
|
currentAnimation.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool triggerComboClear(JudgementResult judgementResult)
|
||||||
|
=> (judgementResult.ComboAtJudgement + 1) % 50 == 0 && judgementResult.Judgement.AffectsCombo && judgementResult.IsHit;
|
||||||
|
|
||||||
|
private bool triggerSwellClear(JudgementResult judgementResult)
|
||||||
|
=> judgementResult.Judgement is TaikoSwellJudgement && judgementResult.IsHit;
|
||||||
|
}
|
||||||
|
}
|
@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
{
|
{
|
||||||
new BarLineGenerator<BarLine>(Beatmap).BarLines.ForEach(bar => Playfield.Add(bar.Major ? new DrawableBarLineMajor(bar) : new DrawableBarLine(bar)));
|
new BarLineGenerator<BarLine>(Beatmap).BarLines.ForEach(bar => Playfield.Add(bar.Major ? new DrawableBarLineMajor(bar) : new DrawableBarLine(bar)));
|
||||||
|
|
||||||
AddInternal(scroller = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.TaikoScroller), _ => Empty())
|
FrameStableComponents.Add(scroller = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Scroller), _ => Empty())
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Depth = float.MaxValue
|
Depth = float.MaxValue
|
||||||
|
@ -12,6 +12,7 @@ using osu.Framework.Input.Bindings;
|
|||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Taiko.Audio;
|
using osu.Game.Rulesets.Taiko.Audio;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.UI
|
namespace osu.Game.Rulesets.Taiko.UI
|
||||||
@ -145,6 +146,9 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
centreHit.Colour = colours.Pink;
|
centreHit.Colour = colours.Pink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Resolved(canBeNull: true)]
|
||||||
|
private GameplayClock gameplayClock { get; set; }
|
||||||
|
|
||||||
public bool OnPressed(TaikoAction action)
|
public bool OnPressed(TaikoAction action)
|
||||||
{
|
{
|
||||||
Drawable target = null;
|
Drawable target = null;
|
||||||
@ -157,6 +161,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
target = centreHit;
|
target = centreHit;
|
||||||
back = centre;
|
back = centre;
|
||||||
|
|
||||||
|
if (gameplayClock?.IsSeeking != true)
|
||||||
drumSample.Centre?.Play();
|
drumSample.Centre?.Play();
|
||||||
}
|
}
|
||||||
else if (action == RimAction)
|
else if (action == RimAction)
|
||||||
@ -164,6 +169,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
target = rimHit;
|
target = rimHit;
|
||||||
back = rim;
|
back = rim;
|
||||||
|
|
||||||
|
if (gameplayClock?.IsSeeking != true)
|
||||||
drumSample.Rim?.Play();
|
drumSample.Rim?.Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
133
osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs
Normal file
133
osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Animations;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.UI
|
||||||
|
{
|
||||||
|
public sealed class TaikoMascotAnimation : BeatSyncedContainer
|
||||||
|
{
|
||||||
|
private readonly TextureAnimation textureAnimation;
|
||||||
|
|
||||||
|
private int currentFrame;
|
||||||
|
|
||||||
|
public double DisplayTime;
|
||||||
|
|
||||||
|
public TaikoMascotAnimation(TaikoMascotAnimationState state)
|
||||||
|
{
|
||||||
|
InternalChild = textureAnimation = createTextureAnimation(state).With(animation =>
|
||||||
|
{
|
||||||
|
animation.Origin = animation.Anchor = Anchor.BottomLeft;
|
||||||
|
animation.Scale = new Vector2(0.51f); // close enough to stable
|
||||||
|
});
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
Origin = Anchor = Anchor.BottomLeft;
|
||||||
|
|
||||||
|
// needs to be always present to prevent the animation clock consuming time spent when not present.
|
||||||
|
AlwaysPresent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Completed => !textureAnimation.IsPlaying || textureAnimation.PlaybackPosition >= textureAnimation.Duration;
|
||||||
|
|
||||||
|
public override void Show()
|
||||||
|
{
|
||||||
|
base.Show();
|
||||||
|
DisplayTime = Time.Current;
|
||||||
|
textureAnimation.Seek(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||||
|
{
|
||||||
|
// assume that if the animation is playing on its own, it's independent from the beat and doesn't need to be touched.
|
||||||
|
if (textureAnimation.FrameCount == 0 || textureAnimation.IsPlaying)
|
||||||
|
return;
|
||||||
|
|
||||||
|
textureAnimation.GotoFrame(currentFrame);
|
||||||
|
currentFrame = (currentFrame + 1) % textureAnimation.FrameCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextureAnimation createTextureAnimation(TaikoMascotAnimationState state)
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case TaikoMascotAnimationState.Clear:
|
||||||
|
return new ClearMascotTextureAnimation();
|
||||||
|
|
||||||
|
case TaikoMascotAnimationState.Idle:
|
||||||
|
case TaikoMascotAnimationState.Kiai:
|
||||||
|
case TaikoMascotAnimationState.Fail:
|
||||||
|
return new ManualMascotTextureAnimation(state);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(state), $"Mascot animations for state {state} are not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ManualMascotTextureAnimation : TextureAnimation
|
||||||
|
{
|
||||||
|
private readonly TaikoMascotAnimationState state;
|
||||||
|
|
||||||
|
public ManualMascotTextureAnimation(TaikoMascotAnimationState state)
|
||||||
|
{
|
||||||
|
this.state = state;
|
||||||
|
|
||||||
|
IsPlaying = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(ISkinSource skin)
|
||||||
|
{
|
||||||
|
for (int frameIndex = 0; true; frameIndex++)
|
||||||
|
{
|
||||||
|
var texture = getAnimationFrame(skin, state, frameIndex);
|
||||||
|
|
||||||
|
if (texture == null)
|
||||||
|
break;
|
||||||
|
|
||||||
|
AddFrame(texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ClearMascotTextureAnimation : TextureAnimation
|
||||||
|
{
|
||||||
|
private const float clear_animation_speed = 1000 / 10f;
|
||||||
|
|
||||||
|
private static readonly int[] clear_animation_sequence = { 0, 1, 2, 3, 4, 5, 6, 5, 6, 5, 4, 3, 2, 1, 0 };
|
||||||
|
|
||||||
|
public ClearMascotTextureAnimation()
|
||||||
|
{
|
||||||
|
DefaultFrameLength = clear_animation_speed;
|
||||||
|
Loop = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(ISkinSource skin)
|
||||||
|
{
|
||||||
|
foreach (var frameIndex in clear_animation_sequence)
|
||||||
|
{
|
||||||
|
var texture = getAnimationFrame(skin, TaikoMascotAnimationState.Clear, frameIndex);
|
||||||
|
|
||||||
|
if (texture == null)
|
||||||
|
// as per https://osu.ppy.sh/help/wiki/Skinning/osu!taiko#pippidon
|
||||||
|
break;
|
||||||
|
|
||||||
|
AddFrame(texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Texture getAnimationFrame(ISkin skin, TaikoMascotAnimationState state, int frameIndex)
|
||||||
|
=> skin.GetTexture($"pippidon{state.ToString().ToLower()}{frameIndex}");
|
||||||
|
}
|
||||||
|
}
|
13
osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimationState.cs
Normal file
13
osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimationState.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// 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.Taiko.UI
|
||||||
|
{
|
||||||
|
public enum TaikoMascotAnimationState
|
||||||
|
{
|
||||||
|
Idle,
|
||||||
|
Clear,
|
||||||
|
Kiai,
|
||||||
|
Fail
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
|||||||
using osu.Game.Rulesets.Taiko.Judgements;
|
using osu.Game.Rulesets.Taiko.Judgements;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.UI
|
namespace osu.Game.Rulesets.Taiko.UI
|
||||||
{
|
{
|
||||||
@ -32,6 +33,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
private JudgementContainer<DrawableTaikoJudgement> judgementContainer;
|
private JudgementContainer<DrawableTaikoJudgement> judgementContainer;
|
||||||
private ScrollingHitObjectContainer drumRollHitContainer;
|
private ScrollingHitObjectContainer drumRollHitContainer;
|
||||||
internal Drawable HitTarget;
|
internal Drawable HitTarget;
|
||||||
|
private SkinnableDrawable mascot;
|
||||||
|
|
||||||
private ProxyContainer topLevelHitContainer;
|
private ProxyContainer topLevelHitContainer;
|
||||||
private ProxyContainer barlineContainer;
|
private ProxyContainer barlineContainer;
|
||||||
@ -125,12 +127,20 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
mascot = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Mascot), _ => Empty())
|
||||||
|
{
|
||||||
|
Origin = Anchor.BottomLeft,
|
||||||
|
Anchor = Anchor.TopLeft,
|
||||||
|
RelativePositionAxes = Axes.Y,
|
||||||
|
RelativeSizeAxes = Axes.None,
|
||||||
|
Y = 0.2f
|
||||||
|
},
|
||||||
topLevelHitContainer = new ProxyContainer
|
topLevelHitContainer = new ProxyContainer
|
||||||
{
|
{
|
||||||
Name = "Top level hit objects",
|
Name = "Top level hit objects",
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
drumRollHitContainer.CreateProxy()
|
drumRollHitContainer.CreateProxy(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +152,8 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
// This is basically allowing for correct alignment as relative pieces move around them.
|
// This is basically allowing for correct alignment as relative pieces move around them.
|
||||||
rightArea.Padding = new MarginPadding { Left = leftArea.DrawWidth };
|
rightArea.Padding = new MarginPadding { Left = leftArea.DrawWidth };
|
||||||
hitTargetOffsetContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 };
|
hitTargetOffsetContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 };
|
||||||
|
|
||||||
|
mascot.Scale = new Vector2(DrawHeight / DEFAULT_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Add(DrawableHitObject h)
|
public override void Add(DrawableHitObject h)
|
||||||
|
@ -13,18 +13,16 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
private const float default_relative_height = TaikoPlayfield.DEFAULT_HEIGHT / 768;
|
private const float default_relative_height = TaikoPlayfield.DEFAULT_HEIGHT / 768;
|
||||||
private const float default_aspect = 16f / 9f;
|
private const float default_aspect = 16f / 9f;
|
||||||
|
|
||||||
public TaikoPlayfieldAdjustmentContainer()
|
|
||||||
{
|
|
||||||
Anchor = Anchor.CentreLeft;
|
|
||||||
Origin = Anchor.CentreLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
float aspectAdjust = Math.Clamp(Parent.ChildSize.X / Parent.ChildSize.Y, 0.4f, 4) / default_aspect;
|
float aspectAdjust = Math.Clamp(Parent.ChildSize.X / Parent.ChildSize.Y, 0.4f, 4) / default_aspect;
|
||||||
Size = new Vector2(1, default_relative_height * aspectAdjust);
|
Size = new Vector2(1, default_relative_height * aspectAdjust);
|
||||||
|
|
||||||
|
// Position the taiko playfield exactly one playfield from the top of the screen.
|
||||||
|
RelativePositionAxes = Axes.Y;
|
||||||
|
Y = Size.Y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
@ -28,14 +29,15 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
private static IEnumerable<string> allBeatmaps => TestResources.GetStore().GetAvailableResources().Where(res => res.EndsWith(".osu"));
|
private static IEnumerable<string> allBeatmaps => TestResources.GetStore().GetAvailableResources().Where(res => res.EndsWith(".osu"));
|
||||||
|
|
||||||
[TestCaseSource(nameof(allBeatmaps))]
|
[TestCaseSource(nameof(allBeatmaps))]
|
||||||
public void TestBeatmap(string name)
|
public void TestEncodeDecodeStability(string name)
|
||||||
{
|
{
|
||||||
var decoded = decode(name, out var encoded);
|
var decoded = decodeFromLegacy(TestResources.GetStore().GetStream(name));
|
||||||
|
var decodedAfterEncode = decodeFromLegacy(encodeToLegacy(decoded));
|
||||||
|
|
||||||
sort(decoded);
|
sort(decoded);
|
||||||
sort(encoded);
|
sort(decodedAfterEncode);
|
||||||
|
|
||||||
Assert.That(encoded.Serialize(), Is.EqualTo(decoded.Serialize()));
|
Assert.That(decodedAfterEncode.Serialize(), Is.EqualTo(decoded.Serialize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sort(IBeatmap beatmap)
|
private void sort(IBeatmap beatmap)
|
||||||
@ -48,27 +50,22 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IBeatmap decode(string filename, out IBeatmap encoded)
|
private IBeatmap decodeFromLegacy(Stream stream)
|
||||||
{
|
{
|
||||||
using (var stream = TestResources.GetStore().GetStream(filename))
|
using (var reader = new LineBufferedReader(stream))
|
||||||
using (var sr = new LineBufferedReader(stream))
|
return convert(new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader));
|
||||||
{
|
|
||||||
var legacyDecoded = convert(new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(sr));
|
|
||||||
|
|
||||||
using (var ms = new MemoryStream())
|
|
||||||
using (var sw = new StreamWriter(ms))
|
|
||||||
using (var sr2 = new LineBufferedReader(ms, true))
|
|
||||||
{
|
|
||||||
new LegacyBeatmapEncoder(legacyDecoded).Encode(sw);
|
|
||||||
|
|
||||||
sw.Flush();
|
|
||||||
ms.Position = 0;
|
|
||||||
|
|
||||||
encoded = convert(new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(sr2));
|
|
||||||
|
|
||||||
return legacyDecoded;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Stream encodeToLegacy(IBeatmap beatmap)
|
||||||
|
{
|
||||||
|
var stream = new MemoryStream();
|
||||||
|
|
||||||
|
using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true))
|
||||||
|
new LegacyBeatmapEncoder(beatmap).Encode(writer);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IBeatmap convert(IBeatmap beatmap)
|
private IBeatmap convert(IBeatmap beatmap)
|
||||||
|
@ -26,7 +26,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
var storyboard = decoder.Decode(stream);
|
var storyboard = decoder.Decode(stream);
|
||||||
|
|
||||||
Assert.IsTrue(storyboard.HasDrawable);
|
Assert.IsTrue(storyboard.HasDrawable);
|
||||||
Assert.AreEqual(5, storyboard.Layers.Count());
|
Assert.AreEqual(6, storyboard.Layers.Count());
|
||||||
|
|
||||||
StoryboardLayer background = storyboard.Layers.FirstOrDefault(l => l.Depth == 3);
|
StoryboardLayer background = storyboard.Layers.FirstOrDefault(l => l.Depth == 3);
|
||||||
Assert.IsNotNull(background);
|
Assert.IsNotNull(background);
|
||||||
@ -56,6 +56,13 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
Assert.IsTrue(foreground.VisibleWhenPassing);
|
Assert.IsTrue(foreground.VisibleWhenPassing);
|
||||||
Assert.AreEqual("Foreground", foreground.Name);
|
Assert.AreEqual("Foreground", foreground.Name);
|
||||||
|
|
||||||
|
StoryboardLayer overlay = storyboard.Layers.FirstOrDefault(l => l.Depth == int.MinValue);
|
||||||
|
Assert.IsNotNull(overlay);
|
||||||
|
Assert.IsEmpty(overlay.Elements);
|
||||||
|
Assert.IsTrue(overlay.VisibleWhenFailing);
|
||||||
|
Assert.IsTrue(overlay.VisibleWhenPassing);
|
||||||
|
Assert.AreEqual("Overlay", overlay.Name);
|
||||||
|
|
||||||
int spriteCount = background.Elements.Count(x => x.GetType() == typeof(StoryboardSprite));
|
int spriteCount = background.Elements.Count(x => x.GetType() == typeof(StoryboardSprite));
|
||||||
int animationCount = background.Elements.Count(x => x.GetType() == typeof(StoryboardAnimation));
|
int animationCount = background.Elements.Count(x => x.GetType() == typeof(StoryboardAnimation));
|
||||||
int sampleCount = background.Elements.Count(x => x.GetType() == typeof(StoryboardSampleInfo));
|
int sampleCount = background.Elements.Count(x => x.GetType() == typeof(StoryboardSampleInfo));
|
||||||
|
@ -156,8 +156,8 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
var manager = osu.Dependencies.Get<BeatmapManager>();
|
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
|
|
||||||
// ReSharper disable once AccessToModifiedClosure
|
// ReSharper disable once AccessToModifiedClosure
|
||||||
manager.ItemAdded += _ => Interlocked.Increment(ref itemAddRemoveFireCount);
|
manager.ItemAdded.BindValueChanged(_ => Interlocked.Increment(ref itemAddRemoveFireCount));
|
||||||
manager.ItemRemoved += _ => Interlocked.Increment(ref itemAddRemoveFireCount);
|
manager.ItemRemoved.BindValueChanged(_ => Interlocked.Increment(ref itemAddRemoveFireCount));
|
||||||
|
|
||||||
var imported = await LoadOszIntoOsu(osu);
|
var imported = await LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
|
73
osu.Game.Tests/NonVisual/BarLineGeneratorTest.cs
Normal file
73
osu.Game.Tests/NonVisual/BarLineGeneratorTest.cs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Utils;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Beatmaps.Timing;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.NonVisual
|
||||||
|
{
|
||||||
|
public class BarLineGeneratorTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestRoundingErrorCompensation()
|
||||||
|
{
|
||||||
|
// The aim of this test is to make sure bar line generation compensates for floating-point errors.
|
||||||
|
// The premise of the test is that we have a single timing point that should result in bar lines
|
||||||
|
// that start at a time point that is a whole number every seventh beat.
|
||||||
|
|
||||||
|
// The fact it's every seventh beat is important - it's a number indivisible by 2, which makes
|
||||||
|
// it susceptible to rounding inaccuracies. In fact this was originally spotted in cases of maps
|
||||||
|
// that met exactly this criteria.
|
||||||
|
|
||||||
|
const int beat_length_numerator = 2000;
|
||||||
|
const int beat_length_denominator = 7;
|
||||||
|
const TimeSignatures signature = TimeSignatures.SimpleQuadruple;
|
||||||
|
|
||||||
|
var beatmap = new Beatmap
|
||||||
|
{
|
||||||
|
HitObjects = new List<HitObject>
|
||||||
|
{
|
||||||
|
new HitObject { StartTime = 0 },
|
||||||
|
new HitObject { StartTime = 120_000 }
|
||||||
|
},
|
||||||
|
ControlPointInfo = new ControlPointInfo()
|
||||||
|
};
|
||||||
|
|
||||||
|
beatmap.ControlPointInfo.Add(0, new TimingControlPoint
|
||||||
|
{
|
||||||
|
BeatLength = (double)beat_length_numerator / beat_length_denominator,
|
||||||
|
TimeSignature = signature
|
||||||
|
});
|
||||||
|
|
||||||
|
var barLines = new BarLineGenerator<BarLine>(beatmap).BarLines;
|
||||||
|
|
||||||
|
for (int i = 0; i * beat_length_denominator < barLines.Count; i++)
|
||||||
|
{
|
||||||
|
var barLine = barLines[i * beat_length_denominator];
|
||||||
|
var expectedTime = beat_length_numerator * (int)signature * i;
|
||||||
|
|
||||||
|
// every seventh bar's start time should be at least greater than the whole number we expect.
|
||||||
|
// It cannot be less, as that can affect overlapping scroll algorithms
|
||||||
|
// (the previous timing point might be chosen incorrectly if this is not the case)
|
||||||
|
Assert.GreaterOrEqual(barLine.StartTime, expectedTime);
|
||||||
|
|
||||||
|
// on the other side, make sure we don't stray too far from the expected time either.
|
||||||
|
Assert.IsTrue(Precision.AlmostEquals(barLine.StartTime, expectedTime));
|
||||||
|
|
||||||
|
// check major/minor lines for good measure too
|
||||||
|
Assert.AreEqual(i % (int)signature == 0, barLine.Major);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarLine : IBarLine
|
||||||
|
{
|
||||||
|
public double StartTime { get; set; }
|
||||||
|
public bool Major { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,14 +8,23 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.IO;
|
||||||
|
|
||||||
namespace osu.Game.Tests.NonVisual
|
namespace osu.Game.Tests.NonVisual
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class CustomDataDirectoryTest
|
public class CustomDataDirectoryTest
|
||||||
{
|
{
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
if (Directory.Exists(customPath))
|
||||||
|
Directory.Delete(customPath, true);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestDefaultDirectory()
|
public void TestDefaultDirectory()
|
||||||
{
|
{
|
||||||
@ -108,6 +117,163 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMigration()
|
||||||
|
{
|
||||||
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestMigration)))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var osu = loadOsu(host);
|
||||||
|
var storage = osu.Dependencies.Get<Storage>();
|
||||||
|
|
||||||
|
// ensure we perform a save
|
||||||
|
host.Dependencies.Get<FrameworkConfigManager>().Save();
|
||||||
|
|
||||||
|
// ensure we "use" cache
|
||||||
|
host.Storage.GetStorageForDirectory("cache");
|
||||||
|
|
||||||
|
// for testing nested files are not ignored (only top level)
|
||||||
|
host.Storage.GetStorageForDirectory("test-nested").GetStorageForDirectory("cache");
|
||||||
|
|
||||||
|
string defaultStorageLocation = Path.Combine(Environment.CurrentDirectory, "headless", nameof(TestMigration));
|
||||||
|
|
||||||
|
Assert.That(storage.GetFullPath("."), Is.EqualTo(defaultStorageLocation));
|
||||||
|
|
||||||
|
osu.Migrate(customPath);
|
||||||
|
|
||||||
|
Assert.That(storage.GetFullPath("."), Is.EqualTo(customPath));
|
||||||
|
|
||||||
|
// ensure cache was not moved
|
||||||
|
Assert.That(host.Storage.ExistsDirectory("cache"));
|
||||||
|
|
||||||
|
// ensure nested cache was moved
|
||||||
|
Assert.That(!host.Storage.ExistsDirectory(Path.Combine("test-nested", "cache")));
|
||||||
|
Assert.That(storage.ExistsDirectory(Path.Combine("test-nested", "cache")));
|
||||||
|
|
||||||
|
foreach (var file in OsuStorage.IGNORE_FILES)
|
||||||
|
{
|
||||||
|
Assert.That(host.Storage.Exists(file), Is.True);
|
||||||
|
Assert.That(storage.Exists(file), Is.False);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var dir in OsuStorage.IGNORE_DIRECTORIES)
|
||||||
|
{
|
||||||
|
Assert.That(host.Storage.ExistsDirectory(dir), Is.True);
|
||||||
|
Assert.That(storage.ExistsDirectory(dir), Is.False);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.That(new StreamReader(host.Storage.GetStream("storage.ini")).ReadToEnd().Contains($"FullPath = {customPath}"));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
host.Exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMigrationBetweenTwoTargets()
|
||||||
|
{
|
||||||
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestMigrationBetweenTwoTargets)))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var osu = loadOsu(host);
|
||||||
|
|
||||||
|
string customPath2 = $"{customPath}-2";
|
||||||
|
|
||||||
|
const string database_filename = "client.db";
|
||||||
|
|
||||||
|
Assert.DoesNotThrow(() => osu.Migrate(customPath));
|
||||||
|
Assert.That(File.Exists(Path.Combine(customPath, database_filename)));
|
||||||
|
|
||||||
|
Assert.DoesNotThrow(() => osu.Migrate(customPath2));
|
||||||
|
Assert.That(File.Exists(Path.Combine(customPath2, database_filename)));
|
||||||
|
|
||||||
|
Assert.DoesNotThrow(() => osu.Migrate(customPath));
|
||||||
|
Assert.That(File.Exists(Path.Combine(customPath, database_filename)));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
host.Exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMigrationToSameTargetFails()
|
||||||
|
{
|
||||||
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestMigrationToSameTargetFails)))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var osu = loadOsu(host);
|
||||||
|
|
||||||
|
Assert.DoesNotThrow(() => osu.Migrate(customPath));
|
||||||
|
Assert.Throws<ArgumentException>(() => osu.Migrate(customPath));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
host.Exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMigrationToNestedTargetFails()
|
||||||
|
{
|
||||||
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestMigrationToNestedTargetFails)))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var osu = loadOsu(host);
|
||||||
|
|
||||||
|
Assert.DoesNotThrow(() => osu.Migrate(customPath));
|
||||||
|
|
||||||
|
string subFolder = Path.Combine(customPath, "sub");
|
||||||
|
|
||||||
|
if (Directory.Exists(subFolder))
|
||||||
|
Directory.Delete(subFolder, true);
|
||||||
|
|
||||||
|
Directory.CreateDirectory(subFolder);
|
||||||
|
|
||||||
|
Assert.Throws<ArgumentException>(() => osu.Migrate(subFolder));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
host.Exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMigrationToSeeminglyNestedTarget()
|
||||||
|
{
|
||||||
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestMigrationToSeeminglyNestedTarget)))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var osu = loadOsu(host);
|
||||||
|
|
||||||
|
Assert.DoesNotThrow(() => osu.Migrate(customPath));
|
||||||
|
|
||||||
|
string seeminglySubFolder = customPath + "sub";
|
||||||
|
|
||||||
|
if (Directory.Exists(seeminglySubFolder))
|
||||||
|
Directory.Delete(seeminglySubFolder, true);
|
||||||
|
|
||||||
|
Directory.CreateDirectory(seeminglySubFolder);
|
||||||
|
|
||||||
|
osu.Migrate(seeminglySubFolder);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
host.Exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private OsuGameBase loadOsu(GameHost host)
|
private OsuGameBase loadOsu(GameHost host)
|
||||||
{
|
{
|
||||||
var osu = new OsuGameBase();
|
var osu = new OsuGameBase();
|
||||||
|
@ -29,8 +29,22 @@ namespace osu.Game.Tests.ScrollAlgorithms
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestDisplayStartTime()
|
public void TestDisplayStartTime()
|
||||||
{
|
{
|
||||||
// Sequential scroll algorithm approximates the start time
|
// easy cases - time range adjusted for velocity fits within control point duration
|
||||||
// This should be fixed in the future
|
Assert.AreEqual(2500, algorithm.GetDisplayStartTime(5000, 0, 2500, 1)); // 5000 - (2500 / 1)
|
||||||
|
Assert.AreEqual(13750, algorithm.GetDisplayStartTime(15000, 0, 2500, 1)); // 15000 - (2500 / 2)
|
||||||
|
Assert.AreEqual(20000, algorithm.GetDisplayStartTime(25000, 0, 2500, 1)); // 25000 - (2500 / 0.5)
|
||||||
|
|
||||||
|
// hard case - time range adjusted for velocity exceeds control point duration
|
||||||
|
|
||||||
|
// 1st multiplier point takes 10000 / 2500 = 4 scroll lengths
|
||||||
|
// 2nd multiplier point takes 10000 / (2500 / 2) = 8 scroll lengths
|
||||||
|
// 3rd multiplier point takes 2500 / (2500 * 2) = 0.5 scroll lengths up to hitobject start
|
||||||
|
|
||||||
|
// absolute position of the hitobject = 1000 * (4 + 8 + 0.5) = 12500
|
||||||
|
// minus one scroll length allowance = 12500 - 1000 = 11500 = 11.5 [scroll lengths]
|
||||||
|
// therefore the start time lies within the second multiplier point (because 11.5 < 4 + 8)
|
||||||
|
// its exact time position is = 10000 + 7.5 * (2500 / 2) = 19375
|
||||||
|
Assert.AreEqual(19375, algorithm.GetDisplayStartTime(22500, 0, 2500, 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -152,11 +152,12 @@ namespace osu.Game.Tests.Skins
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestSetBeatmapVersionNoFallback()
|
public void TestSetBeatmapVersionFallsBackToUserSkin()
|
||||||
{
|
{
|
||||||
|
// completely ignoring beatmap versions for simplicity.
|
||||||
AddStep("Set user skin version 2.3", () => userSource.Configuration.LegacyVersion = 2.3m);
|
AddStep("Set user skin version 2.3", () => userSource.Configuration.LegacyVersion = 2.3m);
|
||||||
AddStep("Set beatmap skin version null", () => beatmapSource.Configuration.LegacyVersion = 1.7m);
|
AddStep("Set beatmap skin version null", () => beatmapSource.Configuration.LegacyVersion = 1.7m);
|
||||||
AddAssert("Check legacy version lookup", () => requester.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value == 1.7m);
|
AddAssert("Check legacy version lookup", () => requester.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value == 2.3m);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -172,7 +173,6 @@ namespace osu.Game.Tests.Skins
|
|||||||
public void TestIniWithNoVersionFallsBackTo1()
|
public void TestIniWithNoVersionFallsBackTo1()
|
||||||
{
|
{
|
||||||
AddStep("Parse skin with no version", () => userSource.Configuration = new LegacySkinDecoder().Decode(new LineBufferedReader(new MemoryStream())));
|
AddStep("Parse skin with no version", () => userSource.Configuration = new LegacySkinDecoder().Decode(new LineBufferedReader(new MemoryStream())));
|
||||||
AddStep("Set beatmap skin version null", () => beatmapSource.Configuration.LegacyVersion = null);
|
|
||||||
AddAssert("Check legacy version lookup", () => requester.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value == 1.0m);
|
AddAssert("Check legacy version lookup", () => requester.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value == 1.0m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@ -39,15 +37,6 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneUserDimBackgrounds : OsuManualInputManagerTestScene
|
public class TestSceneUserDimBackgrounds : OsuManualInputManagerTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(ScreenWithBeatmapBackground),
|
|
||||||
typeof(PlayerLoader),
|
|
||||||
typeof(Player),
|
|
||||||
typeof(UserDimContainer),
|
|
||||||
typeof(OsuScreen)
|
|
||||||
};
|
|
||||||
|
|
||||||
private DummySongSelect songSelect;
|
private DummySongSelect songSelect;
|
||||||
private TestPlayerLoader playerLoader;
|
private TestPlayerLoader playerLoader;
|
||||||
private LoadBlockingTestPlayer player;
|
private LoadBlockingTestPlayer player;
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -18,7 +17,6 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
{
|
{
|
||||||
public class TestSceneBeatDivisorControl : OsuManualInputManagerTestScene
|
public class TestSceneBeatDivisorControl : OsuManualInputManagerTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(BindableBeatDivisor) };
|
|
||||||
private BeatDivisorControl beatDivisorControl;
|
private BeatDivisorControl beatDivisorControl;
|
||||||
private BindableBeatDivisor bindableBeatDivisor;
|
private BindableBeatDivisor bindableBeatDivisor;
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Screens.Edit.Components.RadioButtons;
|
using osu.Game.Screens.Edit.Components.RadioButtons;
|
||||||
@ -12,8 +10,6 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneEditorComposeRadioButtons : OsuTestScene
|
public class TestSceneEditorComposeRadioButtons : OsuTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(DrawableRadioButton) };
|
|
||||||
|
|
||||||
public TestSceneEditorComposeRadioButtons()
|
public TestSceneEditorComposeRadioButtons()
|
||||||
{
|
{
|
||||||
RadioButtonCollection collection;
|
RadioButtonCollection collection;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -15,8 +13,6 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneEditorMenuBar : OsuTestScene
|
public class TestSceneEditorMenuBar : OsuTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(EditorMenuBar), typeof(ScreenSelectionTabControl) };
|
|
||||||
|
|
||||||
public TestSceneEditorMenuBar()
|
public TestSceneEditorMenuBar()
|
||||||
{
|
{
|
||||||
Add(new Container
|
Add(new Container
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -15,8 +13,6 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneEditorSummaryTimeline : EditorClockTestScene
|
public class TestSceneEditorSummaryTimeline : EditorClockTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(SummaryTimeline) };
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using JetBrains.Annotations;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
@ -13,11 +11,8 @@ using osu.Game.Rulesets.Objects;
|
|||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Osu.Edit;
|
using osu.Game.Rulesets.Osu.Edit;
|
||||||
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles;
|
|
||||||
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components;
|
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
using osu.Game.Screens.Edit.Compose.Components;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Editing
|
namespace osu.Game.Tests.Visual.Editing
|
||||||
@ -25,19 +20,6 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneHitObjectComposer : EditorClockTestScene
|
public class TestSceneHitObjectComposer : EditorClockTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(SelectionHandler),
|
|
||||||
typeof(DragBox),
|
|
||||||
typeof(HitObjectComposer),
|
|
||||||
typeof(OsuHitObjectComposer),
|
|
||||||
typeof(BlueprintContainer),
|
|
||||||
typeof(NotNullAttribute),
|
|
||||||
typeof(HitCirclePiece),
|
|
||||||
typeof(HitCircleSelectionBlueprint),
|
|
||||||
typeof(HitCirclePlacementBlueprint),
|
|
||||||
};
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
||||||
@ -12,11 +10,6 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneTimelineBlueprintContainer : TimelineTestScene
|
public class TestSceneTimelineBlueprintContainer : TimelineTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(TimelineHitObjectBlueprint),
|
|
||||||
};
|
|
||||||
|
|
||||||
public override Drawable CreateTestComponent() => new TimelineBlueprintContainer();
|
public override Drawable CreateTestComponent() => new TimelineBlueprintContainer();
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||||
@ -14,18 +12,6 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneTimingScreen : EditorClockTestScene
|
public class TestSceneTimingScreen : EditorClockTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(ControlPointTable),
|
|
||||||
typeof(ControlPointSettings),
|
|
||||||
typeof(Section<>),
|
|
||||||
typeof(TimingSection),
|
|
||||||
typeof(EffectSection),
|
|
||||||
typeof(SampleSection),
|
|
||||||
typeof(DifficultySection),
|
|
||||||
typeof(RowAttribute)
|
|
||||||
};
|
|
||||||
|
|
||||||
[Cached(typeof(EditorBeatmap))]
|
[Cached(typeof(EditorBeatmap))]
|
||||||
private readonly EditorBeatmap editorBeatmap;
|
private readonly EditorBeatmap editorBeatmap;
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@ -22,14 +20,6 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
{
|
{
|
||||||
public abstract class TimelineTestScene : EditorClockTestScene
|
public abstract class TimelineTestScene : EditorClockTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(TimelineArea),
|
|
||||||
typeof(Timeline),
|
|
||||||
typeof(TimelineButton),
|
|
||||||
typeof(CentreMarker)
|
|
||||||
};
|
|
||||||
|
|
||||||
protected TimelineArea TimelineArea { get; private set; }
|
protected TimelineArea TimelineArea { get; private set; }
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@ -15,11 +14,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneBreakTracker : OsuTestScene
|
public class TestSceneBreakTracker : OsuTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(BreakOverlay),
|
|
||||||
};
|
|
||||||
|
|
||||||
private readonly BreakOverlay breakOverlay;
|
private readonly BreakOverlay breakOverlay;
|
||||||
|
|
||||||
private readonly TestBreakTracker breakTracker;
|
private readonly TestBreakTracker breakTracker;
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -18,13 +17,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
return new FailPlayer();
|
return new FailPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(TestSceneAllRulesetPlayers),
|
|
||||||
typeof(TestPlayer),
|
|
||||||
typeof(Player),
|
|
||||||
};
|
|
||||||
|
|
||||||
protected override void AddCheckSteps()
|
protected override void AddCheckSteps()
|
||||||
{
|
{
|
||||||
AddUntilStep("wait for fail", () => Player.HasFailed);
|
AddUntilStep("wait for fail", () => Player.HasFailed);
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
@ -20,8 +19,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Description("player pause/fail screens")]
|
[Description("player pause/fail screens")]
|
||||||
public class TestSceneGameplayMenuOverlay : OsuManualInputManagerTestScene
|
public class TestSceneGameplayMenuOverlay : OsuManualInputManagerTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(FailOverlay), typeof(PauseOverlay) };
|
|
||||||
|
|
||||||
private FailOverlay failOverlay;
|
private FailOverlay failOverlay;
|
||||||
private PauseOverlay pauseOverlay;
|
private PauseOverlay pauseOverlay;
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -22,13 +20,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
public class TestSceneHitErrorMeter : OsuTestScene
|
public class TestSceneHitErrorMeter : OsuTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(HitErrorMeter),
|
|
||||||
typeof(BarHitErrorMeter),
|
|
||||||
typeof(ColourHitErrorMeter)
|
|
||||||
};
|
|
||||||
|
|
||||||
private BarHitErrorMeter barMeter;
|
private BarHitErrorMeter barMeter;
|
||||||
private BarHitErrorMeter barMeter2;
|
private BarHitErrorMeter barMeter2;
|
||||||
private ColourHitErrorMeter colourMeter;
|
private ColourHitErrorMeter colourMeter;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -15,13 +13,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneKeyCounter : OsuManualInputManagerTestScene
|
public class TestSceneKeyCounter : OsuManualInputManagerTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(KeyCounterKeyboard),
|
|
||||||
typeof(KeyCounterMouse),
|
|
||||||
typeof(KeyCounterDisplay)
|
|
||||||
};
|
|
||||||
|
|
||||||
public TestSceneKeyCounter()
|
public TestSceneKeyCounter()
|
||||||
{
|
{
|
||||||
KeyCounterKeyboard testCounter;
|
KeyCounterKeyboard testCounter;
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.MedalSplash;
|
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
@ -13,12 +10,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneMedalOverlay : OsuTestScene
|
public class TestSceneMedalOverlay : OsuTestScene
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(MedalOverlay),
|
|
||||||
typeof(DrawableMedal),
|
|
||||||
};
|
|
||||||
|
|
||||||
public TestSceneMedalOverlay()
|
public TestSceneMedalOverlay()
|
||||||
{
|
{
|
||||||
AddStep(@"display", () =>
|
AddStep(@"display", () =>
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Game.Beatmaps.Timing;
|
using osu.Game.Beatmaps.Timing;
|
||||||
@ -15,11 +13,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
public class TestSceneNightcoreBeatContainer : TestSceneBeatSyncedContainer
|
public class TestSceneNightcoreBeatContainer : TestSceneBeatSyncedContainer
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(ModNightcore<>)
|
|
||||||
};
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
@ -33,7 +33,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
||||||
public new HUDOverlay HUDOverlay => base.HUDOverlay;
|
public new HUDOverlay HUDOverlay => base.HUDOverlay;
|
||||||
public new bool AllowFail => base.AllowFail;
|
|
||||||
|
public bool AllowFail => base.CheckModsAllowFailure();
|
||||||
|
|
||||||
protected override bool PauseOnFocusLost => false;
|
protected override bool PauseOnFocusLost => false;
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user