1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 12:53:11 +08:00

Merge branch 'master' into disable-unimplemented-mods

This commit is contained in:
Dean Herbert 2018-01-03 13:38:40 +09:00
commit b8fa33459a
10 changed files with 222 additions and 123 deletions

View File

@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Origin = Anchor.Centre; Origin = Anchor.Centre;
Position = HitObject.StackedPosition; Position = HitObject.StackedPosition;
Scale = new Vector2(HitObject.Scale); Scale = new Vector2(h.Scale);
Children = new Drawable[] Children = new Drawable[]
{ {

View File

@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{ {
public class DrawableSpinner : DrawableOsuHitObject public class DrawableSpinner : DrawableOsuHitObject
{ {
private readonly Spinner spinner; protected readonly Spinner Spinner;
public readonly SpinnerDisc Disc; public readonly SpinnerDisc Disc;
public readonly SpinnerTicks Ticks; public readonly SpinnerTicks Ticks;
@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
// we are slightly bigger than our parent, to clip the top and bottom of the circle // we are slightly bigger than our parent, to clip the top and bottom of the circle
Height = 1.3f; Height = 1.3f;
spinner = s; Spinner = s;
Children = new Drawable[] Children = new Drawable[]
{ {
@ -91,7 +91,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
}, },
Disc = new SpinnerDisc(spinner) Disc = new SpinnerDisc(Spinner)
{ {
Scale = Vector2.Zero, Scale = Vector2.Zero,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
@ -115,7 +115,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
}; };
} }
public float Progress => MathHelper.Clamp(Disc.RotationAbsolute / 360 / spinner.SpinsRequired, 0, 1); public float Progress => MathHelper.Clamp(Disc.RotationAbsolute / 360 / Spinner.SpinsRequired, 0, 1);
protected override void CheckForJudgements(bool userTriggered, double timeOffset) protected override void CheckForJudgements(bool userTriggered, double timeOffset)
{ {
@ -136,7 +136,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
glow.FadeColour(completeColour, duration); glow.FadeColour(completeColour, duration);
} }
if (!userTriggered && Time.Current >= spinner.EndTime) if (!userTriggered && Time.Current >= Spinner.EndTime)
{ {
if (Progress >= 1) if (Progress >= 1)
AddJudgement(new OsuJudgement { Result = HitResult.Great }); AddJudgement(new OsuJudgement { Result = HitResult.Great });
@ -144,7 +144,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
AddJudgement(new OsuJudgement { Result = HitResult.Good }); AddJudgement(new OsuJudgement { Result = HitResult.Good });
else if (Progress > .75) else if (Progress > .75)
AddJudgement(new OsuJudgement { Result = HitResult.Meh }); AddJudgement(new OsuJudgement { Result = HitResult.Meh });
else if (Time.Current >= spinner.EndTime) else if (Time.Current >= Spinner.EndTime)
AddJudgement(new OsuJudgement { Result = HitResult.Miss }); AddJudgement(new OsuJudgement { Result = HitResult.Miss });
} }
} }
@ -180,7 +180,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Ticks.Rotation = Disc.Rotation; Ticks.Rotation = Disc.Rotation;
spmCounter.SetRotation(Disc.RotationAbsolute); spmCounter.SetRotation(Disc.RotationAbsolute);
float relativeCircleScale = spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight; float relativeCircleScale = Spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight;
Disc.ScaleTo(relativeCircleScale + (1 - relativeCircleScale) * Progress, 200, Easing.OutQuint); Disc.ScaleTo(relativeCircleScale + (1 - relativeCircleScale) * Progress, 200, Easing.OutQuint);
symbol.RotateTo(Disc.Rotation / 2, 500, Easing.OutQuint); symbol.RotateTo(Disc.Rotation / 2, 500, Easing.OutQuint);
@ -190,22 +190,22 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{ {
base.UpdatePreemptState(); base.UpdatePreemptState();
circleContainer.ScaleTo(spinner.Scale * 0.3f); circleContainer.ScaleTo(Spinner.Scale * 0.3f);
circleContainer.ScaleTo(spinner.Scale, TIME_PREEMPT / 1.4f, Easing.OutQuint); circleContainer.ScaleTo(Spinner.Scale, TIME_PREEMPT / 1.4f, Easing.OutQuint);
Disc.RotateTo(-720); Disc.RotateTo(-720);
symbol.RotateTo(-720); symbol.RotateTo(-720);
mainContainer mainContainer
.ScaleTo(0) .ScaleTo(0)
.ScaleTo(spinner.Scale * circle.DrawHeight / DrawHeight * 1.4f, TIME_PREEMPT - 150, Easing.OutQuint) .ScaleTo(Spinner.Scale * circle.DrawHeight / DrawHeight * 1.4f, TIME_PREEMPT - 150, Easing.OutQuint)
.Then() .Then()
.ScaleTo(1, 500, Easing.OutQuint); .ScaleTo(1, 500, Easing.OutQuint);
} }
protected override void UpdateCurrentState(ArmedState state) protected override void UpdateCurrentState(ArmedState state)
{ {
var sequence = this.Delay(spinner.Duration).FadeOut(160); var sequence = this.Delay(Spinner.Duration).FadeOut(160);
switch (state) switch (state)
{ {

View File

@ -11,11 +11,13 @@ 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;
using OpenTK; using OpenTK;
using osu.Game.Rulesets.Osu.Mods;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Judgements;
using System.Collections.Generic; using System.Collections.Generic;
using System; using System;
using osu.Game.Rulesets.Mods;
using System.Linq;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Osu.Tests namespace osu.Game.Rulesets.Osu.Tests
{ {
@ -24,33 +26,34 @@ namespace osu.Game.Rulesets.Osu.Tests
{ {
public override IReadOnlyList<Type> RequiredTypes => new[] public override IReadOnlyList<Type> RequiredTypes => new[]
{ {
typeof(HitCircle),
typeof(OsuModHidden),
typeof(DrawableHitCircle) typeof(DrawableHitCircle)
}; };
private readonly Container content; private readonly Container content;
protected override Container<Drawable> Content => content; protected override Container<Drawable> Content => content;
private bool auto;
private bool hidden;
private int depthIndex; private int depthIndex;
private int circleSize; protected readonly List<Mod> Mods = new List<Mod>();
private float circleScale = 1;
public TestCaseHitCircle() public TestCaseHitCircle()
{ {
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 })); base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
AddStep("Single", () => testSingle()); AddStep("Miss Big Single", () => testSingle(2));
AddStep("Stream", testStream); AddStep("Miss Medium Single", () => testSingle(5));
AddToggleStep("Auto", v => auto = v); AddStep("Miss Small Single", () => testSingle(7));
AddToggleStep("Hidden", v => hidden = v); AddStep("Hit Big Single", () => testSingle(2, true));
AddSliderStep("CircleSize", 0, 10, 0, s => circleSize = s); AddStep("Hit Medium Single", () => testSingle(5, true));
AddSliderStep("CircleScale", 0.5f, 2, 1, s => circleScale = s); AddStep("Hit Small Single", () => testSingle(7, true));
AddStep("Miss Big Stream", () => testStream(2));
AddStep("Miss Medium Stream", () => testStream(5));
AddStep("Miss Small Stream", () => testStream(7));
AddStep("Hit Big Stream", () => testStream(2, true));
AddStep("Hit Medium Stream", () => testStream(5, true));
AddStep("Hit Small Stream", () => testStream(7, true));
} }
private void testSingle(double timeOffset = 0, Vector2? positionOffset = null) private void testSingle(float circleSize, bool auto = false, double timeOffset = 0, Vector2? positionOffset = null)
{ {
positionOffset = positionOffset ?? Vector2.Zero; positionOffset = positionOffset ?? Vector2.Zero;
@ -66,27 +69,23 @@ namespace osu.Game.Rulesets.Osu.Tests
var drawable = new TestDrawableHitCircle(circle, auto) var drawable = new TestDrawableHitCircle(circle, auto)
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Scale = new Vector2(circleScale),
Depth = depthIndex++ Depth = depthIndex++
}; };
if (auto) foreach (var mod in Mods.OfType<IApplicableToDrawableHitObjects>())
drawable.State.Value = ArmedState.Hit; mod.ApplyToDrawableHitObjects(new[] { drawable });
if (hidden)
new OsuModHidden().ApplyToDrawableHitObjects(new [] { drawable });
Add(drawable); Add(drawable);
} }
private void testStream() private void testStream(float circleSize, bool auto = false)
{ {
Vector2 pos = Vector2.Zero; Vector2 pos = new Vector2(-250, 0);
for (int i = 0; i <= 1000; i += 100) for (int i = 0; i <= 1000; i += 100)
{ {
testSingle(i, pos); testSingle(circleSize, auto, i, pos);
pos += new Vector2(10); pos.X += 50;
} }
} }
@ -103,12 +102,14 @@ namespace osu.Game.Rulesets.Osu.Tests
{ {
if (auto && !userTriggered && timeOffset > 0) if (auto && !userTriggered && timeOffset > 0)
{ {
// pretend we really hit it // force success
AddJudgement(new OsuJudgement AddJudgement(new OsuJudgement
{ {
Result = HitObject.ScoreResultForOffset(timeOffset) Result = HitResult.Great
}); });
State.Value = ArmedState.Hit;
} }
else
base.CheckForJudgements(userTriggered, timeOffset); base.CheckForJudgements(userTriggered, timeOffset);
} }
} }

View File

@ -0,0 +1,22 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Game.Rulesets.Osu.Mods;
namespace osu.Game.Rulesets.Osu.Tests
{
[Ignore("getting CI working")]
public class TestCaseHitCircleHidden : TestCaseHitCircle
{
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
public TestCaseHitCircleHidden()
{
Mods.Add(new OsuModHidden());
}
}
}

View File

@ -13,8 +13,10 @@ 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;
using OpenTK; using OpenTK;
using osu.Game.Rulesets.Osu.Mods;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Game.Rulesets.Mods;
using System.Linq;
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
namespace osu.Game.Rulesets.Osu.Tests namespace osu.Game.Rulesets.Osu.Tests
{ {
@ -23,70 +25,94 @@ namespace osu.Game.Rulesets.Osu.Tests
{ {
public override IReadOnlyList<Type> RequiredTypes => new[] public override IReadOnlyList<Type> RequiredTypes => new[]
{ {
typeof(Slider), typeof(SliderBall),
typeof(HitCircle), typeof(SliderBody),
typeof(OsuModHidden),
typeof(DrawableSlider), typeof(DrawableSlider),
typeof(DrawableHitCircle), typeof(DrawableRepeatPoint),
typeof(DrawableSliderTick), typeof(DrawableOsuHitObject)
typeof(DrawableRepeatPoint)
}; };
private readonly Container content; private readonly Container content;
protected override Container<Drawable> Content => content; protected override Container<Drawable> Content => content;
private bool hidden;
private int repeats;
private int depthIndex; private int depthIndex;
private int circleSize; protected readonly List<Mod> Mods = new List<Mod>();
private float circleScale = 1;
private double speedMultiplier = 2;
private double sliderMultiplier = 2;
public TestCaseSlider() public TestCaseSlider()
{ {
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 })); base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
AddStep("Single", () => testSingle()); AddStep("Big Single", () => testSimpleBig());
AddStep("Stream", testStream); AddStep("Medium Single", () => testSimpleMedium());
AddStep("Repeated", () => testRepeated(repeats)); AddStep("Small Single", () => testSimpleSmall());
AddToggleStep("Hidden", v => hidden = v); AddStep("Big 1 Repeat", () => testSimpleBig(1));
AddSliderStep("Repeats", 1, 10, 1, s => repeats = s); AddStep("Medium 1 Repeat", () => testSimpleMedium(1));
AddSliderStep("CircleSize", 0, 10, 0, s => circleSize = s); AddStep("Small 1 Repeat", () => testSimpleSmall(1));
AddSliderStep("CircleScale", 0.5f, 2, 1, s => circleScale = s); AddStep("Big 2 Repeats", () => testSimpleBig(2));
AddSliderStep("SpeedMultiplier", 0.1, 10, 2, s => speedMultiplier = s); AddStep("Medium 2 Repeats", () => testSimpleMedium(2));
AddSliderStep("SliderMultiplier", 0.1, 10, 2, s => sliderMultiplier = s); AddStep("Small 2 Repeats", () => testSimpleSmall(2));
AddStep("Slow Slider", testSlowSpeed); // slow long sliders take ages already so no repeat steps
AddStep("Slow Short Slider", () => testShortSlowSpeed());
AddStep("Slow Short Slider 1 Repeats", () => testShortSlowSpeed(1));
AddStep("Slow Short Slider 2 Repeats", () => testShortSlowSpeed(2));
AddStep("Fast Slider", () => testHighSpeed());
AddStep("Fast Slider 1 Repeat", () => testHighSpeed(1));
AddStep("Fast Slider 2 Repeats", () => testHighSpeed(2));
AddStep("Fast Short Slider", () => testShortHighSpeed());
AddStep("Fast Short Slider 1 Repeat", () => testShortHighSpeed(1));
AddStep("Fast Short Slider 2 Repeats", () => testShortHighSpeed(2));
AddStep("Perfect Curve", testCurve);
// TODO more curve types?
} }
private void testSingle(double timeOffset = 0, Vector2? positionOffset = null) private void testSimpleBig(int repeats = 0) => createSlider(2, repeats: repeats);
private void testSimpleMedium(int repeats = 0) => createSlider(5, repeats: repeats);
private void testSimpleSmall(int repeats = 0) => createSlider(7, repeats: repeats);
private void testSlowSpeed() => createSlider(speedMultiplier: 0.5);
private void testShortSlowSpeed(int repeats = 0) => createSlider(distance: 100, repeats: repeats, speedMultiplier: 0.5);
private void testHighSpeed(int repeats = 0) => createSlider(repeats: repeats, speedMultiplier: 15);
private void testShortHighSpeed(int repeats = 0) => createSlider(distance: 100, repeats: repeats, speedMultiplier: 15);
private void createSlider(float circleSize = 2, float distance = 400, int repeats = 0, double speedMultiplier = 2)
{ {
positionOffset = positionOffset ?? Vector2.Zero; repeats++; // The first run through the slider is considered a repeat
var repeatSamples = new List<List<SampleInfo>>();
if (repeats > 1)
{
for (int i = 0; i < repeats; i++)
repeatSamples.Add(new List<SampleInfo>());
}
var slider = new Slider var slider = new Slider
{ {
StartTime = Time.Current + 1000 + timeOffset, StartTime = Time.Current + 1000,
Position = new Vector2(-200, 0) + positionOffset.Value, Position = new Vector2(-(distance / 2), 0),
ComboColour = Color4.LightSeaGreen, ComboColour = Color4.LightSeaGreen,
ControlPoints = new List<Vector2> ControlPoints = new List<Vector2>
{ {
new Vector2(-200, 0) + positionOffset.Value, new Vector2(-(distance / 2), 0),
new Vector2(400, 0) + positionOffset.Value, new Vector2(distance / 2, 0),
}, },
Distance = 400 Distance = distance,
RepeatCount = repeats,
RepeatSamples = repeatSamples
}; };
addSlider(slider); addSlider(slider, circleSize, speedMultiplier);
} }
private void testRepeated(int repeats) private void testCurve()
{ {
// The first run through the slider is considered a repeat
repeats++;
var repeatSamples = new List<List<SampleInfo>>();
for (int i = 0; i < repeats; i++)
repeatSamples.Add(new List<SampleInfo>());
var slider = new Slider var slider = new Slider
{ {
StartTime = Time.Current + 1000, StartTime = Time.Current + 1000,
@ -95,52 +121,32 @@ namespace osu.Game.Rulesets.Osu.Tests
ControlPoints = new List<Vector2> ControlPoints = new List<Vector2>
{ {
new Vector2(-200, 0), new Vector2(-200, 0),
new Vector2(400, 0), new Vector2(0, 200),
new Vector2(200, 0)
}, },
Distance = 400, Distance = 600
RepeatCount = repeats,
RepeatSamples = repeatSamples
}; };
addSlider(slider); addSlider(slider, 2, 3);
} }
private void testStream() private void addSlider(Slider slider, float circleSize, double speedMultiplier)
{
Vector2 pos = Vector2.Zero;
for (int i = 0; i <= 1000; i += 100)
{
testSingle(i, pos);
pos += new Vector2(10);
}
}
private void addSlider(Slider slider)
{ {
var cpi = new ControlPointInfo(); var cpi = new ControlPointInfo();
cpi.DifficultyPoints.Add(new DifficultyControlPoint { SpeedMultiplier = speedMultiplier }); cpi.DifficultyPoints.Add(new DifficultyControlPoint { SpeedMultiplier = speedMultiplier });
var difficulty = new BeatmapDifficulty slider.ApplyDefaults(cpi, new BeatmapDifficulty { CircleSize = circleSize });
{
SliderMultiplier = (float)sliderMultiplier,
CircleSize = circleSize
};
slider.ApplyDefaults(cpi, difficulty);
var drawable = new DrawableSlider(slider) var drawable = new DrawableSlider(slider)
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Scale = new Vector2(circleScale),
Depth = depthIndex++ Depth = depthIndex++
}; };
if (hidden) foreach (var mod in Mods.OfType<IApplicableToDrawableHitObjects>())
new OsuModHidden().ApplyToDrawableHitObjects(new [] { drawable }); mod.ApplyToDrawableHitObjects(new[] { drawable });
Add(drawable); Add(drawable);
} }
} }
} }

View File

@ -0,0 +1,22 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Game.Rulesets.Osu.Mods;
namespace osu.Game.Rulesets.Osu.Tests
{
[Ignore("getting CI working")]
public class TestCaseSliderHidden : TestCaseSlider
{
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
public TestCaseSliderHidden()
{
Mods.Add(new OsuModHidden());
}
}
}

View File

@ -3,15 +3,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using OpenTK;
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.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
@ -21,46 +22,67 @@ namespace osu.Game.Rulesets.Osu.Tests
{ {
public override IReadOnlyList<Type> RequiredTypes => new[] public override IReadOnlyList<Type> RequiredTypes => new[]
{ {
typeof(Spinner), typeof(SpinnerDisc),
typeof(OsuModHidden), typeof(DrawableSpinner),
typeof(DrawableSpinner) typeof(DrawableOsuHitObject)
}; };
private readonly Container content; private readonly Container content;
protected override Container<Drawable> Content => content; protected override Container<Drawable> Content => content;
private bool hidden;
private int depthIndex; private int depthIndex;
private int circleSize; protected readonly List<Mod> Mods = new List<Mod>();
private float circleScale = 1;
public TestCaseSpinner() public TestCaseSpinner()
{ {
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 })); base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
AddStep("Single", testSingle); AddStep("Miss Big", () => testSingle(2));
AddToggleStep("Hidden", v => hidden = v); AddStep("Miss Medium", () => testSingle(5));
AddSliderStep("CircleSize", 0, 10, 0, s => circleSize = s); AddStep("Miss Small", () => testSingle(7));
AddSliderStep("CircleScale", 0.5f, 2, 1, s => circleScale = s); AddStep("Hit Big", () => testSingle(2, true));
AddStep("Hit Medium", () => testSingle(5, true));
AddStep("Hit Small", () => testSingle(7, true));
} }
private void testSingle() private void testSingle(float circleSize, bool auto = false)
{ {
var spinner = new Spinner { StartTime = Time.Current + 1000, EndTime = Time.Current + 4000 }; var spinner = new Spinner { StartTime = Time.Current + 1000, EndTime = Time.Current + 4000 };
spinner.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = circleSize }); spinner.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = circleSize });
var drawable = new DrawableSpinner(spinner) var drawable = new TestDrawableSpinner(spinner, auto)
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Scale = new Vector2(circleScale),
Depth = depthIndex++ Depth = depthIndex++
}; };
if (hidden) foreach (var mod in Mods.OfType<IApplicableToDrawableHitObjects>())
new OsuModHidden().ApplyToDrawableHitObjects(new [] { drawable }); mod.ApplyToDrawableHitObjects(new[] { drawable });
Add(drawable); Add(drawable);
} }
private class TestDrawableSpinner : DrawableSpinner
{
private bool auto;
public TestDrawableSpinner(Spinner s, bool auto) : base(s)
{
this.auto = auto;
}
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
{
if (auto && !userTriggered && Time.Current > Spinner.StartTime + Spinner.Duration / 2 && Progress < 1)
{
// force completion only once to not break human interaction
Disc.RotationAbsolute = Spinner.SpinsRequired * 360;
auto = false;
}
base.CheckForJudgements(userTriggered, timeOffset);
}
}
} }
} }

View File

@ -0,0 +1,22 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Game.Rulesets.Osu.Mods;
namespace osu.Game.Rulesets.Osu.Tests
{
[Ignore("getting CI working")]
public class TestCaseSpinnerHidden : TestCaseSpinner
{
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
public TestCaseSpinnerHidden()
{
Mods.Add(new OsuModHidden());
}
}
}

View File

@ -88,9 +88,12 @@
<Compile Include="OsuInputManager.cs" /> <Compile Include="OsuInputManager.cs" />
<Compile Include="Replays\OsuReplayInputHandler.cs" /> <Compile Include="Replays\OsuReplayInputHandler.cs" />
<Compile Include="Tests\TestCaseHitCircle.cs" /> <Compile Include="Tests\TestCaseHitCircle.cs" />
<Compile Include="Tests\TestCaseHitCircleHidden.cs" />
<Compile Include="Tests\TestCasePerformancePoints.cs" /> <Compile Include="Tests\TestCasePerformancePoints.cs" />
<Compile Include="Tests\TestCaseSlider.cs" /> <Compile Include="Tests\TestCaseSlider.cs" />
<Compile Include="Tests\TestCaseSliderHidden.cs" />
<Compile Include="Tests\TestCaseSpinner.cs" /> <Compile Include="Tests\TestCaseSpinner.cs" />
<Compile Include="Tests\TestCaseSpinnerHidden.cs" />
<Compile Include="UI\Cursor\CursorTrail.cs" /> <Compile Include="UI\Cursor\CursorTrail.cs" />
<Compile Include="UI\Cursor\GameplayCursor.cs" /> <Compile Include="UI\Cursor\GameplayCursor.cs" />
<Compile Include="UI\OsuSettings.cs" /> <Compile Include="UI\OsuSettings.cs" />

View File

@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Mods
} }
} }
public class ModAutoplay : Mod public class ModAutoplay : Mod, IApplicableFailOverride
{ {
public override string Name => "Autoplay"; public override string Name => "Autoplay";
public override string ShortenedName => "AT"; public override string ShortenedName => "AT";
@ -29,5 +29,6 @@ namespace osu.Game.Rulesets.Mods
public override string Description => "Watch a perfect automated play through the song"; public override string Description => "Watch a perfect automated play through the song";
public override double ScoreMultiplier => 0; public override double ScoreMultiplier => 0;
public override Type[] IncompatibleMods => new[] { typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail) }; public override Type[] IncompatibleMods => new[] { typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail) };
public bool AllowFail => false;
} }
} }