mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 14:03:21 +08:00
Merge branch 'master' into editor-timing-screen-change-handling
This commit is contained in:
commit
d3e1da5922
@ -52,6 +52,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.904.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.904.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.1001.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.1004.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -9,7 +9,7 @@ using osu.Framework.Android;
|
|||||||
|
|
||||||
namespace osu.Android
|
namespace osu.Android
|
||||||
{
|
{
|
||||||
[Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.FullSensor, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize, HardwareAccelerated = false)]
|
[Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.FullUser, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize, HardwareAccelerated = false)]
|
||||||
public class OsuGameActivity : AndroidGameActivity
|
public class OsuGameActivity : AndroidGameActivity
|
||||||
{
|
{
|
||||||
protected override Framework.Game CreateGame() => new OsuGameAndroid();
|
protected override Framework.Game CreateGame() => new OsuGameAndroid();
|
||||||
|
@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
if (!result.Type.AffectsCombo() || !result.HasResult)
|
if (!result.Type.AffectsCombo() || !result.HasResult)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (result.Type == HitResult.Miss)
|
if (!result.IsHit)
|
||||||
{
|
{
|
||||||
updateCombo(0, null);
|
updateCombo(0, null);
|
||||||
return;
|
return;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// 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.Linq;
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -13,7 +14,8 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
|
|||||||
{
|
{
|
||||||
public class TestSceneHoldNote : ManiaHitObjectTestScene
|
public class TestSceneHoldNote : ManiaHitObjectTestScene
|
||||||
{
|
{
|
||||||
public TestSceneHoldNote()
|
[Test]
|
||||||
|
public void TestHoldNote()
|
||||||
{
|
{
|
||||||
AddToggleStep("toggle hitting", v =>
|
AddToggleStep("toggle hitting", v =>
|
||||||
{
|
{
|
||||||
|
@ -28,25 +28,33 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneNotes : OsuTestScene
|
public class TestSceneNotes : OsuTestScene
|
||||||
{
|
{
|
||||||
[BackgroundDependencyLoader]
|
[Test]
|
||||||
private void load()
|
public void TestVariousNotes()
|
||||||
{
|
{
|
||||||
Child = new FillFlowContainer
|
DrawableNote note1 = null;
|
||||||
|
DrawableNote note2 = null;
|
||||||
|
DrawableHoldNote holdNote1 = null;
|
||||||
|
DrawableHoldNote holdNote2 = null;
|
||||||
|
|
||||||
|
AddStep("create notes", () =>
|
||||||
{
|
{
|
||||||
Clock = new FramedClock(new ManualClock()),
|
Child = new FillFlowContainer
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
AutoSizeAxes = Axes.Both,
|
|
||||||
Direction = FillDirection.Horizontal,
|
|
||||||
Spacing = new Vector2(20),
|
|
||||||
Children = new[]
|
|
||||||
{
|
{
|
||||||
createNoteDisplay(ScrollingDirection.Down, 1, out var note1),
|
Clock = new FramedClock(new ManualClock()),
|
||||||
createNoteDisplay(ScrollingDirection.Up, 2, out var note2),
|
Anchor = Anchor.Centre,
|
||||||
createHoldNoteDisplay(ScrollingDirection.Down, 1, out var holdNote1),
|
Origin = Anchor.Centre,
|
||||||
createHoldNoteDisplay(ScrollingDirection.Up, 2, out var holdNote2),
|
AutoSizeAxes = Axes.Both,
|
||||||
}
|
Direction = FillDirection.Horizontal,
|
||||||
};
|
Spacing = new Vector2(20),
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
createNoteDisplay(ScrollingDirection.Down, 1, out note1),
|
||||||
|
createNoteDisplay(ScrollingDirection.Up, 2, out note2),
|
||||||
|
createHoldNoteDisplay(ScrollingDirection.Down, 1, out holdNote1),
|
||||||
|
createHoldNoteDisplay(ScrollingDirection.Up, 2, out holdNote2),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
AddAssert("note 1 facing downwards", () => verifyAnchors(note1, Anchor.y2));
|
AddAssert("note 1 facing downwards", () => verifyAnchors(note1, Anchor.y2));
|
||||||
AddAssert("note 2 facing upwards", () => verifyAnchors(note2, Anchor.y0));
|
AddAssert("note 2 facing upwards", () => verifyAnchors(note2, Anchor.y0));
|
||||||
|
@ -2,10 +2,40 @@
|
|||||||
// 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 osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Judgements
|
namespace osu.Game.Rulesets.Mania.Judgements
|
||||||
{
|
{
|
||||||
public class ManiaJudgement : Judgement
|
public class ManiaJudgement : Judgement
|
||||||
{
|
{
|
||||||
|
protected override double HealthIncreaseFor(HitResult result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case HitResult.LargeTickHit:
|
||||||
|
return DEFAULT_MAX_HEALTH_INCREASE * 0.1;
|
||||||
|
|
||||||
|
case HitResult.LargeTickMiss:
|
||||||
|
return -DEFAULT_MAX_HEALTH_INCREASE * 0.1;
|
||||||
|
|
||||||
|
case HitResult.Meh:
|
||||||
|
return -DEFAULT_MAX_HEALTH_INCREASE * 0.5;
|
||||||
|
|
||||||
|
case HitResult.Ok:
|
||||||
|
return -DEFAULT_MAX_HEALTH_INCREASE * 0.3;
|
||||||
|
|
||||||
|
case HitResult.Good:
|
||||||
|
return DEFAULT_MAX_HEALTH_INCREASE * 0.1;
|
||||||
|
|
||||||
|
case HitResult.Great:
|
||||||
|
return DEFAULT_MAX_HEALTH_INCREASE * 0.8;
|
||||||
|
|
||||||
|
case HitResult.Perfect:
|
||||||
|
return DEFAULT_MAX_HEALTH_INCREASE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return base.HealthIncreaseFor(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,7 +243,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
endHold();
|
endHold();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tail.Result.Type == HitResult.Miss)
|
if (Tail.Judged && !Tail.IsHit)
|
||||||
HasBroken = true;
|
HasBroken = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
if (!userTriggered)
|
if (!userTriggered)
|
||||||
{
|
{
|
||||||
if (!HitObject.HitWindows.CanBeHit(timeOffset))
|
if (!HitObject.HitWindows.CanBeHit(timeOffset))
|
||||||
ApplyResult(r => r.Type = HitResult.Miss);
|
ApplyResult(r => r.Type = r.Judgement.MinResult);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||||
{
|
{
|
||||||
@ -136,7 +135,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Causes this <see cref="DrawableManiaHitObject"/> to get missed, disregarding all conditions in implementations of <see cref="DrawableHitObject.CheckForResult"/>.
|
/// Causes this <see cref="DrawableManiaHitObject"/> to get missed, disregarding all conditions in implementations of <see cref="DrawableHitObject.CheckForResult"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void MissForcefully() => ApplyResult(r => r.Type = HitResult.Miss);
|
public void MissForcefully() => ApplyResult(r => r.Type = r.Judgement.MinResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class DrawableManiaHitObject<TObject> : DrawableManiaHitObject
|
public abstract class DrawableManiaHitObject<TObject> : DrawableManiaHitObject
|
||||||
|
@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
if (!userTriggered)
|
if (!userTriggered)
|
||||||
{
|
{
|
||||||
if (!HitObject.HitWindows.CanBeHit(timeOffset))
|
if (!HitObject.HitWindows.CanBeHit(timeOffset))
|
||||||
ApplyResult(r => r.Type = HitResult.Miss);
|
ApplyResult(r => r.Type = r.Judgement.MinResult);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
private int depthIndex;
|
private int depthIndex;
|
||||||
|
|
||||||
public TestSceneHitCircle()
|
[Test]
|
||||||
|
public void TestVariousHitCircles()
|
||||||
{
|
{
|
||||||
AddStep("Miss Big Single", () => SetContents(() => testSingle(2)));
|
AddStep("Miss Big Single", () => SetContents(() => testSingle(2)));
|
||||||
AddStep("Miss Medium Single", () => SetContents(() => testSingle(5)));
|
AddStep("Miss Medium Single", () => SetContents(() => testSingle(5)));
|
||||||
|
@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
HitObjects = { new HitCircle { Position = new Vector2(256, 192) } }
|
HitObjects = { new HitCircle { Position = new Vector2(256, 192) } }
|
||||||
},
|
},
|
||||||
PassCondition = () => Player.Results.Count > 0 && Player.Results[0].TimeOffset < -hitWindows.WindowFor(HitResult.Meh) && Player.Results[0].Type == HitResult.Miss
|
PassCondition = () => Player.Results.Count > 0 && Player.Results[0].TimeOffset < -hitWindows.WindowFor(HitResult.Meh) && !Player.Results[0].IsHit
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
Autoplay = false,
|
Autoplay = false,
|
||||||
Beatmap = beatmap,
|
Beatmap = beatmap,
|
||||||
PassCondition = () => Player.Results.Count > 0 && Player.Results[0].TimeOffset >= hitWindows.WindowFor(HitResult.Meh) && Player.Results[0].Type == HitResult.Miss
|
PassCondition = () => Player.Results.Count > 0 && Player.Results[0].TimeOffset >= hitWindows.WindowFor(HitResult.Meh) && !Player.Results[0].IsHit
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
private int depthIndex;
|
private int depthIndex;
|
||||||
|
|
||||||
public TestSceneSlider()
|
[Test]
|
||||||
|
public void TestVariousSliders()
|
||||||
{
|
{
|
||||||
AddStep("Big Single", () => SetContents(() => testSimpleBig()));
|
AddStep("Big Single", () => SetContents(() => testSimpleBig()));
|
||||||
AddStep("Medium Single", () => SetContents(() => testSimpleMedium()));
|
AddStep("Medium Single", () => SetContents(() => testSimpleMedium()));
|
||||||
|
@ -314,11 +314,11 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
private bool assertMaxJudge() => judgementResults.Any() && judgementResults.All(t => t.Type == t.Judgement.MaxResult);
|
private bool assertMaxJudge() => judgementResults.Any() && judgementResults.All(t => t.Type == t.Judgement.MaxResult);
|
||||||
|
|
||||||
private bool assertHeadMissTailTracked() => judgementResults[^2].Type == HitResult.IgnoreHit && judgementResults.First().Type == HitResult.Miss;
|
private bool assertHeadMissTailTracked() => judgementResults[^2].Type == HitResult.SmallTickHit && !judgementResults.First().IsHit;
|
||||||
|
|
||||||
private bool assertMidSliderJudgements() => judgementResults[^2].Type == HitResult.IgnoreHit;
|
private bool assertMidSliderJudgements() => judgementResults[^2].Type == HitResult.SmallTickHit;
|
||||||
|
|
||||||
private bool assertMidSliderJudgementFail() => judgementResults[^2].Type == HitResult.IgnoreMiss;
|
private bool assertMidSliderJudgementFail() => judgementResults[^2].Type == HitResult.SmallTickMiss;
|
||||||
|
|
||||||
private ScoreAccessibleReplayPlayer currentPlayer;
|
private ScoreAccessibleReplayPlayer currentPlayer;
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
if (!userTriggered)
|
if (!userTriggered)
|
||||||
{
|
{
|
||||||
if (!HitObject.HitWindows.CanBeHit(timeOffset))
|
if (!HitObject.HitWindows.CanBeHit(timeOffset))
|
||||||
ApplyResult(r => r.Type = HitResult.Miss);
|
ApplyResult(r => r.Type = r.Judgement.MinResult);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
var circleResult = (OsuHitCircleJudgementResult)r;
|
var circleResult = (OsuHitCircleJudgementResult)r;
|
||||||
|
|
||||||
// Todo: This should also consider misses, but they're a little more interesting to handle, since we don't necessarily know the position at the time of a miss.
|
// Todo: This should also consider misses, but they're a little more interesting to handle, since we don't necessarily know the position at the time of a miss.
|
||||||
if (result != HitResult.Miss)
|
if (result.IsHit())
|
||||||
{
|
{
|
||||||
var localMousePosition = ToLocalSpace(inputManager.CurrentState.Mouse.Position);
|
var localMousePosition = ToLocalSpace(inputManager.CurrentState.Mouse.Position);
|
||||||
circleResult.CursorPositionAtHit = HitObject.StackedPosition + (localMousePosition - DrawSize / 2);
|
circleResult.CursorPositionAtHit = HitObject.StackedPosition + (localMousePosition - DrawSize / 2);
|
||||||
|
@ -8,7 +8,6 @@ using osu.Game.Rulesets.Judgements;
|
|||||||
using osu.Game.Rulesets.Osu.Judgements;
|
using osu.Game.Rulesets.Osu.Judgements;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||||
{
|
{
|
||||||
@ -68,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Causes this <see cref="DrawableOsuHitObject"/> to get missed, disregarding all conditions in implementations of <see cref="DrawableHitObject.CheckForResult"/>.
|
/// Causes this <see cref="DrawableOsuHitObject"/> to get missed, disregarding all conditions in implementations of <see cref="DrawableHitObject.CheckForResult"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void MissForcefully() => ApplyResult(r => r.Type = HitResult.Miss);
|
public void MissForcefully() => ApplyResult(r => r.Type = r.Judgement.MinResult);
|
||||||
|
|
||||||
protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(HitObject, judgement);
|
protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(HitObject, judgement);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ using osu.Game.Configuration;
|
|||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
@ -67,7 +66,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
if (JudgedObject != null)
|
if (JudgedObject != null)
|
||||||
{
|
{
|
||||||
lightingColour = JudgedObject.AccentColour.GetBoundCopy();
|
lightingColour = JudgedObject.AccentColour.GetBoundCopy();
|
||||||
lightingColour.BindValueChanged(colour => Lighting.Colour = Result.Type == HitResult.Miss ? Color4.Transparent : colour.NewValue, true);
|
lightingColour.BindValueChanged(colour => Lighting.Colour = Result.IsHit ? colour.NewValue : Color4.Transparent, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -13,7 +13,6 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Skinning;
|
using osu.Game.Rulesets.Osu.Skinning;
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
@ -250,7 +249,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
// rather than doing it this way, we should probably attach the sample to the tail circle.
|
// rather than doing it this way, we should probably attach the sample to the tail circle.
|
||||||
// this can only be done after we stop using LegacyLastTick.
|
// this can only be done after we stop using LegacyLastTick.
|
||||||
if (TailCircle.Result.Type != HitResult.Miss)
|
if (TailCircle.IsHit)
|
||||||
base.PlaySamples();
|
base.PlaySamples();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
else if (Progress > .75)
|
else if (Progress > .75)
|
||||||
r.Type = HitResult.Meh;
|
r.Type = HitResult.Meh;
|
||||||
else if (Time.Current >= Spinner.EndTime)
|
else if (Time.Current >= Spinner.EndTime)
|
||||||
r.Type = HitResult.Miss;
|
r.Type = r.Judgement.MinResult;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
private Spinner spinner;
|
private Spinner spinner;
|
||||||
|
|
||||||
|
private const float initial_scale = 1.3f;
|
||||||
private const float idle_alpha = 0.2f;
|
private const float idle_alpha = 0.2f;
|
||||||
private const float tracking_alpha = 0.4f;
|
private const float tracking_alpha = 0.4f;
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
// 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
|
||||||
// this should probably be revisited when scaled spinners are a thing.
|
// this should probably be revisited when scaled spinners are a thing.
|
||||||
Scale = new Vector2(1.3f);
|
Scale = new Vector2(initial_scale);
|
||||||
|
|
||||||
Anchor = Anchor.Centre;
|
Anchor = Anchor.Centre;
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
@ -117,8 +118,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
fill.Alpha = (float)Interpolation.Damp(fill.Alpha, drawableSpinner.RotationTracker.Tracking ? tracking_alpha : idle_alpha, 0.98f, (float)Math.Abs(Clock.ElapsedFrameTime));
|
fill.Alpha = (float)Interpolation.Damp(fill.Alpha, drawableSpinner.RotationTracker.Tracking ? tracking_alpha : idle_alpha, 0.98f, (float)Math.Abs(Clock.ElapsedFrameTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
const float initial_scale = 0.2f;
|
const float initial_fill_scale = 0.2f;
|
||||||
float targetScale = initial_scale + (1 - initial_scale) * drawableSpinner.Progress;
|
float targetScale = initial_fill_scale + (1 - initial_fill_scale) * drawableSpinner.Progress;
|
||||||
|
|
||||||
fill.Scale = new Vector2((float)Interpolation.Lerp(fill.Scale.X, targetScale, Math.Clamp(Math.Abs(Time.Elapsed) / 100, 0, 1)));
|
fill.Scale = new Vector2((float)Interpolation.Lerp(fill.Scale.X, targetScale, Math.Clamp(Math.Abs(Time.Elapsed) / 100, 0, 1)));
|
||||||
mainContainer.Rotation = drawableSpinner.RotationTracker.Rotation;
|
mainContainer.Rotation = drawableSpinner.RotationTracker.Rotation;
|
||||||
@ -129,41 +130,54 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
if (!(drawableHitObject is DrawableSpinner))
|
if (!(drawableHitObject is DrawableSpinner))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
centre.ScaleTo(0);
|
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt, true))
|
||||||
mainContainer.ScaleTo(0);
|
|
||||||
|
|
||||||
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt / 2, true))
|
|
||||||
{
|
{
|
||||||
// constant ambient rotation to give the spinner "spinning" character.
|
this.ScaleTo(initial_scale);
|
||||||
this.RotateTo((float)(25 * spinner.Duration / 2000), spinner.TimePreempt + spinner.Duration);
|
this.RotateTo(0);
|
||||||
|
|
||||||
centre.ScaleTo(0.3f, spinner.TimePreempt / 4, Easing.OutQuint);
|
|
||||||
mainContainer.ScaleTo(0.2f, spinner.TimePreempt / 4, Easing.OutQuint);
|
|
||||||
|
|
||||||
using (BeginDelayedSequence(spinner.TimePreempt / 2, true))
|
using (BeginDelayedSequence(spinner.TimePreempt / 2, true))
|
||||||
{
|
{
|
||||||
centre.ScaleTo(0.5f, spinner.TimePreempt / 2, Easing.OutQuint);
|
// constant ambient rotation to give the spinner "spinning" character.
|
||||||
mainContainer.ScaleTo(1, spinner.TimePreempt / 2, Easing.OutQuint);
|
this.RotateTo((float)(25 * spinner.Duration / 2000), spinner.TimePreempt + spinner.Duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
using (BeginDelayedSequence(spinner.TimePreempt + spinner.Duration + drawableHitObject.Result.TimeOffset, true))
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case ArmedState.Hit:
|
||||||
|
this.ScaleTo(initial_scale * 1.2f, 320, Easing.Out);
|
||||||
|
this.RotateTo(mainContainer.Rotation + 180, 320);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ArmedState.Miss:
|
||||||
|
this.ScaleTo(initial_scale * 0.8f, 320, Easing.In);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt, true))
|
||||||
|
{
|
||||||
|
centre.ScaleTo(0);
|
||||||
|
mainContainer.ScaleTo(0);
|
||||||
|
|
||||||
|
using (BeginDelayedSequence(spinner.TimePreempt / 2, true))
|
||||||
|
{
|
||||||
|
centre.ScaleTo(0.3f, spinner.TimePreempt / 4, Easing.OutQuint);
|
||||||
|
mainContainer.ScaleTo(0.2f, spinner.TimePreempt / 4, Easing.OutQuint);
|
||||||
|
|
||||||
|
using (BeginDelayedSequence(spinner.TimePreempt / 2, true))
|
||||||
|
{
|
||||||
|
centre.ScaleTo(0.5f, spinner.TimePreempt / 2, Easing.OutQuint);
|
||||||
|
mainContainer.ScaleTo(1, spinner.TimePreempt / 2, Easing.OutQuint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// transforms we have from completing the spinner will be rolled back, so reapply immediately.
|
// transforms we have from completing the spinner will be rolled back, so reapply immediately.
|
||||||
updateComplete(state == ArmedState.Hit, 0);
|
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt, true))
|
||||||
|
updateComplete(state == ArmedState.Hit, 0);
|
||||||
using (BeginDelayedSequence(spinner.Duration, true))
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case ArmedState.Hit:
|
|
||||||
this.ScaleTo(Scale * 1.2f, 320, Easing.Out);
|
|
||||||
this.RotateTo(mainContainer.Rotation + 180, 320);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ArmedState.Miss:
|
|
||||||
this.ScaleTo(Scale * 0.8f, 320, Easing.In);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateComplete(bool complete, double duration)
|
private void updateComplete(bool complete, double duration)
|
||||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
|
|
||||||
public class SliderTailJudgement : OsuJudgement
|
public class SliderTailJudgement : OsuJudgement
|
||||||
{
|
{
|
||||||
public override HitResult MaxResult => HitResult.IgnoreHit;
|
public override HitResult MaxResult => HitResult.SmallTickHit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,9 +70,7 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
this.FadeOut();
|
|
||||||
drawableSpinner.ApplyCustomUpdateState += updateStateTransforms;
|
drawableSpinner.ApplyCustomUpdateState += updateStateTransforms;
|
||||||
|
|
||||||
updateStateTransforms(drawableSpinner, drawableSpinner.State.Value);
|
updateStateTransforms(drawableSpinner, drawableSpinner.State.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,12 +81,19 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
|
|
||||||
var spinner = (Spinner)drawableSpinner.HitObject;
|
var spinner = (Spinner)drawableSpinner.HitObject;
|
||||||
|
|
||||||
|
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt, true))
|
||||||
|
this.FadeOut();
|
||||||
|
|
||||||
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimeFadeIn / 2, true))
|
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimeFadeIn / 2, true))
|
||||||
this.FadeInFromZero(spinner.TimeFadeIn / 2);
|
this.FadeInFromZero(spinner.TimeFadeIn / 2);
|
||||||
|
|
||||||
fixedMiddle.FadeColour(Color4.White);
|
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt, true))
|
||||||
using (BeginAbsoluteSequence(spinner.StartTime, true))
|
{
|
||||||
fixedMiddle.FadeColour(Color4.Red, spinner.Duration);
|
fixedMiddle.FadeColour(Color4.White);
|
||||||
|
|
||||||
|
using (BeginDelayedSequence(spinner.TimePreempt, true))
|
||||||
|
fixedMiddle.FadeColour(Color4.Red, spinner.Duration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
|
@ -88,9 +88,7 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
this.FadeOut();
|
|
||||||
drawableSpinner.ApplyCustomUpdateState += updateStateTransforms;
|
drawableSpinner.ApplyCustomUpdateState += updateStateTransforms;
|
||||||
|
|
||||||
updateStateTransforms(drawableSpinner, drawableSpinner.State.Value);
|
updateStateTransforms(drawableSpinner, drawableSpinner.State.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,6 +99,9 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
|
|
||||||
var spinner = drawableSpinner.HitObject;
|
var spinner = drawableSpinner.HitObject;
|
||||||
|
|
||||||
|
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt, true))
|
||||||
|
this.FadeOut();
|
||||||
|
|
||||||
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimeFadeIn / 2, true))
|
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimeFadeIn / 2, true))
|
||||||
this.FadeInFromZero(spinner.TimeFadeIn / 2);
|
this.FadeInFromZero(spinner.TimeFadeIn / 2);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -30,8 +29,8 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
|
|
||||||
private readonly Random rng = new Random(1337);
|
private readonly Random rng = new Random(1337);
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[Test]
|
||||||
private void load()
|
public void TestVariousHits()
|
||||||
{
|
{
|
||||||
AddStep("Hit", () => addHitJudgement(false));
|
AddStep("Hit", () => addHitJudgement(false));
|
||||||
AddStep("Strong hit", () => addStrongHitJudgement(false));
|
AddStep("Strong hit", () => addStrongHitJudgement(false));
|
||||||
|
@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Taiko.Judgements
|
|||||||
{
|
{
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
case HitResult.Great:
|
case HitResult.SmallTickHit:
|
||||||
return 0.15;
|
return 0.15;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -107,7 +107,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
if (!(obj is DrawableDrumRollTick))
|
if (!(obj is DrawableDrumRollTick))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (result.Type > HitResult.Miss)
|
if (result.IsHit)
|
||||||
rollingHits++;
|
rollingHits++;
|
||||||
else
|
else
|
||||||
rollingHits--;
|
rollingHits--;
|
||||||
@ -132,7 +132,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
ApplyResult(r => r.Type = countHit >= HitObject.RequiredGreatHits ? HitResult.Great : HitResult.Ok);
|
ApplyResult(r => r.Type = countHit >= HitObject.RequiredGreatHits ? HitResult.Great : HitResult.Ok);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ApplyResult(r => r.Type = HitResult.Miss);
|
ApplyResult(r => r.Type = r.Judgement.MinResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateStateTransforms(ArmedState state)
|
protected override void UpdateStateTransforms(ArmedState state)
|
||||||
|
@ -143,7 +143,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
if (!userTriggered)
|
if (!userTriggered)
|
||||||
{
|
{
|
||||||
if (!HitObject.HitWindows.CanBeHit(timeOffset))
|
if (!HitObject.HitWindows.CanBeHit(timeOffset))
|
||||||
ApplyResult(r => r.Type = HitResult.Miss);
|
ApplyResult(r => r.Type = r.Judgement.MinResult);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!validActionPressed)
|
if (!validActionPressed)
|
||||||
ApplyResult(r => r.Type = HitResult.Miss);
|
ApplyResult(r => r.Type = r.Judgement.MinResult);
|
||||||
else
|
else
|
||||||
ApplyResult(r => r.Type = result);
|
ApplyResult(r => r.Type = result);
|
||||||
}
|
}
|
||||||
|
@ -211,9 +211,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
tick.TriggerResult(false);
|
tick.TriggerResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
var hitResult = numHits > HitObject.RequiredHits / 2 ? HitResult.Ok : HitResult.Miss;
|
ApplyResult(r => r.Type = numHits > HitObject.RequiredHits / 2 ? HitResult.Ok : r.Judgement.MinResult);
|
||||||
|
|
||||||
ApplyResult(r => r.Type = hitResult);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
|||||||
private double hpMultiplier;
|
private double hpMultiplier;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// HP multiplier for a <see cref="HitResult.Miss"/>.
|
/// HP multiplier for a <see cref="HitResult"/> that does not satisfy <see cref="HitResultExtensions.IsHit"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private double hpMissMultiplier;
|
private double hpMissMultiplier;
|
||||||
|
|
||||||
@ -45,6 +45,6 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override double GetHealthIncreaseFor(JudgementResult result)
|
protected override double GetHealthIncreaseFor(JudgementResult result)
|
||||||
=> base.GetHealthIncreaseFor(result) * (result.Type == HitResult.Miss ? hpMissMultiplier : hpMultiplier);
|
=> base.GetHealthIncreaseFor(result) * (result.IsHit ? hpMultiplier : hpMissMultiplier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning
|
|||||||
if (r?.Type.AffectsCombo() == false)
|
if (r?.Type.AffectsCombo() == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
passing = r == null || r.Type > HitResult.Miss;
|
passing = r == null || r.IsHit;
|
||||||
|
|
||||||
foreach (var sprite in InternalChildren.OfType<ScrollerSprite>())
|
foreach (var sprite in InternalChildren.OfType<ScrollerSprite>())
|
||||||
sprite.Passing = passing;
|
sprite.Passing = passing;
|
||||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
Alpha = 0.15f;
|
Alpha = 0.15f;
|
||||||
Masking = true;
|
Masking = true;
|
||||||
|
|
||||||
if (result == HitResult.Miss)
|
if (!result.IsHit())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool isRim = (judgedObject.HitObject as Hit)?.Type == HitType.Rim;
|
bool isRim = (judgedObject.HitObject as Hit)?.Type == HitType.Rim;
|
||||||
|
@ -12,6 +12,14 @@ namespace osu.Game.Tests.Editing
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class EditorChangeHandlerTest
|
public class EditorChangeHandlerTest
|
||||||
{
|
{
|
||||||
|
private int stateChangedFired;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
stateChangedFired = 0;
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestSaveRestoreState()
|
public void TestSaveRestoreState()
|
||||||
{
|
{
|
||||||
@ -23,6 +31,8 @@ namespace osu.Game.Tests.Editing
|
|||||||
addArbitraryChange(beatmap);
|
addArbitraryChange(beatmap);
|
||||||
handler.SaveState();
|
handler.SaveState();
|
||||||
|
|
||||||
|
Assert.That(stateChangedFired, Is.EqualTo(1));
|
||||||
|
|
||||||
Assert.That(handler.CanUndo.Value, Is.True);
|
Assert.That(handler.CanUndo.Value, Is.True);
|
||||||
Assert.That(handler.CanRedo.Value, Is.False);
|
Assert.That(handler.CanRedo.Value, Is.False);
|
||||||
|
|
||||||
@ -30,6 +40,8 @@ namespace osu.Game.Tests.Editing
|
|||||||
|
|
||||||
Assert.That(handler.CanUndo.Value, Is.False);
|
Assert.That(handler.CanUndo.Value, Is.False);
|
||||||
Assert.That(handler.CanRedo.Value, Is.True);
|
Assert.That(handler.CanRedo.Value, Is.True);
|
||||||
|
|
||||||
|
Assert.That(stateChangedFired, Is.EqualTo(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -45,6 +57,7 @@ namespace osu.Game.Tests.Editing
|
|||||||
|
|
||||||
Assert.That(handler.CanUndo.Value, Is.True);
|
Assert.That(handler.CanUndo.Value, Is.True);
|
||||||
Assert.That(handler.CanRedo.Value, Is.False);
|
Assert.That(handler.CanRedo.Value, Is.False);
|
||||||
|
Assert.That(stateChangedFired, Is.EqualTo(1));
|
||||||
|
|
||||||
string hash = handler.CurrentStateHash;
|
string hash = handler.CurrentStateHash;
|
||||||
|
|
||||||
@ -52,6 +65,7 @@ namespace osu.Game.Tests.Editing
|
|||||||
handler.SaveState();
|
handler.SaveState();
|
||||||
|
|
||||||
Assert.That(hash, Is.EqualTo(handler.CurrentStateHash));
|
Assert.That(hash, Is.EqualTo(handler.CurrentStateHash));
|
||||||
|
Assert.That(stateChangedFired, Is.EqualTo(1));
|
||||||
|
|
||||||
handler.RestoreState(-1);
|
handler.RestoreState(-1);
|
||||||
|
|
||||||
@ -60,6 +74,7 @@ namespace osu.Game.Tests.Editing
|
|||||||
// we should only be able to restore once even though we saved twice.
|
// we should only be able to restore once even though we saved twice.
|
||||||
Assert.That(handler.CanUndo.Value, Is.False);
|
Assert.That(handler.CanUndo.Value, Is.False);
|
||||||
Assert.That(handler.CanRedo.Value, Is.True);
|
Assert.That(handler.CanRedo.Value, Is.True);
|
||||||
|
Assert.That(stateChangedFired, Is.EqualTo(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -71,6 +86,8 @@ namespace osu.Game.Tests.Editing
|
|||||||
|
|
||||||
for (int i = 0; i < EditorChangeHandler.MAX_SAVED_STATES; i++)
|
for (int i = 0; i < EditorChangeHandler.MAX_SAVED_STATES; i++)
|
||||||
{
|
{
|
||||||
|
Assert.That(stateChangedFired, Is.EqualTo(i));
|
||||||
|
|
||||||
addArbitraryChange(beatmap);
|
addArbitraryChange(beatmap);
|
||||||
handler.SaveState();
|
handler.SaveState();
|
||||||
}
|
}
|
||||||
@ -114,7 +131,10 @@ namespace osu.Game.Tests.Editing
|
|||||||
{
|
{
|
||||||
var beatmap = new EditorBeatmap(new Beatmap());
|
var beatmap = new EditorBeatmap(new Beatmap());
|
||||||
|
|
||||||
return (new EditorChangeHandler(beatmap), beatmap);
|
var changeHandler = new EditorChangeHandler(beatmap);
|
||||||
|
|
||||||
|
changeHandler.OnStateChange += () => stateChangedFired++;
|
||||||
|
return (changeHandler, beatmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addArbitraryChange(EditorBeatmap beatmap)
|
private void addArbitraryChange(EditorBeatmap beatmap)
|
||||||
|
39
osu.Game.Tests/NonVisual/GameplayClockTest.cs
Normal file
39
osu.Game.Tests/NonVisual/GameplayClockTest.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Timing;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.NonVisual
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class GameplayClockTest
|
||||||
|
{
|
||||||
|
[TestCase(0)]
|
||||||
|
[TestCase(1)]
|
||||||
|
public void TestTrueGameplayRateWithZeroAdjustment(double underlyingClockRate)
|
||||||
|
{
|
||||||
|
var framedClock = new FramedClock(new ManualClock { Rate = underlyingClockRate });
|
||||||
|
var gameplayClock = new TestGameplayClock(framedClock);
|
||||||
|
|
||||||
|
gameplayClock.MutableNonGameplayAdjustments.Add(new BindableDouble());
|
||||||
|
|
||||||
|
Assert.That(gameplayClock.TrueGameplayRate, Is.EqualTo(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestGameplayClock : GameplayClock
|
||||||
|
{
|
||||||
|
public List<Bindable<double>> MutableNonGameplayAdjustments { get; } = new List<Bindable<double>>();
|
||||||
|
|
||||||
|
public override IEnumerable<Bindable<double>> NonGameplayAdjustments => MutableNonGameplayAdjustments;
|
||||||
|
|
||||||
|
public TestGameplayClock(IFrameBasedClock underlyingClock)
|
||||||
|
: base(underlyingClock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,8 @@ using System;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
@ -22,6 +24,9 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
|
|
||||||
protected override bool EditorComponentsReady => Editor.ChildrenOfType<SetupScreen>().SingleOrDefault()?.IsLoaded == true;
|
protected override bool EditorComponentsReady => Editor.ChildrenOfType<SetupScreen>().SingleOrDefault()?.IsLoaded == true;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private BeatmapManager beatmapManager { get; set; }
|
||||||
|
|
||||||
public override void SetUpSteps()
|
public override void SetUpSteps()
|
||||||
{
|
{
|
||||||
AddStep("set dummy", () => Beatmap.Value = new DummyWorkingBeatmap(Audio, null));
|
AddStep("set dummy", () => Beatmap.Value = new DummyWorkingBeatmap(Audio, null));
|
||||||
@ -38,6 +43,15 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
{
|
{
|
||||||
AddStep("save beatmap", () => Editor.Save());
|
AddStep("save beatmap", () => Editor.Save());
|
||||||
AddAssert("new beatmap persisted", () => EditorBeatmap.BeatmapInfo.ID > 0);
|
AddAssert("new beatmap persisted", () => EditorBeatmap.BeatmapInfo.ID > 0);
|
||||||
|
AddAssert("new beatmap in database", () => beatmapManager.QueryBeatmapSet(s => s.ID == EditorBeatmap.BeatmapInfo.BeatmapSet.ID)?.DeletePending == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestExitWithoutSave()
|
||||||
|
{
|
||||||
|
AddStep("exit without save", () => Editor.Exit());
|
||||||
|
AddUntilStep("wait for exit", () => !Editor.IsCurrentScreen());
|
||||||
|
AddAssert("new beatmap not persisted", () => beatmapManager.QueryBeatmapSet(s => s.ID == EditorBeatmap.BeatmapInfo.BeatmapSet.ID)?.DeletePending == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -40,17 +40,28 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
Playfield.DisplayJudgements.Value = false;
|
Playfield.DisplayJudgements.Value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Resolved(canBeNull: true)]
|
||||||
|
private IEditorChangeHandler changeHandler { get; set; }
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
beatmap.HitObjectAdded += addHitObject;
|
beatmap.HitObjectAdded += addHitObject;
|
||||||
beatmap.HitObjectUpdated += updateReplay;
|
|
||||||
beatmap.HitObjectRemoved += removeHitObject;
|
beatmap.HitObjectRemoved += removeHitObject;
|
||||||
|
|
||||||
|
if (changeHandler != null)
|
||||||
|
{
|
||||||
|
// for now only regenerate replay on a finalised state change, not HitObjectUpdated.
|
||||||
|
changeHandler.OnStateChange += updateReplay;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
beatmap.HitObjectUpdated += _ => updateReplay();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateReplay(HitObject obj = null) =>
|
private void updateReplay() => drawableRuleset.RegenerateAutoplay();
|
||||||
drawableRuleset.RegenerateAutoplay();
|
|
||||||
|
|
||||||
private void addHitObject(HitObject hitObject)
|
private void addHitObject(HitObject hitObject)
|
||||||
{
|
{
|
||||||
@ -58,8 +69,6 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
|
|
||||||
drawableRuleset.Playfield.Add(drawableObject);
|
drawableRuleset.Playfield.Add(drawableObject);
|
||||||
drawableRuleset.Playfield.PostProcess();
|
drawableRuleset.Playfield.PostProcess();
|
||||||
|
|
||||||
updateReplay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeHitObject(HitObject hitObject)
|
private void removeHitObject(HitObject hitObject)
|
||||||
@ -68,8 +77,6 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
|
|
||||||
drawableRuleset.Playfield.Remove(drawableObject);
|
drawableRuleset.Playfield.Remove(drawableObject);
|
||||||
drawableRuleset.Playfield.PostProcess();
|
drawableRuleset.Playfield.PostProcess();
|
||||||
|
|
||||||
drawableRuleset.RegenerateAutoplay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool PropagatePositionalInputSubTree => false;
|
public override bool PropagatePositionalInputSubTree => false;
|
||||||
|
@ -109,40 +109,40 @@ namespace osu.Game.Rulesets.Judgements
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case HitResult.SmallTickHit:
|
case HitResult.SmallTickHit:
|
||||||
return DEFAULT_MAX_HEALTH_INCREASE * 0.05;
|
return DEFAULT_MAX_HEALTH_INCREASE * 0.5;
|
||||||
|
|
||||||
case HitResult.SmallTickMiss:
|
case HitResult.SmallTickMiss:
|
||||||
return -DEFAULT_MAX_HEALTH_INCREASE * 0.05;
|
return -DEFAULT_MAX_HEALTH_INCREASE * 0.5;
|
||||||
|
|
||||||
case HitResult.LargeTickHit:
|
case HitResult.LargeTickHit:
|
||||||
return DEFAULT_MAX_HEALTH_INCREASE * 0.1;
|
return DEFAULT_MAX_HEALTH_INCREASE;
|
||||||
|
|
||||||
case HitResult.LargeTickMiss:
|
case HitResult.LargeTickMiss:
|
||||||
return -DEFAULT_MAX_HEALTH_INCREASE * 0.1;
|
return -DEFAULT_MAX_HEALTH_INCREASE;
|
||||||
|
|
||||||
case HitResult.Miss:
|
case HitResult.Miss:
|
||||||
return -DEFAULT_MAX_HEALTH_INCREASE;
|
return -DEFAULT_MAX_HEALTH_INCREASE;
|
||||||
|
|
||||||
case HitResult.Meh:
|
case HitResult.Meh:
|
||||||
return -DEFAULT_MAX_HEALTH_INCREASE * 0.5;
|
return -DEFAULT_MAX_HEALTH_INCREASE * 0.05;
|
||||||
|
|
||||||
case HitResult.Ok:
|
case HitResult.Ok:
|
||||||
return -DEFAULT_MAX_HEALTH_INCREASE * 0.3;
|
return DEFAULT_MAX_HEALTH_INCREASE * 0.5;
|
||||||
|
|
||||||
case HitResult.Good:
|
case HitResult.Good:
|
||||||
return DEFAULT_MAX_HEALTH_INCREASE * 0.1;
|
return DEFAULT_MAX_HEALTH_INCREASE * 0.75;
|
||||||
|
|
||||||
case HitResult.Great:
|
case HitResult.Great:
|
||||||
return DEFAULT_MAX_HEALTH_INCREASE * 0.8;
|
|
||||||
|
|
||||||
case HitResult.Perfect:
|
|
||||||
return DEFAULT_MAX_HEALTH_INCREASE;
|
return DEFAULT_MAX_HEALTH_INCREASE;
|
||||||
|
|
||||||
|
case HitResult.Perfect:
|
||||||
|
return DEFAULT_MAX_HEALTH_INCREASE * 1.05;
|
||||||
|
|
||||||
case HitResult.SmallBonus:
|
case HitResult.SmallBonus:
|
||||||
return DEFAULT_MAX_HEALTH_INCREASE * 0.1;
|
return DEFAULT_MAX_HEALTH_INCREASE * 0.5;
|
||||||
|
|
||||||
case HitResult.LargeBonus:
|
case HitResult.LargeBonus:
|
||||||
return DEFAULT_MAX_HEALTH_INCREASE * 0.2;
|
return DEFAULT_MAX_HEALTH_INCREASE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,19 +506,8 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
|
|
||||||
Result.TimeOffset = Math.Min(HitObject.HitWindows.WindowFor(HitResult.Miss), Time.Current - endTime);
|
Result.TimeOffset = Math.Min(HitObject.HitWindows.WindowFor(HitResult.Miss), Time.Current - endTime);
|
||||||
|
|
||||||
switch (Result.Type)
|
if (Result.HasResult)
|
||||||
{
|
updateState(Result.IsHit ? ArmedState.Hit : ArmedState.Miss);
|
||||||
case HitResult.None:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HitResult.Miss:
|
|
||||||
updateState(ArmedState.Miss);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
updateState(ArmedState.Hit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
OnNewResult?.Invoke(this, Result);
|
OnNewResult?.Invoke(this, Result);
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,8 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
private DependencyContainer dependencies;
|
private DependencyContainer dependencies;
|
||||||
|
|
||||||
|
private bool isNewBeatmap;
|
||||||
|
|
||||||
protected override UserActivity InitialActivity => new UserActivity.Editing(Beatmap.Value.BeatmapInfo);
|
protected override UserActivity InitialActivity => new UserActivity.Editing(Beatmap.Value.BeatmapInfo);
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
@ -113,8 +115,6 @@ namespace osu.Game.Screens.Edit
|
|||||||
// todo: remove caching of this and consume via editorBeatmap?
|
// todo: remove caching of this and consume via editorBeatmap?
|
||||||
dependencies.Cache(beatDivisor);
|
dependencies.Cache(beatDivisor);
|
||||||
|
|
||||||
bool isNewBeatmap = false;
|
|
||||||
|
|
||||||
if (Beatmap.Value is DummyWorkingBeatmap)
|
if (Beatmap.Value is DummyWorkingBeatmap)
|
||||||
{
|
{
|
||||||
isNewBeatmap = true;
|
isNewBeatmap = true;
|
||||||
@ -287,6 +287,9 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
protected void Save()
|
protected void Save()
|
||||||
{
|
{
|
||||||
|
// no longer new after first user-triggered save.
|
||||||
|
isNewBeatmap = false;
|
||||||
|
|
||||||
// apply any set-level metadata changes.
|
// apply any set-level metadata changes.
|
||||||
beatmapManager.Update(playableBeatmap.BeatmapInfo.BeatmapSet);
|
beatmapManager.Update(playableBeatmap.BeatmapInfo.BeatmapSet);
|
||||||
|
|
||||||
@ -435,10 +438,20 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
public override bool OnExiting(IScreen next)
|
public override bool OnExiting(IScreen next)
|
||||||
{
|
{
|
||||||
if (!exitConfirmed && dialogOverlay != null && HasUnsavedChanges && !(dialogOverlay.CurrentDialog is PromptForSaveDialog))
|
if (!exitConfirmed)
|
||||||
{
|
{
|
||||||
dialogOverlay?.Push(new PromptForSaveDialog(confirmExit, confirmExitWithSave));
|
// if the confirm dialog is already showing (or we can't show it, ie. in tests) exit without save.
|
||||||
return true;
|
if (dialogOverlay == null || dialogOverlay.CurrentDialog is PromptForSaveDialog)
|
||||||
|
{
|
||||||
|
confirmExit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNewBeatmap || HasUnsavedChanges)
|
||||||
|
{
|
||||||
|
dialogOverlay?.Push(new PromptForSaveDialog(confirmExit, confirmExitWithSave));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Background.FadeColour(Color4.White, 500);
|
Background.FadeColour(Color4.White, 500);
|
||||||
@ -456,6 +469,12 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
private void confirmExit()
|
private void confirmExit()
|
||||||
{
|
{
|
||||||
|
if (isNewBeatmap)
|
||||||
|
{
|
||||||
|
// confirming exit without save means we should delete the new beatmap completely.
|
||||||
|
beatmapManager.Delete(playableBeatmap.BeatmapInfo.BeatmapSet);
|
||||||
|
}
|
||||||
|
|
||||||
exitConfirmed = true;
|
exitConfirmed = true;
|
||||||
this.Exit();
|
this.Exit();
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ namespace osu.Game.Screens.Edit
|
|||||||
public readonly Bindable<bool> CanUndo = new Bindable<bool>();
|
public readonly Bindable<bool> CanUndo = new Bindable<bool>();
|
||||||
public readonly Bindable<bool> CanRedo = new Bindable<bool>();
|
public readonly Bindable<bool> CanRedo = new Bindable<bool>();
|
||||||
|
|
||||||
|
public event Action OnStateChange;
|
||||||
|
|
||||||
private readonly LegacyEditorBeatmapPatcher patcher;
|
private readonly LegacyEditorBeatmapPatcher patcher;
|
||||||
private readonly List<byte[]> savedStates = new List<byte[]>();
|
private readonly List<byte[]> savedStates = new List<byte[]>();
|
||||||
|
|
||||||
@ -106,6 +108,8 @@ namespace osu.Game.Screens.Edit
|
|||||||
savedStates.Add(newState);
|
savedStates.Add(newState);
|
||||||
|
|
||||||
currentState = savedStates.Count - 1;
|
currentState = savedStates.Count - 1;
|
||||||
|
|
||||||
|
OnStateChange?.Invoke();
|
||||||
updateBindables();
|
updateBindables();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,6 +137,7 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
isRestoring = false;
|
isRestoring = false;
|
||||||
|
|
||||||
|
OnStateChange?.Invoke();
|
||||||
updateBindables();
|
updateBindables();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +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 osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit
|
namespace osu.Game.Screens.Edit
|
||||||
@ -10,6 +11,11 @@ namespace osu.Game.Screens.Edit
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IEditorChangeHandler
|
public interface IEditorChangeHandler
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Fired whenever a state change occurs.
|
||||||
|
/// </summary>
|
||||||
|
event Action OnStateChange;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Begins a bulk state change event. <see cref="EndChange"/> should be invoked soon after.
|
/// Begins a bulk state change event. <see cref="EndChange"/> should be invoked soon after.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -18,6 +18,8 @@ namespace osu.Game.Screens.Edit.Timing
|
|||||||
{
|
{
|
||||||
private LabelledTextBox textBox;
|
private LabelledTextBox textBox;
|
||||||
|
|
||||||
|
private TriangleButton button;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
protected Bindable<ControlPointGroup> SelectedGroup { get; private set; }
|
protected Bindable<ControlPointGroup> SelectedGroup { get; private set; }
|
||||||
|
|
||||||
@ -52,7 +54,7 @@ namespace osu.Game.Screens.Edit.Timing
|
|||||||
{
|
{
|
||||||
Label = "Time"
|
Label = "Time"
|
||||||
},
|
},
|
||||||
new TriangleButton
|
button = new TriangleButton
|
||||||
{
|
{
|
||||||
Text = "Use current time",
|
Text = "Use current time",
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
@ -82,18 +84,22 @@ namespace osu.Game.Screens.Edit.Timing
|
|||||||
if (group.NewValue == null)
|
if (group.NewValue == null)
|
||||||
{
|
{
|
||||||
textBox.Text = string.Empty;
|
textBox.Text = string.Empty;
|
||||||
|
|
||||||
textBox.Current.Disabled = true;
|
textBox.Current.Disabled = true;
|
||||||
|
button.Enabled.Value = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
textBox.Current.Disabled = false;
|
textBox.Current.Disabled = false;
|
||||||
|
button.Enabled.Value = true;
|
||||||
|
|
||||||
textBox.Text = $"{group.NewValue.Time:n0}";
|
textBox.Text = $"{group.NewValue.Time:n0}";
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeSelectedGroupTime(in double time)
|
private void changeSelectedGroupTime(in double time)
|
||||||
{
|
{
|
||||||
if (time == SelectedGroup.Value.Time)
|
if (SelectedGroup.Value == null || time == SelectedGroup.Value.Time)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
changeHandler?.BeginChange();
|
changeHandler?.BeginChange();
|
||||||
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
|
using osu.Framework.Utils;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play
|
namespace osu.Game.Screens.Play
|
||||||
{
|
{
|
||||||
@ -47,7 +48,12 @@ namespace osu.Game.Screens.Play
|
|||||||
double baseRate = Rate;
|
double baseRate = Rate;
|
||||||
|
|
||||||
foreach (var adjustment in NonGameplayAdjustments)
|
foreach (var adjustment in NonGameplayAdjustments)
|
||||||
|
{
|
||||||
|
if (Precision.AlmostEquals(adjustment.Value, 0))
|
||||||
|
return 0;
|
||||||
|
|
||||||
baseRate /= adjustment.Value;
|
baseRate /= adjustment.Value;
|
||||||
|
}
|
||||||
|
|
||||||
return baseRate;
|
return baseRate;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ using osuTK;
|
|||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play.HUD
|
namespace osu.Game.Screens.Play.HUD
|
||||||
{
|
{
|
||||||
@ -106,7 +105,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
|
|
||||||
public void Flash(JudgementResult result)
|
public void Flash(JudgementResult result)
|
||||||
{
|
{
|
||||||
if (result.Type == HitResult.Miss)
|
if (!result.IsHit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Scheduler.AddOnce(flash);
|
Scheduler.AddOnce(flash);
|
||||||
|
@ -48,7 +48,7 @@ namespace osu.Game.Screens.Ranking.Statistics
|
|||||||
/// <param name="hitEvents">The <see cref="HitEvent"/>s to display the timing distribution of.</param>
|
/// <param name="hitEvents">The <see cref="HitEvent"/>s to display the timing distribution of.</param>
|
||||||
public HitEventTimingDistributionGraph(IReadOnlyList<HitEvent> hitEvents)
|
public HitEventTimingDistributionGraph(IReadOnlyList<HitEvent> hitEvents)
|
||||||
{
|
{
|
||||||
this.hitEvents = hitEvents.Where(e => !(e.HitObject.HitWindows is HitWindows.EmptyHitWindows) && e.Result != HitResult.Miss).ToList();
|
this.hitEvents = hitEvents.Where(e => !(e.HitObject.HitWindows is HitWindows.EmptyHitWindows) && e.Result.IsHit()).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
|
@ -20,7 +20,7 @@ namespace osu.Game.Screens.Ranking.Statistics
|
|||||||
public UnstableRate(IEnumerable<HitEvent> hitEvents)
|
public UnstableRate(IEnumerable<HitEvent> hitEvents)
|
||||||
: base("Unstable Rate")
|
: base("Unstable Rate")
|
||||||
{
|
{
|
||||||
var timeOffsets = hitEvents.Where(e => !(e.HitObject.HitWindows is HitWindows.EmptyHitWindows) && e.Result != HitResult.Miss)
|
var timeOffsets = hitEvents.Where(e => !(e.HitObject.HitWindows is HitWindows.EmptyHitWindows) && e.Result.IsHit())
|
||||||
.Select(ev => ev.TimeOffset).ToArray();
|
.Select(ev => ev.TimeOffset).ToArray();
|
||||||
Value = 10 * standardDeviation(timeOffsets);
|
Value = 10 * standardDeviation(timeOffsets);
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2020.1001.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2020.1004.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.904.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.904.0" />
|
||||||
<PackageReference Include="Sentry" Version="2.1.6" />
|
<PackageReference Include="Sentry" Version="2.1.6" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.26.0" />
|
<PackageReference Include="SharpCompress" Version="0.26.0" />
|
||||||
|
@ -70,7 +70,7 @@
|
|||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.1001.0" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.1004.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.904.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.904.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. -->
|
<!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. -->
|
||||||
@ -80,7 +80,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2020.1001.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2020.1004.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.26.0" />
|
<PackageReference Include="SharpCompress" Version="0.26.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
|
Loading…
Reference in New Issue
Block a user